Openssl "approval failed" error during EVP_EncryptFinal_ex, delphi

While working with the openSSL library, I encountered a problem with EVP_EncryptFinal_ex. Specifically, it fails with a fatal error ./crypto/evp/evp_enc.c(348) OpenSSL internal error, assertion failed: b <= sizeof ctx -> buf each time, independent of the algorithm (aes or des).

Here is my code. It is maximally simplified.

 procedure AESTest; var key : TBytes; keyLen : Integer; dataIn : string; dataOut : TBytes; inLen, outLen, resLen : integer; // Context of an algorithm pointer e_ctx : Pointer; begin // 256 bit key keyLen := 32; setlength(key, KeyLen); RAND_bytes(@(key[0]), KeyLen); // Input data to encrypt dataIn := 'Simple data of 29 bits length'; inLen := length(dataIn); // Init ctx e_ctx := EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(e_ctx); EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc, nil, @key[0], nil); // Prepare ouput buf in order to openSSL docs outLen := inLen + EVP_CIPHER_CTX_block_size(e_ctx) - 1; setlength(dataOut, outLen); EVP_EncryptUpdate(e_ctx, @dataOut[0], outLen, @dataIn[1], inLen); EVP_EncryptFinal_ex(e_ctx, @dataOut[outLen], resLen); outLen := outLen + resLen; setlength(dataOut, outLen); // ... here goes decryption part but it does not matter now end; 

To be precise, we used import:

 const LIB_DLL_NAME = 'libeay32.dll'; type PEVP_CIPHER_CTX : Pointer; PEVP_CIPHER : Pointer; function EVP_CIPHER_CTX_new : PEVP_CIPHER_CTX; cdecl; external LIB_DLL_NAME; procedure EVP_CIPHER_CTX_init(a: PEVP_CIPHER_CTX); cdecl; external LIB_DLL_NAME; function EVP_aes_256_cbc : PEVP_CIPHER_CTX; cdecl; external LIB_DLL_NAME; function RAND_bytes(Arr : PByte; ArrLen : integer) : integer; cdecl; external LIB_DLL_NAME; function EVP_CIPHER_CTX_block_size(ctx: PEVP_CIPHER_CTX): integer; cdecl; external LIB_DLL_NAME; function EVP_EncryptInit_ex(ctx: PEVP_CIPHER_CTX; cipher_type: PEVP_CIPHER; Engine : Pointer; key: PByte; iv: PByte): integer; cdecl; external LIB_DLL_NAME; function EVP_EncryptUpdate(ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer; data_in: PByte; inl: integer): integer; cdecl; external LIB_DLL_NAME; function EVP_EncryptFinal_ex(ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer): integer; external LIB_DLL_NAME; 

I really tried to read the source code (evp_enc.c) and found the following statement:

  OPENSSL_assert(b <= sizeof ctx->buf); 

Here b is the block size for the current cypher. This statement makes sense, but still I can’t understand how this can be unsuccessful in my code.

I have been trying to solve this problem for a couple of days, and I would appreciate any advice.

UPDATE: Here are two lines from evp_enc.c:

  b=ctx->cipher->block_size; OPENSSL_assert(b <= sizeof ctx->buf); 

according to the code, b is the block size for the current encryption, for aes_256_cbc - 16 bits.

+4
source share
1 answer

The problem is the declaration of the EVP_EncryptFinal_ex function. You add the cdecl directive (as in all other functions). So, the new declaration will be:

 function EVP_EncryptFinal_ex(ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer): integer; cdecl; external LIB_DLL_NAME; 
+2
source

All Articles