mbedtls/tests/suites/test_suite_des.function
Gilles Peskine 7820a574f1 Catch failures of AES or DES operations
Declare all AES and DES functions that return int as needing to have
their result checked, and do check the result in our code.

A DES or AES block operation can fail in alternative implementations of
mbedtls_internal_aes_encrypt() (under MBEDTLS_AES_ENCRYPT_ALT),
mbedtls_internal_aes_decrypt() (under MBEDTLS_AES_DECRYPT_ALT),
mbedtls_des_crypt_ecb() (under MBEDTLS_DES_CRYPT_ECB_ALT),
mbedtls_des3_crypt_ecb() (under MBEDTLS_DES3_CRYPT_ECB_ALT).
A failure can happen if the accelerator peripheral is in a bad state.
Several block modes were not catching the error.

This commit does the following code changes, grouped together to avoid
having an intermediate commit where the build fails:

* Add MBEDTLS_CHECK_RETURN to all functions returning int in aes.h and des.h.
* Fix all places where this causes a GCC warning, indicating that our code
  was not properly checking the result of an AES operation:
    * In library code: on failure, goto exit and return ret.
    * In pkey programs: goto exit.
    * In the benchmark program: exit (not ideal since there's no error
      message, but it's what the code currently does for failures).
    * In test code: TEST_ASSERT.
* Changelog entry.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
2021-09-27 16:22:08 +02:00

276 lines
7 KiB
C

/* BEGIN_HEADER */
#include "mbedtls/des.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_DES_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void des_check_weak( data_t * key, int ret )
{
TEST_ASSERT( mbedtls_des_key_check_weak( key->x ) == ret );
}
/* END_CASE */
/* BEGIN_CASE */
void des_encrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
{
unsigned char output[100];
mbedtls_des_context ctx;
memset(output, 0x00, 100);
mbedtls_des_init( &ctx );
TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
exit:
mbedtls_des_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void des_decrypt_ecb( data_t * key_str, data_t * src_str, data_t * dst )
{
unsigned char output[100];
mbedtls_des_context ctx;
memset(output, 0x00, 100);
mbedtls_des_init( &ctx );
TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
TEST_ASSERT( mbedtls_des_crypt_ecb( &ctx, src_str->x, output ) == 0 );
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
exit:
mbedtls_des_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void des_encrypt_cbc( data_t * key_str, data_t * iv_str,
data_t * src_str, data_t * dst, int cbc_result )
{
unsigned char output[100];
mbedtls_des_context ctx;
memset(output, 0x00, 100);
mbedtls_des_init( &ctx );
TEST_ASSERT( mbedtls_des_setkey_enc( &ctx, key_str->x ) == 0 );
TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
if( cbc_result == 0 )
{
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
dst->len ) == 0 );
}
exit:
mbedtls_des_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void des_decrypt_cbc( data_t * key_str, data_t * iv_str,
data_t * src_str, data_t * dst,
int cbc_result )
{
unsigned char output[100];
mbedtls_des_context ctx;
memset(output, 0x00, 100);
mbedtls_des_init( &ctx );
TEST_ASSERT( mbedtls_des_setkey_dec( &ctx, key_str->x ) == 0 );
TEST_ASSERT( mbedtls_des_crypt_cbc( &ctx, MBEDTLS_DES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
if( cbc_result == 0 )
{
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
dst->len ) == 0 );
}
exit:
mbedtls_des_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void des3_encrypt_ecb( int key_count, data_t * key_str,
data_t * src_str, data_t * dst )
{
unsigned char output[100];
mbedtls_des3_context ctx;
memset(output, 0x00, 100);
mbedtls_des3_init( &ctx );
if( key_count == 2 )
TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
else if( key_count == 3 )
TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
else
TEST_ASSERT( 0 );
TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
exit:
mbedtls_des3_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void des3_decrypt_ecb( int key_count, data_t * key_str,
data_t * src_str, data_t * dst )
{
unsigned char output[100];
mbedtls_des3_context ctx;
memset(output, 0x00, 100);
mbedtls_des3_init( &ctx );
if( key_count == 2 )
TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
else if( key_count == 3 )
TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
else
TEST_ASSERT( 0 );
TEST_ASSERT( mbedtls_des3_crypt_ecb( &ctx, src_str->x, output ) == 0 );
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, 8, dst->len ) == 0 );
exit:
mbedtls_des3_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void des3_encrypt_cbc( int key_count, data_t * key_str,
data_t * iv_str, data_t * src_str,
data_t * dst, int cbc_result )
{
unsigned char output[100];
mbedtls_des3_context ctx;
memset(output, 0x00, 100);
mbedtls_des3_init( &ctx );
if( key_count == 2 )
TEST_ASSERT( mbedtls_des3_set2key_enc( &ctx, key_str->x ) == 0 );
else if( key_count == 3 )
TEST_ASSERT( mbedtls_des3_set3key_enc( &ctx, key_str->x ) == 0 );
else
TEST_ASSERT( 0 );
TEST_ASSERT( mbedtls_des3_crypt_cbc( &ctx, MBEDTLS_DES_ENCRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
if( cbc_result == 0 )
{
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x,
src_str->len, dst->len ) == 0 );
}
exit:
mbedtls_des3_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC */
void des3_decrypt_cbc( int key_count, data_t * key_str,
data_t * iv_str, data_t * src_str,
data_t * dst, int cbc_result )
{
unsigned char output[100];
mbedtls_des3_context ctx;
memset(output, 0x00, 100);
mbedtls_des3_init( &ctx );
if( key_count == 2 )
TEST_ASSERT( mbedtls_des3_set2key_dec( &ctx, key_str->x ) == 0 );
else if( key_count == 3 )
TEST_ASSERT( mbedtls_des3_set3key_dec( &ctx, key_str->x ) == 0 );
else
TEST_ASSERT( 0 );
TEST_ASSERT( mbedtls_des3_crypt_cbc( &ctx, MBEDTLS_DES_DECRYPT, src_str->len, iv_str->x, src_str->x, output ) == cbc_result );
if( cbc_result == 0 )
{
TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, src_str->len,
dst->len ) == 0 );
}
exit:
mbedtls_des3_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void des_key_parity_run( )
{
int i, j, cnt;
unsigned char key[MBEDTLS_DES_KEY_SIZE];
unsigned int parity;
memset( key, 0, MBEDTLS_DES_KEY_SIZE );
cnt = 0;
// Iterate through all possible byte values
//
for( i = 0; i < 32; i++ )
{
for( j = 0; j < 8; j++ )
key[j] = cnt++;
// Set the key parity according to the table
//
mbedtls_des_key_set_parity( key );
// Check the parity with a function
//
for( j = 0; j < 8; j++ )
{
parity = key[j] ^ ( key[j] >> 4 );
parity = parity ^
( parity >> 1 ) ^
( parity >> 2 ) ^
( parity >> 3 );
parity &= 1;
if( parity != 1 )
TEST_ASSERT( 0 );
}
// Check the parity with the table
//
TEST_ASSERT( mbedtls_des_key_check_key_parity( key ) == 0 );
}
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void des_selftest( )
{
TEST_ASSERT( mbedtls_des_self_test( 1 ) == 0 );
}
/* END_CASE */