Merge remote-tracking branch 'upstream-public/pr/964' into development

This commit is contained in:
Gilles Peskine 2018-01-02 16:24:29 +01:00
commit 17196cd3be
5 changed files with 230 additions and 206 deletions

View File

@ -36,9 +36,13 @@
#define MBEDTLS_AES_ENCRYPT 1 #define MBEDTLS_AES_ENCRYPT 1
#define MBEDTLS_AES_DECRYPT 0 #define MBEDTLS_AES_DECRYPT 0
/* Error codes in range 0x0020-0x0022 */
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
/* Error codes in range 0x0023-0x0023 */
#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 /**< Feature not available, e.g. unsupported AES key size. */
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus) !defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline

View File

@ -52,7 +52,7 @@
* GCM 2 0x0012-0x0014 * GCM 2 0x0012-0x0014
* BLOWFISH 2 0x0016-0x0018 * BLOWFISH 2 0x0016-0x0018
* THREADING 3 0x001A-0x001E * THREADING 3 0x001A-0x001E
* AES 2 0x0020-0x0022 * AES 2 0x0020-0x0022 0x0023-0x0023
* CAMELLIA 2 0x0024-0x0026 * CAMELLIA 2 0x0024-0x0026
* XTEA 1 0x0028-0x0028 * XTEA 1 0x0028-0x0028
* BASE64 2 0x002A-0x002C * BASE64 2 0x002A-0x002C

View File

@ -1235,9 +1235,11 @@ static const int aes_test_ctr_len[3] =
*/ */
int mbedtls_aes_self_test( int verbose ) int mbedtls_aes_self_test( int verbose )
{ {
int ret = 0, i, j, u, v; int ret = 0, i, j, u, mode;
unsigned int keybits;
unsigned char key[32]; unsigned char key[32];
unsigned char buf[64]; unsigned char buf[64];
const unsigned char *aes_tests;
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) #if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
unsigned char iv[16]; unsigned char iv[16];
#endif #endif
@ -1263,45 +1265,52 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_ecb_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf );
if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_ecb_enc[u];
}
for( j = 0; j < 10000; j++ ) /*
mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); * AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) * MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
} }
for( j = 0; j < 10000; j++ )
{
ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
if( ret != 0 )
goto exit;
}
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1;
goto exit;
} }
if( verbose != 0 ) if( verbose != 0 )
@ -1318,56 +1327,65 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( iv , 0, 16 ); memset( iv , 0, 16 );
memset( prv, 0, 16 ); memset( prv, 0, 16 );
memset( buf, 0, 16 ); memset( buf, 0, 16 );
if( v == MBEDTLS_AES_DECRYPT ) if( mode == MBEDTLS_AES_DECRYPT )
{ {
mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
aes_tests = aes_test_cbc_dec[u];
for( j = 0; j < 10000; j++ )
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
} }
else else
{ {
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
aes_tests = aes_test_cbc_enc[u];
}
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{
mbedtls_printf( "skipped\n" );
continue;
}
else if( ret != 0 )
{
goto exit;
}
for( j = 0; j < 10000; j++ ) for( j = 0; j < 10000; j++ )
{
if( mode == MBEDTLS_AES_ENCRYPT )
{ {
unsigned char tmp[16]; unsigned char tmp[16];
mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
memcpy( tmp, prv, 16 ); memcpy( tmp, prv, 16 );
memcpy( prv, buf, 16 ); memcpy( prv, buf, 16 );
memcpy( buf, tmp, 16 ); memcpy( buf, tmp, 16 );
} }
if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
{ if( ret != 0 )
if( verbose != 0 ) goto exit;
mbedtls_printf( "failed\n" );
}
if( memcmp( buf, aes_tests, 16 ) != 0 )
{
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1384,46 +1402,53 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; keybits = 128 + u * 64;
mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_cfb128_iv, 16 ); memcpy( iv, aes_test_cfb128_iv, 16 );
memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
/*
if( v == MBEDTLS_AES_DECRYPT ) * AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 )
{ {
memcpy( buf, aes_test_cfb128_ct[u], 64 ); mbedtls_printf( "skipped\n" );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); continue;
}
if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) else if( ret != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
} }
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy( buf, aes_test_cfb128_ct[u], 64 );
aes_tests = aes_test_cfb128_pt;
} }
else else
{ {
memcpy( buf, aes_test_cfb128_pt, 64 ); memcpy( buf, aes_test_cfb128_pt, 64 );
mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); aes_tests = aes_test_cfb128_ct[u];
}
if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_tests, 64 ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1440,52 +1465,42 @@ int mbedtls_aes_self_test( int verbose )
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
{ {
u = i >> 1; u = i >> 1;
v = i & 1; mode = i & 1;
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-CTR-128 (%s): ", mbedtls_printf( " AES-CTR-128 (%s): ",
( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
memcpy( key, aes_test_ctr_key[u], 16 ); memcpy( key, aes_test_ctr_key[u], 16 );
offset = 0; offset = 0;
mbedtls_aes_setkey_enc( &ctx, key, 128 ); if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
if( v == MBEDTLS_AES_DECRYPT )
{
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_ct[u], len );
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
buf, buf );
if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit; goto exit;
}
len = aes_test_ctr_len[u];
if( mode == MBEDTLS_AES_DECRYPT )
{
memcpy( buf, aes_test_ctr_ct[u], len );
aes_tests = aes_test_ctr_pt[u];
} }
else else
{ {
len = aes_test_ctr_len[u];
memcpy( buf, aes_test_ctr_pt[u], len ); memcpy( buf, aes_test_ctr_pt[u], len );
aes_tests = aes_test_ctr_ct[u];
}
mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
buf, buf ); stream_block, buf, buf );
if( ret != 0 )
goto exit;
if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) if( memcmp( buf, aes_tests, len ) != 0 )
{ {
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1; ret = 1;
goto exit; goto exit;
} }
}
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -1498,6 +1513,9 @@ int mbedtls_aes_self_test( int verbose )
ret = 0; ret = 0;
exit: exit:
if( ret != 0 && verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_aes_free( &ctx ); mbedtls_aes_free( &ctx );
return( ret ); return( ret );

View File

@ -520,6 +520,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "AES - Feature not available, e.g. unsupported AES key size" );
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ASN1_PARSE_C) #if defined(MBEDTLS_ASN1_PARSE_C)

View File

@ -46,6 +46,7 @@
#endif #endif
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h"
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
@ -748,34 +749,48 @@ int mbedtls_gcm_self_test( int verbose )
int i, j, ret; int i, j, ret;
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
mbedtls_gcm_init( &ctx );
for( j = 0; j < 3; j++ ) for( j = 0; j < 3; j++ )
{ {
int key_len = 128 + 64 * j; int key_len = 128 + 64 * j;
for( i = 0; i < MAX_TESTS; i++ ) for( i = 0; i < MAX_TESTS; i++ )
{ {
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "enc" ); key_len, i, "enc" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
/*
* AES-192 is an optional feature that may be unavailable when
* there is an alternative underlying implementation i.e. when
* MBEDTLS_AES_ALT is defined.
*/
if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && key_len == 192 )
{
mbedtls_printf( "skipped\n" );
break;
}
else if( ret != 0 )
{
goto exit;
}
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
pt_len[i], pt_len[i],
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i], additional[add_index[i]], add_len[i],
pt[pt_index[i]], buf, 16, tag_buf ); pt[pt_index[i]], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
if( ret != 0 || if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -783,11 +798,16 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ", mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "dec" ); key_len, i, "dec" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
pt_len[i], pt_len[i],
@ -795,14 +815,14 @@ int mbedtls_gcm_self_test( int verbose )
additional[add_index[i]], add_len[i], additional[add_index[i]], add_len[i],
ct[j * 6 + i], buf, 16, tag_buf ); ct[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 || if( ret != 0 )
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -810,66 +830,51 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "enc" ); key_len, i, "enc" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] ); additional[add_index[i]], add_len[i] );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( pt_len[i] > 32 ) if( pt_len[i] > 32 )
{ {
size_t rest_len = pt_len[i] - 32; size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
buf + 32 ); buf + 32 );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
else else
{ {
ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 || if( ret != 0 )
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
@ -877,80 +882,75 @@ int mbedtls_gcm_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
mbedtls_gcm_init( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "dec" ); key_len, i, "dec" );
mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
iv[iv_index[i]], iv_len[i], iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i] ); additional[add_index[i]], add_len[i] );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
if( pt_len[i] > 32 ) if( pt_len[i] > 32 )
{ {
size_t rest_len = pt_len[i] - 32; size_t rest_len = pt_len[i] - 32;
ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
buf + 32 ); buf + 32 );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
else else
{ {
ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf ); ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
buf );
if( ret != 0 ) if( ret != 0 )
{ goto exit;
if( verbose != 0 )
mbedtls_printf( "failed\n" );
return( 1 );
}
} }
ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
if( ret != 0 || if( ret != 0 )
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || goto exit;
if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{ {
if( verbose != 0 ) ret = 1;
mbedtls_printf( "failed\n" ); goto exit;
return( 1 );
} }
mbedtls_gcm_free( &ctx ); mbedtls_gcm_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
} }
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "\n" ); mbedtls_printf( "\n" );
return( 0 ); ret = 0;
exit:
if( ret != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
mbedtls_gcm_free( &ctx );
}
return( ret );
} }
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ #endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */