luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit a94046e17ae7f874de5e3b64686fef376aac7aa4
parent 66a97175590473fce07b6ce5f952ea8faa37abbf
Author: luajitos <bbhbb2094@gmail.com>
Date:   Sat,  6 Dec 2025 15:43:00 +0000

Changed crypto cli to base64

Diffstat:
Mcrypto/crypto.c | 85+++++++++++++++++++++++++++++--------------------------------------------------
Miso_includes/apps/com.luajitos.crypto/src/init.lua | 117++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 147 insertions(+), 55 deletions(-)

diff --git a/crypto/crypto.c b/crypto/crypto.c @@ -252,37 +252,14 @@ static const uint8_t* get_encrypted_from_arg(lua_State *L, int arg, size_t *len) } /* - * Get key from base64 or binary string + * Get key from binary string * Returns pointer to key data (valid until Lua string is collected) */ static const uint8_t* get_key_from_arg(lua_State *L, int arg, size_t *key_len) { size_t len; const char *key_str = luaL_checklstring(L, arg, &len); - - /* Check if it's base64 (longer than 32 bytes means it's likely base64) */ - if (len > 32) { - /* Assume base64 */ - size_t decoded_len; - uint8_t *decoded = base64_decode(key_str, len, &decoded_len); - if (!decoded || decoded_len != 32) { - if (decoded) free(decoded); - luaL_error(L, "Key must be 32 bytes (decoded from base64)"); - return NULL; - } - /* Store decoded key in Lua string on stack */ - lua_pushlstring(L, (const char*)decoded, 32); - lua_replace(L, arg); - free(decoded); - *key_len = 32; - return (const uint8_t*)lua_tolstring(L, arg, key_len); - } else if (len == 32) { - /* Binary key */ - *key_len = len; - return (const uint8_t*)key_str; - } else { - luaL_error(L, "Key must be 32 bytes"); - return NULL; - } + *key_len = len; + return (const uint8_t*)key_str; } /* generateKey() - Generate a random 32-byte key (returns binary string) */ @@ -365,8 +342,8 @@ static int l_decrypt(lua_State *L) { return 1; } -/* encryptString(key, plaintext) - Encrypt and return base64 string */ -static int l_encryptString(lua_State *L) { +/* encryptAsBase64(key, plaintext) - Encrypt and return base64 string */ +static int l_encryptAsBase64(lua_State *L) { size_t key_len; const uint8_t *key = get_key_from_arg(L, 1, &key_len); @@ -393,8 +370,8 @@ static int l_encryptString(lua_State *L) { return 1; } -/* decryptString(key, base64_encrypted) - Decrypt from base64 string */ -static int l_decryptString(lua_State *L) { +/* decryptFromBase64(key, base64_encrypted) - Decrypt from base64 string */ +static int l_decryptFromBase64(lua_State *L) { size_t key_len; const uint8_t *key = get_key_from_arg(L, 1, &key_len); @@ -1101,8 +1078,8 @@ static const luaL_Reg crypto_functions[] = { /* AES-256-GCM (default) */ {"encrypt", l_encrypt}, {"decrypt", l_decrypt}, - {"encryptString", l_encryptString}, - {"decryptString", l_decryptString}, + {"encryptAsBase64", l_encryptAsBase64}, + {"decryptFromBase64", l_decryptFromBase64}, /* ChaCha20-Poly1305 */ {"encryptChaCha", l_encryptChaCha}, @@ -1147,28 +1124,28 @@ int luaopen_crypto(lua_State *L) { /* Create module table */ luaL_newlib(L, crypto_functions); - /* Create AES subtable - crypto.AES.encrypt/encryptString/decrypt/decryptString (AES-256-GCM) */ + /* Create AES subtable - crypto.AES.encrypt/encryptAsBase64/decrypt/decryptFromBase64 (AES-256-GCM) */ lua_newtable(L); lua_pushcfunction(L, l_encrypt); lua_setfield(L, -2, "encrypt"); - lua_pushcfunction(L, l_encryptString); - lua_setfield(L, -2, "encryptString"); + lua_pushcfunction(L, l_encryptAsBase64); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decrypt); lua_setfield(L, -2, "decrypt"); - lua_pushcfunction(L, l_decryptString); - lua_setfield(L, -2, "decryptString"); + lua_pushcfunction(L, l_decryptFromBase64); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "AES"); - /* Create AES128 subtable - crypto.AES128.encrypt/encryptString/decrypt/decryptString (AES-128-GCM) */ + /* Create AES128 subtable - crypto.AES128.encrypt/encryptAsBase64/decrypt/decryptFromBase64 (AES-128-GCM) */ lua_newtable(L); lua_pushcfunction(L, l_encryptAES128); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptAES128String); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptAES128); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptAES128String); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "AES128"); /* Create ChaCha20 subtable */ @@ -1176,11 +1153,11 @@ int luaopen_crypto(lua_State *L) { lua_pushcfunction(L, l_encryptChaCha); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptChaChaString); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptChaCha); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptChaChaString); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "ChaCha20"); /* Create XChaCha20 subtable */ @@ -1188,11 +1165,11 @@ int luaopen_crypto(lua_State *L) { lua_pushcfunction(L, l_encryptXChaCha); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptXChaChaString); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptXChaCha); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptXChaChaString); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "XChaCha20"); /* Create Serpent subtable */ @@ -1200,11 +1177,11 @@ int luaopen_crypto(lua_State *L) { lua_pushcfunction(L, l_encryptSerpent); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptSerpentString); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptSerpent); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptSerpentString); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "Serpent"); /* Create Twofish subtable */ @@ -1212,11 +1189,11 @@ int luaopen_crypto(lua_State *L) { lua_pushcfunction(L, l_encryptTwofish); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptTwofishString); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptTwofish); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptTwofishString); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "Twofish"); /* Create Salsa20 subtable */ @@ -1224,11 +1201,11 @@ int luaopen_crypto(lua_State *L) { lua_pushcfunction(L, l_encryptSalsa); lua_setfield(L, -2, "encrypt"); lua_pushcfunction(L, l_encryptSalsaString); - lua_setfield(L, -2, "encryptString"); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decryptSalsa); lua_setfield(L, -2, "decrypt"); lua_pushcfunction(L, l_decryptSalsaString); - lua_setfield(L, -2, "decryptString"); + lua_setfield(L, -2, "decryptFromBase64"); lua_setfield(L, -2, "Salsa20"); /* Register hash functions directly on crypto table */ @@ -1400,12 +1377,12 @@ int luaopen_crypto(lua_State *L) { /* Keep default encrypt/decrypt at top level (AES) for convenience */ lua_pushcfunction(L, l_encrypt); lua_setfield(L, -2, "encrypt"); - lua_pushcfunction(L, l_encryptString); - lua_setfield(L, -2, "encryptString"); + lua_pushcfunction(L, l_encryptAsBase64); + lua_setfield(L, -2, "encryptAsBase64"); lua_pushcfunction(L, l_decrypt); lua_setfield(L, -2, "decrypt"); - lua_pushcfunction(L, l_decryptString); - lua_setfield(L, -2, "decryptString"); + lua_pushcfunction(L, l_decryptFromBase64); + lua_setfield(L, -2, "decryptFromBase64"); return 1; } diff --git a/iso_includes/apps/com.luajitos.crypto/src/init.lua b/iso_includes/apps/com.luajitos.crypto/src/init.lua @@ -124,6 +124,31 @@ local function fromHex(hex) return binary end +-- Helper function to detect and convert key from hex or base64 to binary +local function parseKey(keyStr) + if not keyStr then return nil, "No key provided" end + + -- Check if it looks like hex (only hex chars, even length) + local hexClean = keyStr:gsub("%s+", "") + if hexClean:match("^[0-9a-fA-F]+$") and #hexClean % 2 == 0 then + -- It's hex + return fromHex(hexClean) + end + + -- Check if it looks like base64 + local b64Clean = keyStr:gsub("%s+", "") + if b64Clean:match("^[A-Za-z0-9+/]+=*$") and #b64Clean % 4 == 0 then + -- It's base64 + local decoded = base64.decode(b64Clean) + if decoded then + return decoded + end + end + + -- Assume it's raw binary/text + return keyStr +end + -- Helper function to format output based on options local function formatOutput(data, options) if not data then return "nil" end @@ -230,12 +255,18 @@ if #args == 0 then print(" X25519.publicKey <privkey_hex> - Derive public key") print(" X25519.shared <privkey_hex> <pubkey_hex> - Compute shared secret") print("") + print("Encryption (key auto-detected as hex, base64, or raw):") + print(" encrypt <cipher> <key> <data>") + print(" decrypt <cipher> <key> <ciphertext>") + print(" Ciphers: AES-256-GCM, ChaCha20-Poly1305, Serpent-256-GCM,") + print(" Twofish-256-GCM, Salsa20-Poly1305") + print("") print("Random:") print(" random <bytes> - Generate random bytes") print(" newKey <bytes> - Generate cryptographic key") print("") print("Options:") - print(" -key/-k <value> - Specify key (hex encoded)") + print(" -key/-k <value> - Specify key (hex, base64, or raw)") print(" -salt/-s <value> - Specify salt") print(" -iterations/-i <num> - Number of iterations (default: 100000)") print(" -b64/-base64 - Output in base64 format (default: hex)") @@ -246,6 +277,8 @@ if #args == 0 then print(" crypto PBKDF2 \"mypassword\" -salt \"randomsalt\" -i 100000") print(" crypto Ed25519.keypair -b64") print(" crypto random 32 -b64") + print(" crypto encrypt AES-256-GCM <key-hex-or-b64> \"secret data\"") + print(" crypto decrypt AES-256-GCM <key-hex-or-b64> <ciphertext>") return end @@ -541,6 +574,88 @@ elseif command == "newKey" then print("Error: Failed to generate key") end +-- Encryption +elseif command == "encrypt" then + if #positional < 4 then + print("Error: encrypt requires cipher, key, and data arguments") + print("Usage: crypto encrypt <cipher> <key> <data>") + return + end + local cipher = positional[2] + local keyStr = positional[3] + local plaintext = positional[4] + + -- Auto-convert key from hex/base64 to binary + local key, err = parseKey(keyStr) + if not key then + print("Error: Invalid key: " .. (err or "unknown error")) + return + end + + -- Map cipher name to crypto function + local cipherFuncs = { + ["AES-256-GCM"] = crypto["AES-256-GCM"], + ["ChaCha20-Poly1305"] = crypto["ChaCha20-Poly1305"], + ["Serpent-256-GCM"] = crypto["Serpent-256-GCM"], + ["Twofish-256-GCM"] = crypto["Twofish-256-GCM"], + ["Salsa20-Poly1305"] = crypto["Salsa20-Poly1305"] + } + + local cipherMod = cipherFuncs[cipher] + if not cipherMod then + print("Error: Unknown cipher '" .. cipher .. "'") + print("Valid ciphers: AES-256-GCM, ChaCha20-Poly1305, Serpent-256-GCM, Twofish-256-GCM, Salsa20-Poly1305") + return + end + + local ciphertext, encErr = cipherMod.encryptAsBase64(plaintext, key) + if ciphertext then + print(ciphertext) + else + print("Error: Encryption failed: " .. (encErr or "unknown error")) + end + +-- Decryption +elseif command == "decrypt" then + if #positional < 4 then + print("Error: decrypt requires cipher, key, and ciphertext arguments") + print("Usage: crypto decrypt <cipher> <key> <ciphertext>") + return + end + local cipher = positional[2] + local keyStr = positional[3] + local ciphertext = positional[4] + + -- Auto-convert key from hex/base64 to binary + local key, err = parseKey(keyStr) + if not key then + print("Error: Invalid key: " .. (err or "unknown error")) + return + end + + -- Map cipher name to crypto function + local cipherFuncs = { + ["AES-256-GCM"] = crypto["AES-256-GCM"], + ["ChaCha20-Poly1305"] = crypto["ChaCha20-Poly1305"], + ["Serpent-256-GCM"] = crypto["Serpent-256-GCM"], + ["Twofish-256-GCM"] = crypto["Twofish-256-GCM"], + ["Salsa20-Poly1305"] = crypto["Salsa20-Poly1305"] + } + + local cipherMod = cipherFuncs[cipher] + if not cipherMod then + print("Error: Unknown cipher '" .. cipher .. "'") + print("Valid ciphers: AES-256-GCM, ChaCha20-Poly1305, Serpent-256-GCM, Twofish-256-GCM, Salsa20-Poly1305") + return + end + + local plaintext, decErr = cipherMod.decryptFromBase64(ciphertext, key) + if plaintext then + print(plaintext) + else + print("Error: Decryption failed: " .. (decErr or "unknown error")) + end + else print("Error: Unknown command '" .. command .. "'") print("Use 'crypto' without arguments for help")