1/* BEGIN_HEADER */
2
3#include <stdint.h>
4#include "psa/crypto.h"
5
6/* END_HEADER */
7
8/* BEGIN_DEPENDENCIES
9 * depends_on:MBEDTLS_PSA_CRYPTO_C
10 * END_DEPENDENCIES
11 */
12
13/* BEGIN_CASE */
14void hash_finish(int alg_arg, data_t *input, data_t *expected_hash)
15{
16    psa_algorithm_t alg = alg_arg;
17    unsigned char actual_hash[PSA_HASH_MAX_SIZE];
18    size_t actual_hash_length;
19    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
20
21    PSA_ASSERT(psa_crypto_init());
22
23    PSA_ASSERT(psa_hash_setup(&operation, alg));
24    PSA_ASSERT(psa_hash_update(&operation,
25                               input->x, input->len));
26    PSA_ASSERT(psa_hash_finish(&operation,
27                               actual_hash, sizeof(actual_hash),
28                               &actual_hash_length));
29    TEST_MEMORY_COMPARE(expected_hash->x, expected_hash->len,
30                        actual_hash, actual_hash_length);
31
32exit:
33    psa_hash_abort(&operation);
34    PSA_DONE();
35}
36/* END_CASE */
37
38/* BEGIN_CASE */
39void hmac(int alg_arg, char *input, data_t *expected_mac)
40{
41    psa_algorithm_t alg = PSA_ALG_HMAC(alg_arg);
42
43    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
44    psa_key_type_t key_type = PSA_KEY_TYPE_HMAC;
45    const uint8_t key_data[] = { // 32 bytes of 0xaa
46        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
47        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
48        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
49    };
50    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
51
52    PSA_ASSERT(psa_crypto_init());
53
54    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
55    psa_set_key_algorithm(&attributes, alg);
56    psa_set_key_type(&attributes, key_type);
57    PSA_ASSERT(psa_import_key(&attributes, key_data, sizeof(key_data), &key));
58
59    uint8_t mac[PSA_MAC_MAX_SIZE + 10] = { 0 };
60    size_t mac_length = 0;
61
62    size_t input_len = strlen(input);
63    PSA_ASSERT(psa_mac_compute(key, alg, (uint8_t const *) input, input_len, mac, sizeof(mac),
64                               &mac_length));
65
66    // manual comparison against expected MAC
67    ASSERT_COMPARE(expected_mac->x, expected_mac->len, mac, mac_length);
68
69    // use psa_mac_verify to compare to expected MAC
70    PSA_ASSERT(psa_mac_verify(key, alg, (uint8_t const *) input, input_len, expected_mac->x,
71                              expected_mac->len));
72
73    // corrupt the MAC and check that psa_mac_verify fails
74    expected_mac->x[0] ^= 0x7f;
75    TEST_EQUAL(psa_mac_verify(key, alg, (uint8_t const *) input, input_len, expected_mac->x,
76                              expected_mac->len), PSA_ERROR_INVALID_SIGNATURE);
77
78    PSA_ASSERT(psa_destroy_key(key));
79exit:
80    PSA_DONE();
81}
82/* END_CASE */
83
84/* BEGIN_CASE */
85void hash_verify(int alg_arg, data_t *input, data_t *expected_hash)
86{
87    psa_algorithm_t alg = alg_arg;
88    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
89
90    PSA_ASSERT(psa_crypto_init());
91
92    PSA_ASSERT(psa_hash_setup(&operation, alg));
93    PSA_ASSERT(psa_hash_update(&operation,
94                               input->x,
95                               input->len));
96    PSA_ASSERT(psa_hash_verify(&operation,
97                               expected_hash->x,
98                               expected_hash->len));
99
100exit:
101    psa_hash_abort(&operation);
102    PSA_DONE();
103}
104/* END_CASE */
105
106/* BEGIN_CASE */
107void hash_multi_part(int alg_arg, data_t *input, data_t *expected_hash)
108{
109    psa_algorithm_t alg = alg_arg;
110    unsigned char actual_hash[PSA_HASH_MAX_SIZE];
111    size_t actual_hash_length;
112    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
113    psa_hash_operation_t operation2 = PSA_HASH_OPERATION_INIT;
114    uint32_t len = 0;
115
116    PSA_ASSERT(psa_crypto_init());
117
118    do {
119        memset(actual_hash, 0, sizeof(actual_hash));
120        PSA_ASSERT(psa_hash_setup(&operation, alg));
121
122        PSA_ASSERT(psa_hash_update(&operation,
123                                   input->x, len));
124        PSA_ASSERT(psa_hash_clone(&operation, &operation2));
125        PSA_ASSERT(psa_hash_update(&operation,
126                                   input->x + len, input->len - len));
127        PSA_ASSERT(psa_hash_update(&operation2,
128                                   input->x + len, input->len - len));
129
130        PSA_ASSERT(psa_hash_finish(&operation,
131                                   actual_hash, sizeof(actual_hash),
132                                   &actual_hash_length));
133        TEST_MEMORY_COMPARE(expected_hash->x, expected_hash->len,
134                            actual_hash, actual_hash_length);
135
136        PSA_ASSERT(psa_hash_finish(&operation2,
137                                   actual_hash, sizeof(actual_hash),
138                                   &actual_hash_length));
139        TEST_MEMORY_COMPARE(expected_hash->x, expected_hash->len,
140                            actual_hash, actual_hash_length);
141    } while (len++ != input->len);
142
143exit:
144    psa_hash_abort(&operation);
145    psa_hash_abort(&operation2);
146    PSA_DONE();
147}
148/* END_CASE */
149