Merge pull request #5573 from superna9999/5176-5177-5178-5179-tsl-record-hmac

TLS record HMAC
This commit is contained in:
Manuel Pégourié-Gonnard 2022-03-21 11:36:44 +01:00 committed by GitHub
commit f4042f076b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 477 additions and 1625 deletions

View file

@ -437,6 +437,126 @@ void mbedtls_ct_memcpy_offset( unsigned char *dest,
}
}
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(PSA_WANT_ALG_SHA_384)
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH( PSA_ALG_SHA_384 )
#elif defined(PSA_WANT_ALG_SHA_256)
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH( PSA_ALG_SHA_256 )
#else /* See check_config.h */
#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH( PSA_ALG_SHA_1 )
#endif
int mbedtls_ct_hmac( mbedtls_svc_key_id_t key,
psa_algorithm_t mac_alg,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output )
{
/*
* This function breaks the HMAC abstraction and uses psa_hash_clone()
* extension in order to get constant-flow behaviour.
*
* HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
* concatenation, and okey/ikey are the XOR of the key with some fixed bit
* patterns (see RFC 2104, sec. 2).
*
* We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
* hashing up to minlen, then cloning the context, and for each byte up
* to maxlen finishing up the hash computation, keeping only the
* correct result.
*
* Then we only need to compute HASH(okey + inner_hash) and we're done.
*/
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( mac_alg );
const size_t block_size = PSA_HASH_BLOCK_LENGTH( hash_alg );
unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
const size_t hash_size = PSA_HASH_LENGTH( hash_alg );
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
size_t hash_length;
unsigned char aux_out[PSA_HASH_MAX_SIZE];
psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
size_t offset;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t mac_key_length;
size_t i;
#define PSA_CHK( func_call ) \
do { \
status = (func_call); \
if( status != PSA_SUCCESS ) \
goto cleanup; \
} while( 0 )
/* Export MAC key
* We assume key length is always exactly the output size
* which is never more than the block size, thus we use block_size
* as the key buffer size.
*/
PSA_CHK( psa_export_key( key, key_buf, block_size, &mac_key_length ) );
/* Calculate ikey */
for( i = 0; i < mac_key_length; i++ )
key_buf[i] = (unsigned char)( key_buf[i] ^ 0x36 );
for(; i < block_size; ++i )
key_buf[i] = 0x36;
PSA_CHK( psa_hash_setup( &operation, hash_alg ) );
/* Now compute inner_hash = HASH(ikey + msg) */
PSA_CHK( psa_hash_update( &operation, key_buf, block_size ) );
PSA_CHK( psa_hash_update( &operation, add_data, add_data_len ) );
PSA_CHK( psa_hash_update( &operation, data, min_data_len ) );
/* For each possible length, compute the hash up to that point */
for( offset = min_data_len; offset <= max_data_len; offset++ )
{
PSA_CHK( psa_hash_clone( &operation, &aux_operation ) );
PSA_CHK( psa_hash_finish( &aux_operation, aux_out,
PSA_HASH_MAX_SIZE, &hash_length ) );
/* Keep only the correct inner_hash in the output buffer */
mbedtls_ct_memcpy_if_eq( output, aux_out, hash_size,
offset, data_len_secret );
if( offset < max_data_len )
PSA_CHK( psa_hash_update( &operation, data + offset, 1 ) );
}
/* Abort current operation to prepare for final operation */
PSA_CHK( psa_hash_abort( &operation ) );
/* Calculate okey */
for( i = 0; i < mac_key_length; i++ )
key_buf[i] = (unsigned char)( ( key_buf[i] ^ 0x36 ) ^ 0x5C );
for(; i < block_size; ++i )
key_buf[i] = 0x5C;
/* Now compute HASH(okey + inner_hash) */
PSA_CHK( psa_hash_setup( &operation, hash_alg ) );
PSA_CHK( psa_hash_update( &operation, key_buf, block_size ) );
PSA_CHK( psa_hash_update( &operation, output, hash_size ) );
PSA_CHK( psa_hash_finish( &operation, output, hash_size, &hash_length ) );
#undef PSA_CHK
cleanup:
mbedtls_platform_zeroize( key_buf, MAX_HASH_BLOCK_LENGTH );
mbedtls_platform_zeroize( aux_out, PSA_HASH_MAX_SIZE );
psa_hash_abort( &operation );
psa_hash_abort( &aux_operation );
return( psa_ssl_status_to_mbedtls( status ) );
}
#undef MAX_HASH_BLOCK_LENGTH
#else
int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
const unsigned char *add_data,
size_t add_data_len,
@ -520,6 +640,7 @@ cleanup:
mbedtls_md_free( &aux );
return( ret );
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */

View file

@ -276,6 +276,17 @@ void mbedtls_ct_memcpy_offset( unsigned char *dest,
* \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
* The hardware accelerator failed.
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO)
int mbedtls_ct_hmac( mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
const unsigned char *add_data,
size_t add_data_len,
const unsigned char *data,
size_t data_len_secret,
size_t min_data_len,
size_t max_data_len,
unsigned char *output );
#else
int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
const unsigned char *add_data,
size_t add_data_len,
@ -284,6 +295,7 @@ int mbedtls_ct_hmac( mbedtls_md_context_t *ctx,
size_t min_data_len,
size_t max_data_len,
unsigned char *output );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */

View file

@ -954,8 +954,14 @@ struct mbedtls_ssl_transform
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t psa_mac_enc; /*!< MAC (encryption) */
mbedtls_svc_key_id_t psa_mac_dec; /*!< MAC (decryption) */
psa_algorithm_t psa_mac_alg; /*!< psa MAC algorithm */
#else
mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */
mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
int encrypt_then_mac; /*!< flag for EtM activation */

View file

@ -673,11 +673,35 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
unsigned char mac[MBEDTLS_SSL_MAC_ADD];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
size_t sign_mac_length = 0;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
transform->minor_ver,
transform->taglen );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_mac_sign_setup( &operation, transform->psa_mac_enc,
transform->psa_mac_alg );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_disabled;
status = psa_mac_update( &operation, add_data, add_data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_disabled;
status = psa_mac_update( &operation, data, rec->data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_disabled;
status = psa_mac_sign_finish( &operation, mac, MBEDTLS_SSL_MAC_ADD,
&sign_mac_length );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_disabled;
#else
ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
add_data_len );
if( ret != 0 )
@ -691,6 +715,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
if( ret != 0 )
goto hmac_failed_etm_disabled;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
memcpy( data + rec->data_len, mac, transform->maclen );
#endif
@ -704,6 +729,12 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
hmac_failed_etm_disabled:
mbedtls_platform_zeroize( mac, transform->maclen );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = psa_ssl_status_to_mbedtls( status );
status = psa_mac_abort( &operation );
if( ret == 0 && status != PSA_SUCCESS )
ret = psa_ssl_status_to_mbedtls( status );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
@ -998,6 +1029,10 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
if( auth_done == 0 )
{
unsigned char mac[MBEDTLS_SSL_MAC_ADD];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
size_t sign_mac_length = 0;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/*
* MAC(MAC_write_key, seq_num +
@ -1021,6 +1056,25 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
add_data_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_mac_sign_setup( &operation, transform->psa_mac_enc,
transform->psa_mac_alg );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
status = psa_mac_update( &operation, add_data, add_data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
status = psa_mac_update( &operation, data, rec->data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
status = psa_mac_sign_finish( &operation, mac, MBEDTLS_SSL_MAC_ADD,
&sign_mac_length );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
#else
ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
add_data_len );
@ -1036,6 +1090,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
if( ret != 0 )
goto hmac_failed_etm_enabled;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
memcpy( data + rec->data_len, mac, transform->maclen );
@ -1045,6 +1100,12 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
hmac_failed_etm_enabled:
mbedtls_platform_zeroize( mac, transform->maclen );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = psa_ssl_status_to_mbedtls( status );
status = psa_mac_abort( &operation );
if( ret == 0 && status != PSA_SUCCESS )
ret = psa_ssl_status_to_mbedtls( status );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
@ -1331,7 +1392,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
#else
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
#endif /* MBEDTLS_USE_PSA_CRYPTO */
MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
@ -1353,6 +1418,26 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
/* Calculate expected MAC. */
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
add_data_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_mac_verify_setup( &operation, transform->psa_mac_dec,
transform->psa_mac_alg );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
status = psa_mac_update( &operation, add_data, add_data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
status = psa_mac_update( &operation, data, rec->data_len );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
/* Compare expected MAC with MAC at the end of the record. */
status = psa_mac_verify_finish( &operation, data + rec->data_len,
transform->maclen );
if( status != PSA_SUCCESS )
goto hmac_failed_etm_enabled;
#else
ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
add_data_len );
if( ret != 0 )
@ -1381,10 +1466,18 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
ret = MBEDTLS_ERR_SSL_INVALID_MAC;
goto hmac_failed_etm_enabled;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
auth_done++;
hmac_failed_etm_enabled:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = psa_ssl_status_to_mbedtls( status );
status = psa_mac_abort( &operation );
if( ret == 0 && status != PSA_SUCCESS )
ret = psa_ssl_status_to_mbedtls( status );
#else
mbedtls_platform_zeroize( mac_expect, transform->maclen );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ret != 0 )
{
if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
@ -1621,10 +1714,18 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
const size_t max_len = rec->data_len + padlen;
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_ct_hmac( transform->psa_mac_dec,
transform->psa_mac_alg,
add_data, add_data_len,
data, rec->data_len, min_len, max_len,
mac_expect );
#else
ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
add_data, add_data_len,
data, rec->data_len, min_len, max_len,
mac_expect );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
@ -5612,8 +5713,13 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_destroy_key( transform->psa_mac_enc );
psa_destroy_key( transform->psa_mac_dec );
#else
mbedtls_md_free( &transform->md_ctx_enc );
mbedtls_md_free( &transform->md_ctx_dec );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif
mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );

View file

@ -610,9 +610,14 @@ void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform )
#endif
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
transform->psa_mac_enc = MBEDTLS_SVC_KEY_ID_INIT;
transform->psa_mac_dec = MBEDTLS_SVC_KEY_ID_INIT;
#else
mbedtls_md_init( &transform->md_ctx_enc );
mbedtls_md_init( &transform->md_ctx_dec );
#endif
#endif
}
void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
@ -7196,6 +7201,7 @@ static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
if( mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_STREAM ||
mbedtls_cipher_info_get_mode( cipher_info ) == MBEDTLS_MODE_CBC )
{
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
/* Initialize HMAC contexts */
if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
@ -7203,6 +7209,7 @@ static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
goto end;
}
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
/* Get MAC length */
mac_key_len = mbedtls_md_get_size( md_info );
@ -7310,23 +7317,6 @@ static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
goto end;
}
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
/* For HMAC-based ciphersuites, initialize the HMAC transforms.
For AEAD-based ciphersuites, there is nothing to do here. */
if( mac_key_len != 0 )
{
ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
if( ret != 0 )
goto end;
ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
if( ret != 0 )
goto end;
}
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
((void) mac_dec);
((void) mac_enc);
if( ssl != NULL && ssl->f_export_keys != NULL )
{
ssl->f_export_keys( ssl->p_export_keys,
@ -7431,6 +7421,66 @@ static int ssl_tls12_populate_transform( mbedtls_ssl_transform *transform,
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
/* For HMAC-based ciphersuites, initialize the HMAC transforms.
For AEAD-based ciphersuites, there is nothing to do here. */
if( mac_key_len != 0 )
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
alg = mbedtls_psa_translate_md( ciphersuite_info->mac );
if( alg == 0 )
{
ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_md_type_to_psa", ret );
goto end;
}
transform->psa_mac_alg = PSA_ALG_HMAC( alg );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
psa_set_key_algorithm( &attributes, PSA_ALG_HMAC( alg ) );
psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
if( ( status = psa_import_key( &attributes,
mac_enc, mac_key_len,
&transform->psa_mac_enc ) ) != PSA_SUCCESS )
{
ret = psa_ssl_status_to_mbedtls( status );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_mac_key", ret );
goto end;
}
if( ( transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER ||
transform->psa_alg == PSA_ALG_CBC_NO_PADDING ) &&
transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED )
/* mbedtls_ct_hmac() requires the key to be exportable */
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT |
PSA_KEY_USAGE_VERIFY_HASH );
else
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
if( ( status = psa_import_key( &attributes,
mac_dec, mac_key_len,
&transform->psa_mac_dec ) ) != PSA_SUCCESS )
{
ret = psa_ssl_status_to_mbedtls( status );
MBEDTLS_SSL_DEBUG_RET( 1, "psa_import_mac_key", ret );
goto end;
}
#else
ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
if( ret != 0 )
goto end;
ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
if( ret != 0 )
goto end;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
((void) mac_dec);
((void) mac_enc);
end:
mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
return( ret );

View file

@ -1319,6 +1319,25 @@ component_test_full_cmake_clang () {
}
component_test_memsan_constant_flow () {
# This tests both (1) accesses to undefined memory, and (2) branches or
# memory access depending on secret values. To distinguish between those:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
# - or alternatively, change the build type to MemSanDbg, which enables
# origin tracking and nicer stack traces (which are useful for debugging
# anyway), and check if the origin was TEST_CF_SECRET() or something else.
msg "build: cmake MSan (clang), full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
scripts/config.py full
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_AESNI_C # memsan doesn't grok asm
CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
make
msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, Msan + constant flow)"
make test
}
component_test_memsan_constant_flow_psa () {
# This tests both (1) accesses to undefined memory, and (2) branches or
# memory access depending on secret values. To distinguish between those:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
@ -1337,6 +1356,29 @@ component_test_memsan_constant_flow () {
}
component_test_valgrind_constant_flow () {
# This tests both (1) everything that valgrind's memcheck usually checks
# (heap buffer overflows, use of uninitialized memory, use-after-free,
# etc.) and (2) branches or memory access depending on secret values,
# which will be reported as uninitialized memory. To distinguish between
# secret and actually uninitialized:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
# - or alternatively, build with debug info and manually run the offending
# test suite with valgrind --track-origins=yes, then check if the origin
# was TEST_CF_SECRET() or something else.
msg "build: cmake release GCC, full config minus MBEDTLS_USE_PSA_CRYPTO with constant flow testing"
scripts/config.py full
scripts/config.py set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
cmake -D CMAKE_BUILD_TYPE:String=Release .
make
# this only shows a summary of the results (how many of each type)
# details are left in Testing/<date>/DynamicAnalysis.xml
msg "test: main suites (full minus MBEDTLS_USE_PSA_CRYPTO, valgrind + constant flow)"
make memcheck
}
component_test_valgrind_constant_flow_psa () {
# This tests both (1) everything that valgrind's memcheck usually checks
# (heap buffer overflows, use of uninitialized memory, use-after-free,
# etc.) and (2) branches or memory access depending on secret values,

File diff suppressed because it is too large Load diff

View file

@ -1359,6 +1359,47 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
memset( md0, 0x5, maclen );
memset( md1, 0x6, maclen );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
alg = mbedtls_psa_translate_md( mbedtls_md_get_type( md_info ) );
CHK( alg != 0 );
t_out->psa_mac_alg = PSA_ALG_HMAC( alg );
t_in->psa_mac_alg = PSA_ALG_HMAC( alg );
t_in->psa_mac_enc = MBEDTLS_SVC_KEY_ID_INIT;
t_out->psa_mac_enc = MBEDTLS_SVC_KEY_ID_INIT;
t_in->psa_mac_dec = MBEDTLS_SVC_KEY_ID_INIT;
t_out->psa_mac_dec = MBEDTLS_SVC_KEY_ID_INIT;
psa_reset_key_attributes( &attributes );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_MESSAGE );
psa_set_key_algorithm( &attributes, PSA_ALG_HMAC( alg ) );
psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
CHK( psa_import_key( &attributes,
md0, maclen,
&t_in->psa_mac_enc ) == PSA_SUCCESS );
CHK( psa_import_key( &attributes,
md1, maclen,
&t_out->psa_mac_enc ) == PSA_SUCCESS );
if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
etm == MBEDTLS_SSL_ETM_DISABLED )
/* mbedtls_ct_hmac() requires the key to be exportable */
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT |
PSA_KEY_USAGE_VERIFY_HASH );
else
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
CHK( psa_import_key( &attributes,
md1, maclen,
&t_in->psa_mac_dec ) == PSA_SUCCESS );
CHK( psa_import_key( &attributes,
md0, maclen,
&t_out->psa_mac_dec ) == PSA_SUCCESS );
#else
CHK( mbedtls_md_setup( &t_out->md_ctx_enc, md_info, 1 ) == 0 );
CHK( mbedtls_md_setup( &t_out->md_ctx_dec, md_info, 1 ) == 0 );
CHK( mbedtls_md_setup( &t_in->md_ctx_enc, md_info, 1 ) == 0 );
@ -1372,6 +1413,7 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
md1, maclen ) == 0 );
CHK( mbedtls_md_hmac_starts( &t_out->md_ctx_dec,
md0, maclen ) == 0 );
#endif
}
#else
((void) hash_id);
@ -1468,10 +1510,6 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
t_out->maclen = maclen;
t_in->maclen = maclen;
break;
case 1: /* Partial tag */
t_out->maclen = 10;
t_in->maclen = 10;
break;
default:
ret = 1;
goto cleanup;
@ -1520,6 +1558,7 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
if ( alg != MBEDTLS_SSL_NULL_CIPHER )
{
psa_reset_key_attributes( &attributes );
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
psa_set_key_algorithm( &attributes, alg );
psa_set_key_type( &attributes, key_type );
@ -1884,6 +1923,8 @@ void perform_handshake( handshake_test_options* options )
#endif
int expected_handshake_result = 0;
USE_PSA_INIT( );
mbedtls_test_message_queue server_queue, client_queue;
mbedtls_test_message_socket_context server_context, client_context;
mbedtls_message_socket_init( &server_context );
@ -2242,6 +2283,7 @@ exit:
if( context_buf != NULL )
mbedtls_free( context_buf );
#endif
USE_PSA_DONE( );
}
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
@ -3699,6 +3741,10 @@ void ssl_decrypt_non_etm_cbc( int cipher_type, int hash_id, int trunc_hmac,
unsigned char padlen; /* excluding the padding_length byte */
unsigned char add_data[13];
unsigned char mac[MBEDTLS_MD_MAX_SIZE];
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
size_t sign_mac_length = 0;
#endif
int exp_ret;
int ret;
const unsigned char pad_max_len = 255; /* Per the standard */
@ -3782,11 +3828,24 @@ void ssl_decrypt_non_etm_cbc( int cipher_type, int hash_id, int trunc_hmac,
*/
/* MAC with additional data */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
TEST_EQUAL( PSA_SUCCESS, psa_mac_sign_setup( &operation,
t0.psa_mac_enc,
t0.psa_mac_alg ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation, add_data, 13 ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation,
rec.buf + rec.data_offset,
rec.data_len ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_sign_finish( &operation,
mac, MBEDTLS_MD_MAX_SIZE,
&sign_mac_length ) );
#else
TEST_EQUAL( 0, mbedtls_md_hmac_update( &t0.md_ctx_enc, add_data, 13 ) );
TEST_EQUAL( 0, mbedtls_md_hmac_update( &t0.md_ctx_enc,
rec.buf + rec.data_offset,
rec.data_len ) );
TEST_EQUAL( 0, mbedtls_md_hmac_finish( &t0.md_ctx_enc, mac ) );
#endif
memcpy( rec.buf + rec.data_offset + rec.data_len, mac, t0.maclen );
rec.data_len += t0.maclen;
@ -4814,7 +4873,7 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
void handshake_version( int dtls, int client_min_version, int client_max_version,
int server_min_version, int server_max_version,
int expected_negotiated_version )
@ -4837,7 +4896,7 @@ void handshake_version( int dtls, int client_min_version, int client_max_version
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
void handshake_psk_cipher( char* cipher, int pk_alg, data_t *psk_str, int dtls )
{
handshake_test_options options;
@ -4855,7 +4914,7 @@ void handshake_psk_cipher( char* cipher, int pk_alg, data_t *psk_str, int dtls )
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
void handshake_cipher( char* cipher, int pk_alg, int dtls )
{
test_handshake_psk_cipher( cipher, pk_alg, NULL, dtls );
@ -4865,7 +4924,7 @@ void handshake_cipher( char* cipher, int pk_alg, int dtls )
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_USE_PSA_CRYPTO:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED:MBEDTLS_ENTROPY_C:MBEDTLS_CTR_DRBG_C */
void app_data( int mfl, int cli_msg_len, int srv_msg_len,
int expected_cli_fragments,
int expected_srv_fragments, int dtls )
@ -5026,8 +5085,15 @@ void ssl_cf_hmac( int hash )
* Test the function mbedtls_ct_hmac() against a reference
* implementation.
*/
#if defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_algorithm_t alg;
psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
#else
mbedtls_md_context_t ctx, ref_ctx;
const mbedtls_md_info_t *md_info;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
size_t out_len, block_size;
size_t min_in_len, in_len, max_in_len, i;
/* TLS additional data is 13 bytes (hence the "lucky 13" name) */
@ -5037,6 +5103,20 @@ void ssl_cf_hmac( int hash )
unsigned char *out = NULL;
unsigned char rec_num = 0;
USE_PSA_INIT( );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
alg = PSA_ALG_HMAC( mbedtls_psa_translate_md( hash ) );
out_len = PSA_HASH_LENGTH( alg );
block_size = PSA_HASH_BLOCK_LENGTH( alg );
/* mbedtls_ct_hmac() requires the key to be exportable */
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT |
PSA_KEY_USAGE_VERIFY_HASH );
psa_set_key_algorithm( &attributes, PSA_ALG_HMAC( alg ) );
psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
#else
mbedtls_md_init( &ctx );
mbedtls_md_init( &ref_ctx );
@ -5045,10 +5125,18 @@ void ssl_cf_hmac( int hash )
out_len = mbedtls_md_get_size( md_info );
TEST_ASSERT( out_len != 0 );
block_size = hash == MBEDTLS_MD_SHA384 ? 128 : 64;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Use allocated out buffer to catch overwrites */
ASSERT_ALLOC( out, out_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
/* Set up dummy key */
memset( ref_out, 42, sizeof( ref_out ) );
TEST_EQUAL( PSA_SUCCESS, psa_import_key( &attributes,
ref_out, out_len,
&key ) );
#else
/* Set up contexts with the given hash and a dummy key */
TEST_EQUAL( 0, mbedtls_md_setup( &ctx, md_info, 1 ) );
TEST_EQUAL( 0, mbedtls_md_setup( &ref_ctx, md_info, 1 ) );
@ -5056,6 +5144,7 @@ void ssl_cf_hmac( int hash )
TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ctx, ref_out, out_len ) );
TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ref_ctx, ref_out, out_len ) );
memset( ref_out, 0, sizeof( ref_out ) );
#endif
/*
* Test all possible lengths up to a point. The difference between
@ -5082,13 +5171,31 @@ void ssl_cf_hmac( int hash )
/* Get the function's result */
TEST_CF_SECRET( &in_len, sizeof( in_len ) );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
TEST_EQUAL( 0, mbedtls_ct_hmac( key, PSA_ALG_HMAC( alg ),
add_data, sizeof( add_data ),
data, in_len,
min_in_len, max_in_len,
out ) );
#else
TEST_EQUAL( 0, mbedtls_ct_hmac( &ctx, add_data, sizeof( add_data ),
data, in_len,
min_in_len, max_in_len,
out ) );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
TEST_CF_PUBLIC( &in_len, sizeof( in_len ) );
TEST_CF_PUBLIC( out, out_len );
#if defined(MBEDTLS_USE_PSA_CRYPTO)
TEST_EQUAL( PSA_SUCCESS, psa_mac_verify_setup( &operation,
key, alg ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation, add_data,
sizeof( add_data ) ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation,
data, in_len ) );
TEST_EQUAL( PSA_SUCCESS, psa_mac_verify_finish( &operation,
out, out_len ) );
#else
/* Compute the reference result */
TEST_EQUAL( 0, mbedtls_md_hmac_update( &ref_ctx, add_data,
sizeof( add_data ) ) );
@ -5098,6 +5205,7 @@ void ssl_cf_hmac( int hash )
/* Compare */
ASSERT_COMPARE( out, out_len, ref_out, out_len );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
}
mbedtls_free( data );
@ -5105,11 +5213,18 @@ void ssl_cf_hmac( int hash )
}
exit:
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_mac_abort( &operation );
psa_destroy_key( key );
#else
mbedtls_md_free( &ref_ctx );
mbedtls_md_free( &ctx );
#endif /* MBEDTLS_USE_PSA_CRYPTO */
mbedtls_free( data );
mbedtls_free( out );
USE_PSA_DONE( );
}
/* END_CASE */