mimxrt1180_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file mimxrt1180_crypto_pkc.c
3  * @brief i.MX RT1180 public-key hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "fsl_device_registers.h"
36 #include "ele_crypto.h"
37 #include "core/crypto.h"
40 #include "pkc/rsa.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (MIMXRT1180_CRYPTO_PKC_SUPPORT == ENABLED)
45 
46 //ELE RSA parameters
47 SDK_ALIGN(static EleRsaArgs eleRsaArgs, 8);
48 
49 
50 #if (RSA_SUPPORT == ENABLED)
51 
52 /**
53  * @brief RSA private key generation
54  * @param[in] prngAlgo PRNG algorithm
55  * @param[in] prngContext Pointer to the PRNG context
56  * @param[in] k Required bit length of the modulus n
57  * @param[in] e Public exponent (3, 5, 17, 257 or 65537)
58  * @param[out] privateKey RSA private key
59  * @return Error code
60  **/
61 
62 error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext,
63  size_t k, uint_t e, RsaPrivateKey *privateKey)
64 {
65  error_t error;
66  size_t eLen;
67  status_t status;
68  ele_generic_rsa_t genericRsa = {0};
69 
70  //Check parameters
71  if(privateKey == NULL)
73 
74  //Check the length of the modulus
75  if(k > 4096)
77 
78  //Check the value of the public exponent
79  if(e == 3 || e == 5 || e == 17)
80  {
81  eleRsaArgs.e[0] = e & 0xFF;
82  eLen = 1;
83  }
84  else if(e == 257)
85  {
86  eleRsaArgs.e[0] = (e >> 8) & 0xFF;
87  eleRsaArgs.e[1] = e & 0xFF;
88  eLen = 2;
89  }
90  else if(e == 65537)
91  {
92  eleRsaArgs.e[0] = (e >> 16) & 0xFF;
93  eleRsaArgs.e[1] = (e >> 8) & 0xFF;
94  eleRsaArgs.e[2] = e & 0xFF;
95  eLen = 3;
96  }
97  else
98  {
100  }
101 
102  //Acquire exclusive access to the ELE module
104 
105  //Set RSA parameters
106  genericRsa.key_size = k;
107  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
108  genericRsa.modulus_size = (k + 7) / 8;
109  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
110  genericRsa.priv_exponent_size = (k + 7) / 8;
111  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
112  genericRsa.pub_exponent_size = eLen;
113 
114  //Generate an RSA private key
115  status = ELE_GenericRsaKeygen(MU_APPS_S3MUA, &genericRsa);
116 
117  //Check status code
118  if(status == kStatus_Success)
119  {
120  //Copy the public exponent
121  error = mpiSetValue(&privateKey->e, e);
122 
123  //Check status code
124  if(!error)
125  {
126  //Copy the private exponent
127  error = mpiReadRaw(&privateKey->d, eleRsaArgs.d, (k + 7) / 8);
128  }
129 
130  //Check status code
131  if(!error)
132  {
133  //Copy the modulus
134  error = mpiReadRaw(&privateKey->n, eleRsaArgs.n, (k + 7) / 8);
135  }
136 
137  //Check status code
138  if(!error)
139  {
140  //The first factor is not generated by the hardware
141  error = mpiSetValue(&privateKey->p, 0);
142  }
143 
144  //Check status code
145  if(!error)
146  {
147  //The second factor is not generated by the hardware
148  error = mpiSetValue(&privateKey->q, 0);
149  }
150 
151  //Check status code
152  if(!error)
153  {
154  //The first factor's CRT exponent is not generated by the hardware
155  error = mpiSetValue(&privateKey->dp, 0);
156  }
157 
158  //Check status code
159  if(!error)
160  {
161  //The second factor's CRT exponent is not generated by the hardware
162  error = mpiSetValue(&privateKey->dq, 0);
163  }
164 
165  //Check status code
166  if(!error)
167  {
168  //The CRT coefficient is not generated by the hardware
169  error = mpiSetValue(&privateKey->qinv, 0);
170  }
171  }
172  else
173  {
174  //Report an error
175  error = ERROR_FAILURE;
176  }
177 
178  //Release exclusive access to the ELE module
180 
181  //Return status code
182  return error;
183 }
184 
185 
186 /**
187  * @brief RSAES-PKCS1-v1_5 encryption operation
188  * @param[in] prngAlgo PRNG algorithm
189  * @param[in] prngContext Pointer to the PRNG context
190  * @param[in] key Recipient's RSA public key
191  * @param[in] message Message to be encrypted
192  * @param[in] messageLen Length of the message to be encrypted
193  * @param[out] ciphertext Ciphertext resulting from the encryption operation
194  * @param[out] ciphertextLen Length of the resulting ciphertext
195  * @return Error code
196  **/
197 
198 error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext,
199  const RsaPublicKey *key, const uint8_t *message, size_t messageLen,
200  uint8_t *ciphertext, size_t *ciphertextLen)
201 {
202  error_t error;
203  size_t nLen;
204  size_t eLen;
205  status_t status;
206  ele_generic_rsa_t genericRsa = {0};
207 
208  //Check parameters
209  if(prngAlgo == NULL || prngContext == NULL)
211  if(key == NULL || message == NULL)
213  if(ciphertext == NULL || ciphertextLen == NULL)
215 
216  //Get the length of the modulus, in bits
217  nLen = mpiGetBitLength(&key->n);
218  //Get the length of the public exponent, in bytes
219  eLen = mpiGetByteLength(&key->e);
220 
221  //The accelerator supports operand lengths up to 4096 bits
222  if(nLen <= 4096 && eLen <= 512 && messageLen <= 512)
223  {
224  //Acquire exclusive access to the ELE module
226 
227  //Copy the modulus
228  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
229  //Copy the public exponent
230  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
231  //Copy the message to be encrypted
232  osMemcpy(eleRsaArgs.m, message, messageLen);
233 
234  //Set RSA parameters
235  genericRsa.algo = RSA_PKCS1_V1_5_CRYPT;
236  genericRsa.mode = kEncryption;
237  genericRsa.key_size = nLen;
238  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
239  genericRsa.modulus_size = (nLen + 7) / 8;
240  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
241  genericRsa.pub_exponent_size = eLen;
242  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
243  genericRsa.plaintext_size = messageLen;
244  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
245  genericRsa.ciphertext_size = (nLen + 7) / 8;
246  genericRsa.flags = kFlagDigest;
247 
248  //Perform RSAES-PKCS1-v1_5 encryption
249  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
250 
251  //Check status code
252  if(status == kStatus_Success)
253  {
254  //Copy the resulting ciphertext
255  osMemcpy(ciphertext, eleRsaArgs.c, (nLen + 7) / 8);
256  //Return the length of the ciphertext
257  *ciphertextLen = (nLen + 7) / 8;
258 
259  //Successful processing
260  error = NO_ERROR;
261  }
262  else
263  {
264  //Report an error
265  error = ERROR_FAILURE;
266  }
267 
268  //Release exclusive access to the ELE module
270  }
271  else
272  {
273  //Report an error
274  error = ERROR_INVALID_LENGTH;
275  }
276 
277  //Return status code
278  return error;
279 }
280 
281 
282 /**
283  * @brief RSAES-PKCS1-v1_5 decryption operation
284  * @param[in] key Recipient's RSA private key
285  * @param[in] ciphertext Ciphertext to be decrypted
286  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
287  * @param[out] message Output buffer where to store the decrypted message
288  * @param[in] messageSize Size of the output buffer
289  * @param[out] messageLen Length of the decrypted message
290  * @return Error code
291  **/
292 
294  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
295  size_t messageSize, size_t *messageLen)
296 {
297  error_t error;
298  size_t nLen;
299  size_t dLen;
300  status_t status;
301  ele_generic_rsa_t genericRsa = {0};
302 
303  //Check parameters
304  if(key == NULL || ciphertext == NULL)
306  if(message == NULL || messageSize == 0 || messageLen == NULL)
308 
309  //Get the length of the modulus, in bits
310  nLen = mpiGetBitLength(&key->n);
311  //Get the length of the private exponent, in bytes
312  dLen = mpiGetByteLength(&key->d);
313 
314  //The accelerator supports operand lengths up to 4096 bits
315  if(nLen <= 4096 && dLen <= 512 && ciphertextLen <= 512)
316  {
317  //Acquire exclusive access to the ELE module
319 
320  //Copy the modulus
321  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
322  //Copy the private exponent
323  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
324  //Copy the ciphertext to be decrypted
325  osMemcpy(eleRsaArgs.c, ciphertext, ciphertextLen);
326 
327  //Set RSA parameters
328  genericRsa.algo = RSA_PKCS1_V1_5_CRYPT;
329  genericRsa.mode = kDecryption;
330  genericRsa.key_size = nLen;
331  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
332  genericRsa.modulus_size = (nLen + 7) / 8;
333  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
334  genericRsa.priv_exponent_size = dLen;
335  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
336  genericRsa.ciphertext_size = ciphertextLen;
337  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
338  genericRsa.plaintext_size = (nLen + 7) / 8;
339  genericRsa.flags = kFlagDigest;
340 
341  //Perform RSAES-PKCS1-v1_5 decryption
342  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
343 
344  //Check status code
345  if(status == kStatus_Success)
346  {
347  //Check the length of the resulting plaintext
348  if(genericRsa.out_plaintext_len <= messageSize)
349  {
350  //Copy the resulting message
351  osMemcpy(message, eleRsaArgs.m, genericRsa.out_plaintext_len);
352  //Return the length of the message
353  *messageLen = genericRsa.out_plaintext_len;
354 
355  //Successful processing
356  error = NO_ERROR;
357  }
358  else
359  {
360  //Report an error
361  error = ERROR_BUFFER_OVERFLOW;
362  }
363  }
364  else
365  {
366  //Report an error
367  error = ERROR_FAILURE;
368  }
369 
370  //Release exclusive access to the ELE module
372  }
373  else
374  {
375  //Report an error
376  error = ERROR_INVALID_LENGTH;
377  }
378 
379  //Return status code
380  return error;
381 }
382 
383 
384 /**
385  * @brief RSAES-OAEP encryption operation
386  * @param[in] prngAlgo PRNG algorithm
387  * @param[in] prngContext Pointer to the PRNG context
388  * @param[in] key Recipient's RSA public key
389  * @param[in] hash Underlying hash function
390  * @param[in] label Optional label to be associated with the message
391  * @param[in] message Message to be encrypted
392  * @param[in] messageLen Length of the message to be encrypted
393  * @param[out] ciphertext Ciphertext resulting from the encryption operation
394  * @param[out] ciphertextLen Length of the resulting ciphertext
395  * @return Error code
396  **/
397 
398 error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext,
399  const RsaPublicKey *key, const HashAlgo *hash, const char_t *label,
400  const uint8_t *message, size_t messageLen, uint8_t *ciphertext,
401  size_t *ciphertextLen)
402 {
403  error_t error;
404  size_t nLen;
405  size_t eLen;
406  size_t labelLen;
407  status_t status;
408  generic_rsa_algo_t algo;
409  ele_generic_rsa_t genericRsa = {0};
410 
411  //Check parameters
412  if(prngAlgo == NULL || prngContext == NULL)
414  if(key == NULL || message == NULL)
416  if(ciphertext == NULL || ciphertextLen == NULL)
418 
419  //Select the relevant algorithm
420  if(osStrcmp(hash->name, "SHA-1") == 0)
421  {
422  algo = RSA_PKCS1_OAEP_SHA1;
423  }
424  else if(osStrcmp(hash->name, "SHA-224") == 0)
425  {
426  algo = RSA_PKCS1_OAEP_SHA224;
427  }
428  else if(osStrcmp(hash->name, "SHA-256") == 0)
429  {
430  algo = RSA_PKCS1_OAEP_SHA256;
431  }
432  else if(osStrcmp(hash->name, "SHA-384") == 0)
433  {
434  algo = RSA_PKCS1_OAEP_SHA384;
435  }
436  else if(osStrcmp(hash->name, "SHA-512") == 0)
437  {
438  algo = RSA_PKCS1_OAEP_SHA512;
439  }
440  else
441  {
443  }
444 
445  //Get the length of the modulus, in bits
446  nLen = mpiGetBitLength(&key->n);
447  //Get the length of the public exponent, in bytes
448  eLen = mpiGetByteLength(&key->e);
449 
450  //The accelerator supports operand lengths up to 4096 bits
451  if(nLen <= 4096 && eLen <= 512 && messageLen <= 512)
452  {
453  //Acquire exclusive access to the ELE module
455 
456  //Copy the modulus
457  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
458  //Copy the public exponent
459  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
460  //Copy the message to be encrypted
461  osMemcpy(eleRsaArgs.m, message, messageLen);
462 
463  //The label is optional
464  if(label != NULL)
465  {
466  osStrcpy(eleRsaArgs.label, label);
467  labelLen = osStrlen(label);
468  }
469  else
470  {
471  labelLen = 0;
472  }
473 
474  //Set RSA parameters
475  genericRsa.algo = algo;
476  genericRsa.mode = kEncryption;
477  genericRsa.key_size = nLen;
478  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
479  genericRsa.modulus_size = (nLen + 7) / 8;
480  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
481  genericRsa.pub_exponent_size = eLen;
482  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
483  genericRsa.plaintext_size = messageLen;
484  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
485  genericRsa.ciphertext_size = (nLen + 7) / 8;
486  genericRsa.label = (uint32_t) eleRsaArgs.label;
487  genericRsa.label_size = labelLen;
488  genericRsa.flags = kFlagDigest;
489 
490  //Perform RSAES-OAEP encryption
491  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
492 
493  //Check status code
494  if(status == kStatus_Success)
495  {
496  //Copy the resulting ciphertext
497  osMemcpy(ciphertext, eleRsaArgs.c, (nLen + 7) / 8);
498  //Return the length of the ciphertext
499  *ciphertextLen = (nLen + 7) / 8;
500 
501  //Successful processing
502  error = NO_ERROR;
503  }
504  else
505  {
506  //Report an error
507  error = ERROR_FAILURE;
508  }
509 
510  //Release exclusive access to the ELE module
512  }
513  else
514  {
515  //Report an error
516  error = ERROR_INVALID_LENGTH;
517  }
518 
519  //Return status code
520  return error;
521 }
522 
523 
524 /**
525  * @brief RSAES-OAEP decryption operation
526  * @param[in] key Recipient's RSA private key
527  * @param[in] hash Underlying hash function
528  * @param[in] label Optional label to be associated with the message
529  * @param[in] ciphertext Ciphertext to be decrypted
530  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
531  * @param[out] message Output buffer where to store the decrypted message
532  * @param[in] messageSize Size of the output buffer
533  * @param[out] messageLen Length of the decrypted message
534  * @return Error code
535  **/
536 
538  const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen,
539  uint8_t *message, size_t messageSize, size_t *messageLen)
540 {
541  error_t error;
542  size_t nLen;
543  size_t dLen;
544  size_t labelLen;
545  status_t status;
546  generic_rsa_algo_t algo;
547  ele_generic_rsa_t genericRsa = {0};
548 
549  //Check parameters
550  if(key == NULL || ciphertext == NULL)
552  if(message == NULL || messageSize == 0 || messageLen == NULL)
554 
555  //Select the relevant algorithm
556  if(osStrcmp(hash->name, "SHA-1") == 0)
557  {
558  algo = RSA_PKCS1_OAEP_SHA1;
559  }
560  else if(osStrcmp(hash->name, "SHA-224") == 0)
561  {
562  algo = RSA_PKCS1_OAEP_SHA224;
563  }
564  else if(osStrcmp(hash->name, "SHA-256") == 0)
565  {
566  algo = RSA_PKCS1_OAEP_SHA256;
567  }
568  else if(osStrcmp(hash->name, "SHA-384") == 0)
569  {
570  algo = RSA_PKCS1_OAEP_SHA384;
571  }
572  else if(osStrcmp(hash->name, "SHA-512") == 0)
573  {
574  algo = RSA_PKCS1_OAEP_SHA512;
575  }
576  else
577  {
579  }
580 
581  //Get the length of the modulus, in bits
582  nLen = mpiGetBitLength(&key->n);
583  //Get the length of the private exponent, in bytes
584  dLen = mpiGetByteLength(&key->d);
585 
586  //The accelerator supports operand lengths up to 4096 bits
587  if(nLen <= 4096 && dLen <= 512 && ciphertextLen <= 512)
588  {
589  //Acquire exclusive access to the ELE module
591 
592  //Copy the modulus
593  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
594  //Copy the private exponent
595  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
596  //Copy the ciphertext to be decrypted
597  osMemcpy(eleRsaArgs.c, ciphertext, ciphertextLen);
598 
599  //The label is optional
600  if(label != NULL)
601  {
602  osStrcpy(eleRsaArgs.label, label);
603  labelLen = osStrlen(label);
604  }
605  else
606  {
607  labelLen = 0;
608  }
609 
610  //Set RSA parameters
611  genericRsa.algo = algo;
612  genericRsa.mode = kDecryption;
613  genericRsa.key_size = nLen;
614  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
615  genericRsa.modulus_size = (nLen + 7) / 8;
616  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
617  genericRsa.priv_exponent_size = dLen;
618  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
619  genericRsa.ciphertext_size = ciphertextLen;
620  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
621  genericRsa.plaintext_size = (nLen + 7) / 8;
622  genericRsa.label = (uint32_t) eleRsaArgs.label;
623  genericRsa.label_size = labelLen;
624  genericRsa.flags = kFlagDigest;
625 
626  //Perform RSAES-OAEP decryption
627  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
628 
629  //Check status code
630  if(status == kStatus_Success)
631  {
632  //Check the length of the resulting plaintext
633  if(genericRsa.out_plaintext_len <= messageSize)
634  {
635  //Copy the resulting message
636  osMemcpy(message, eleRsaArgs.m, genericRsa.out_plaintext_len);
637  //Return the length of the message
638  *messageLen = genericRsa.out_plaintext_len;
639 
640  //Successful processing
641  error = NO_ERROR;
642  }
643  else
644  {
645  //Report an error
646  error = ERROR_BUFFER_OVERFLOW;
647  }
648  }
649  else
650  {
651  //Report an error
652  error = ERROR_FAILURE;
653  }
654 
655  //Release exclusive access to the ELE module
657  }
658  else
659  {
660  //Report an error
661  error = ERROR_INVALID_LENGTH;
662  }
663 
664  //Return status code
665  return error;
666 }
667 
668 
669 /**
670  * @brief RSASSA-PKCS1-v1_5 signature generation operation
671  * @param[in] key Signer's RSA private key
672  * @param[in] hash Hash function used to digest the message
673  * @param[in] digest Digest of the message to be signed
674  * @param[out] signature Resulting signature
675  * @param[out] signatureLen Length of the resulting signature
676  * @return Error code
677  **/
678 
680  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
681 {
682  error_t error;
683  size_t nLen;
684  size_t dLen;
685  status_t status;
686  generic_rsa_algo_t algo;
687  ele_generic_rsa_t genericRsa = {0};
688 
689  //Check parameters
690  if(key == NULL || hash == NULL || digest == NULL)
692  if(signature == NULL || signatureLen == NULL)
694 
695  //Select the relevant algorithm
696  if(osStrcmp(hash->name, "SHA-224") == 0)
697  {
698  algo = RSA_PKCS1_V1_5_SHA224_SIGN;
699  }
700  else if(osStrcmp(hash->name, "SHA-256") == 0)
701  {
702  algo = RSA_PKCS1_V1_5_SHA256_SIGN;
703  }
704  else if(osStrcmp(hash->name, "SHA-384") == 0)
705  {
706  algo = RSA_PKCS1_V1_5_SHA384_SIGN;
707  }
708  else if(osStrcmp(hash->name, "SHA-512") == 0)
709  {
710  algo = RSA_PKCS1_V1_5_SHA512_SIGN;
711  }
712  else
713  {
715  }
716 
717  //Get the length of the modulus, in bits
718  nLen = mpiGetBitLength(&key->n);
719  //Get the length of the private exponent, in bytes
720  dLen = mpiGetByteLength(&key->d);
721 
722  //The accelerator supports operand lengths up to 4096 bits
723  if(nLen <= 4096 && dLen <= 512)
724  {
725  //Acquire exclusive access to the ELE module
727 
728  //Copy the modulus
729  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
730  //Copy the private exponent
731  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
732  //Copy the digest of the message to be signed
733  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
734 
735  //Set RSA parameters
736  genericRsa.algo = algo;
737  genericRsa.mode = kSignGen;
738  genericRsa.key_size = nLen;
739  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
740  genericRsa.modulus_size = (nLen + 7) / 8;
741  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
742  genericRsa.priv_exponent_size = dLen;
743  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
744  genericRsa.digest_size = hash->digestSize;
745  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
746  genericRsa.signature_size = (nLen + 7) / 8;
747  genericRsa.flags = kFlagDigest;
748 
749  //Perform RSASSA-PKCS1-v1_5 signature generation
750  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
751 
752  //Check status code
753  if(status == kStatus_Success)
754  {
755  //Copy the resulting message
756  osMemcpy(signature, eleRsaArgs.signature, (nLen + 7) / 8);
757  //Return the length of the message
758  *signatureLen = (nLen + 7) / 8;
759 
760  //Successful processing
761  error = NO_ERROR;
762  }
763  else
764  {
765  //Report an error
766  error = ERROR_FAILURE;
767  }
768 
769  //Release exclusive access to the ELE module
771  }
772  else
773  {
774  //Report an error
775  error = ERROR_INVALID_LENGTH;
776  }
777 
778  //Return status code
779  return error;
780 }
781 
782 
783 /**
784  * @brief RSASSA-PKCS1-v1_5 signature verification operation
785  * @param[in] key Signer's RSA public key
786  * @param[in] hash Hash function used to digest the message
787  * @param[in] digest Digest of the message whose signature is to be verified
788  * @param[in] signature Signature to be verified
789  * @param[in] signatureLen Length of the signature to be verified
790  * @return Error code
791  **/
792 
794  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
795 {
796  error_t error;
797  size_t nLen;
798  size_t eLen;
799  status_t status;
800  generic_rsa_algo_t algo;
801  ele_generic_rsa_t genericRsa = {0};
802 
803  //Check parameters
804  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
806 
807  //Select the relevant algorithm
808  if(osStrcmp(hash->name, "SHA-224") == 0)
809  {
810  algo = RSA_PKCS1_V1_5_SHA224_SIGN;
811  }
812  else if(osStrcmp(hash->name, "SHA-256") == 0)
813  {
814  algo = RSA_PKCS1_V1_5_SHA256_SIGN;
815  }
816  else if(osStrcmp(hash->name, "SHA-384") == 0)
817  {
818  algo = RSA_PKCS1_V1_5_SHA384_SIGN;
819  }
820  else if(osStrcmp(hash->name, "SHA-512") == 0)
821  {
822  algo = RSA_PKCS1_V1_5_SHA512_SIGN;
823  }
824  else
825  {
827  }
828 
829  //Get the length of the modulus, in bits
830  nLen = mpiGetBitLength(&key->n);
831  //Get the length of the public exponent, in bytes
832  eLen = mpiGetByteLength(&key->e);
833 
834  //The accelerator supports operand lengths up to 4096 bits
835  if(nLen <= 4096 && eLen <= 512 && signatureLen <= 512)
836  {
837  //Acquire exclusive access to the ELE module
839 
840  //Copy the modulus
841  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
842  //Copy the public exponent
843  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
844  //Copy the digest of the message
845  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
846  //Copy the signature to be verified
847  osMemcpy(eleRsaArgs.signature, signature, signatureLen);
848 
849  //Set RSA parameters
850  genericRsa.algo = algo;
851  genericRsa.mode = kVerification;
852  genericRsa.key_size = nLen;
853  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
854  genericRsa.modulus_size = (nLen + 7) / 8;
855  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
856  genericRsa.pub_exponent_size = eLen;
857  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
858  genericRsa.digest_size = hash->digestSize;
859  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
860  genericRsa.signature_size = signatureLen;
861  genericRsa.flags = kFlagDigest;
862 
863  //Perform RSASSA-PKCS1-v1_5 signature verification
864  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
865 
866  //Check status code
867  if(status == kStatus_Success)
868  {
869  //Valid RSA signature?
870  if(genericRsa.verify_status == kVerifySuccess)
871  {
872  error = NO_ERROR;
873  }
874  else if(genericRsa.verify_status == kVerifyFailure)
875  {
876  error = ERROR_INVALID_SIGNATURE;
877  }
878  else
879  {
880  error = ERROR_FAILURE;
881  }
882  }
883  else
884  {
885  //Report an error
886  error = ERROR_FAILURE;
887  }
888 
889  //Release exclusive access to the ELE module
891  }
892  else
893  {
894  //Report an error
895  error = ERROR_INVALID_LENGTH;
896  }
897 
898  //Return status code
899  return error;
900 }
901 
902 
903 /**
904  * @brief RSASSA-PSS signature generation operation
905  * @param[in] prngAlgo PRNG algorithm
906  * @param[in] prngContext Pointer to the PRNG context
907  * @param[in] key Signer's RSA private key
908  * @param[in] hash Hash function used to digest the message
909  * @param[in] saltLen Length of the salt, in bytes
910  * @param[in] digest Digest of the message to be signed
911  * @param[out] signature Resulting signature
912  * @param[out] signatureLen Length of the resulting signature
913  * @return Error code
914  **/
915 
916 error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
917  const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen,
918  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
919 {
920  error_t error;
921  size_t nLen;
922  size_t dLen;
923  status_t status;
924  generic_rsa_algo_t algo;
925  ele_generic_rsa_t genericRsa = {0};
926 
927  //Check parameters
928  if(key == NULL || hash == NULL || digest == NULL)
930  if(signature == NULL || signatureLen == NULL)
932 
933  //Select the relevant algorithm
934  if(osStrcmp(hash->name, "SHA-224") == 0)
935  {
936  algo = RSA_PKCS1_PSS_MGF1_SHA224;
937  }
938  else if(osStrcmp(hash->name, "SHA-256") == 0)
939  {
940  algo = RSA_PKCS1_PSS_MGF1_SHA256;
941  }
942  else if(osStrcmp(hash->name, "SHA-384") == 0)
943  {
944  algo = RSA_PKCS1_PSS_MGF1_SHA384;
945  }
946  else if(osStrcmp(hash->name, "SHA-512") == 0)
947  {
948  algo = RSA_PKCS1_PSS_MGF1_SHA512;
949  }
950  else
951  {
953  }
954 
955  //Get the length of the modulus, in bits
956  nLen = mpiGetBitLength(&key->n);
957  //Get the length of the private exponent, in bytes
958  dLen = mpiGetByteLength(&key->d);
959 
960  //The accelerator supports operand lengths up to 4096 bits
961  if(nLen <= 4096 && dLen <= 512)
962  {
963  //Acquire exclusive access to the ELE module
965 
966  //Copy the modulus
967  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
968  //Copy the private exponent
969  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
970  //Copy the digest of the message to be signed
971  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
972 
973  //Set RSA parameters
974  genericRsa.algo = algo;
975  genericRsa.mode = kSignGen;
976  genericRsa.key_size = nLen;
977  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
978  genericRsa.modulus_size = (nLen + 7) / 8;
979  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
980  genericRsa.priv_exponent_size = dLen;
981  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
982  genericRsa.digest_size = hash->digestSize;
983  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
984  genericRsa.signature_size = (nLen + 7) / 8;
985  genericRsa.flags = kFlagDigest;
986 
987  //Perform RSASSA-PSS signature generation
988  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
989 
990  //Check status code
991  if(status == kStatus_Success)
992  {
993  //Copy the resulting message
994  osMemcpy(signature, eleRsaArgs.signature, (nLen + 7) / 8);
995  //Return the length of the message
996  *signatureLen = (nLen + 7) / 8;
997 
998  //Successful processing
999  error = NO_ERROR;
1000  }
1001  else
1002  {
1003  //Report an error
1004  error = ERROR_FAILURE;
1005  }
1006 
1007  //Release exclusive access to the ELE module
1009  }
1010  else
1011  {
1012  //Report an error
1013  error = ERROR_INVALID_LENGTH;
1014  }
1015 
1016  //Return status code
1017  return error;
1018 }
1019 
1020 
1021 /**
1022  * @brief RSASSA-PSS signature verification operation
1023  * @param[in] key Signer's RSA public key
1024  * @param[in] hash Hash function used to digest the message
1025  * @param[in] saltLen Length of the salt, in bytes
1026  * @param[in] digest Digest of the message whose signature is to be verified
1027  * @param[in] signature Signature to be verified
1028  * @param[in] signatureLen Length of the signature to be verified
1029  * @return Error code
1030  **/
1031 
1033  size_t saltLen, const uint8_t *digest, const uint8_t *signature,
1034  size_t signatureLen)
1035 {
1036  error_t error;
1037  size_t nLen;
1038  size_t eLen;
1039  status_t status;
1040  generic_rsa_algo_t algo;
1041  ele_generic_rsa_t genericRsa = {0};
1042 
1043  //Check parameters
1044  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1045  return ERROR_INVALID_PARAMETER;
1046 
1047  //Select the relevant algorithm
1048  if(osStrcmp(hash->name, "SHA-224") == 0)
1049  {
1050  algo = RSA_PKCS1_PSS_MGF1_SHA224;
1051  }
1052  else if(osStrcmp(hash->name, "SHA-256") == 0)
1053  {
1054  algo = RSA_PKCS1_PSS_MGF1_SHA256;
1055  }
1056  else if(osStrcmp(hash->name, "SHA-384") == 0)
1057  {
1058  algo = RSA_PKCS1_PSS_MGF1_SHA384;
1059  }
1060  else if(osStrcmp(hash->name, "SHA-512") == 0)
1061  {
1062  algo = RSA_PKCS1_PSS_MGF1_SHA512;
1063  }
1064  else
1065  {
1067  }
1068 
1069  //Get the length of the modulus, in bits
1070  nLen = mpiGetBitLength(&key->n);
1071  //Get the length of the public exponent, in bytes
1072  eLen = mpiGetByteLength(&key->e);
1073 
1074  //The accelerator supports operand lengths up to 4096 bits
1075  if(nLen <= 4096 && eLen <= 512 && signatureLen <= 512)
1076  {
1077  //Acquire exclusive access to the ELE module
1079 
1080  //Copy the modulus
1081  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
1082  //Copy the public exponent
1083  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
1084  //Copy the digest of the message
1085  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
1086  //Copy the signature to be verified
1087  osMemcpy(eleRsaArgs.signature, signature, signatureLen);
1088 
1089  //Set RSA parameters
1090  genericRsa.algo = algo;
1091  genericRsa.mode = kVerification;
1092  genericRsa.key_size = nLen;
1093  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
1094  genericRsa.modulus_size = (nLen + 7) / 8;
1095  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
1096  genericRsa.pub_exponent_size = eLen;
1097  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
1098  genericRsa.digest_size = hash->digestSize;
1099  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
1100  genericRsa.signature_size = signatureLen;
1101  genericRsa.flags = kFlagDigest;
1102 
1103  //Perform RSASSA-PSS signature verification
1104  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
1105 
1106  //Check status code
1107  if(status == kStatus_Success)
1108  {
1109  //Valid RSA signature?
1110  if(genericRsa.verify_status == kVerifySuccess)
1111  {
1112  error = NO_ERROR;
1113  }
1114  else if(genericRsa.verify_status == kVerifyFailure)
1115  {
1116  error = ERROR_INVALID_SIGNATURE;
1117  }
1118  else
1119  {
1120  error = ERROR_FAILURE;
1121  }
1122  }
1123  else
1124  {
1125  //Report an error
1126  error = ERROR_FAILURE;
1127  }
1128 
1129  //Release exclusive access to the ELE module
1131  }
1132  else
1133  {
1134  //Report an error
1135  error = ERROR_INVALID_LENGTH;
1136  }
1137 
1138  //Return status code
1139  return error;
1140 }
1141 
1142 #endif
1143 #endif
Mpi p
First factor.
Definition: rsa.h:72
ELE RSA primitive arguments.
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
#define PrngAlgo
Definition: crypto.h:1008
uint8_t message[]
Definition: chap.h:154
size_t digestSize
Definition: crypto.h:1130
Mpi n
Modulus.
Definition: rsa.h:69
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
i.MX RT1180 public-key hardware accelerator
error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
#define osStrcmp(s1, s2)
Definition: os_port.h:174
Mpi e
Public exponent.
Definition: rsa.h:59
#define osStrlen(s)
Definition: os_port.h:168
Mpi d
Private exponent.
Definition: rsa.h:71
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
Mpi n
Modulus.
Definition: rsa.h:58
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PKCS1-v1_5 signature generation operation.
error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, size_t k, uint_t e, RsaPrivateKey *privateKey)
RSA private key generation.
error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key, const HashAlgo *hash, const char_t *label, const uint8_t *message, size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
RSAES-OAEP encryption operation.
@ ERROR_UNSUPPORTED_HASH_ALGO
Definition: error.h:130
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t
Error codes.
Definition: error.h:43
error_t rsassaPkcs1v15Verify(const RsaPublicKey *key, const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PKCS1-v1_5 signature verification operation.
error_t mpiSetValue(Mpi *r, mpi_sword_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:563
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Mpi q
Second factor.
Definition: rsa.h:73
const char_t * name
Definition: crypto.h:1125
RSA public key.
Definition: rsa.h:57
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
OsMutex mimxrt1180CryptoMutex
Mpi e
Public exponent.
Definition: rsa.h:70
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:255
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key, const uint8_t *message, size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
RSAES-PKCS1-v1_5 encryption operation.
char char_t
Definition: compiler_port.h:55
error_t rsaesPkcs1v15Decrypt(const RsaPrivateKey *key, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message, size_t messageSize, size_t *messageLen)
RSAES-PKCS1-v1_5 decryption operation.
RSA private key.
Definition: rsa.h:68
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
i.MX RT1180 hardware cryptographic accelerator (ELE)
error_t rsaesOaepDecrypt(const RsaPrivateKey *key, const HashAlgo *hash, const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message, size_t messageSize, size_t *messageLen)
RSAES-OAEP decryption operation.
Common interface for hash algorithms.
Definition: crypto.h:1124
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
unsigned int uint_t
Definition: compiler_port.h:57
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
#define osStrcpy(s1, s2)
Definition: os_port.h:210
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
SDK_ALIGN(static EleRsaArgs eleRsaArgs, 8)
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216