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