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