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