blob: 046fef701af97c4a5c14d2fdef20bd8be670b95c [file] [log] [blame]
Maulik Patel5204dc02023-11-08 08:36:31 +00001/*
2 * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "adac_crypto_psa.h"
9#include "psa_adac_debug.h"
10
11#if (defined(PSA_ADAC_CMAC) || defined(PSA_ADAC_HMAC))
12
13psa_status_t psa_adac_mac_verify(psa_algorithm_t alg,
14 const uint8_t *inputs[],
15 size_t input_sizes[],
16 size_t input_count,
17 const uint8_t key[],
18 size_t key_size,
19 uint8_t mac[],
20 size_t mac_size)
21{
22 psa_status_t ret = PSA_ERROR_NOT_SUPPORTED;
23 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
24 psa_key_handle_t handle;
25
26 if (alg == PSA_ALG_CMAC) {
27 if (key_size != 16U) {
28 ret = PSA_ERROR_INVALID_ARGUMENT;
29 } else {
30 ret = PSA_SUCCESS;
31 }
32 }
33
34 if (ret == PSA_SUCCESS) {
35 psa_set_key_usage_flags(&attributes, 0);
36 psa_set_key_algorithm(&attributes, alg);
37 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
38 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
39 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
40 psa_set_key_bits(&attributes, 128);
41
42 ret = psa_import_key(&attributes, key, key_size, &handle);
43 if (ret == PSA_SUCCESS) {
44 psa_mac_operation_t operation = psa_mac_operation_init();
45 ret = psa_mac_verify_setup(&operation, handle, alg);
46 for (size_t i = 0; (ret == PSA_SUCCESS) && (i < input_count); i++) {
47 ret = psa_mac_update(&operation, inputs[i], input_sizes[i]);
48 }
49 if (ret == PSA_SUCCESS) {
50 ret = psa_mac_verify_finish(&operation, mac, mac_size);
51 }
52 psa_destroy_key(handle);
53 psa_mac_abort(&operation);
54 }
55 }
56
57 return ret;
58}
59
60psa_status_t psa_adac_derive_hmac(uint8_t *key,
61 uint8_t *info,
62 size_t size,
63 uint8_t *output)
64{
65 psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
66 psa_key_handle_t handle;
67
68 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
69 psa_set_key_usage_flags(&attributes, 0);
70 psa_set_key_algorithm(&attributes, alg);
71 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
72 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
73 psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE);
74 psa_set_key_bits(&attributes, 256);
75
76 psa_status_t ret = psa_import_key(&attributes, key, 32, &handle);
77 if (ret == PSA_SUCCESS) {
78 psa_key_derivation_operation_t operation = psa_key_derivation_operation_init();
79 ret = psa_key_derivation_setup(&operation, alg);
80 if (ret == PSA_SUCCESS) {
81 ret = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_SECRET, handle);
82 }
83 if (ret == PSA_SUCCESS) {
84 ret = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_INFO, info, size);
85 }
86 if (ret == PSA_SUCCESS) {
87 ret = psa_key_derivation_output_bytes(&operation, output, 32);
88 }
89 psa_destroy_key(handle);
90 psa_key_derivation_abort(&operation);
91 }
92 return ret;
93}
94
95/* A key-derivation function can iterates n times until l bits of keying material are generated.
96 For each of the iterations of the PRF, i=1 to n, do:
97 result(0) = 0;
98 K(i) = PRF (Ki, [i] || Label || 0x00 || Context || length);
99 results(i) = result(i-1) || K(i);
100
101 concisely, result(i) = K(i) || k(i-1) || .... || k(0)*/
102
103/* NIST SP800-108 + Inspiration from SCP03 */
104/* Label || 0x00 || [L]_2 || [i]_2 || Context */
105
106psa_status_t psa_adac_derive_cmac(uint8_t *key, uint8_t *context, size_t context_size, uint8_t *output)
107{
108 psa_algorithm_t alg = PSA_ALG_CMAC;
109 psa_key_handle_t handle;
110 size_t l = 0;
111 uint8_t info[16] = {
112 /* Label = 'PSA ADAC 1.0' */
113 0x50, 0x53, 0x41, 0x20, 0x41, 0x44, 0x41, 0x43, 0x20, 0x31, 0x2E, 0x30,
114 /* Separator (0x00) */
115 0x00,
116 /* [L]_2 = 128 (encoded in 16 bit) */
117 0x00, 0x80,
118 /* [i]_2 = 8-bit counter */
119 0x01
120 /* Context = input */
121 };
122
123 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
124 psa_set_key_usage_flags(&attributes, 0);
125 psa_set_key_algorithm(&attributes, alg);
126 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
127 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
128 psa_set_key_bits(&attributes, 128);
129
130 psa_status_t ret = psa_import_key(&attributes, key, 16, &handle);
131 if (ret == PSA_SUCCESS) {
132 psa_mac_operation_t operation = psa_mac_operation_init();
133 ret = psa_mac_sign_setup(&operation, handle, alg);
134 if (ret == PSA_SUCCESS) {
135 ret = psa_mac_update(&operation, info, sizeof(info));
136 }
137 if (ret == PSA_SUCCESS) {
138 ret = psa_mac_update(&operation, context, context_size);
139 }
140 if (ret == PSA_SUCCESS) {
141 ret = psa_mac_sign_finish(&operation, output, 16, &l);
142 if ((ret == PSA_SUCCESS) && (l != 16U)) {
143 ret = PSA_ERROR_GENERIC_ERROR;
144 }
145 }
146 psa_destroy_key(handle);
147 psa_mac_abort(&operation);
148 }
149
150 return ret;
151}
152
153psa_status_t psa_adac_derive_key(uint8_t *crt,
154 size_t crt_size,
155 uint8_t key_type,
156 uint8_t *key,
157 size_t key_size)
158{
159 psa_status_t ret;
160
161 if (key_type == CMAC_AES) {
162#ifdef PSA_ADAC_CMAC
163 if ((key_size == 16U) && (crt_size >= sizeof(certificate_cmac_cmac_t))) {
164 ret = psa_adac_derive_cmac(key, crt, offsetof(certificate_cmac_cmac_t, signature), key);
165 PSA_ADAC_LOG_DUMP("psa_adac_derive_key", "cmac", key, 16);
166 } else {
167 ret = PSA_ERROR_INVALID_ARGUMENT;
168 }
169#else
170 ret = PSA_ERROR_NOT_SUPPORTED;
171#endif /* PSA_ADAC_CMAC */
172 } else if (key_type == HMAC_SHA256) {
173#ifdef PSA_ADAC_HMAC
174 if ((key_size == 32U) && (crt_size >= sizeof(certificate_hmac_hmac_t))) {
175 ret = psa_adac_derive_hmac(key, crt, offsetof(certificate_hmac_hmac_t, signature), key);
176 PSA_ADAC_LOG_DUMP("psa_adac_derive_key", "hmac", key, 32);
177 } else {
178 ret = PSA_ERROR_INVALID_ARGUMENT;
179 }
180#else
181 ret = PSA_ERROR_NOT_SUPPORTED;
182#endif /* PSA_ADAC_HMAC */
183 } else {
184 ret = PSA_ERROR_NOT_SUPPORTED;
185 }
186
187 return ret;
188}
189
190psa_status_t psa_adac_verify_mac(uint8_t key_type,
191 uint8_t *key,
192 size_t key_size,
193 const uint8_t *inputs[],
194 size_t input_sizes[],
195 size_t input_count,
196 psa_algorithm_t mac_algo,
197 uint8_t *mac,
198 size_t mac_size)
199{
200 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
201 psa_key_handle_t handle = -1;
202 psa_status_t ret = PSA_ERROR_NOT_SUPPORTED;
203 psa_key_type_t type = 0;
204 size_t bits = 0;
205
206#ifdef PSA_ADAC_CMAC
207 if ((key_type == CMAC_AES) && (mac_algo == CMAC_SIGN_ALGORITHM)) {
208 if (key_size != 16U) {
209 ret = PSA_ERROR_INVALID_ARGUMENT;
210 } else {
211 ret = PSA_SUCCESS;
212 type = PSA_KEY_TYPE_AES;
213 bits = 128;
214 }
215 }
216#endif /* PSA_ADAC_CMAC */
217
218#ifdef PSA_ADAC_HMAC
219 if ((key_type == HMAC_SHA256) && (mac_algo == HMAC_SIGN_ALGORITHM)) {
220 if (key_size != 32U) {
221 ret = PSA_ERROR_INVALID_ARGUMENT;
222 } else {
223 ret = PSA_SUCCESS;
224 type = PSA_KEY_TYPE_HMAC;
225 bits = 256;
226 }
227 }
228#endif /* PSA_ADAC_HMAC */
229
230 if (ret == PSA_SUCCESS) {
231 psa_set_key_usage_flags(&attributes, 0);
232 psa_set_key_algorithm(&attributes, mac_algo);
233 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
234 psa_set_key_type(&attributes, type);
235 psa_set_key_bits(&attributes, bits);
236 ret = psa_import_key(&attributes, key, key_size, &handle);
237
238 if (PSA_SUCCESS != ret) {
239 PSA_ADAC_LOG_ERR("self", "Error importing key (%d)\n", ret);
240 } else {
241 psa_mac_operation_t operation = psa_mac_operation_init();
242 ret = psa_mac_verify_setup(&operation, handle, mac_algo);
243 for (size_t i = 0; (ret == PSA_SUCCESS) && (i < input_count); i++) {
244 ret = psa_mac_update(&operation, inputs[i], input_sizes[i]);
245 }
246 if (ret == PSA_SUCCESS) {
247 ret = psa_mac_verify_finish(&operation, mac, mac_size);
248 }
249 if (PSA_SUCCESS != ret) {
250 PSA_ADAC_LOG_ERR("self", "Error during MAC verification (%d)\n", ret);
251 }
252 psa_destroy_key(handle);
253 psa_mac_abort(&operation);
254 }
255 }
256
257 return ret;
258}
259
260#endif /*(defined(PSA_ADAC_CMAC) || defined(PSA_ADAC_HMAC)) */