| /* BEGIN_HEADER */ |
| /* |
| * Test suite for the PSA hash built-in driver |
| * |
| * This test suite exercises some aspects of the built-in PSA driver for |
| * hash algorithms (psa_crypto_hash.c). This code is mostly tested via |
| * the application interface (above the PSA API layer) and via tests of |
| * individual hash modules. The goal of this test suite is to ensure that |
| * the driver dispatch layer behaves correctly even when not invoked via |
| * the API layer, but directly from another driver. |
| * |
| * This test suite is currently incomplete. It focuses on non-regression |
| * tests for past bugs or near misses. |
| */ |
| |
| #include <psa_crypto_hash.h> |
| |
| /* END_HEADER */ |
| |
| /* BEGIN_DEPENDENCIES |
| * depends_on:MBEDTLS_PSA_BUILTIN_HASH |
| * END_DEPENDENCIES |
| */ |
| |
| /* BEGIN_CASE */ |
| void hash_valid_one_shot(int alg_arg, data_t *input, |
| data_t *expected) |
| { |
| psa_algorithm_t alg = alg_arg; |
| uint8_t *output = NULL; |
| size_t output_size = expected->len; |
| size_t length = SIZE_MAX; |
| |
| /* Nominal case */ |
| ASSERT_ALLOC(output, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_compute(alg, input->x, input->len, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected->x, expected->len, output, length); |
| mbedtls_free(output); |
| output = NULL; |
| |
| /* Larger output buffer */ |
| output_size = expected->len + 1; |
| ASSERT_ALLOC(output, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_compute(alg, input->x, input->len, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected->x, expected->len, output, length); |
| mbedtls_free(output); |
| output = NULL; |
| |
| /* We don't test with a smaller output buffer because this isn't |
| * guaranteed to work: the core must pass a sufficiently large |
| * output buffer to the driver. */ |
| |
| exit: |
| mbedtls_free(output); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void hash_valid_multipart(int alg_arg, |
| data_t *input1, data_t *expected1, |
| data_t *input2, data_t *expected2) |
| { |
| psa_algorithm_t alg = alg_arg; |
| uint8_t *output = NULL; |
| size_t output_size = expected1->len; |
| size_t length = SIZE_MAX; |
| mbedtls_psa_hash_operation_t operation0; // original |
| memset(&operation0, 0, sizeof(operation0)); |
| mbedtls_psa_hash_operation_t clone_start; // cloned after setup |
| memset(&clone_start, 0, sizeof(clone_start)); |
| mbedtls_psa_hash_operation_t clone_middle; // cloned between updates |
| memset(&clone_middle, 0, sizeof(clone_middle)); |
| mbedtls_psa_hash_operation_t clone_end; // cloned before finish |
| memset(&clone_end, 0, sizeof(clone_end)); |
| mbedtls_psa_hash_operation_t clone_more; // cloned before finish |
| memset(&clone_more, 0, sizeof(clone_more)); |
| |
| /* Nominal case with two update calls */ |
| ASSERT_ALLOC(output, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_setup(&operation0, alg), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_clone(&operation0, &clone_start), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_update(&operation0, input1->x, input1->len), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_clone(&operation0, &clone_middle), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_update(&operation0, input2->x, input2->len), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_clone(&operation0, &clone_end), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&operation0, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected2->x, expected2->len, output, length); |
| |
| /* Nominal case with an operation cloned after setup */ |
| memset(output, 0, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_update(&clone_start, input1->x, input1->len), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&clone_start, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected1->x, expected1->len, output, length); |
| |
| /* Nominal case with an operation cloned between updates */ |
| memset(output, 0, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_update(&clone_middle, input2->x, input2->len), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&clone_middle, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected2->x, expected2->len, output, length); |
| |
| /* Nominal case with an operation cloned before finish */ |
| TEST_EQUAL(mbedtls_psa_hash_clone(&clone_end, &clone_more), |
| PSA_SUCCESS); |
| memset(output, 0, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&clone_end, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected2->x, expected2->len, output, length); |
| mbedtls_free(output); |
| output = NULL; |
| |
| /* Larger output buffer */ |
| TEST_EQUAL(mbedtls_psa_hash_clone(&clone_more, &clone_end), |
| PSA_SUCCESS); |
| output_size = expected2->len + 1; |
| ASSERT_ALLOC(output, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&clone_end, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected2->x, expected2->len, output, length); |
| mbedtls_free(output); |
| output = NULL; |
| |
| /* We don't test with a smaller output buffer because this isn't |
| * guaranteed to work: the core must pass a sufficiently large |
| * output buffer to the driver. */ |
| |
| /* Nominal case again after an error in a cloned operation */ |
| output_size = expected2->len; |
| ASSERT_ALLOC(output, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&clone_more, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected2->x, expected2->len, output, length); |
| mbedtls_free(output); |
| output = NULL; |
| |
| exit: |
| mbedtls_free(output); |
| mbedtls_psa_hash_abort(&operation0); |
| mbedtls_psa_hash_abort(&clone_start); |
| mbedtls_psa_hash_abort(&clone_middle); |
| mbedtls_psa_hash_abort(&clone_end); |
| mbedtls_psa_hash_abort(&clone_more); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void hash_empty(int alg_arg, data_t *expected) |
| { |
| psa_algorithm_t alg = alg_arg; |
| uint8_t *output = NULL; |
| size_t output_size = expected->len; |
| size_t length = SIZE_MAX; |
| mbedtls_psa_hash_operation_t operation; |
| memset(&operation, 0, sizeof(operation)); |
| |
| ASSERT_ALLOC(output, output_size); |
| |
| /* One-shot */ |
| TEST_EQUAL(mbedtls_psa_hash_compute(alg, NULL, 0, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected->x, expected->len, output, length); |
| |
| /* Multipart, no update */ |
| memset(output, 0, output_size); |
| TEST_EQUAL(mbedtls_psa_hash_setup(&operation, alg), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&operation, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected->x, expected->len, output, length); |
| |
| /* Multipart, one update */ |
| memset(output, 0, output_size); |
| memset(&operation, 0, sizeof(operation)); |
| TEST_EQUAL(mbedtls_psa_hash_setup(&operation, alg), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_update(&operation, NULL, 0), |
| PSA_SUCCESS); |
| TEST_EQUAL(mbedtls_psa_hash_finish(&operation, |
| output, output_size, &length), |
| PSA_SUCCESS); |
| ASSERT_COMPARE(expected->x, expected->len, output, length); |
| |
| exit: |
| mbedtls_free(output); |
| mbedtls_psa_hash_abort(&operation); |
| } |
| /* END_CASE */ |