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 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_TEST
27 #include "module_tests.h"
28 #endif
29
30 #define ASSERT_STATUS(actual, expected) \
31 do \
32 { \
33 if ((actual) != (expected)) \
34 { \
35 printk( \
36 "\tassertion failed at %s:%d - " \
37 "actual:%d expected:%d\r\n", \
38 __FILE__, __LINE__, (psa_status_t)actual, (psa_status_t)expected); \
39 goto exit; \
40 } \
41 } while (0)
42
43 #define SUPP_PSA_MAX_OUTPUT_SIZE 2048
44
45 static uint8_t supp_psa_outbuf[SUPP_PSA_MAX_OUTPUT_SIZE];
46
supp_psa_set_attributes(psa_key_attributes_t * attributes,u32 type,u32 alg,u32 usage)47 static inline void supp_psa_set_attributes(psa_key_attributes_t *attributes, u32 type, u32 alg, u32 usage)
48 {
49 psa_set_key_type(attributes, type);
50 psa_set_key_algorithm(attributes, alg);
51 psa_set_key_usage_flags(attributes, usage);
52 }
53
supp_psa_get_hash_alg(mbedtls_md_type_t type,psa_algorithm_t * alg,int * block_size)54 static void supp_psa_get_hash_alg(mbedtls_md_type_t type, psa_algorithm_t *alg, int *block_size)
55 {
56 switch (type)
57 {
58 case MBEDTLS_MD_MD5:
59 *alg = PSA_ALG_MD5;
60 break;
61 case MBEDTLS_MD_SHA1:
62 *alg = PSA_ALG_SHA_1;
63 break;
64 case MBEDTLS_MD_SHA224:
65 *alg = PSA_ALG_SHA_224;
66 break;
67 case MBEDTLS_MD_SHA256:
68 *alg = PSA_ALG_SHA_256;
69 break;
70 case MBEDTLS_MD_SHA384:
71 *alg = PSA_ALG_SHA_384;
72 break;
73 case MBEDTLS_MD_SHA512:
74 *alg = PSA_ALG_SHA_512;
75 break;
76 case MBEDTLS_MD_RIPEMD160:
77 *alg = PSA_ALG_RIPEMD160;
78 break;
79 default:
80 *alg = PSA_ALG_NONE;
81 break;
82 }
83 *block_size = PSA_HASH_LENGTH(*alg);
84 }
85
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)86 static psa_status_t supp_psa_cipher_operation(psa_cipher_operation_t *operation,
87 const uint8_t *input,
88 size_t input_size,
89 size_t part_size,
90 uint8_t *output,
91 size_t output_size,
92 size_t *output_len)
93 {
94 psa_status_t status;
95 size_t bytes_to_write = 0;
96 size_t bytes_written = 0;
97 size_t len = 0;
98
99 *output_len = 0;
100 while (bytes_written != input_size)
101 {
102 bytes_to_write = (input_size - bytes_written > part_size ? part_size : input_size - bytes_written);
103
104 status = psa_cipher_update(operation, input + bytes_written, bytes_to_write, output + *output_len,
105 output_size - *output_len, &len);
106 ASSERT_STATUS(status, PSA_SUCCESS);
107
108 bytes_written += bytes_to_write;
109 *output_len += len;
110 }
111
112 status = psa_cipher_finish(operation, output + *output_len, output_size - *output_len, &len);
113 ASSERT_STATUS(status, PSA_SUCCESS);
114 *output_len += len;
115
116 exit:
117 return status;
118 }
119
120 #if defined(MBEDTLS_AES_C) || defined(CONFIG_PSA_WANT_KEY_TYPE_AES)
121 #define SUPP_PSA_AES_BLOCK_SIZE 16
122
aes_128_encrypt_block_psa(const u8 * key,const u8 * in,u8 * out)123 int aes_128_encrypt_block_psa(const u8 *key, const u8 *in, u8 *out)
124 {
125 psa_status_t status;
126 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
127 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
128 psa_algorithm_t alg = PSA_ALG_ECB_NO_PADDING;
129 size_t out_len = 0;
130
131 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_AES, alg, PSA_KEY_USAGE_ENCRYPT);
132
133 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
134 ASSERT_STATUS(status, PSA_SUCCESS);
135 psa_reset_key_attributes(&attributes);
136
137 status = psa_cipher_encrypt(key_id, alg, in, SUPP_PSA_BLOCK_SIZE_128, out, SUPP_PSA_BLOCK_SIZE_128, &out_len);
138 ASSERT_STATUS(status, PSA_SUCCESS);
139
140 exit:
141 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
142 {
143 psa_destroy_key(key_id);
144 }
145 return (int)status;
146 }
147
aes_128_cbc_encrypt_psa(const u8 * key,const u8 * iv,u8 * data,size_t data_len)148 int aes_128_cbc_encrypt_psa(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
149 {
150 psa_status_t status;
151 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
152 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
153 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
154 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
155 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
156 size_t out_len = 0;
157
158 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
159 {
160 printk("%s invalid input len %d", __func__, data_len);
161 return -1;
162 }
163
164 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_ENCRYPT);
165
166 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
167 ASSERT_STATUS(status, PSA_SUCCESS);
168 psa_reset_key_attributes(&attributes);
169
170 status = psa_cipher_encrypt_setup(&operation, key_id, alg);
171 ASSERT_STATUS(status, PSA_SUCCESS);
172
173 status = psa_cipher_set_iv(&operation, iv, PSA_CIPHER_IV_LENGTH(key_type, alg));
174 ASSERT_STATUS(status, PSA_SUCCESS);
175
176 memset(supp_psa_outbuf, 0x0, data_len);
177 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
178 supp_psa_outbuf, data_len, &out_len);
179 ASSERT_STATUS(status, PSA_SUCCESS);
180
181 memcpy(data, supp_psa_outbuf, out_len);
182 exit:
183 psa_cipher_abort(&operation);
184 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
185 {
186 psa_destroy_key(key_id);
187 }
188 return (int)status;
189 }
190
aes_128_cbc_decrypt_psa(const u8 * key,const u8 * iv,u8 * data,size_t data_len)191 int aes_128_cbc_decrypt_psa(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
192 {
193 psa_status_t status;
194 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
195 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
196 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
197 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
198 psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
199 size_t out_len = 0;
200
201 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
202 {
203 printk("%s invalid input len %d", __func__, data_len);
204 return -1;
205 }
206
207 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_DECRYPT);
208
209 status = psa_import_key(&attributes, key, SUPP_PSA_BLOCK_SIZE_128, &key_id);
210 ASSERT_STATUS(status, PSA_SUCCESS);
211 psa_reset_key_attributes(&attributes);
212
213 status = psa_cipher_decrypt_setup(&operation, key_id, alg);
214 ASSERT_STATUS(status, PSA_SUCCESS);
215
216 status = psa_cipher_set_iv(&operation, iv, PSA_CIPHER_IV_LENGTH(key_type, alg));
217 ASSERT_STATUS(status, PSA_SUCCESS);
218
219 memset(supp_psa_outbuf, 0x0, data_len);
220 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
221 supp_psa_outbuf, data_len, &out_len);
222 ASSERT_STATUS(status, PSA_SUCCESS);
223
224 memcpy(data, supp_psa_outbuf, out_len);
225 exit:
226 psa_cipher_abort(&operation);
227 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
228 {
229 psa_destroy_key(key_id);
230 }
231 return (int)status;
232 }
233
aes_ctr_encrypt_psa(const u8 * key,size_t key_len,const u8 * nonce,u8 * data,size_t data_len)234 int aes_ctr_encrypt_psa(const u8 *key, size_t key_len, const u8 *nonce, u8 *data, size_t data_len)
235 {
236 psa_status_t status;
237 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
238 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
239 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
240 psa_key_type_t key_type = PSA_KEY_TYPE_AES;
241 psa_algorithm_t alg = PSA_ALG_CTR;
242 size_t out_len = 0;
243
244 if (data_len > SUPP_PSA_MAX_OUTPUT_SIZE)
245 {
246 printk("%s invalid input len %d", __func__, data_len);
247 return -1;
248 }
249
250 supp_psa_set_attributes(&attributes, key_type, alg, PSA_KEY_USAGE_ENCRYPT);
251
252 status = psa_import_key(&attributes, key, key_len, &key_id);
253 ASSERT_STATUS(status, PSA_SUCCESS);
254 psa_reset_key_attributes(&attributes);
255
256 status = psa_cipher_encrypt_setup(&operation, key_id, alg);
257 ASSERT_STATUS(status, PSA_SUCCESS);
258
259 status = psa_cipher_set_iv(&operation, nonce, PSA_CIPHER_IV_LENGTH(key_type, alg));
260 ASSERT_STATUS(status, PSA_SUCCESS);
261
262 memset(supp_psa_outbuf, 0x0, data_len);
263 status = supp_psa_cipher_operation(&operation, data, data_len, PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type),
264 supp_psa_outbuf, data_len, &out_len);
265 ASSERT_STATUS(status, PSA_SUCCESS);
266
267 memcpy(data, supp_psa_outbuf, out_len);
268 exit:
269 psa_cipher_abort(&operation);
270 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
271 {
272 psa_destroy_key(key_id);
273 }
274 return (int)status;
275 }
276 #endif
277
278 #if defined(MBEDTLS_CMAC_C) || defined(CONFIG_PSA_WANT_ALG_CMAC)
omac1_aes_vector_psa(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)279 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)
280 {
281 psa_status_t status;
282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
283 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
284 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
285 psa_algorithm_t alg = PSA_ALG_CMAC;
286 int i;
287 size_t out_len = 0;
288
289 switch (key_len)
290 {
291 case SUPP_PSA_BLOCK_SIZE_128:
292 /* fall through */
293 case SUPP_PSA_BLOCK_SIZE_192:
294 /* fall through */
295 case SUPP_PSA_BLOCK_SIZE_256:
296 break;
297 default:
298 return -1;
299 }
300
301 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_AES, alg, PSA_KEY_USAGE_SIGN_MESSAGE);
302
303 status = psa_import_key(&attributes, key, key_len, &key_id);
304 ASSERT_STATUS(status, PSA_SUCCESS);
305 psa_reset_key_attributes(&attributes);
306
307 status = psa_mac_sign_setup(&operation, key_id, alg);
308 ASSERT_STATUS(status, PSA_SUCCESS);
309
310 for (i = 0; i < num_elem; i++)
311 {
312 status = psa_mac_update(&operation, addr[i], len[i]);
313 ASSERT_STATUS(status, PSA_SUCCESS);
314 }
315
316 status = psa_mac_sign_finish(&operation, mac, PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, key_len * 8, alg), &out_len);
317 ASSERT_STATUS(status, PSA_SUCCESS);
318
319 exit:
320 psa_mac_abort(&operation);
321 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
322 {
323 psa_destroy_key(key_id);
324 }
325 return (int)status;
326 }
327 #endif
328
md_vector_psa(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac,mbedtls_md_type_t md_type)329 int md_vector_psa(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac, mbedtls_md_type_t md_type)
330 {
331 psa_status_t status;
332 psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
333 psa_algorithm_t alg = PSA_ALG_NONE;
334 int block_size;
335 int i;
336 size_t out_len = 0;
337
338 supp_psa_get_hash_alg(md_type, &alg, &block_size);
339 if (alg == PSA_ALG_NONE)
340 {
341 printk("md_vector unknown md type %d\r\n", md_type);
342 return -1;
343 }
344
345 status = psa_hash_setup(&operation, alg);
346 ASSERT_STATUS(status, PSA_SUCCESS);
347
348 for (i = 0; i < num_elem; i++)
349 {
350 status = psa_hash_update(&operation, addr[i], len[i]);
351 ASSERT_STATUS(status, PSA_SUCCESS);
352 }
353
354 status = psa_hash_finish(&operation, mac, block_size, &out_len);
355 ASSERT_STATUS(status, PSA_SUCCESS);
356
357 exit:
358 psa_hash_abort(&operation);
359 return (int)status;
360 }
361
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)362 int hmac_vector_psa(const u8 *key,
363 size_t key_len,
364 size_t num_elem,
365 const u8 *addr[],
366 const size_t *len,
367 u8 *mac,
368 mbedtls_md_type_t md_type)
369 {
370 psa_status_t status;
371 psa_algorithm_t alg = PSA_ALG_NONE;
372 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
373 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
374 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
375 int block_size;
376 int i;
377 size_t out_len = 0;
378
379 supp_psa_get_hash_alg(md_type, &alg, &block_size);
380 if (alg == PSA_ALG_NONE)
381 {
382 printk("hmac_vector unknown md type %d\r\n", md_type);
383 return -1;
384 }
385 alg = PSA_ALG_HMAC(alg);
386
387 supp_psa_set_attributes(&attributes, PSA_KEY_TYPE_HMAC, alg, PSA_KEY_USAGE_SIGN_MESSAGE);
388
389 status = psa_import_key(&attributes, key, key_len, &key_id);
390 ASSERT_STATUS(status, PSA_SUCCESS);
391 psa_reset_key_attributes(&attributes);
392
393 status = psa_mac_sign_setup(&operation, key_id, alg);
394 ASSERT_STATUS(status, PSA_SUCCESS);
395
396 for (i = 0; i < num_elem; i++)
397 {
398 status = psa_mac_update(&operation, addr[i], len[i]);
399 ASSERT_STATUS(status, PSA_SUCCESS);
400 }
401
402 status = psa_mac_sign_finish(&operation, mac, PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, key_len * 8, alg), &out_len);
403 ASSERT_STATUS(status, PSA_SUCCESS);
404
405 exit:
406 psa_mac_abort(&operation);
407 if (key_id != MBEDTLS_SVC_KEY_ID_INIT)
408 {
409 psa_destroy_key(key_id);
410 }
411 return (int)status;
412 }
413
pbkdf2_sha1_psa(mbedtls_md_type_t md_alg,const u8 * password,size_t plen,const unsigned char * salt,size_t slen,unsigned int iteration_count,uint32_t key_length,unsigned char * output)414 int pbkdf2_sha1_psa(mbedtls_md_type_t md_alg, const u8 *password, size_t plen,
415 const unsigned char *salt, size_t slen,
416 unsigned int iteration_count, uint32_t key_length,
417 unsigned char *output)
418 {
419 psa_status_t status;
420 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
421 psa_algorithm_t alg = PSA_ALG_NONE;
422 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
423 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
424 int block_size;
425
426 supp_psa_get_hash_alg(md_alg, &alg, &block_size);
427 if (alg == PSA_ALG_NONE) {
428 printk("unknown md type %d\r\n", md_alg);
429 }
430
431 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
432 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
433 psa_set_key_algorithm(&attributes, PSA_ALG_PBKDF2_HMAC(alg));
434 psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
435 psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(plen));
436
437 status = psa_import_key(&attributes, password, plen, &key_id);
438 ASSERT_STATUS(status, PSA_SUCCESS);
439
440 status = psa_key_derivation_setup(&operation, PSA_ALG_PBKDF2_HMAC(alg));
441 ASSERT_STATUS(status, PSA_SUCCESS);
442
443 status = psa_key_derivation_input_integer(&operation, PSA_KEY_DERIVATION_INPUT_COST,
444 iteration_count);
445 ASSERT_STATUS(status, PSA_SUCCESS);
446
447 status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT, salt,
448 slen);
449 ASSERT_STATUS(status, PSA_SUCCESS);
450
451 status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_PASSWORD,
452 key_id);
453 ASSERT_STATUS(status, PSA_SUCCESS);
454
455 status = psa_key_derivation_output_bytes(&operation, output, key_length);
456 ASSERT_STATUS(status, PSA_SUCCESS);
457
458 exit:
459 psa_key_derivation_abort(&operation);
460 psa_destroy_key(key_id);
461 return (int)status;
462 }
463
supp_psa_crypto_init(void)464 int supp_psa_crypto_init(void)
465 {
466 int ret;
467
468 ret = (int)psa_crypto_init();
469 if (ret)
470 {
471 printk("supp_psa_crypto_init failed ret %d", ret);
472 return ret;
473 }
474
475 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_TEST
476 ret = crypto_module_tests();
477 if (ret)
478 {
479 printk("crypto_module_tests failed ret %d", ret);
480 return ret;
481 }
482 #endif
483 return ret;
484 }
485
supp_psa_crypto_deinit(void)486 void supp_psa_crypto_deinit(void)
487 {
488 mbedtls_psa_crypto_free();
489 }
490