Во время работы с библиотекой openSSL я столкнулся с проблемой с EVP_EncryptFinal_ex. Конкретно, он терпит неудачу с фатальной ошибкой ./crypto/evp/evp_enc.c(348) OpenSSL internal error, assertion failed: b <= sizeof ctx -> buf
каждый раз, не зависящий от алгоритма (aes или des).Ошибка при открытии ошибки «assertion failed» во время EVP_EncryptFinal_ex, delphi
Вот мой код. Он максимально упрощен.
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;
Просто чтобы быть точным, импорт используется:
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;
Я на самом деле пытался читать исходные коды (evp_enc.c) и нашел утверждение:
OPENSSL_assert(b <= sizeof ctx->buf);
Здесь b
является размер блока для текущего cypher. Это утверждение имеет смысл, но все же я не могу понять, как это может быть неудачно в моем коде.
Я пытаюсь решить эту проблему уже пару дней, и я был бы признателен за любые советы.
ОБНОВЛЕНИЕ: Вот две строки из evp_enc.c:
b=ctx->cipher->block_size;
OPENSSL_assert(b <= sizeof ctx->buf);
в соответствии с кодом, В представляет собой размер блока для текущего шифра, для aes_256_cbc это 16 бит длиной.
утверждение означает, что 'b' больше' SizeOf (ctx-> ЬиЕ) '. Что на самом деле означает 'b'? –