1 /*
2 * Copyright The Mbed TLS Contributors
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * Copyright 2023-2024 NXP
20 *
21 * @file supp_psa_api.c
22 * @brief This file provides wpa supplicant crypto mbedtls PSA APIs.
23 */
24
25 #include "supp_psa_api.h"
26
27 #define ASSERT_STATUS(actual, expected) \
28 do \
29 { \
30 if ((actual) != (expected)) \
31 { \
32 printk( \
33 "\tassertion failed at %s:%d - " \
34 "actual:%d expected:%d\r\n", \
35 __FILE__, __LINE__, (psa_status_t)actual, (psa_status_t)expected); \
36 goto exit; \
37 } \
38 } while (0)
39
40 #define SUPP_PSA_MAX_OUTPUT_SIZE 2048
41
42 static uint8_t supp_psa_outbuf[SUPP_PSA_MAX_OUTPUT_SIZE];
43
supp_psa_set_attributes(psa_key_attributes_t * attributes,u32 type,u32 alg,u32 usage)44 static inline void supp_psa_set_attributes(psa_key_attributes_t *attributes, u32 type, u32 alg, u32 usage)
45 {
46 psa_set_key_type(attributes, type);
47 psa_set_key_algorithm(attributes, alg);
48 psa_set_key_usage_flags(attributes, usage);
49 }
50
supp_psa_get_hash_alg(mbedtls_md_type_t type,psa_algorithm_t * alg,int * block_size)51 static void supp_psa_get_hash_alg(mbedtls_md_type_t type, psa_algorithm_t *alg, int *block_size)
52 {
53 switch (type)
54 {
55 case MBEDTLS_MD_MD5:
56 *alg = PSA_ALG_MD5;
57 break;
58 case MBEDTLS_MD_SHA1:
59 *alg = PSA_ALG_SHA_1;
60 break;
61 case MBEDTLS_MD_SHA224:
62 *alg = PSA_ALG_SHA_224;
63 break;
64 case MBEDTLS_MD_SHA256:
65 *alg = PSA_ALG_SHA_256;
66 break;
67 case MBEDTLS_MD_SHA384:
68 *alg = PSA_ALG_SHA_384;
69 break;
70 case MBEDTLS_MD_SHA512:
71 *alg = PSA_ALG_SHA_512;
72 break;
73 case MBEDTLS_MD_RIPEMD160:
74 *alg = PSA_ALG_RIPEMD160;
75 break;
76 default:
77 *alg = PSA_ALG_NONE;
78 break;
79 }
80 *block_size = PSA_HASH_LENGTH(*alg);
81 }
82
supp_psa_cipher_operation(psa_cipher_operation_t * operation,const uint8_t * input,size_t input_size,size_t part_size,uint8_t * output,size_t output_size,size_t * output_len)83 static psa_status_t supp_psa_cipher_operation(psa_cipher_operation_t *operation,
84 const uint8_t *input,
85 size_t input_size,
86 size_t part_size,
87 uint8_t *output,
88 size_t output_size,
89 size_t *output_len)
90 {
91 psa_status_t status;
92 size_t bytes_to_write = 0;
93 size_t bytes_written = 0;
94 size_t len = 0;
95
96 *output_len = 0;
97 while (bytes_written != input_size)
98 {
99 bytes_to_write = (input_size - bytes_written > part_size ? part_size : input_size - bytes_written);
100
101 status = psa_cipher_update(operation, input + bytes_written, bytes_to_write, output + *output_len,
102 output_size - *output_len, &len);
103 ASSERT_STATUS(status, PSA_SUCCESS);
104
105 bytes_written += bytes_to_write;
106 *output_len += len;
107 }
108
109 status = psa_cipher_finish(operation, output + *output_len, output_size - *output_len, &len);
110 ASSERT_STATUS(status, PSA_SUCCESS);
111 *output_len += len;
112
113 exit:
114 return status;
115 }
116
117 #ifdef MBEDTLS_AES_C
118 #define SUPP_PSA_AES_BLOCK_SIZE 16
119
aes_128_encrypt_block_psa(const u8 * key,const u8 * in,u8 * out)120 int aes_128_encrypt_block_psa(const u8 *key, const u8 *in, u8 *out)
121 {
122 psa_status_t status;
123 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
124 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
125 psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING;
126 size_t out_len = 0;
127
128 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_AES, alg, PSA_KEY_USAGE_ENCRYPT);
129
130 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
131 ASSERT_STATUS(status, PSA_SUCCESS);
132 psa_reset_key_attributes(&attributes);
133
134 status = psa_cipher_encrypt(key_id, alg, in, SUPP_PSA_BLOCK_SIZE_128, out, SUPP_PSA_BLOCK_SIZE_128, &out_len);
135 ASSERT_STATUS(status, PSA_SUCCESS);
136
137 exit:
138 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
139 {
140 psa_destroy_key(key_id);
141 }
142 return (int)status;
143 }
144
aes_128_cbc_encrypt_psa(const u8 * key,const u8 * iv,u8 * data,size_t data_len)145 int aes_128_cbc_encrypt_psa(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
146 {
147 psa_status_t status;
148 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
149 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
150 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
151 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
152 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
153 size_t out_len = 0;
154
155 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
156 {
157 printk("%s invalid input len %d", __func__, data_len);
158 return -1;
159 }
160
161 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_ENCRYPT);
162
163 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
164 ASSERT_STATUS(status, PSA_SUCCESS);
165 psa_reset_key_attributes(&attributes);
166
167 status = psa_cipher_encrypt_setup(&operation, key_id, alg);
168 ASSERT_STATUS(status, PSA_SUCCESS);
169
170 status = psa_cipher_set_iv(&operation, iv, PSA_CIPHER_IV_LENGTH(key_type, alg));
171 ASSERT_STATUS(status, PSA_SUCCESS);
172
173 memset(supp_psa_outbuf, 0x0, data_len);
174 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
175 supp_psa_outbuf, data_len, &out_len);
176 ASSERT_STATUS(status, PSA_SUCCESS);
177
178 memcpy(data, supp_psa_outbuf, out_len);
179 exit:
180 psa_cipher_abort(&operation);
181 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
182 {
183 psa_destroy_key(key_id);
184 }
185 return (int)status;
186 }
187
aes_128_cbc_decrypt_psa(const u8 * key,const u8 * iv,u8 * data,size_t data_len)188 int aes_128_cbc_decrypt_psa(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
189 {
190 psa_status_t status;
191 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
192 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
193 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
194 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
195 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
196 size_t out_len = 0;
197
198 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
199 {
200 printk("%s invalid input len %d", __func__, data_len);
201 return -1;
202 }
203
204 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_DECRYPT);
205
206 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
207 ASSERT_STATUS(status, PSA_SUCCESS);
208 psa_reset_key_attributes(&attributes);
209
210 status = psa_cipher_decrypt_setup(&operation, key_id, alg);
211 ASSERT_STATUS(status, PSA_SUCCESS);
212
213 status = psa_cipher_set_iv(&operation, iv, PSA_CIPHER_IV_LENGTH(key_type, alg));
214 ASSERT_STATUS(status, PSA_SUCCESS);
215
216 memset(supp_psa_outbuf, 0x0, data_len);
217 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
218 supp_psa_outbuf, data_len, &out_len);
219 ASSERT_STATUS(status, PSA_SUCCESS);
220
221 memcpy(data, supp_psa_outbuf, out_len);
222 exit:
223 psa_cipher_abort(&operation);
224 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
225 {
226 psa_destroy_key(key_id);
227 }
228 return (int)status;
229 }
230
aes_ctr_encrypt_psa(const u8 * key,size_t key_len,const u8 * nonce,u8 * data,size_t data_len)231 int aes_ctr_encrypt_psa(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len)
232 {
233 psa_status_t status;
234 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
235 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
236 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
237 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
238 psa_algorithm_t alg = PSA_ALG_CTR;
239 size_t out_len = 0;
240
241 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
242 {
243 printk("%s invalid input len %d", __func__, data_len);
244 return -1;
245 }
246
247 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_ENCRYPT);
248
249 status = psa_import_key(&attributes, key, key_len, &key_id);
250 ASSERT_STATUS(status, PSA_SUCCESS);
251 psa_reset_key_attributes(&attributes);
252
253 status = psa_cipher_encrypt_setup(&operation, key_id, alg);
254 ASSERT_STATUS(status, PSA_SUCCESS);
255
256 status = psa_cipher_set_iv(&operation, nonce, PSA_CIPHER_IV_LENGTH(key_type, alg));
257 ASSERT_STATUS(status, PSA_SUCCESS);
258
259 memset(supp_psa_outbuf, 0x0, data_len);
260 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
261 supp_psa_outbuf, data_len, &out_len);
262 ASSERT_STATUS(status, PSA_SUCCESS);
263
264 memcpy(data, supp_psa_outbuf, out_len);
265 exit:
266 psa_cipher_abort(&operation);
267 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
268 {
269 psa_destroy_key(key_id);
270 }
271 return (int)status;
272 }
273 #endif
274
275 #ifdef MBEDTLS_CMAC_C
omac1_aes_vector_psa(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)276 int omac1_aes_vector_psa(const u8 *key, size_t key_len, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
277 {
278 psa_status_t status;
279 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
280 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
281 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
282 psa_algorithm_t alg = PSA_ALG_CMAC;
283 int i;
284 size_t out_len = 0;
285
286 switch (key_len)
287 {
288 case SUPP_PSA_BLOCK_SIZE_128:
289 /* fall through */
290 case SUPP_PSA_BLOCK_SIZE_192:
291 /* fall through */
292 case SUPP_PSA_BLOCK_SIZE_256:
293 break;
294 default:
295 return -1;
296 }
297
298 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_AES, alg, PSA_KEY_USAGE_SIGN_MESSAGE);
299
300 status = psa_import_key(&attributes, key, key_len, &key_id);
301 ASSERT_STATUS(status, PSA_SUCCESS);
302 psa_reset_key_attributes(&attributes);
303
304 status = psa_mac_sign_setup(&operation, key_id, alg);
305 ASSERT_STATUS(status, PSA_SUCCESS);
306
307 for (i = 0; i < num_elem; i++)
308 {
309 status = psa_mac_update(&operation, addr[i], len[i]);
310 ASSERT_STATUS(status, PSA_SUCCESS);
311 }
312
313 status = psa_mac_sign_finish(&operation, mac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, key_len * 8, alg), &out_len);
314 ASSERT_STATUS(status, PSA_SUCCESS);
315
316 exit:
317 psa_mac_abort(&operation);
318 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
319 {
320 psa_destroy_key(key_id);
321 }
322 return (int)status;
323 }
324 #endif
325
md_vector_psa(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,mbedtls_md_type_t md_type)326 int md_vector_psa(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac, mbedtls_md_type_t md_type)
327 {
328 psa_status_t status;
329 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
330 psa_algorithm_t alg = PSA_ALG_NONE;
331 int block_size;
332 int i;
333 size_t out_len = 0;
334
335 supp_psa_get_hash_alg(md_type, &alg, &block_size);
336 if (alg == PSA_ALG_NONE)
337 {
338 printk("md_vector unknown md type %d\r\n", md_type);
339 return -1;
340 }
341
342 status = psa_hash_setup(&operation, alg);
343 ASSERT_STATUS(status, PSA_SUCCESS);
344
345 for (i = 0; i < num_elem; i++)
346 {
347 status = psa_hash_update(&operation, addr[i], len[i]);
348 ASSERT_STATUS(status, PSA_SUCCESS);
349 }
350
351 status = psa_hash_finish(&operation, mac, block_size, &out_len);
352 ASSERT_STATUS(status, PSA_SUCCESS);
353
354 exit:
355 psa_hash_abort(&operation);
356 return (int)status;
357 }
358
hmac_vector_psa(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,mbedtls_md_type_t md_type)359 int hmac_vector_psa(const u8 *key,
360 size_t key_len,
361 size_t num_elem,
362 const u8 *addr[],
363 const size_t *len,
364 u8 *mac,
365 mbedtls_md_type_t md_type)
366 {
367 psa_status_t status;
368 psa_algorithm_t alg = PSA_ALG_NONE;
369 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
370 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
371 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
372 int block_size;
373 int i;
374 size_t out_len = 0;
375
376 supp_psa_get_hash_alg(md_type, &alg, &block_size);
377 if (alg == PSA_ALG_NONE)
378 {
379 printk("hmac_vector unknown md type %d\r\n", md_type);
380 return -1;
381 }
382 alg = PSA_ALG_HMAC(alg);
383
384 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_HMAC, alg, PSA_KEY_USAGE_SIGN_MESSAGE);
385
386 status = psa_import_key(&attributes, key, key_len, &key_id);
387 ASSERT_STATUS(status, PSA_SUCCESS);
388 psa_reset_key_attributes(&attributes);
389
390 status = psa_mac_sign_setup(&operation, key_id, alg);
391 ASSERT_STATUS(status, PSA_SUCCESS);
392
393 for (i = 0; i < num_elem; i++)
394 {
395 status = psa_mac_update(&operation, addr[i], len[i]);
396 ASSERT_STATUS(status, PSA_SUCCESS);
397 }
398
399 status = psa_mac_sign_finish(&operation, mac, PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, key_len * 8, alg), &out_len);
400 ASSERT_STATUS(status, PSA_SUCCESS);
401
402 exit:
403 psa_mac_abort(&operation);
404 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
405 {
406 psa_destroy_key(key_id);
407 }
408 return (int)status;
409 }
410
supp_psa_crypto_init(void)411 int supp_psa_crypto_init(void)
412 {
413 return psa_crypto_init();
414 }
415
supp_psa_crypto_deinit(void)416 void supp_psa_crypto_deinit(void)
417 {
418 mbedtls_psa_crypto_free();
419 }
420