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-2026 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.6.6
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 || key == NULL ||
210  message == NULL || ciphertext == NULL || ciphertextLen == NULL)
211  {
213  }
214 
215  //Get the length of the modulus, in bits
216  nLen = mpiGetBitLength(&key->n);
217  //Get the length of the public exponent, in bytes
218  eLen = mpiGetByteLength(&key->e);
219 
220  //The accelerator supports operand lengths up to 4096 bits
221  if(nLen <= 4096 && eLen <= 512 && messageLen <= 512)
222  {
223  //Acquire exclusive access to the ELE module
225 
226  //Copy the modulus
227  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
228  //Copy the public exponent
229  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
230  //Copy the message to be encrypted
231  osMemcpy(eleRsaArgs.m, message, messageLen);
232 
233  //Set RSA parameters
234  genericRsa.algo = RSA_PKCS1_V1_5_CRYPT;
235  genericRsa.mode = kEncryption;
236  genericRsa.key_size = nLen;
237  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
238  genericRsa.modulus_size = (nLen + 7) / 8;
239  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
240  genericRsa.pub_exponent_size = eLen;
241  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
242  genericRsa.plaintext_size = messageLen;
243  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
244  genericRsa.ciphertext_size = (nLen + 7) / 8;
245  genericRsa.flags = kFlagDigest;
246 
247  //Perform RSAES-PKCS1-v1_5 encryption
248  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
249 
250  //Check status code
251  if(status == kStatus_Success)
252  {
253  //Copy the resulting ciphertext
254  osMemcpy(ciphertext, eleRsaArgs.c, (nLen + 7) / 8);
255  //Return the length of the ciphertext
256  *ciphertextLen = (nLen + 7) / 8;
257 
258  //Successful processing
259  error = NO_ERROR;
260  }
261  else
262  {
263  //Report an error
264  error = ERROR_FAILURE;
265  }
266 
267  //Release exclusive access to the ELE module
269  }
270  else
271  {
272  //Report an error
273  error = ERROR_INVALID_LENGTH;
274  }
275 
276  //Return status code
277  return error;
278 }
279 
280 
281 /**
282  * @brief RSAES-PKCS1-v1_5 decryption operation
283  * @param[in] key Recipient's RSA private key
284  * @param[in] ciphertext Ciphertext to be decrypted
285  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
286  * @param[out] message Output buffer where to store the decrypted message
287  * @param[in] messageSize Size of the output buffer
288  * @param[out] messageLen Length of the decrypted message
289  * @return Error code
290  **/
291 
293  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
294  size_t messageSize, size_t *messageLen)
295 {
296  error_t error;
297  size_t nLen;
298  size_t dLen;
299  status_t status;
300  ele_generic_rsa_t genericRsa = {0};
301 
302  //Check parameters
303  if(key == NULL || ciphertext == NULL || message == NULL ||
304  messageSize == 0 || messageLen == NULL)
305  {
307  }
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 Hash function
390  * @param[in] mgfHash MGF hash function
391  * @param[in] label Optional label to be associated with the message
392  * @param[in] labelLen Length of the label, in bytes
393  * @param[in] message Message to be encrypted
394  * @param[in] messageLen Length of the message to be encrypted
395  * @param[out] ciphertext Ciphertext resulting from the encryption operation
396  * @param[out] ciphertextLen Length of the resulting ciphertext
397  * @return Error code
398  **/
399 
400 error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext,
401  const RsaPublicKey *key, const HashAlgo *hash, const HashAlgo *mgfHash,
402  const char_t *label, size_t labelLen, const uint8_t *message,
403  size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
404 {
405  error_t error;
406  size_t nLen;
407  size_t eLen;
408  size_t labelLen;
409  status_t status;
410  generic_rsa_algo_t algo;
411  ele_generic_rsa_t genericRsa = {0};
412 
413  //Check parameters
414  if(prngAlgo == NULL || prngContext == NULL || key == NULL || hash == NULL ||
415  mgfHash == NULL || message == NULL || ciphertext == NULL ||
416  ciphertextLen == NULL)
417  {
419  }
420 
421  //Select the relevant algorithm
422  if(osStrcmp(hash->name, "SHA-1") == 0)
423  {
424  algo = RSA_PKCS1_OAEP_SHA1;
425  }
426  else if(osStrcmp(hash->name, "SHA-224") == 0)
427  {
428  algo = RSA_PKCS1_OAEP_SHA224;
429  }
430  else if(osStrcmp(hash->name, "SHA-256") == 0)
431  {
432  algo = RSA_PKCS1_OAEP_SHA256;
433  }
434  else if(osStrcmp(hash->name, "SHA-384") == 0)
435  {
436  algo = RSA_PKCS1_OAEP_SHA384;
437  }
438  else if(osStrcmp(hash->name, "SHA-512") == 0)
439  {
440  algo = RSA_PKCS1_OAEP_SHA512;
441  }
442  else
443  {
445  }
446 
447  //Get the length of the modulus, in bits
448  nLen = mpiGetBitLength(&key->n);
449  //Get the length of the public exponent, in bytes
450  eLen = mpiGetByteLength(&key->e);
451 
452  //The accelerator supports operand lengths up to 4096 bits
453  if(nLen <= 4096 && eLen <= 512 && messageLen <= 512)
454  {
455  //Acquire exclusive access to the ELE module
457 
458  //Copy the modulus
459  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
460  //Copy the public exponent
461  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
462  //Copy the message to be encrypted
463  osMemcpy(eleRsaArgs.m, message, messageLen);
464 
465  //The label is optional
466  if(label != NULL)
467  {
468  osStrcpy(eleRsaArgs.label, label);
469  labelLen = osStrlen(label);
470  }
471  else
472  {
473  labelLen = 0;
474  }
475 
476  //Set RSA parameters
477  genericRsa.algo = algo;
478  genericRsa.mode = kEncryption;
479  genericRsa.key_size = nLen;
480  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
481  genericRsa.modulus_size = (nLen + 7) / 8;
482  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
483  genericRsa.pub_exponent_size = eLen;
484  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
485  genericRsa.plaintext_size = messageLen;
486  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
487  genericRsa.ciphertext_size = (nLen + 7) / 8;
488  genericRsa.label = (uint32_t) eleRsaArgs.label;
489  genericRsa.label_size = labelLen;
490  genericRsa.flags = kFlagDigest;
491 
492  //Perform RSAES-OAEP encryption
493  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
494 
495  //Check status code
496  if(status == kStatus_Success)
497  {
498  //Copy the resulting ciphertext
499  osMemcpy(ciphertext, eleRsaArgs.c, (nLen + 7) / 8);
500  //Return the length of the ciphertext
501  *ciphertextLen = (nLen + 7) / 8;
502 
503  //Successful processing
504  error = NO_ERROR;
505  }
506  else
507  {
508  //Report an error
509  error = ERROR_FAILURE;
510  }
511 
512  //Release exclusive access to the ELE module
514  }
515  else
516  {
517  //Report an error
518  error = ERROR_INVALID_LENGTH;
519  }
520 
521  //Return status code
522  return error;
523 }
524 
525 
526 /**
527  * @brief RSAES-OAEP decryption operation
528  * @param[in] key Recipient's RSA private key
529  * @param[in] hash Hash function
530  * @param[in] mgfHash MGF hash function
531  * @param[in] label Optional label to be associated with the message
532  * @param[in] labelLen Length of the label, in bytes
533  * @param[in] ciphertext Ciphertext to be decrypted
534  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
535  * @param[out] message Output buffer where to store the decrypted message
536  * @param[in] messageSize Size of the output buffer
537  * @param[out] messageLen Length of the decrypted message
538  * @return Error code
539  **/
540 
542  const HashAlgo *mgfHash, const char_t *label, size_t labelLen,
543  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
544  size_t messageSize, size_t *messageLen)
545 {
546  error_t error;
547  size_t nLen;
548  size_t dLen;
549  size_t labelLen;
550  status_t status;
551  generic_rsa_algo_t algo;
552  ele_generic_rsa_t genericRsa = {0};
553 
554  //Check parameters
555  if(key == NULL || hash == NULL || mgfHash == NULL || ciphertext == NULL ||
556  message == NULL || messageSize == 0 || messageLen == NULL)
557  {
559  }
560 
561  //Select the relevant algorithm
562  if(osStrcmp(hash->name, "SHA-1") == 0)
563  {
564  algo = RSA_PKCS1_OAEP_SHA1;
565  }
566  else if(osStrcmp(hash->name, "SHA-224") == 0)
567  {
568  algo = RSA_PKCS1_OAEP_SHA224;
569  }
570  else if(osStrcmp(hash->name, "SHA-256") == 0)
571  {
572  algo = RSA_PKCS1_OAEP_SHA256;
573  }
574  else if(osStrcmp(hash->name, "SHA-384") == 0)
575  {
576  algo = RSA_PKCS1_OAEP_SHA384;
577  }
578  else if(osStrcmp(hash->name, "SHA-512") == 0)
579  {
580  algo = RSA_PKCS1_OAEP_SHA512;
581  }
582  else
583  {
585  }
586 
587  //Get the length of the modulus, in bits
588  nLen = mpiGetBitLength(&key->n);
589  //Get the length of the private exponent, in bytes
590  dLen = mpiGetByteLength(&key->d);
591 
592  //The accelerator supports operand lengths up to 4096 bits
593  if(nLen <= 4096 && dLen <= 512 && ciphertextLen <= 512)
594  {
595  //Acquire exclusive access to the ELE module
597 
598  //Copy the modulus
599  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
600  //Copy the private exponent
601  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
602  //Copy the ciphertext to be decrypted
603  osMemcpy(eleRsaArgs.c, ciphertext, ciphertextLen);
604 
605  //The label is optional
606  if(label != NULL)
607  {
608  osStrcpy(eleRsaArgs.label, label);
609  labelLen = osStrlen(label);
610  }
611  else
612  {
613  labelLen = 0;
614  }
615 
616  //Set RSA parameters
617  genericRsa.algo = algo;
618  genericRsa.mode = kDecryption;
619  genericRsa.key_size = nLen;
620  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
621  genericRsa.modulus_size = (nLen + 7) / 8;
622  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
623  genericRsa.priv_exponent_size = dLen;
624  genericRsa.ciphertext = (uint32_t) eleRsaArgs.c;
625  genericRsa.ciphertext_size = ciphertextLen;
626  genericRsa.plaintext = (uint32_t) eleRsaArgs.m;
627  genericRsa.plaintext_size = (nLen + 7) / 8;
628  genericRsa.label = (uint32_t) eleRsaArgs.label;
629  genericRsa.label_size = labelLen;
630  genericRsa.flags = kFlagDigest;
631 
632  //Perform RSAES-OAEP decryption
633  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
634 
635  //Check status code
636  if(status == kStatus_Success)
637  {
638  //Check the length of the resulting plaintext
639  if(genericRsa.out_plaintext_len <= messageSize)
640  {
641  //Copy the resulting message
642  osMemcpy(message, eleRsaArgs.m, genericRsa.out_plaintext_len);
643  //Return the length of the message
644  *messageLen = genericRsa.out_plaintext_len;
645 
646  //Successful processing
647  error = NO_ERROR;
648  }
649  else
650  {
651  //Report an error
652  error = ERROR_BUFFER_OVERFLOW;
653  }
654  }
655  else
656  {
657  //Report an error
658  error = ERROR_FAILURE;
659  }
660 
661  //Release exclusive access to the ELE module
663  }
664  else
665  {
666  //Report an error
667  error = ERROR_INVALID_LENGTH;
668  }
669 
670  //Return status code
671  return error;
672 }
673 
674 
675 /**
676  * @brief RSASSA-PKCS1-v1_5 signature generation operation
677  * @param[in] key Signer's RSA private key
678  * @param[in] hash Hash function used to digest the message
679  * @param[in] digest Digest of the message to be signed
680  * @param[out] signature Resulting signature
681  * @param[out] signatureLen Length of the resulting signature
682  * @return Error code
683  **/
684 
686  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
687 {
688  error_t error;
689  size_t nLen;
690  size_t dLen;
691  status_t status;
692  generic_rsa_algo_t algo;
693  ele_generic_rsa_t genericRsa = {0};
694 
695  //Check parameters
696  if(key == NULL || hash == NULL || digest == NULL || signature == NULL ||
697  signatureLen == NULL)
698  {
700  }
701 
702  //Select the relevant algorithm
703  if(osStrcmp(hash->name, "SHA-224") == 0)
704  {
705  algo = RSA_PKCS1_V1_5_SHA224_SIGN;
706  }
707  else if(osStrcmp(hash->name, "SHA-256") == 0)
708  {
709  algo = RSA_PKCS1_V1_5_SHA256_SIGN;
710  }
711  else if(osStrcmp(hash->name, "SHA-384") == 0)
712  {
713  algo = RSA_PKCS1_V1_5_SHA384_SIGN;
714  }
715  else if(osStrcmp(hash->name, "SHA-512") == 0)
716  {
717  algo = RSA_PKCS1_V1_5_SHA512_SIGN;
718  }
719  else
720  {
722  }
723 
724  //Get the length of the modulus, in bits
725  nLen = mpiGetBitLength(&key->n);
726  //Get the length of the private exponent, in bytes
727  dLen = mpiGetByteLength(&key->d);
728 
729  //The accelerator supports operand lengths up to 4096 bits
730  if(nLen <= 4096 && dLen <= 512)
731  {
732  //Acquire exclusive access to the ELE module
734 
735  //Copy the modulus
736  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
737  //Copy the private exponent
738  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
739  //Copy the digest of the message to be signed
740  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
741 
742  //Set RSA parameters
743  genericRsa.algo = algo;
744  genericRsa.mode = kSignGen;
745  genericRsa.key_size = nLen;
746  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
747  genericRsa.modulus_size = (nLen + 7) / 8;
748  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
749  genericRsa.priv_exponent_size = dLen;
750  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
751  genericRsa.digest_size = hash->digestSize;
752  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
753  genericRsa.signature_size = (nLen + 7) / 8;
754  genericRsa.flags = kFlagDigest;
755 
756  //Perform RSASSA-PKCS1-v1_5 signature generation
757  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
758 
759  //Check status code
760  if(status == kStatus_Success)
761  {
762  //Copy the resulting message
763  osMemcpy(signature, eleRsaArgs.signature, (nLen + 7) / 8);
764  //Return the length of the message
765  *signatureLen = (nLen + 7) / 8;
766 
767  //Successful processing
768  error = NO_ERROR;
769  }
770  else
771  {
772  //Report an error
773  error = ERROR_FAILURE;
774  }
775 
776  //Release exclusive access to the ELE module
778  }
779  else
780  {
781  //Report an error
782  error = ERROR_INVALID_LENGTH;
783  }
784 
785  //Return status code
786  return error;
787 }
788 
789 
790 /**
791  * @brief RSASSA-PKCS1-v1_5 signature verification operation
792  * @param[in] key Signer's RSA public key
793  * @param[in] hash Hash function used to digest the message
794  * @param[in] digest Digest of the message whose signature is to be verified
795  * @param[in] signature Signature to be verified
796  * @param[in] signatureLen Length of the signature to be verified
797  * @return Error code
798  **/
799 
801  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
802 {
803  error_t error;
804  size_t nLen;
805  size_t eLen;
806  status_t status;
807  generic_rsa_algo_t algo;
808  ele_generic_rsa_t genericRsa = {0};
809 
810  //Check parameters
811  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
813 
814  //Select the relevant algorithm
815  if(osStrcmp(hash->name, "SHA-224") == 0)
816  {
817  algo = RSA_PKCS1_V1_5_SHA224_SIGN;
818  }
819  else if(osStrcmp(hash->name, "SHA-256") == 0)
820  {
821  algo = RSA_PKCS1_V1_5_SHA256_SIGN;
822  }
823  else if(osStrcmp(hash->name, "SHA-384") == 0)
824  {
825  algo = RSA_PKCS1_V1_5_SHA384_SIGN;
826  }
827  else if(osStrcmp(hash->name, "SHA-512") == 0)
828  {
829  algo = RSA_PKCS1_V1_5_SHA512_SIGN;
830  }
831  else
832  {
834  }
835 
836  //Get the length of the modulus, in bits
837  nLen = mpiGetBitLength(&key->n);
838  //Get the length of the public exponent, in bytes
839  eLen = mpiGetByteLength(&key->e);
840 
841  //The accelerator supports operand lengths up to 4096 bits
842  if(nLen <= 4096 && eLen <= 512 && signatureLen <= 512)
843  {
844  //Acquire exclusive access to the ELE module
846 
847  //Copy the modulus
848  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
849  //Copy the public exponent
850  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
851  //Copy the digest of the message
852  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
853  //Copy the signature to be verified
854  osMemcpy(eleRsaArgs.signature, signature, signatureLen);
855 
856  //Set RSA parameters
857  genericRsa.algo = algo;
858  genericRsa.mode = kVerification;
859  genericRsa.key_size = nLen;
860  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
861  genericRsa.modulus_size = (nLen + 7) / 8;
862  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
863  genericRsa.pub_exponent_size = eLen;
864  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
865  genericRsa.digest_size = hash->digestSize;
866  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
867  genericRsa.signature_size = signatureLen;
868  genericRsa.flags = kFlagDigest;
869 
870  //Perform RSASSA-PKCS1-v1_5 signature verification
871  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
872 
873  //Check status code
874  if(status == kStatus_Success)
875  {
876  //Valid RSA signature?
877  if(genericRsa.verify_status == kVerifySuccess)
878  {
879  error = NO_ERROR;
880  }
881  else if(genericRsa.verify_status == kVerifyFailure)
882  {
883  error = ERROR_INVALID_SIGNATURE;
884  }
885  else
886  {
887  error = ERROR_FAILURE;
888  }
889  }
890  else
891  {
892  //Report an error
893  error = ERROR_FAILURE;
894  }
895 
896  //Release exclusive access to the ELE module
898  }
899  else
900  {
901  //Report an error
902  error = ERROR_INVALID_LENGTH;
903  }
904 
905  //Return status code
906  return error;
907 }
908 
909 
910 /**
911  * @brief RSASSA-PSS signature generation operation
912  * @param[in] prngAlgo PRNG algorithm
913  * @param[in] prngContext Pointer to the PRNG context
914  * @param[in] key Signer's RSA private key
915  * @param[in] hash Hash function used to digest the message
916  * @param[in] mgfHash MGF hash function
917  * @param[in] saltLen Length of the salt, in bytes
918  * @param[in] digest Digest of the message to be signed
919  * @param[out] signature Resulting signature
920  * @param[out] signatureLen Length of the resulting signature
921  * @return Error code
922  **/
923 
924 error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
925  const RsaPrivateKey *key, const HashAlgo *hash, const HashAlgo *mgfHash,
926  size_t saltLen, const uint8_t *digest, uint8_t *signature,
927  size_t *signatureLen)
928 {
929  error_t error;
930  size_t nLen;
931  size_t dLen;
932  status_t status;
933  generic_rsa_algo_t algo;
934  ele_generic_rsa_t genericRsa = {0};
935 
936  //Check parameters
937  if(prngAlgo == NULL || prngContext == NULL || key == NULL || hash == NULL ||
938  mgfHash == NULL || digest == NULL || signature == NULL ||
939  signatureLen == NULL)
940  {
942  }
943 
944  //Select the relevant algorithm
945  if(osStrcmp(hash->name, "SHA-224") == 0)
946  {
947  algo = RSA_PKCS1_PSS_MGF1_SHA224;
948  }
949  else if(osStrcmp(hash->name, "SHA-256") == 0)
950  {
951  algo = RSA_PKCS1_PSS_MGF1_SHA256;
952  }
953  else if(osStrcmp(hash->name, "SHA-384") == 0)
954  {
955  algo = RSA_PKCS1_PSS_MGF1_SHA384;
956  }
957  else if(osStrcmp(hash->name, "SHA-512") == 0)
958  {
959  algo = RSA_PKCS1_PSS_MGF1_SHA512;
960  }
961  else
962  {
964  }
965 
966  //Get the length of the modulus, in bits
967  nLen = mpiGetBitLength(&key->n);
968  //Get the length of the private exponent, in bytes
969  dLen = mpiGetByteLength(&key->d);
970 
971  //The accelerator supports operand lengths up to 4096 bits
972  if(nLen <= 4096 && dLen <= 512)
973  {
974  //Acquire exclusive access to the ELE module
976 
977  //Copy the modulus
978  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
979  //Copy the private exponent
980  mpiWriteRaw(&key->d, eleRsaArgs.d, dLen);
981  //Copy the digest of the message to be signed
982  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
983 
984  //Set RSA parameters
985  genericRsa.algo = algo;
986  genericRsa.mode = kSignGen;
987  genericRsa.key_size = nLen;
988  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
989  genericRsa.modulus_size = (nLen + 7) / 8;
990  genericRsa.priv_exponent = (uint32_t) eleRsaArgs.d;
991  genericRsa.priv_exponent_size = dLen;
992  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
993  genericRsa.digest_size = hash->digestSize;
994  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
995  genericRsa.signature_size = (nLen + 7) / 8;
996  genericRsa.flags = kFlagDigest;
997 
998  //Perform RSASSA-PSS signature generation
999  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
1000 
1001  //Check status code
1002  if(status == kStatus_Success)
1003  {
1004  //Copy the resulting message
1005  osMemcpy(signature, eleRsaArgs.signature, (nLen + 7) / 8);
1006  //Return the length of the message
1007  *signatureLen = (nLen + 7) / 8;
1008 
1009  //Successful processing
1010  error = NO_ERROR;
1011  }
1012  else
1013  {
1014  //Report an error
1015  error = ERROR_FAILURE;
1016  }
1017 
1018  //Release exclusive access to the ELE module
1020  }
1021  else
1022  {
1023  //Report an error
1024  error = ERROR_INVALID_LENGTH;
1025  }
1026 
1027  //Return status code
1028  return error;
1029 }
1030 
1031 
1032 /**
1033  * @brief RSASSA-PSS signature verification operation
1034  * @param[in] key Signer's RSA public key
1035  * @param[in] hash Hash function used to digest the message
1036  * @param[in] mgfHash MGF hash function
1037  * @param[in] saltLen Length of the salt, in bytes
1038  * @param[in] digest Digest of the message whose signature is to be verified
1039  * @param[in] signature Signature to be verified
1040  * @param[in] signatureLen Length of the signature to be verified
1041  * @return Error code
1042  **/
1043 
1045  const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest,
1046  const uint8_t *signature, size_t signatureLen)
1047 {
1048  error_t error;
1049  size_t nLen;
1050  size_t eLen;
1051  status_t status;
1052  generic_rsa_algo_t algo;
1053  ele_generic_rsa_t genericRsa = {0};
1054 
1055  //Check parameters
1056  if(key == NULL || hash == NULL || mgfHash == NULL || digest == NULL ||
1057  signature == NULL)
1058  {
1059  return ERROR_INVALID_PARAMETER;
1060  }
1061 
1062  //Select the relevant algorithm
1063  if(osStrcmp(hash->name, "SHA-224") == 0)
1064  {
1065  algo = RSA_PKCS1_PSS_MGF1_SHA224;
1066  }
1067  else if(osStrcmp(hash->name, "SHA-256") == 0)
1068  {
1069  algo = RSA_PKCS1_PSS_MGF1_SHA256;
1070  }
1071  else if(osStrcmp(hash->name, "SHA-384") == 0)
1072  {
1073  algo = RSA_PKCS1_PSS_MGF1_SHA384;
1074  }
1075  else if(osStrcmp(hash->name, "SHA-512") == 0)
1076  {
1077  algo = RSA_PKCS1_PSS_MGF1_SHA512;
1078  }
1079  else
1080  {
1082  }
1083 
1084  //Get the length of the modulus, in bits
1085  nLen = mpiGetBitLength(&key->n);
1086  //Get the length of the public exponent, in bytes
1087  eLen = mpiGetByteLength(&key->e);
1088 
1089  //The accelerator supports operand lengths up to 4096 bits
1090  if(nLen <= 4096 && eLen <= 512 && signatureLen <= 512)
1091  {
1092  //Acquire exclusive access to the ELE module
1094 
1095  //Copy the modulus
1096  mpiWriteRaw(&key->n, eleRsaArgs.n, (nLen + 7) / 8);
1097  //Copy the public exponent
1098  mpiWriteRaw(&key->e, eleRsaArgs.e, eLen);
1099  //Copy the digest of the message
1100  osMemcpy(eleRsaArgs.digest, digest, hash->digestSize);
1101  //Copy the signature to be verified
1102  osMemcpy(eleRsaArgs.signature, signature, signatureLen);
1103 
1104  //Set RSA parameters
1105  genericRsa.algo = algo;
1106  genericRsa.mode = kVerification;
1107  genericRsa.key_size = nLen;
1108  genericRsa.modulus = (uint32_t) eleRsaArgs.n;
1109  genericRsa.modulus_size = (nLen + 7) / 8;
1110  genericRsa.pub_exponent = (uint32_t) eleRsaArgs.e;
1111  genericRsa.pub_exponent_size = eLen;
1112  genericRsa.digest = (uint32_t) eleRsaArgs.digest;
1113  genericRsa.digest_size = hash->digestSize;
1114  genericRsa.signature = (uint32_t) eleRsaArgs.signature;
1115  genericRsa.signature_size = signatureLen;
1116  genericRsa.flags = kFlagDigest;
1117 
1118  //Perform RSASSA-PSS signature verification
1119  status = ELE_GenericRsa(MU_APPS_S3MUA, &genericRsa);
1120 
1121  //Check status code
1122  if(status == kStatus_Success)
1123  {
1124  //Valid RSA signature?
1125  if(genericRsa.verify_status == kVerifySuccess)
1126  {
1127  error = NO_ERROR;
1128  }
1129  else if(genericRsa.verify_status == kVerifyFailure)
1130  {
1131  error = ERROR_INVALID_SIGNATURE;
1132  }
1133  else
1134  {
1135  error = ERROR_FAILURE;
1136  }
1137  }
1138  else
1139  {
1140  //Report an error
1141  error = ERROR_FAILURE;
1142  }
1143 
1144  //Release exclusive access to the ELE module
1146  }
1147  else
1148  {
1149  //Report an error
1150  error = ERROR_INVALID_LENGTH;
1151  }
1152 
1153  //Return status code
1154  return error;
1155 }
1156 
1157 #endif
1158 #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:1140
uint8_t message[]
Definition: chap.h:154
size_t digestSize
Definition: crypto.h:1249
Mpi n
Modulus.
Definition: rsa.h:69
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
i.MX RT1180 public-key hardware accelerator
#define osStrcmp(s1, s2)
Definition: os_port.h:177
Mpi e
Public exponent.
Definition: rsa.h:59
#define osStrlen(s)
Definition: os_port.h:171
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 rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key, const HashAlgo *hash, const HashAlgo *mgfHash, const char_t *label, size_t labelLen, const uint8_t *message, size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
RSAES-OAEP encryption operation.
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_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:147
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_FAILURE
Generic error code.
Definition: error.h:45
Mpi q
Second factor.
Definition: rsa.h:73
const char_t * name
Definition: crypto.h:1244
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 rsaesOaepDecrypt(const RsaPrivateKey *key, const HashAlgo *hash, const HashAlgo *mgfHash, const char_t *label, size_t labelLen, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message, size_t messageSize, size_t *messageLen)
RSAES-OAEP decryption operation.
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)
Common interface for hash algorithms.
Definition: crypto.h:1243
error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
unsigned int uint_t
Definition: compiler_port.h:57
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
#define osStrcpy(s1, s2)
Definition: os_port.h:213
@ 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