4

openSSLライブラリを使用しているときに、EVP_EncryptFinal_exで問題が発生しました。具体的には、./crypto/evp/evp_enc.c(348) OpenSSL internal error, assertion failed: b <= sizeof ctx -> bufアルゴリズム(aesまたはdes)に依存せず、毎回致命的なエラーで失敗します。

これが私のコードです。可能な限り簡略化されています。

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のブロックのサイズです。このアサーションは理にかなっていますが、それでもコードでどのように失敗する可能性があるのか​​理解できません。

私はすでに数日間この問題を克服しようとしています。アドバイスをいただければ幸いです。

更新: evp_enc.cからの2行は次のとおりです。

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

コードによると、bは現在の暗号のブロックのサイズであり、aes_256_cbcの場合は16ビット長です。

4

1 に答える 1

2

問題は、関数の宣言にありますEVP_EncryptFinal_excdecl(他のすべての関数と同様に)ディレクティブを追加する必要があります。したがって、新しい宣言は次のようになります。

function EVP_EncryptFinal_ex(ctx: PEVP_CIPHER_CTX; data_out: PByte; var outl: integer): integer; cdecl; external LIB_DLL_NAME;
于 2013-03-13T09:08:10.407 に答える