e7e900973f
- lib/crypto/: 9-module crypto library (Hash, HMAC, Base64/URL, Random, AES, RSA, ECDSA, Ed25519, JWT) - rt/runtime.c: +346 lines OpenSSL crypto primitives (SHA-1/384/512, HMAC, Base64URL, AES-CBC/GCM, RSA, ECDSA, Ed25519) - apps/nexus/: multi-threaded HTTP/1.1 + HTTP/2 detect + WebSocket server - apps/jwt-pitbul/: JWT CLI tool (sign, verify, decode, keygen) - apps/boko-framework/: FastAPI-inspired async web framework - test_crypto/: crypto library test suite (23 tests)
68 lines
2.7 KiB
Plaintext
68 lines
2.7 KiB
Plaintext
// =============================================================================
|
|
// Std::Crypto::Aes — AES-256-CBC and AES-256-GCM encryption/decryption
|
|
// =============================================================================
|
|
module Std::Crypto::Aes {
|
|
|
|
import Std::Mem::{Alloc, Free};
|
|
import Std::String::{String_Len};
|
|
|
|
extern func bux_random_bytes(buf: *void, len: int) -> int;
|
|
extern func bux_aes_256_cbc_encrypt(plain: String, plainlen: int, key: String, iv: String, outlen: *int) -> String;
|
|
extern func bux_aes_256_cbc_decrypt(cipher: String, cipherlen: int, key: String, iv: String, outlen: *int) -> String;
|
|
extern func bux_aes_256_gcm_encrypt(plain: String, plainlen: int, key: String, iv: String, tag: *void, outlen: *int) -> String;
|
|
extern func bux_aes_256_gcm_decrypt(cipher: String, cipherlen: int, key: String, iv: String, tag: String, outlen: *int) -> String;
|
|
|
|
// --- AES-256-CBC ---
|
|
|
|
const AES_KEY_SIZE: int = 32; // 256 bits
|
|
const AES_IV_SIZE: int = 16; // 128 bits
|
|
const AES_GCM_TAG_SIZE: int = 16;
|
|
|
|
// Generate a random 256-bit AES key (returns raw 32 bytes)
|
|
func Aes_GenerateKey() -> String {
|
|
let buf: *void = Alloc(AES_KEY_SIZE as uint);
|
|
if bux_random_bytes(buf, AES_KEY_SIZE) != 1 {
|
|
Free(buf);
|
|
return "";
|
|
}
|
|
return buf as String;
|
|
}
|
|
|
|
// Generate a random 128-bit IV (returns raw 16 bytes)
|
|
func Aes_GenerateIV() -> String {
|
|
let buf: *void = Alloc(AES_IV_SIZE as uint);
|
|
if bux_random_bytes(buf, AES_IV_SIZE) != 1 {
|
|
Free(buf);
|
|
return "";
|
|
}
|
|
return buf as String;
|
|
}
|
|
|
|
// AES-256-CBC encrypt. plain and key are binary strings, iv is 16 bytes.
|
|
// Returns ciphertext (may be longer than plain due to PKCS#7 padding).
|
|
func Aes_CbcEncrypt(plain: String, key: String, iv: String) -> String {
|
|
let outlen: int = 0;
|
|
return bux_aes_256_cbc_encrypt(plain, String_Len(plain) as int, key, iv, &outlen);
|
|
}
|
|
|
|
// AES-256-CBC decrypt. Returns plaintext.
|
|
func Aes_CbcDecrypt(cipher: String, key: String, iv: String) -> String {
|
|
let outlen: int = 0;
|
|
return bux_aes_256_cbc_decrypt(cipher, String_Len(cipher) as int, key, iv, &outlen);
|
|
}
|
|
|
|
// --- AES-256-GCM (Authenticated Encryption) ---
|
|
|
|
// AES-256-GCM encrypt. Returns ciphertext. tag receives 16-byte authentication tag.
|
|
func Aes_GcmEncrypt(plain: String, key: String, iv: String, tag: *void) -> String {
|
|
let outlen: int = 0;
|
|
return bux_aes_256_gcm_encrypt(plain, String_Len(plain) as int, key, iv, tag, &outlen);
|
|
}
|
|
|
|
// AES-256-GCM decrypt. Returns plaintext. tag must be the 16-byte auth tag from encryption.
|
|
func Aes_GcmDecrypt(cipher: String, key: String, iv: String, tag: String) -> String {
|
|
let outlen: int = 0;
|
|
return bux_aes_256_gcm_decrypt(cipher, String_Len(cipher) as int, key, iv, tag, &outlen);
|
|
}
|
|
}
|