1 /*
2  * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 /** \file cc3xx_internal_rsa_util.c
9  *
10  * This file contains the implementation of the internal utility functions used
11  * to manipulate RSA types and key formats
12  *
13  */
14 
15 #include "cc3xx_internal_rsa_util.h"
16 #include "cc3xx_internal_asn1_util.h"
17 
18 #include "cc3xx_psa_api_config.h"
19 
20 #include "cc_common.h"
21 #include "cc_rnd_error.h"
22 #include "cc_rsa_build.h"
23 #include "cc_rsa_error.h"
24 #include "cc_rsa_types.h"
25 #include "psa/crypto.h"
26 
27 #if defined(MBEDTLS_PLATFORM_C)
28 #include "mbedtls/platform.h"
29 #else
30 #include <stdio.h>
31 #include <stdlib.h>
32 #define mbedtls_printf printf
33 #define mbedtls_calloc calloc
34 #define mbedtls_free free
35 #endif
36 
37 /* To be able to include the PSA style configuration */
38 #include "mbedtls/build_info.h"
39 
40 /*  This function checks if the first byte of a pointer is zero and
41  *  skips it when it is. We need this when we convert a PSA RSA key
42  *  to the CryptoCell internal type because the PSA key will use the
43  *  DER encoding to store its value. The DER encoding is using 2's
44  *  complement representation when storing integeters which will add
45  *  a leading zero byte when the MSB of a number is 1. CryptoCell
46  *  does not allows this form so the leading zero needs to be removed.
47  */
skip_leading_zero(uint8_t ** ptr,size_t * ptr_size)48 static void skip_leading_zero(uint8_t **ptr, size_t *ptr_size)
49 {
50     if (ptr == NULL || ptr_size == NULL) {
51         return;
52     }
53 
54     if (*ptr == NULL) {
55         return;
56     }
57 
58     if ((*ptr)[0] == 0 && ((*ptr)[1] & 0x80)) {
59         (*ptr)++;
60         *ptr_size -= 1;
61     }
62 }
63 
64 /** \defgroup internal_rsa_util Internal RSA utility functions
65  *
66  *  Internal functions required to provide utilities for handling RSA type
67  *  conversions
68  *
69  *  @{
70  */
cc3xx_rsa_psa_pub_to_cc_pub(const uint8_t * psa_pub_key_buffer,size_t psa_pub_key_buffer_size,CCRsaUserPubKey_t * UserPubKey_ptr)71 psa_status_t cc3xx_rsa_psa_pub_to_cc_pub(const uint8_t *psa_pub_key_buffer,
72                                          size_t psa_pub_key_buffer_size,
73                                          CCRsaUserPubKey_t *UserPubKey_ptr)
74 
75 {
76     uint8_t *pub_key_buffer_start_pnt = (uint8_t *)psa_pub_key_buffer;
77     uint8_t **pub_key_buffer_start = &pub_key_buffer_start_pnt;
78     uint8_t *pub_key_buffer_end =
79         (uint8_t *)psa_pub_key_buffer + psa_pub_key_buffer_size;
80     uint8_t *n_ptr;
81     size_t n_len;
82     uint8_t *e_ptr;
83     size_t e_len;
84     size_t len;
85     int ret;
86     CCError_t cc_err = CC_FAIL;
87 
88     /* Move the pointer after the sequence */
89     ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
90                              CC3XX_TAG_ASN1_CONSTRUCTED |
91                                  CC3XX_TAG_ASN1_SEQUENCE);
92     if (ret < 0) {
93         cc_err = CC_FAIL;
94         goto end;
95     }
96 
97     /* Get the modulus n */
98     ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
99                              CC3XX_TAG_ASN1_INTEGER);
100     if (ret < 0) {
101         cc_err = CC_FAIL;
102         goto end;
103     }
104 
105     n_ptr = *pub_key_buffer_start;
106     n_len = len;
107     skip_leading_zero(&n_ptr, &n_len);
108 
109     *pub_key_buffer_start += len;
110 
111     /* Get the exponent e */
112     ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
113                              CC3XX_TAG_ASN1_INTEGER);
114     if (ret < 0) {
115         cc_err = CC_FAIL;
116         goto end;
117     }
118 
119     e_ptr = *pub_key_buffer_start;
120     e_len = len;
121     skip_leading_zero(&e_ptr, &e_len);
122 
123     *pub_key_buffer_start += len;
124 
125     cc_err = CC_RsaPubKeyBuild(UserPubKey_ptr, e_ptr, e_len, n_ptr, n_len);
126 
127 end:
128     return cc3xx_rsa_cc_error_to_psa_error(cc_err);
129 }
130 
cc3xx_rsa_psa_priv_to_cc_pub(const uint8_t * psa_priv_key_buffer,size_t psa_priv_key_buffer_size,CCRsaUserPubKey_t * UserPubKey_ptr)131 psa_status_t cc3xx_rsa_psa_priv_to_cc_pub(const uint8_t *psa_priv_key_buffer,
132                                           size_t psa_priv_key_buffer_size,
133                                           CCRsaUserPubKey_t *UserPubKey_ptr)
134 
135 {
136     uint8_t *priv_key_buffer_start_pnt = (uint8_t *)psa_priv_key_buffer;
137     uint8_t **priv_key_buffer_start = &priv_key_buffer_start_pnt;
138     uint8_t *priv_key_buffer_end =
139         (uint8_t *)psa_priv_key_buffer + psa_priv_key_buffer_size;
140     uint8_t *n_ptr;
141     size_t n_len;
142     uint8_t *e_ptr;
143     size_t e_len;
144     size_t len;
145     int dummy;
146     int ret;
147     CCError_t cc_err = CC_FAIL;
148 
149     /* Move the pointer after the sequence */
150     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
151                              CC3XX_TAG_ASN1_CONSTRUCTED |
152                                  CC3XX_TAG_ASN1_SEQUENCE);
153     if (ret < 0) {
154         cc_err = CC_FAIL;
155         goto end;
156     }
157 
158     /* Move the pointer after the version */
159     ret = cc3xx_asn1_get_int(priv_key_buffer_start, priv_key_buffer_end, &dummy);
160     if (ret < 0) {
161         cc_err = CC_FAIL;
162         goto end;
163     }
164 
165     /* Get the modulus n */
166     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
167                              CC3XX_TAG_ASN1_INTEGER);
168     if (ret < 0) {
169         cc_err = CC_FAIL;
170         goto end;
171     }
172 
173     n_ptr = *priv_key_buffer_start;
174     n_len = len;
175     skip_leading_zero(&n_ptr, &n_len);
176 
177     *priv_key_buffer_start += len;
178 
179     /* Get the exponent e */
180     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
181                              CC3XX_TAG_ASN1_INTEGER);
182     if (ret < 0) {
183         cc_err = CC_FAIL;
184         goto end;
185     }
186 
187     e_ptr = *priv_key_buffer_start;
188     e_len = len;
189     skip_leading_zero(&e_ptr, &e_len);
190 
191     *priv_key_buffer_start += len;
192 
193     cc_err = CC_RsaPubKeyBuild(UserPubKey_ptr, e_ptr, e_len, n_ptr, n_len);
194 
195 end:
196     return cc3xx_rsa_cc_error_to_psa_error(cc_err);
197 }
198 
cc3xx_rsa_psa_priv_to_cc_priv(const uint8_t * psa_priv_key_buffer,size_t psa_priv_key_buffer_size,CCRsaUserPrivKey_t * UserPrivKey_ptr)199 psa_status_t cc3xx_rsa_psa_priv_to_cc_priv(const uint8_t *psa_priv_key_buffer,
200                                            size_t psa_priv_key_buffer_size,
201                                            CCRsaUserPrivKey_t *UserPrivKey_ptr)
202 
203 {
204     uint8_t *p_ptr;
205     size_t p_len;
206     uint8_t *q_ptr;
207     size_t q_len;
208     uint8_t *dP_ptr;
209     size_t dP_len;
210     uint8_t *dQ_ptr;
211     size_t dQ_len;
212     uint8_t *qInv_ptr;
213     size_t qInv_len;
214     int ret;
215     size_t len;
216     int dummy;
217     CCError_t cc_err = CC_FAIL;
218 
219     uint8_t *priv_key_buffer_start_pnt = (uint8_t *)psa_priv_key_buffer;
220     uint8_t **priv_key_buffer_start = &priv_key_buffer_start_pnt;
221     uint8_t *priv_key_buffer_end =
222         (uint8_t *)psa_priv_key_buffer + psa_priv_key_buffer_size;
223 
224     /* Move the pointer after the sequence */
225     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
226                              CC3XX_TAG_ASN1_CONSTRUCTED |
227                                  CC3XX_TAG_ASN1_SEQUENCE);
228     if (ret < 0) {
229         cc_err = CC_FAIL;
230         goto end;
231     }
232 
233     /* Move the pointer after the version */
234     ret =
235         cc3xx_asn1_get_int(priv_key_buffer_start, priv_key_buffer_end, &dummy);
236     if (ret < 0) {
237         cc_err = CC_FAIL;
238         goto end;
239     }
240 
241     /* Move the pointer after the modulus n */
242     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
243                              CC3XX_TAG_ASN1_INTEGER);
244     if (ret < 0) {
245         cc_err = CC_FAIL;
246         goto end;
247     }
248     *priv_key_buffer_start += len;
249 
250     /* Move the pointer after the publicExponent e*/
251     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
252                              CC3XX_TAG_ASN1_INTEGER);
253     if (ret < 0) {
254         cc_err = CC_FAIL;
255         goto end;
256     }
257     *priv_key_buffer_start += len;
258 
259     /* Move the pointer after the privateExponent d */
260     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
261                              CC3XX_TAG_ASN1_INTEGER);
262     if (ret < 0) {
263         cc_err = CC_FAIL;
264         goto end;
265     }
266     *priv_key_buffer_start += len;
267 
268     /* Get the P */
269     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
270                              CC3XX_TAG_ASN1_INTEGER);
271     if (ret < 0) {
272         cc_err = CC_FAIL;
273         goto end;
274     }
275 
276     p_ptr = *priv_key_buffer_start;
277     p_len = len;
278     skip_leading_zero(&p_ptr, &p_len);
279 
280     *priv_key_buffer_start += len;
281 
282     /* Get the Q */
283     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
284                              CC3XX_TAG_ASN1_INTEGER);
285     if (ret < 0) {
286         cc_err = CC_FAIL;
287         goto end;
288     }
289 
290     q_ptr = *priv_key_buffer_start;
291     q_len = len;
292     skip_leading_zero(&q_ptr, &q_len);
293 
294     *priv_key_buffer_start += len;
295 
296     /* Get the dP */
297     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
298                              CC3XX_TAG_ASN1_INTEGER);
299     if (ret < 0) {
300         cc_err = CC_FAIL;
301         goto end;
302     }
303 
304     dP_ptr = *priv_key_buffer_start;
305     dP_len = len;
306     skip_leading_zero(&dP_ptr, &dP_len);
307 
308     *priv_key_buffer_start += len;
309 
310     /* Get the dQ */
311     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
312                              CC3XX_TAG_ASN1_INTEGER);
313     if (ret < 0) {
314         cc_err = CC_FAIL;
315         goto end;
316     }
317 
318     dQ_ptr = *priv_key_buffer_start;
319     dQ_len = len;
320     skip_leading_zero(&dQ_ptr, &dQ_len);
321 
322     *priv_key_buffer_start += len;
323 
324     /* Get the dInv */
325     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
326                              CC3XX_TAG_ASN1_INTEGER);
327     if (ret < 0) {
328         cc_err = CC_FAIL;
329         goto end;
330     }
331 
332     qInv_ptr = *priv_key_buffer_start;
333     qInv_len = len;
334     skip_leading_zero(&qInv_ptr, &qInv_len);
335 
336     *priv_key_buffer_start += len;
337 
338     cc_err = CC_RsaPrivKeyCrtBuild(UserPrivKey_ptr, p_ptr, p_len, q_ptr, q_len,
339                                    dP_ptr, dP_len, dQ_ptr, dQ_len, qInv_ptr,
340                                    qInv_len);
341 end:
342     return cc3xx_rsa_cc_error_to_psa_error(cc_err);
343 }
344 
cc3xx_rsa_psa_priv_to_psa_publ(uint8_t * priv_key_buffer,size_t priv_key_buffer_size,uint8_t * publ_key_buffer,size_t publ_key_buffer_size,size_t * publ_key_buffer_length)345 psa_status_t cc3xx_rsa_psa_priv_to_psa_publ(uint8_t *priv_key_buffer,
346                                             size_t priv_key_buffer_size,
347                                             uint8_t *publ_key_buffer,
348                                             size_t publ_key_buffer_size,
349                                             size_t *publ_key_buffer_length)
350 {
351     uint8_t *priv_key_buffer_start_pnt = priv_key_buffer;
352     uint8_t **priv_key_buffer_start = &priv_key_buffer_start_pnt;
353     uint8_t *priv_key_buffer_end = priv_key_buffer + priv_key_buffer_size;
354     uint8_t *n_pnt;
355     size_t n_len;
356     uint8_t *e_pnt;
357     size_t e_len;
358 
359     uint8_t *pub_key_buffer_end_pnt = publ_key_buffer + publ_key_buffer_size;
360     uint8_t **pub_key_buffer_end = &pub_key_buffer_end_pnt;
361 
362     CCError_t cc_err = CC_FAIL;
363     int bytes_written;
364     size_t buffer_used;
365     size_t len;
366     int ret;
367     int dummy;
368 
369     /* Initialise the return value to 0 */
370     *publ_key_buffer_length = 0;
371 
372     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
373                         CC3XX_TAG_ASN1_CONSTRUCTED | CC3XX_TAG_ASN1_SEQUENCE);
374     if (ret < 0) {
375         cc_err = CC_FAIL;
376         goto end;
377     }
378 
379     ret = cc3xx_asn1_get_int(priv_key_buffer_start, priv_key_buffer_end,
380                              &dummy);
381     if (ret < 0) {
382         cc_err = CC_FAIL;
383         goto end;
384     }
385 
386     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
387                              CC3XX_TAG_ASN1_INTEGER);
388     if (ret < 0) {
389         cc_err = CC_FAIL;
390         goto end;
391     }
392 
393     n_pnt = *priv_key_buffer_start;
394     n_len = len;
395 
396     *priv_key_buffer_start += len;
397 
398     ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
399                              CC3XX_TAG_ASN1_INTEGER);
400     if (ret < 0) {
401         cc_err = CC_FAIL;
402         goto end;
403     }
404 
405     e_pnt = *priv_key_buffer_start;
406     e_len = len;
407 
408     bytes_written = cc3xx_asn1_write_big_integer(pub_key_buffer_end,
409                                                  publ_key_buffer, e_pnt, e_len);
410     buffer_used = bytes_written;
411     if (bytes_written < 0) {
412         cc_err = CC_OUT_OF_RESOURCE_ERROR;
413         goto end;
414     }
415 
416     bytes_written = cc3xx_asn1_write_big_integer(pub_key_buffer_end,
417                                                  publ_key_buffer, n_pnt, n_len);
418     buffer_used += bytes_written;
419     if (bytes_written < 0) {
420         cc_err = CC_OUT_OF_RESOURCE_ERROR;
421         goto end;
422     }
423 
424     bytes_written = cc3xx_asn1_write_len(pub_key_buffer_end, publ_key_buffer,
425                                          buffer_used);
426     buffer_used += bytes_written;
427     if (bytes_written < 0) {
428         cc_err = CC_OUT_OF_RESOURCE_ERROR;
429         goto end;
430     }
431 
432     bytes_written = cc3xx_asn1_write_tag(pub_key_buffer_end, publ_key_buffer,
433                         CC3XX_TAG_ASN1_SEQUENCE | CC3XX_TAG_ASN1_CONSTRUCTED);
434     buffer_used += bytes_written;
435     if (bytes_written < 0) {
436         cc_err = CC_OUT_OF_RESOURCE_ERROR;
437         goto end;
438     }
439 
440     /* The asn1 functions write to the end of the buffer.
441      * Move the data to the beginning and erase remaining data
442      * at the original location.
443      */
444     if (2 * buffer_used <= publ_key_buffer_size) {
445         CC_PalMemMove(publ_key_buffer,
446                       publ_key_buffer + publ_key_buffer_size - buffer_used,
447                       buffer_used);
448         CC_PalMemSetZero(publ_key_buffer + publ_key_buffer_size - buffer_used,
449                          buffer_used);
450         cc_err = CC_OK;
451     } else if ((size_t)buffer_used < publ_key_buffer_size) {
452         CC_PalMemMove(publ_key_buffer,
453                       publ_key_buffer + publ_key_buffer_size - buffer_used,
454                       buffer_used);
455         CC_PalMemSetZero(publ_key_buffer + buffer_used,
456                          publ_key_buffer_size - buffer_used);
457         cc_err = CC_OK;
458     } else {
459         return PSA_ERROR_BUFFER_TOO_SMALL;
460     }
461 
462     *publ_key_buffer_length = buffer_used;
463 
464 end:
465     return cc3xx_rsa_cc_error_to_psa_error(cc_err);
466 }
467 
cc3xx_rsa_save_der_priv_key(uint8_t * key_buffer,size_t key_buffer_size,uint32_t * n,uint32_t * e,uint32_t * d,uint32_t * p,uint32_t * q,uint32_t * dP,uint32_t * dQ,uint32_t * qInv,size_t d_size_bytes,size_t * key_buffer_length)468 psa_status_t cc3xx_rsa_save_der_priv_key(uint8_t *key_buffer,
469                                          size_t key_buffer_size, uint32_t *n,
470                                          uint32_t *e, uint32_t *d, uint32_t *p,
471                                          uint32_t *q, uint32_t *dP, uint32_t *dQ,
472                                          uint32_t *qInv, size_t d_size_bytes,
473                                          size_t *key_buffer_length)
474 {
475     uint8_t *key_buffer_end_pnt = key_buffer + key_buffer_size;
476     uint8_t **key_buffer_end = &key_buffer_end_pnt;
477     CCError_t cc_err = CC_FAIL;
478     uint8_t *temp_buff = NULL;
479     int bytes_written;
480     size_t buffer_used;
481 
482     /* Initialise the return value to 0 */
483     *key_buffer_length = 0;
484 
485     temp_buff = (uint8_t *)mbedtls_calloc(1, d_size_bytes);
486     if (temp_buff == NULL) {
487         cc_err = CC_OUT_OF_RESOURCE_ERROR;
488         goto end;
489     }
490 
491     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
492                                                       qInv, d_size_bytes / 2);
493     if (cc_err != CC_OK) {
494         goto end;
495     }
496 
497     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
498                                                  temp_buff, d_size_bytes / 2);
499     buffer_used = bytes_written;
500     if (bytes_written < 0) {
501         cc_err = CC_OUT_OF_RESOURCE_ERROR;
502         goto end;
503     }
504 
505     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
506                                                       dQ, d_size_bytes / 2);
507     if (cc_err != CC_OK) {
508         goto end;
509     }
510 
511     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
512                                                  temp_buff, d_size_bytes / 2);
513     buffer_used += bytes_written;
514     if (bytes_written < 0) {
515         cc_err = CC_OUT_OF_RESOURCE_ERROR;
516         goto end;
517     }
518 
519     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
520                                                       dP, d_size_bytes / 2);
521     if (cc_err != CC_OK) {
522         goto end;
523     }
524 
525     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
526                                                  temp_buff, d_size_bytes / 2);
527     buffer_used += bytes_written;
528     if (bytes_written < 0) {
529         cc_err = CC_OUT_OF_RESOURCE_ERROR;
530         goto end;
531     }
532 
533     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
534                                                       q, d_size_bytes / 2);
535     if (cc_err != CC_OK) {
536         goto end;
537     }
538 
539     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
540                                                  temp_buff, d_size_bytes / 2);
541     buffer_used += bytes_written;
542     if (bytes_written < 0) {
543         cc_err = CC_OUT_OF_RESOURCE_ERROR;
544         goto end;
545     }
546 
547     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
548                                                       p, d_size_bytes / 2);
549     if (cc_err != CC_OK) {
550         goto end;
551     }
552 
553     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
554                                                  temp_buff, d_size_bytes / 2);
555     buffer_used += bytes_written;
556     if (bytes_written < 0) {
557         cc_err = CC_OUT_OF_RESOURCE_ERROR;
558         goto end;
559     }
560 
561     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
562                                                       d, d_size_bytes);
563     if (cc_err != CC_OK) {
564         goto end;
565     }
566 
567     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
568                                                  temp_buff, d_size_bytes);
569     buffer_used += bytes_written;
570     if (bytes_written < 0) {
571         cc_err = CC_OUT_OF_RESOURCE_ERROR;
572         goto end;
573     }
574 
575     CC_PalMemCopy(temp_buff, (uint8_t *)e, 3);
576 
577     bytes_written =
578         cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer, temp_buff, 3);
579     buffer_used += bytes_written;
580     if (bytes_written < 0) {
581         cc_err = CC_OUT_OF_RESOURCE_ERROR;
582         goto end;
583     }
584 
585     cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
586                                                       n, d_size_bytes);
587     if (cc_err != CC_OK) {
588         goto end;
589     }
590 
591     bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
592                                                  temp_buff, d_size_bytes);
593     buffer_used += bytes_written;
594     if (bytes_written < 0) {
595         cc_err = CC_OUT_OF_RESOURCE_ERROR;
596         goto end;
597     }
598 
599     bytes_written = cc3xx_asn1_write_int(key_buffer_end, key_buffer, 0);
600     buffer_used += bytes_written;
601     if (bytes_written < 0) {
602         cc_err = CC_OUT_OF_RESOURCE_ERROR;
603         goto end;
604     }
605 
606     bytes_written =
607         cc3xx_asn1_write_len(key_buffer_end, key_buffer, buffer_used);
608     buffer_used += bytes_written;
609     if (bytes_written < 0) {
610         cc_err = CC_OUT_OF_RESOURCE_ERROR;
611         goto end;
612     }
613 
614     bytes_written = cc3xx_asn1_write_tag(key_buffer_end, key_buffer,
615                                          CC3XX_TAG_ASN1_SEQUENCE |
616                                              CC3XX_TAG_ASN1_CONSTRUCTED);
617     buffer_used += bytes_written;
618     if (bytes_written < 0) {
619         cc_err = CC_OUT_OF_RESOURCE_ERROR;
620         goto end;
621     }
622 
623     /* The asn1 functions write to the end of the buffer.
624      * Move the data to the beginning and erase remaining data
625      * at the original location. */
626 
627     if (2 * buffer_used <= key_buffer_size) {
628         CC_PalMemMove(key_buffer, key_buffer + key_buffer_size - buffer_used,
629                       buffer_used);
630         CC_PalMemSetZero(key_buffer + key_buffer_size - buffer_used,
631                          buffer_used);
632     } else if ((size_t)buffer_used < key_buffer_size) {
633         CC_PalMemMove(key_buffer, key_buffer + key_buffer_size - buffer_used,
634                       buffer_used);
635         CC_PalMemSetZero(key_buffer + buffer_used,
636                          key_buffer_size - buffer_used);
637     }
638 
639     /* Reports as output the size in byte of the DER key just written */
640     *key_buffer_length = buffer_used;
641 
642 end:
643     if (temp_buff) {
644         /* zeroing temp buffers  */
645         CC_PalMemSetZero(temp_buff, d_size_bytes);
646         mbedtls_free(temp_buff);
647     }
648 
649     return cc3xx_rsa_cc_error_to_psa_error(cc_err);
650 }
651 
cc3xx_rsa_cc_error_to_psa_error(CCError_t cc_error)652 psa_status_t cc3xx_rsa_cc_error_to_psa_error(CCError_t cc_error)
653 {
654 #ifndef CC3XX_CONFIG_ENABLE_CC_TO_PSA_TYPE_CONVERSION
655     /* Limited coverage error code conversion routine */
656     switch (cc_error) {
657     case CC_SUCCESS:
658         return PSA_SUCCESS;
659     case CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE:
660     case CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE:
661         return PSA_ERROR_BUFFER_TOO_SMALL;
662     case CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY:
663     case CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY:
664     case CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER:
665         return PSA_ERROR_INVALID_SIGNATURE;
666     default:
667         return PSA_ERROR_HARDWARE_FAILURE;
668     }
669 #else /* CC3XX_CONFIG_ENABLE_CC_TO_PSA_TYPE_CONVERSION */
670     psa_status_t err;
671     /* Full coverage error code conversion routine */
672     switch (cc_error) {
673     case CC_SUCCESS:
674         return PSA_SUCCESS;
675         break;
676 
677     case CC_RSA_BASE_MGF_MASK_TOO_LONG:
678     case CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG:
679     case CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG:
680     case CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG:
681     case CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG:
682     case CC_RSA_CONV_TO_CRT_INVALID_TEMP_BUFF_POINTER_ERROR:
683     case CC_RSA_DATA_POINTER_INVALID_ERROR:
684     case CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE:
685     case CC_RSA_DECRYPT_OUTPUT_SIZE_POINTER_ERROR:
686     case CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE:
687     case CC_RSA_GET_DER_HASH_MODE_ILLEGAL:
688     case CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR:
689     case CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR:
690     case CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR:
691     case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR:
692     case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_PTR_ERROR:
693     case CC_RSA_INVALID_CRT_COEFF_VAL:
694     case CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE:
695     case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL:
696     case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR:
697     case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR:
698     case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_PTR_ERROR:
699     case CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR:
700     case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE:
701     case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR:
702     case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_POINTER_ERROR:
703     case CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR:
704     case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL:
705     case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR:
706     case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR:
707     case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_PTR_ERROR:
708     case CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR:
709     case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE:
710     case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR:
711     case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_POINTER_ERROR:
712     case CC_RSA_INVALID_DECRYPRION_MODE_ERROR:
713     case CC_RSA_INVALID_EXPONENT_POINTER_ERROR:
714     case CC_RSA_INVALID_EXPONENT_SIZE:
715     case CC_RSA_INVALID_EXPONENT_VAL:
716     case CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER:
717     case CC_RSA_INVALID_MESSAGE_BUFFER_SIZE:
718     case CC_RSA_INVALID_MESSAGE_DATA_SIZE:
719     case CC_RSA_INVALID_MODULUS_ERROR:
720     case CC_RSA_INVALID_MODULUS_POINTER_ERROR:
721     case CC_RSA_INVALID_MODULUS_SIZE:
722     case CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER:
723     case CC_RSA_INVALID_OUTPUT_POINTER_ERROR:
724     case CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR:
725     case CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR:
726     case CC_RSA_INVALID_PTR_ERROR:
727     case CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR:
728     case CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER:
729     case CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR:
730     case CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID:
731     case CC_RSA_MGF_ILLEGAL_ARG_ERROR:
732     case CC_RSA_MODULUS_EVEN_ERROR:
733     case CC_RSA_PKCS1_VER_ARG_ERROR:
734     case CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID:
735     case CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR:
736     case CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR:
737     case CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR:
738     case CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR:
739     case CC_RSA_WRONG_PRIVATE_KEY_TYPE:
740     case CC_RSA_INVALID_MESSAGE_VAL:
741     case CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE:
742     case CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING:
743     case CC_RSA_OAEP_DECODE_ERROR:
744         err = PSA_ERROR_INVALID_ARGUMENT;
745         break;
746 
747     case CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE:
748     case CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE:
749         err = PSA_ERROR_BUFFER_TOO_SMALL;
750         break;
751 
752     case CC_RSA_KEY_GEN_CONDITIONAL_TEST_FAIL_ERROR:
753     case CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW:
754     case CC_RSA_KEY_GENERATION_FAILURE_ERROR:
755         err = PSA_ERROR_GENERIC_ERROR;
756         break;
757 
758     case CC_RSA_CAN_NOT_GENERATE_RAND_IN_RANGE:
759     case CC_RSA_ERROR_IN_RANDOM_OPERATION_FOR_ENCODE:
760     case CC_RND_STATE_PTR_INVALID_ERROR:
761     case CC_RND_GEN_VECTOR_FUNC_ERROR:
762         err = PSA_ERROR_GENERIC_ERROR;
763         break;
764 
765     case CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY:
766     case CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY:
767         err = PSA_ERROR_INVALID_SIGNATURE;
768         break;
769 
770     /* For now, there is no better error code for malloc failure, both in CC and
771      * PSA status
772      */
773     case CC_OUT_OF_RESOURCE_ERROR:
774         err = PSA_ERROR_INSUFFICIENT_MEMORY;
775         break;
776 
777     default:
778         CC_PAL_LOG_ERR("Unknown CC_ERROR %d", cc_error);
779         err = PSA_ERROR_GENERIC_ERROR;
780         break;
781     }
782 
783     CC_PAL_LOG_DEBUG("Converted CC_ERROR %d (0x%x) to PSA_ERROR %d",
784                      cc_error, cc_error, err);
785     return err;
786 #endif /* CC3XX_CONFIG_ENABLE_CC_TO_PSA_TYPE_CONVERSION */
787 }
788 /** @} */ // end of internal_rsa_util
789