2013-03-12 41 views
4

在使用openSSL庫時,我遇到了EVP_EncryptFinal_ex問題。 具體而言,它每次都會因致命錯誤./crypto/evp/evp_enc.c(348) OpenSSL internal error, assertion failed: b <= sizeof ctx -> buf而失敗,而不依賴於算法(aes或des)。在EVP_EncryptFinal_ex期間openssl錯誤「斷言失敗」,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是大小當前密碼的一個塊。這個斷言是有道理的,但我仍然無法弄清楚它是如何在我的代碼中失敗的。

我試圖解決這個問題好幾天了,我會很感激任何意見。

UPDATE:下面是evp_enc.c兩行:

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

根據碼,b是塊大小爲當前密碼,用於aes_256_cbc它是16位長。

+0

斷言意味着'B'比'的sizeof(則將ctx-> BUF)'更大。 「b」代表什麼? – 2013-03-12 01:32:09

回答

2

問題在於你的函數EVP_EncryptFinal_ex的聲明。你應該添加cdecl指令(就像所有其他功能一樣)。 因此,新的聲明將是:

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