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