/* 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 */
