Squashed 'lib/mbedtls/external/mbedtls/' content from commit 2ca6c285a0dd

git-subtree-dir: lib/mbedtls/external/mbedtls
git-subtree-split: 2ca6c285a0dd3f33982dd57299012dacab1ff206
diff --git a/tests/suites/test_suite_constant_time_hmac.function b/tests/suites/test_suite_constant_time_hmac.function
new file mode 100644
index 0000000..0e870d8
--- /dev/null
+++ b/tests/suites/test_suite_constant_time_hmac.function
@@ -0,0 +1,159 @@
+/* BEGIN_HEADER */
+
+#include <mbedtls/constant_time.h>
+#include <mbedtls/md.h>
+#include <constant_time_internal.h>
+#include "mbedtls/psa_util.h"
+#include <ssl_misc.h>
+
+#include <test/constant_flow.h>
+/* END_HEADER */
+
+/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_MAC:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC:MBEDTLS_TEST_HOOKS */
+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) */
+    unsigned char add_data[13];
+    unsigned char ref_out[MBEDTLS_MD_MAX_SIZE];
+    unsigned char *data = NULL;
+    unsigned char *out = NULL;
+    unsigned char rec_num = 0;
+
+    USE_PSA_INIT();
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+    alg = PSA_ALG_HMAC(mbedtls_md_psa_alg_from_type(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);
+
+    md_info = mbedtls_md_info_from_type(hash);
+    TEST_ASSERT(md_info != NULL);
+    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 */
+    TEST_CALLOC(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));
+    memset(ref_out, 42, sizeof(ref_out));
+    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
+     * max_in_len and min_in_len is at most 255, and make sure they both vary
+     * by at least one block size.
+     */
+    for (max_in_len = 0; max_in_len <= 255 + block_size; max_in_len++) {
+        mbedtls_test_set_step(max_in_len * 10000);
+
+        /* Use allocated in buffer to catch overreads */
+        TEST_CALLOC(data, max_in_len);
+
+        min_in_len = max_in_len > 255 ? max_in_len - 255 : 0;
+        for (in_len = min_in_len; in_len <= max_in_len; in_len++) {
+            mbedtls_test_set_step(max_in_len * 10000 + in_len);
+
+            /* Set up dummy data and add_data */
+            rec_num++;
+            memset(add_data, rec_num, sizeof(add_data));
+            for (i = 0; i < in_len; i++) {
+                data[i] = (i & 0xff) ^ rec_num;
+            }
+
+            /* 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)));
+            TEST_EQUAL(0, mbedtls_md_hmac_update(&ref_ctx, data, in_len));
+            TEST_EQUAL(0, mbedtls_md_hmac_finish(&ref_ctx, ref_out));
+            TEST_EQUAL(0, mbedtls_md_hmac_reset(&ref_ctx));
+
+            /* Compare */
+            TEST_MEMORY_COMPARE(out, out_len, ref_out, out_len);
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+        }
+
+        mbedtls_free(data);
+        data = NULL;
+    }
+
+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 */