static int digest_reset(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); const EVP_MD *t = EVP_MD_CTX_md(c); if (!EVP_MD_CTX_cleanup(c)) { return crypto_error(L); } EVP_MD_CTX_init(c); if (!EVP_DigestInit_ex(c, t, NULL)) { return crypto_error(L); } return 0; }
static int rand_write(lua_State *L) { const char *name = luaL_optstring(L, 1, 0); char tmp[256]; int n; if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) return crypto_error(L); n = RAND_write_file(name); if (n == 0) return crypto_error(L); lua_pushnumber(L, n); return 1; }
static int sign_fsign(lua_State *L) { /* parameter 1 is the 'crypto.sign' table */ const char *type_name = luaL_checkstring(L, 2); const EVP_MD *type = EVP_get_digestbyname(type_name); if (type == NULL) { luaL_argerror(L, 2, "invalid digest type"); return 0; } else { EVP_MD_CTX c; size_t input_len = 0; const unsigned char *input = (unsigned char *) luaL_checklstring(L, 3, &input_len); unsigned int output_len = 0; unsigned char *buffer = NULL; EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 4, LUACRYPTO_PKEYNAME); EVP_MD_CTX_init(&c); EVP_SignInit_ex(&c, type, NULL); buffer = (unsigned char*)malloc((size_t)EVP_PKEY_size(*pkey)); EVP_SignUpdate(&c, input, input_len); if (!EVP_SignFinal(&c, buffer, &output_len, *pkey)) { EVP_MD_CTX_cleanup(&c); free(buffer); return crypto_error(L); } EVP_MD_CTX_cleanup(&c); lua_pushlstring(L, (char*) buffer, output_len); free(buffer); return 1; } }
static int verify_fverify(lua_State *L) { /* parameter 1 is the 'crypto.verify' table */ const char *type_name = luaL_checkstring(L, 2); const EVP_MD *type = EVP_get_digestbyname(type_name); if (type == NULL) { luaL_argerror(L, 1, "invalid digest type"); return 0; } else { EVP_MD_CTX c; size_t input_len = 0; const unsigned char *input = (unsigned char *) luaL_checklstring(L, 3, &input_len); size_t sig_len = 0; const unsigned char *sig = (unsigned char *) luaL_checklstring(L, 4, &sig_len); EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 5, LUACRYPTO_PKEYNAME); int ret; EVP_MD_CTX_init(&c); EVP_VerifyInit_ex(&c, type, NULL); EVP_VerifyUpdate(&c, input, input_len); ret = EVP_VerifyFinal(&c, sig, sig_len, *pkey); EVP_MD_CTX_cleanup(&c); if (ret == -1) return crypto_error(L); lua_pushboolean(L, ret); return 1; } }
static int encrypt_fencrypt(lua_State *L) { /* parameter 1 is the 'crypto.encrypt' table */ const EVP_CIPHER *type; size_t input_len = 0; const unsigned char *input = (unsigned char *) luaL_checklstring(L, 3, &input_len); size_t key_len = 0, iv_len = 0; const char *key = NULL, *iv = NULL; int pad = 0, size_to_return = 0; EVP_CIPHER_CTX c; int output_len = 0; int len = 0; unsigned char *buffer; if (!parse_f_enc_params(L, (EVP_CIPHER**)&type, (char**)&key, &key_len, (char**)&iv, &iv_len, &pad, &size_to_return)) { return size_to_return; } if (!init_encryptor_decryptor(EVP_EncryptInit_ex, L, &c, type, key, key_len, iv, iv_len, pad, &size_to_return)) { return size_to_return; } buffer = (unsigned char*)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(&c)); if (!EVP_EncryptUpdate(&c, buffer, &len, input, (int)input_len)) { EVP_CIPHER_CTX_cleanup(&c); free(buffer); return crypto_error(L); } output_len += len; if (!EVP_EncryptFinal_ex(&c, &buffer[output_len], &len)) { EVP_CIPHER_CTX_cleanup(&c); free(buffer); return crypto_error(L); } output_len += len; lua_pushlstring(L, (char*) buffer, (size_t)output_len); free(buffer); EVP_CIPHER_CTX_cleanup(&c); return 1; }
static int digest_gc(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); if (!EVP_MD_CTX_cleanup(c)) { return crypto_error(L); } return 1; }
static int decrypt_gc(lua_State *L) { EVP_CIPHER_CTX *c = (EVP_CIPHER_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DECRYPTNAME); if (!EVP_CIPHER_CTX_cleanup(c)) { return crypto_error(L); } return 1; }
static int rand_load(lua_State *L) { const char *name = luaL_optstring(L, 1, NULL); #if CRYPTO_OPENSSL char tmp[256]; int n; if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) return crypto_error(L); n = RAND_load_file(name, WRITE_FILE_COUNT); if (n == 0) return crypto_error(L); lua_pushnumber(L, n); #elif CRYPTO_GCRYPT if (name != NULL) gcry_control(GCRYCTL_SET_RANDOM_SEED_FILE, name); lua_pushnumber(L, 0.0); #endif return 1; }
static int digest_clone(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); EVP_MD_CTX *d = digest_pnew(L); EVP_MD_CTX_init(d); if (!EVP_MD_CTX_copy_ex(d, c)) { return crypto_error(L); } return 1; }
static int digest_fdigest(lua_State *L) { const char *type_name = luaL_checkstring(L, 2); const EVP_MD *type = EVP_get_digestbyname(type_name); const char *s = luaL_checkstring(L, 3); unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int written = 0; EVP_MD_CTX *c; if (type == NULL) { luaL_argerror(L, 1, "invalid digest type"); return 0; } c = EVP_MD_CTX_create(); if (!EVP_DigestInit_ex(c, type, NULL)) { EVP_MD_CTX_destroy(c); return crypto_error(L); } if (!EVP_DigestUpdate(c, s, lua_strlen(L, 3))) { EVP_MD_CTX_destroy(c); return crypto_error(L); } if (!EVP_DigestFinal_ex(c, digest, &written)) { EVP_MD_CTX_destroy(c); return crypto_error(L); } EVP_MD_CTX_destroy(c); if (lua_toboolean(L, 4)) lua_pushlstring(L, (char *)digest, written); else { char *hex = (char*)calloc(sizeof(char), written*2 + 1); unsigned int i; for (i = 0; i < written; i++) sprintf(hex + 2*i, "%02x", digest[i]); lua_pushlstring(L, hex, written*2); free(hex); } return 1; }
static int digest_update(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); const char *s = luaL_checkstring(L, 2); if (!EVP_DigestUpdate(c, s, lua_strlen(L, 2))) { return crypto_error(L); } lua_settop(L, 1); return 1; }
static int decrypt_final(lua_State *L) { EVP_CIPHER_CTX *c = (EVP_CIPHER_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DECRYPTNAME); int output_len = 0; unsigned char buffer[EVP_MAX_BLOCK_LENGTH]; if (!EVP_DecryptFinal_ex(c, buffer, &output_len)) { return crypto_error(L); } lua_pushlstring(L, (char*) buffer, (size_t)output_len); return 1; }
static int digest_final(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); EVP_MD_CTX *d = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int written = 0; unsigned int i; char *hex; if (lua_isstring(L, 2)) { const char *s = luaL_checkstring(L, 2); if(!EVP_DigestUpdate(c, s, lua_strlen(L, 2))) { return crypto_error(L); } } d = EVP_MD_CTX_create(); if (!EVP_MD_CTX_copy_ex(d, c)) { return crypto_error(L); } if (!EVP_DigestFinal_ex(d, digest, &written)) { return crypto_error(L); } EVP_MD_CTX_destroy(d); if (lua_toboolean(L, 3)) lua_pushlstring(L, (char *)digest, written); else { hex = (char*)calloc(sizeof(char), written*2 + 1); for (i = 0; i < written; i++) sprintf(hex + 2*i, "%02x", digest[i]); lua_pushlstring(L, hex, written*2); free(hex); } return 1; }
static int rand_do_bytes(lua_State *L, int (*bytes)(unsigned char *, int)) { size_t count = luaL_checkint(L, 1); unsigned char tmp[256], *buf = tmp; if (count > sizeof tmp) buf = malloc(count); if (!buf) return luaL_error(L, "out of memory"); else if (!bytes(buf, count)) return crypto_error(L); lua_pushlstring(L, (char *)buf, count); if (buf != tmp) free(buf); return 1; }
static int rand_write(lua_State *L) { const char *name = luaL_optstring(L, 1, NULL); #if CRYPTO_OPENSSL char tmp[256]; int n; if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) return crypto_error(L); n = RAND_write_file(name); if (n == 0) return crypto_error(L); lua_pushnumber(L, n); #elif CRYPTO_GCRYPT /* this is a BUG() in gcrypt. not sure if it refers to the lib or to the caller, but it does not work (to set twice this file) */ /* if (name != NULL) gcry_control(GCRYCTL_SET_RANDOM_SEED_FILE,name); */ gcry_control(GCRYCTL_UPDATE_RANDOM_SEED_FILE); lua_pushnumber(L, 0.0); #endif return 1; }
static int verify_final(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_VERIFYNAME); size_t sig_len = 0; const unsigned char *sig = (unsigned char *) luaL_checklstring(L, 2, &sig_len); EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 3, LUACRYPTO_PKEYNAME); int ret; ret = EVP_VerifyFinal(c, sig, sig_len, *pkey); if (ret == -1) return crypto_error(L); lua_pushboolean(L, ret); return 1; }
static int digest_fnew(lua_State *L) { const char *s = luaL_checkstring(L, 1); const EVP_MD *digest = EVP_get_digestbyname(s); EVP_MD_CTX *c; if (digest == NULL) return luaL_argerror(L, 1, "invalid digest/cipher type"); c = digest_pnew(L); EVP_MD_CTX_init(c); if (EVP_DigestInit_ex(c, digest, NULL) != 1) return crypto_error(L); return 1; }
static int sign_fnew(lua_State *L) { const char *s = luaL_checkstring(L, 1); const EVP_MD *md = EVP_get_digestbyname(s); EVP_MD_CTX *c; if (md == NULL) return luaL_argerror(L, 1, "invalid digest type"); c = sign_pnew(L); EVP_MD_CTX_init(c); if (EVP_SignInit_ex(c, md, NULL) != 1) return crypto_error(L); return 1; }
static int decrypt_update(lua_State *L) { EVP_CIPHER_CTX *c = (EVP_CIPHER_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DECRYPTNAME); size_t input_len = 0; const unsigned char *input = (unsigned char *) luaL_checklstring(L, 2, &input_len); int output_len = 0; unsigned char *buffer = NULL; buffer = (unsigned char*)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(c)); if (!EVP_DecryptUpdate(c, buffer, &output_len, input, (int)input_len)) { return crypto_error(L); } lua_pushlstring(L, (char*) buffer, (size_t)output_len); free(buffer); return 1; }
static int sign_final(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_SIGNNAME); unsigned int output_len = 0; unsigned char *buffer; EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 2, LUACRYPTO_PKEYNAME); buffer = (unsigned char*)malloc((size_t)EVP_PKEY_size(*pkey)); if (!EVP_SignFinal(c, buffer, &output_len, *pkey)) { free(buffer); return crypto_error(L); } lua_pushlstring(L, (char*) buffer, output_len); free(buffer); return 1; }