1/* BEGIN_HEADER */ 2 3#include <mbedtls/constant_time.h> 4#include <mbedtls/legacy_or_psa.h> 5#include <mbedtls/md.h> 6#include <constant_time_internal.h> 7#include <hash_info.h> 8 9#include <test/constant_flow.h> 10/* END_HEADER */ 11 12/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC:MBEDTLS_TEST_HOOKS */ 13void ssl_cf_hmac( int hash ) 14{ 15 /* 16 * Test the function mbedtls_ct_hmac() against a reference 17 * implementation. 18 */ 19#if defined(MBEDTLS_USE_PSA_CRYPTO) 20 mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 21 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 22 psa_algorithm_t alg; 23 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; 24#else 25 mbedtls_md_context_t ctx, ref_ctx; 26 const mbedtls_md_info_t *md_info; 27#endif /* MBEDTLS_USE_PSA_CRYPTO */ 28 size_t out_len, block_size; 29 size_t min_in_len, in_len, max_in_len, i; 30 /* TLS additional data is 13 bytes (hence the "lucky 13" name) */ 31 unsigned char add_data[13]; 32 unsigned char ref_out[MBEDTLS_HASH_MAX_SIZE]; 33 unsigned char *data = NULL; 34 unsigned char *out = NULL; 35 unsigned char rec_num = 0; 36 37 USE_PSA_INIT( ); 38 39#if defined(MBEDTLS_USE_PSA_CRYPTO) 40 alg = PSA_ALG_HMAC( mbedtls_hash_info_psa_from_md( hash ) ); 41 42 out_len = PSA_HASH_LENGTH( alg ); 43 block_size = PSA_HASH_BLOCK_LENGTH( alg ); 44 45 /* mbedtls_ct_hmac() requires the key to be exportable */ 46 psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT | 47 PSA_KEY_USAGE_VERIFY_HASH ); 48 psa_set_key_algorithm( &attributes, PSA_ALG_HMAC( alg ) ); 49 psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); 50#else 51 mbedtls_md_init( &ctx ); 52 mbedtls_md_init( &ref_ctx ); 53 54 md_info = mbedtls_md_info_from_type( hash ); 55 TEST_ASSERT( md_info != NULL ); 56 out_len = mbedtls_md_get_size( md_info ); 57 TEST_ASSERT( out_len != 0 ); 58 block_size = hash == MBEDTLS_MD_SHA384 ? 128 : 64; 59#endif /* MBEDTLS_USE_PSA_CRYPTO */ 60 61 /* Use allocated out buffer to catch overwrites */ 62 ASSERT_ALLOC( out, out_len ); 63 64#if defined(MBEDTLS_USE_PSA_CRYPTO) 65 /* Set up dummy key */ 66 memset( ref_out, 42, sizeof( ref_out ) ); 67 TEST_EQUAL( PSA_SUCCESS, psa_import_key( &attributes, 68 ref_out, out_len, 69 &key ) ); 70#else 71 /* Set up contexts with the given hash and a dummy key */ 72 TEST_EQUAL( 0, mbedtls_md_setup( &ctx, md_info, 1 ) ); 73 TEST_EQUAL( 0, mbedtls_md_setup( &ref_ctx, md_info, 1 ) ); 74 memset( ref_out, 42, sizeof( ref_out ) ); 75 TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ctx, ref_out, out_len ) ); 76 TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ref_ctx, ref_out, out_len ) ); 77 memset( ref_out, 0, sizeof( ref_out ) ); 78#endif 79 80 /* 81 * Test all possible lengths up to a point. The difference between 82 * max_in_len and min_in_len is at most 255, and make sure they both vary 83 * by at least one block size. 84 */ 85 for( max_in_len = 0; max_in_len <= 255 + block_size; max_in_len++ ) 86 { 87 mbedtls_test_set_step( max_in_len * 10000 ); 88 89 /* Use allocated in buffer to catch overreads */ 90 ASSERT_ALLOC( data, max_in_len ); 91 92 min_in_len = max_in_len > 255 ? max_in_len - 255 : 0; 93 for( in_len = min_in_len; in_len <= max_in_len; in_len++ ) 94 { 95 mbedtls_test_set_step( max_in_len * 10000 + in_len ); 96 97 /* Set up dummy data and add_data */ 98 rec_num++; 99 memset( add_data, rec_num, sizeof( add_data ) ); 100 for( i = 0; i < in_len; i++ ) 101 data[i] = ( i & 0xff ) ^ rec_num; 102 103 /* Get the function's result */ 104 TEST_CF_SECRET( &in_len, sizeof( in_len ) ); 105#if defined(MBEDTLS_USE_PSA_CRYPTO) 106 TEST_EQUAL( 0, mbedtls_ct_hmac( key, PSA_ALG_HMAC( alg ), 107 add_data, sizeof( add_data ), 108 data, in_len, 109 min_in_len, max_in_len, 110 out ) ); 111#else 112 TEST_EQUAL( 0, mbedtls_ct_hmac( &ctx, add_data, sizeof( add_data ), 113 data, in_len, 114 min_in_len, max_in_len, 115 out ) ); 116#endif /* MBEDTLS_USE_PSA_CRYPTO */ 117 TEST_CF_PUBLIC( &in_len, sizeof( in_len ) ); 118 TEST_CF_PUBLIC( out, out_len ); 119 120#if defined(MBEDTLS_USE_PSA_CRYPTO) 121 TEST_EQUAL( PSA_SUCCESS, psa_mac_verify_setup( &operation, 122 key, alg ) ); 123 TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation, add_data, 124 sizeof( add_data ) ) ); 125 TEST_EQUAL( PSA_SUCCESS, psa_mac_update( &operation, 126 data, in_len ) ); 127 TEST_EQUAL( PSA_SUCCESS, psa_mac_verify_finish( &operation, 128 out, out_len ) ); 129#else 130 /* Compute the reference result */ 131 TEST_EQUAL( 0, mbedtls_md_hmac_update( &ref_ctx, add_data, 132 sizeof( add_data ) ) ); 133 TEST_EQUAL( 0, mbedtls_md_hmac_update( &ref_ctx, data, in_len ) ); 134 TEST_EQUAL( 0, mbedtls_md_hmac_finish( &ref_ctx, ref_out ) ); 135 TEST_EQUAL( 0, mbedtls_md_hmac_reset( &ref_ctx ) ); 136 137 /* Compare */ 138 ASSERT_COMPARE( out, out_len, ref_out, out_len ); 139#endif /* MBEDTLS_USE_PSA_CRYPTO */ 140 } 141 142 mbedtls_free( data ); 143 data = NULL; 144 } 145 146exit: 147#if defined(MBEDTLS_USE_PSA_CRYPTO) 148 psa_mac_abort( &operation ); 149 psa_destroy_key( key ); 150#else 151 mbedtls_md_free( &ref_ctx ); 152 mbedtls_md_free( &ctx ); 153#endif /* MBEDTLS_USE_PSA_CRYPTO */ 154 155 mbedtls_free( data ); 156 mbedtls_free( out ); 157 158 USE_PSA_DONE( ); 159} 160/* END_CASE */ 161