From 1dc2fd245875520f78f1e01575b8348b358b339b Mon Sep 17 00:00:00 2001 From: tmeissner Date: Wed, 15 Jul 2020 16:52:52 +0200 Subject: [PATCH] Use co-sim for descryption tests also --- aes/sim/vhdl/tb_aes.c | 140 ++++++++++++++++++++++++---------------- aes/sim/vhdl/tb_aes.tcl | 7 ++ aes/sim/vhdl/tb_aes.vhd | 9 +-- 3 files changed, 98 insertions(+), 58 deletions(-) diff --git a/aes/sim/vhdl/tb_aes.c b/aes/sim/vhdl/tb_aes.c index 4a4f458..750bdce 100644 --- a/aes/sim/vhdl/tb_aes.c +++ b/aes/sim/vhdl/tb_aes.c @@ -71,79 +71,111 @@ void uchar_to_slv(unsigned char* datain, char* dataout, int bytelen) { } -void handleErrors(void) -{ - ERR_print_errors_fp(stderr); - abort(); +void handleErrors(void) { + + ERR_print_errors_fp(stderr); + abort(); + } int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, - unsigned char *ciphertext) -{ - EVP_CIPHER_CTX *ctx; + unsigned char *ciphertext) { + + EVP_CIPHER_CTX *ctx; + + int len; + int ciphertext_len; - int len; + // Create and initialise the context + if(!(ctx = EVP_CIPHER_CTX_new())) + handleErrors(); - int ciphertext_len; + // Initialise the encryption operation, no IV needed in ECB mode + if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL)) + handleErrors(); - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) - handleErrors(); + // We don't want padding + if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0)) + handleErrors(); - /* - * Initialise the encryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits - */ - if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL)) - handleErrors(); + // Provide the message to be encrypted, and obtain the encrypted output + if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) + handleErrors(); + ciphertext_len = len; - if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0)) + // Finalise the encryption. No further bytes are written as padding is switched off + if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); + ciphertext_len += len; + + // Clean up + EVP_CIPHER_CTX_free(ctx); + + return ciphertext_len; - /* - * Provide the message to be encrypted, and obtain the encrypted output. - * EVP_EncryptUpdate can be called multiple times if necessary - */ - if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) - handleErrors(); - ciphertext_len = len; - - /* - * Finalise the encryption. Further ciphertext bytes may be written at - * this stage. - */ - if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) - handleErrors(); - ciphertext_len += len; - - /* Clean up */ - EVP_CIPHER_CTX_free(ctx); - - return ciphertext_len; } -void cryptData(char* datain, char* key, char mode, char* dataout, int len) { +int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, + unsigned char *plaintext) { - unsigned char c_data[len+1]; - unsigned char c_key[len+1]; - unsigned char c_data_e[len+1]; - int ciphertext_len; + EVP_CIPHER_CTX *ctx; + + int len; + int plaintext_len; + + // Create and initialise the context + if(!(ctx = EVP_CIPHER_CTX_new())) + handleErrors(); + + // Initialise the decryption operation, no IV needed in ECB mode + if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL)) + handleErrors(); + + // We don't want padding + if(1 != EVP_CIPHER_CTX_set_padding(ctx, 0)) + handleErrors(); + + // Provide the message to be decrypted, and obtain the decrypted output + if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) + handleErrors(); + plaintext_len = len; - c_data[len] = 0; - c_key[len] = 0; - c_data_e[len] = 0; + // Finalise the decryption. No further bytes are written as padding is switched off + if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) + handleErrors(); + plaintext_len += len; + + // Clean up + EVP_CIPHER_CTX_free(ctx); - slv_to_uchar(datain, c_data, 16); - slv_to_uchar(key, c_key, 16); + return plaintext_len; + +} - ciphertext_len = encrypt(c_data, 128/8, c_key, c_data_e); - uchar_to_slv(c_data_e, dataout, 16); +void cryptData(char* datain, char* key, char mode, char* dataout, int bytelen) { + + int crypt_len; + unsigned char c_din[bytelen]; + unsigned char c_key[bytelen]; + unsigned char c_dout[bytelen]; + + slv_to_uchar(datain, c_din, bytelen); + slv_to_uchar(key, c_key, bytelen); + + if (mode) { + crypt_len = encrypt(c_din, bytelen, c_key, c_dout); + } else { + crypt_len = decrypt(c_din, bytelen, c_key, c_dout); + } + + if (crypt_len != 16) { + printf("Warning: crypt operation returned with unexpected length %d\n", crypt_len); + } + + uchar_to_slv(c_dout, dataout, bytelen); return; diff --git a/aes/sim/vhdl/tb_aes.tcl b/aes/sim/vhdl/tb_aes.tcl index 4562d87..5a38f05 100644 --- a/aes/sim/vhdl/tb_aes.tcl +++ b/aes/sim/vhdl/tb_aes.tcl @@ -8,4 +8,11 @@ lappend signals "top.tb_aes.s_datain" lappend signals "top.tb_aes.s_validout_enc" lappend signals "top.tb_aes.s_acceptin_enc" lappend signals "top.tb_aes.s_dataout_enc" +lappend signals "top.tb_aes.s_validin_dec" +lappend signals "top.tb_aes.s_acceptout_dec" +lappend signals "top.tb_aes.s_key" +lappend signals "top.tb_aes.s_datain" +lappend signals "top.tb_aes.s_validout_dec" +lappend signals "top.tb_aes.s_acceptin_dec" +lappend signals "top.tb_aes.s_dataout_dec" set num_added [ gtkwave::addSignalsFromList $signals ] diff --git a/aes/sim/vhdl/tb_aes.vhd b/aes/sim/vhdl/tb_aes.vhd index dafcaf6..4775ef9 100644 --- a/aes/sim/vhdl/tb_aes.vhd +++ b/aes/sim/vhdl/tb_aes.vhd @@ -59,7 +59,7 @@ architecture rtl of tb_aes is key : in std_logic_vector(0 to 127); mode : in boolean; dataout : out std_logic_vector(0 to 127); - len : in integer) is + bytelen : in integer) is begin report "VHPIDIRECT cryptData" severity failure; end procedure; @@ -129,7 +129,7 @@ begin v_datain := v_random.RandSlv(128); s_key <= v_key; s_datain <= v_datain; - cryptData(swap(v_datain), swap(v_key), true, v_dataout, 128); + cryptData(swap(v_datain), swap(v_key), true, v_dataout, v_datain'length/8); wait until s_acceptout_enc = '1' and rising_edge(s_clk); s_validin_enc <= '0'; wait until s_validout_enc = '1' and rising_edge(s_clk); @@ -146,14 +146,15 @@ begin wait until rising_edge(s_clk); s_validin_dec <= '1'; v_key := x"2b7e151628aed2a6abf7158809cf4f3c"; - v_datain := x"3925841D02DC09FBDC118597196A0B32"; + v_datain := v_random.RandSlv(128); s_key <= v_key; s_datain <= v_datain; + cryptData(swap(v_datain), swap(v_key), false, v_dataout, v_datain'length/8); wait until s_acceptout_dec = '1' and rising_edge(s_clk); s_validin_dec <= '0'; wait until s_validout_dec = '1' and rising_edge(s_clk); s_acceptin_dec <= '1'; - assert s_dataout_dec = x"3243f6a8885a308d313198a2e0370734" + assert s_dataout_dec = swap(v_dataout) report "Decryption error" severity failure; wait until rising_edge(s_clk);