rsa.c
Go to the documentation of this file.
1 /**
2  * @file rsa.c
3  * @brief RSA public-key cryptography standard
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  * @section Description
28  *
29  * RSA is an algorithm for public-key cryptography which is suitable for signing
30  * as well as encryption. Refer to the following RFCs for complete details:
31  * - RFC 2313: PKCS #1: RSA Encryption Version 1.5
32  * - RFC 3447: PKCS #1: RSA Cryptography Specifications Version 2.1
33  * - RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2
34  *
35  * @author Oryx Embedded SARL (www.oryx-embedded.com)
36  * @version 2.6.6
37  **/
38 
39 //Switch to the appropriate trace level
40 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
41 
42 //Dependencies
43 #include "core/crypto.h"
44 #include "pkc/rsa.h"
45 #include "pkc/rsa_misc.h"
46 #include "debug.h"
47 
48 //Check crypto library configuration
49 #if (RSA_SUPPORT == ENABLED)
50 
51 //PKCS #1 OID (1.2.840.113549.1.1)
52 const uint8_t PKCS1_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01};
53 //RSA encryption OID (1.2.840.113549.1.1.1)
54 const uint8_t RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01};
55 
56 //MD2 with RSA encryption OID (1.2.840.113549.1.1.2)
57 const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02};
58 //MD5 with RSA encryption OID (1.2.840.113549.1.1.4)
59 const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04};
60 //SHA-1 with RSA encryption OID (1.2.840.113549.1.1.5)
61 const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05};
62 //SHA-224 with RSA encryption OID (1.2.840.113549.1.1.14)
63 const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E};
64 //SHA-256 with RSA encryption OID (1.2.840.113549.1.1.11)
65 const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B};
66 //SHA-384 with RSA encryption OID (1.2.840.113549.1.1.12)
67 const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C};
68 //SHA-512 with RSA encryption OID (1.2.840.113549.1.1.13)
69 const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D};
70 //SHA-512/224 with RSA encryption OID (1.2.840.113549.1.1.15)
71 const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0F};
72 //SHA-512/256 with RSA encryption OID (1.2.840.113549.1.1.16)
73 const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x10};
74 
75 //RSASSA-PKCS1-v1_5 signature with SHA-3-224 OID (2.16.840.1.101.3.4.3.13)
76 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0D};
77 //RSASSA-PKCS1-v1_5 signature with SHA-3-256 OID (2.16.840.1.101.3.4.3.14)
78 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0E};
79 //RSASSA-PKCS1-v1_5 signature with SHA-3-384 OID (2.16.840.1.101.3.4.3.15)
80 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0F};
81 //RSASSA-PKCS1-v1_5 signature with SHA-3-512 OID (2.16.840.1.101.3.4.3.16)
82 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x10};
83 
84 //RSASSA-PSS OID (1.2.840.113549.1.1.10)
85 const uint8_t RSASSA_PSS_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A};
86 //RSASSA-PSS-SHAKE128 OID (1.3.6.1.5.5.7.6.30)
87 const uint8_t RSASSA_PSS_SHAKE128_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x1E};
88 //RSASSA-PSS-SHAKE256 OID (1.3.6.1.5.5.7.6.31)
89 const uint8_t RSASSA_PSS_SHAKE256_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x1F};
90 
91 //MGF1 OID (1.2.840.113549.1.1.8)
92 const uint8_t MGF1_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x08};
93 
94 
95 /**
96  * @brief Initialize an RSA public key
97  * @param[in] key Pointer to the RSA public key to initialize
98  **/
99 
101 {
102  //Initialize multiple precision integers
103  mpiInit(&key->n);
104  mpiInit(&key->e);
105 }
106 
107 
108 /**
109  * @brief Release an RSA public key
110  * @param[in] key Pointer to the RSA public key to free
111  **/
112 
114 {
115  //Free multiple precision integers
116  mpiFree(&key->n);
117  mpiFree(&key->e);
118 }
119 
120 
121 /**
122  * @brief Initialize an RSA private key
123  * @param[in] key Pointer to the RSA private key to initialize
124  **/
125 
127 {
128  //Initialize multiple precision integers
129  mpiInit(&key->n);
130  mpiInit(&key->e);
131  mpiInit(&key->d);
132  mpiInit(&key->p);
133  mpiInit(&key->q);
134  mpiInit(&key->dp);
135  mpiInit(&key->dq);
136  mpiInit(&key->qinv);
137 
138  //Initialize private key slot
139  key->slot = -1;
140 }
141 
142 
143 /**
144  * @brief Release an RSA private key
145  * @param[in] key Pointer to the RSA private key to free
146  **/
147 
149 {
150  //Free multiple precision integers
151  mpiFree(&key->n);
152  mpiFree(&key->e);
153  mpiFree(&key->d);
154  mpiFree(&key->p);
155  mpiFree(&key->q);
156  mpiFree(&key->dp);
157  mpiFree(&key->dq);
158  mpiFree(&key->qinv);
159 }
160 
161 
162 /**
163  * @brief RSA key pair generation
164  * @param[in] prngAlgo PRNG algorithm
165  * @param[in] prngContext Pointer to the PRNG context
166  * @param[in] k Required bit length of the modulus n
167  * @param[in] e Public exponent (3, 5, 17, 257 or 65537)
168  * @param[out] privateKey RSA private key
169  * @param[out] publicKey RSA public key
170  * @return Error code
171  **/
172 
173 error_t rsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext,
174  size_t k, uint_t e, RsaPrivateKey *privateKey, RsaPublicKey *publicKey)
175 {
176  error_t error;
177 
178  //Generate a private key
179  error = rsaGeneratePrivateKey(prngAlgo, prngContext, k, e, privateKey);
180 
181  //Check status code
182  if(!error)
183  {
184  //Derive the public key from the private key
185  error = rsaGeneratePublicKey(privateKey, publicKey);
186  }
187 
188  //Return status code
189  return error;
190 }
191 
192 
193 /**
194  * @brief RSA private key generation
195  * @param[in] prngAlgo PRNG algorithm
196  * @param[in] prngContext Pointer to the PRNG context
197  * @param[in] k Required bit length of the modulus n
198  * @param[in] e Public exponent (3, 5, 17, 257 or 65537)
199  * @param[out] privateKey RSA private key
200  * @return Error code
201  **/
202 
203 __weak_func error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext,
204  size_t k, uint_t e, RsaPrivateKey *privateKey)
205 {
206  error_t error;
207  Mpi t1;
208  Mpi t2;
209  Mpi phy;
210 
211  //Check parameters
212  if(prngAlgo == NULL || prngContext == NULL || privateKey == NULL)
214 
215  //Check the length of the modulus
216  if(k < 8)
218 
219  //Check the value of the public exponent
220  if(e != 3 && e != 5 && e != 17 && e != 257 && e != 65537)
222 
223  //Initialize multiple precision integers
224  mpiInit(&t1);
225  mpiInit(&t2);
226  mpiInit(&phy);
227 
228  //Save public exponent
229  MPI_CHECK(mpiSetValue(&privateKey->e, e));
230 
231  //Generate a large random prime p
232  do
233  {
234  do
235  {
236  //Generate a random number of bit length k/2
237  MPI_CHECK(mpiRand(&privateKey->p, k / 2, prngAlgo, prngContext));
238  //Set the low bit (this ensures the number is odd)
239  MPI_CHECK(mpiSetBitValue(&privateKey->p, 0, 1));
240  //Set the two highest bits (this ensures that the high bit of n is also set)
241  MPI_CHECK(mpiSetBitValue(&privateKey->p, k / 2 - 1, 1));
242  MPI_CHECK(mpiSetBitValue(&privateKey->p, k / 2 - 2, 1));
243 
244  //Test whether p is a probable prime
245  error = mpiCheckProbablePrime(&privateKey->p);
246 
247  //Repeat until an acceptable value is found
248  } while(error == ERROR_INVALID_VALUE);
249 
250  //Check status code
251  MPI_CHECK(error);
252 
253  //Compute p mod e
254  MPI_CHECK(mpiMod(&t1, &privateKey->p, &privateKey->e));
255 
256  //Repeat as long as p mod e = 1
257  } while(mpiCompInt(&t1, 1) == 0);
258 
259  //Generate a large random prime q
260  do
261  {
262  do
263  {
264  //Generate random number of bit length k - k/2
265  MPI_CHECK(mpiRand(&privateKey->q, k - (k / 2), prngAlgo, prngContext));
266  //Set the low bit (this ensures the number is odd)
267  MPI_CHECK(mpiSetBitValue(&privateKey->q, 0, 1));
268  //Set the two highest bits (this ensures that the high bit of n is also set)
269  MPI_CHECK(mpiSetBitValue(&privateKey->q, k - (k / 2) - 1, 1));
270  MPI_CHECK(mpiSetBitValue(&privateKey->q, k - (k / 2) - 2, 1));
271 
272  //Test whether q is a probable prime
273  error = mpiCheckProbablePrime(&privateKey->q);
274 
275  //Repeat until an acceptable value is found
276  } while(error == ERROR_INVALID_VALUE);
277 
278  //Check status code
279  MPI_CHECK(error);
280 
281  //Compute q mod e
282  MPI_CHECK(mpiMod(&t2, &privateKey->q, &privateKey->e));
283 
284  //Repeat as long as p mod e = 1
285  } while(mpiCompInt(&t2, 1) == 0);
286 
287  //Make sure p an q are distinct
288  if(mpiComp(&privateKey->p, &privateKey->q) == 0)
289  {
291  }
292 
293  //If p < q, then swap p and q (this only matters if the CRT form of
294  //the private key is used)
295  if(mpiComp(&privateKey->p, &privateKey->q) < 0)
296  {
297  //Swap primes
298  mpiCopy(&t1, &privateKey->p);
299  mpiCopy(&privateKey->p, &privateKey->q);
300  mpiCopy(&privateKey->q, &t1);
301  }
302 
303  //Compute the modulus n = pq
304  MPI_CHECK(mpiMul(&privateKey->n, &privateKey->p, &privateKey->q));
305 
306  //Compute phy = (p-1)(q-1)
307  MPI_CHECK(mpiSubInt(&t1, &privateKey->p, 1));
308  MPI_CHECK(mpiSubInt(&t2, &privateKey->q, 1));
309  MPI_CHECK(mpiMul(&phy, &t1, &t2));
310 
311  //Compute d = e^-1 mod phy
312  MPI_CHECK(mpiInvMod(&privateKey->d, &privateKey->e, &phy));
313  //Compute dP = d mod (p-1)
314  MPI_CHECK(mpiMod(&privateKey->dp, &privateKey->d, &t1));
315  //Compute dQ = d mod (q-1)
316  MPI_CHECK(mpiMod(&privateKey->dq, &privateKey->d, &t2));
317  //Compute qInv = q^-1 mod p
318  MPI_CHECK(mpiInvMod(&privateKey->qinv, &privateKey->q, &privateKey->p));
319 
320  //Debug message
321  TRACE_DEBUG("RSA private key:\r\n");
322  TRACE_DEBUG(" Modulus:\r\n");
323  TRACE_DEBUG_MPI(" ", &privateKey->n);
324  TRACE_DEBUG(" Public exponent:\r\n");
325  TRACE_DEBUG_MPI(" ", &privateKey->e);
326  TRACE_DEBUG(" Private exponent:\r\n");
327  TRACE_DEBUG_MPI(" ", &privateKey->d);
328  TRACE_DEBUG(" Prime 1:\r\n");
329  TRACE_DEBUG_MPI(" ", &privateKey->p);
330  TRACE_DEBUG(" Prime 2:\r\n");
331  TRACE_DEBUG_MPI(" ", &privateKey->q);
332  TRACE_DEBUG(" Prime exponent 1:\r\n");
333  TRACE_DEBUG_MPI(" ", &privateKey->dp);
334  TRACE_DEBUG(" Prime exponent 2:\r\n");
335  TRACE_DEBUG_MPI(" ", &privateKey->dq);
336  TRACE_DEBUG(" Coefficient:\r\n");
337  TRACE_DEBUG_MPI(" ", &privateKey->qinv);
338 
339 end:
340  //Release multiple precision integers
341  mpiFree(&t1);
342  mpiFree(&t2);
343  mpiFree(&phy);
344 
345  //Any error to report?
346  if(error)
347  {
348  //Release RSA private key
349  rsaFreePrivateKey(privateKey);
350  }
351 
352  //Return status code
353  return error;
354 }
355 
356 
357 /**
358  * @brief Derive the public key from an RSA private key
359  * @param[in] privateKey RSA private key
360  * @param[out] publicKey RSA public key
361  * @return Error code
362  **/
363 
365  RsaPublicKey *publicKey)
366 {
367  error_t error;
368 
369  //Check parameters
370  if(privateKey == NULL || publicKey == NULL)
372 
373  //The public key is (n, e)
374  MPI_CHECK(mpiCopy(&publicKey->n, &privateKey->n));
375  MPI_CHECK(mpiCopy(&publicKey->e, &privateKey->e));
376 
377  //Debug message
378  TRACE_DEBUG("RSA public key:\r\n");
379  TRACE_DEBUG(" Modulus:\r\n");
380  TRACE_DEBUG_MPI(" ", &publicKey->n);
381  TRACE_DEBUG(" Public exponent:\r\n");
382  TRACE_DEBUG_MPI(" ", &publicKey->e);
383 
384 end:
385  //Any error to report?
386  if(error)
387  {
388  //Release RSA public key
389  rsaFreePublicKey(publicKey);
390  }
391 
392  //Return status code
393  return error;
394 }
395 
396 
397 /**
398  * @brief RSAES-PKCS1-v1_5 encryption operation
399  * @param[in] prngAlgo PRNG algorithm
400  * @param[in] prngContext Pointer to the PRNG context
401  * @param[in] key Recipient's RSA public key
402  * @param[in] message Message to be encrypted
403  * @param[in] messageLen Length of the message to be encrypted
404  * @param[out] ciphertext Ciphertext resulting from the encryption operation
405  * @param[out] ciphertextLen Length of the resulting ciphertext
406  * @return Error code
407  **/
408 
409 __weak_func error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo,
410  void *prngContext, const RsaPublicKey *key, const uint8_t *message,
411  size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
412 {
413  error_t error;
414  uint_t k;
415  uint8_t *em;
416  Mpi m;
417  Mpi c;
418 
419  //Check parameters
420  if(prngAlgo == NULL || prngContext == NULL || key == NULL ||
421  message == NULL || ciphertext == NULL || ciphertextLen == NULL)
422  {
424  }
425 
426  //Debug message
427  TRACE_DEBUG("RSAES-PKCS1-v1_5 encryption...\r\n");
428  TRACE_DEBUG(" Modulus:\r\n");
429  TRACE_DEBUG_MPI(" ", &key->n);
430  TRACE_DEBUG(" Public exponent:\r\n");
431  TRACE_DEBUG_MPI(" ", &key->e);
432  TRACE_DEBUG(" Message:\r\n");
433  TRACE_DEBUG_ARRAY(" ", message, messageLen);
434 
435  //Initialize multiple-precision integers
436  mpiInit(&m);
437  mpiInit(&c);
438 
439  //Get the length in octets of the modulus n
440  k = mpiGetByteLength(&key->n);
441 
442  //Point to the buffer where the encoded message EM will be formatted
443  em = ciphertext;
444 
445  //EME-PKCS1-v1_5 encoding
446  error = emePkcs1v15Encode(prngAlgo, prngContext, message, messageLen, em, k);
447  //Any error to report?
448  if(error)
449  return error;
450 
451  //Debug message
452  TRACE_DEBUG(" Encoded message:\r\n");
453  TRACE_DEBUG_ARRAY(" ", em, k);
454 
455  //Start of exception handling block
456  do
457  {
458  //Convert the encoded message EM to an integer message representative m
459  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
460  //Conversion failed?
461  if(error)
462  break;
463 
464  //Apply the RSAEP encryption primitive
465  error = rsaep(key, &m, &c);
466  //Any error to report?
467  if(error)
468  break;
469 
470  //Convert the ciphertext representative c to a ciphertext of length k octets
471  error = mpiExport(&c, ciphertext, k, MPI_FORMAT_BIG_ENDIAN);
472  //Conversion failed?
473  if(error)
474  break;
475 
476  //Length of the resulting ciphertext
477  *ciphertextLen = k;
478 
479  //Debug message
480  TRACE_DEBUG(" Ciphertext:\r\n");
481  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
482 
483  //End of exception handling block
484  } while(0);
485 
486  //Free previously allocated memory
487  mpiFree(&m);
488  mpiFree(&c);
489 
490  //Return status code
491  return error;
492 }
493 
494 
495 /**
496  * @brief RSAES-PKCS1-v1_5 decryption operation
497  * @param[in] key Recipient's RSA private key
498  * @param[in] ciphertext Ciphertext to be decrypted
499  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
500  * @param[out] message Output buffer where to store the decrypted message
501  * @param[in] messageSize Size of the output buffer
502  * @param[out] messageLen Length of the decrypted message
503  * @return Error code
504  **/
505 
507  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
508  size_t messageSize, size_t *messageLen)
509 {
510  error_t error;
511  uint_t k;
512  size_t i;
513  size_t j;
514  size_t n;
515  uint8_t b;
516  uint32_t a;
517  uint32_t badPadding;
518  uint32_t badLength;
519  Mpi c;
520  Mpi m;
521 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
522  uint8_t *em;
523 #else
524  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
525 #endif
526 
527  //Check parameters
528  if(key == NULL || ciphertext == NULL || message == NULL ||
529  messageSize == 0 || messageLen == NULL)
530  {
532  }
533 
534  //Debug message
535  TRACE_DEBUG("RSAES-PKCS1-v1_5 decryption...\r\n");
536  TRACE_DEBUG(" Modulus:\r\n");
537  TRACE_DEBUG_MPI(" ", &key->n);
538  TRACE_DEBUG(" Public exponent:\r\n");
539  TRACE_DEBUG_MPI(" ", &key->e);
540  TRACE_DEBUG(" Private exponent:\r\n");
541  TRACE_DEBUG_MPI(" ", &key->d);
542  TRACE_DEBUG(" Prime 1:\r\n");
543  TRACE_DEBUG_MPI(" ", &key->p);
544  TRACE_DEBUG(" Prime 2:\r\n");
545  TRACE_DEBUG_MPI(" ", &key->q);
546  TRACE_DEBUG(" Prime exponent 1:\r\n");
547  TRACE_DEBUG_MPI(" ", &key->dp);
548  TRACE_DEBUG(" Prime exponent 2:\r\n");
549  TRACE_DEBUG_MPI(" ", &key->dq);
550  TRACE_DEBUG(" Coefficient:\r\n");
551  TRACE_DEBUG_MPI(" ", &key->qinv);
552  TRACE_DEBUG(" Ciphertext:\r\n");
553  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
554 
555  //Initialize multiple-precision integers
556  mpiInit(&c);
557  mpiInit(&m);
558 
559  //Get the length in octets of the modulus n
560  k = mpiGetByteLength(&key->n);
561 
562  //Check the length of the ciphertext
563  if(ciphertextLen != k || ciphertextLen < 11)
564  return ERROR_INVALID_LENGTH;
565 
566 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
567  //Allocate a buffer to store the encoded message EM
568  em = cryptoAllocMem(k);
569  //Failed to allocate memory?
570  if(em == NULL)
571  return ERROR_OUT_OF_MEMORY;
572 #else
573  //Check the length of the modulus
574  if(k > sizeof(em))
575  return ERROR_BUFFER_OVERFLOW;
576 #endif
577 
578  //Start of exception handling block
579  do
580  {
581  //Convert the ciphertext to an integer ciphertext representative c
582  error = mpiImport(&c, ciphertext, ciphertextLen, MPI_FORMAT_BIG_ENDIAN);
583  //Conversion failed?
584  if(error)
585  break;
586 
587  //Apply the RSADP decryption primitive
588  error = rsadp(key, &c, &m);
589  //Any error to report?
590  if(error)
591  break;
592 
593  //Convert the message representative m to an encoded message EM of
594  //length k octets
595  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
596  //Conversion failed?
597  if(error)
598  break;
599 
600  //Debug message
601  TRACE_DEBUG(" Encoded message:\r\n");
602  TRACE_DEBUG_ARRAY(" ", em, k);
603 
604  //EME-PKCS1-v1_5 decoding
605  badPadding = emePkcs1v15Decode(em, k, &n);
606 
607  //Check whether the output buffer is large enough to hold the decrypted
608  //message
609  badLength = CRYPTO_TEST_LT_32(messageSize, n);
610 
611  //Copy the decrypted message, byte per byte
612  for(i = 0; i < messageSize; i++)
613  {
614  //Read the whole encoded message EM
615  for(b = 0, j = 0; j < k; j++)
616  {
617  //Constant time implementation
618  a = CRYPTO_TEST_EQ_32(j, k - n + i);
619  b = CRYPTO_SELECT_8(b, em[j], a);
620  }
621 
622  //Save the value of the current byte
623  message[i] = b;
624  }
625 
626  //Return the length of the decrypted message
627  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
628 
629  //Check whether the decryption operation is successful
630  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
631  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
632 
633  //Debug message
634  TRACE_DEBUG(" Message:\r\n");
635  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
636 
637  //End of exception handling block
638  } while(0);
639 
640 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
641  //Release the encoded message
642  cryptoFreeMem(em);
643 #endif
644 
645  //Release multiple precision integers
646  mpiFree(&c);
647  mpiFree(&m);
648 
649  //Return status code
650  return error;
651 }
652 
653 
654 /**
655  * @brief RSAES-OAEP encryption operation
656  * @param[in] prngAlgo PRNG algorithm
657  * @param[in] prngContext Pointer to the PRNG context
658  * @param[in] key Recipient's RSA public key
659  * @param[in] hash Hash function
660  * @param[in] mgfHash MGF hash function
661  * @param[in] label Optional label to be associated with the message
662  * @param[in] labelLen Length of the label, in bytes
663  * @param[in] message Message to be encrypted
664  * @param[in] messageLen Length of the message to be encrypted
665  * @param[out] ciphertext Ciphertext resulting from the encryption operation
666  * @param[out] ciphertextLen Length of the resulting ciphertext
667  * @return Error code
668  **/
669 
670 __weak_func error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo,
671  void *prngContext, const RsaPublicKey *key, const HashAlgo *hash,
672  const HashAlgo *mgfHash, const char_t *label, size_t labelLen,
673  const uint8_t *message, size_t messageLen, uint8_t *ciphertext,
674  size_t *ciphertextLen)
675 {
676  error_t error;
677  uint_t k;
678  uint8_t *em;
679  Mpi m;
680  Mpi c;
681 
682  //Check parameters
683  if(prngAlgo == NULL || prngContext == NULL || key == NULL || hash == NULL ||
684  mgfHash == NULL || message == NULL || ciphertext == NULL ||
685  ciphertextLen == NULL)
686  {
688  }
689 
690  //Debug message
691  TRACE_DEBUG("RSAES-OAEP encryption...\r\n");
692  TRACE_DEBUG(" Modulus:\r\n");
693  TRACE_DEBUG_MPI(" ", &key->n);
694  TRACE_DEBUG(" Public exponent:\r\n");
695  TRACE_DEBUG_MPI(" ", &key->e);
696  TRACE_DEBUG(" Message:\r\n");
697  TRACE_DEBUG_ARRAY(" ", message, messageLen);
698 
699  //Initialize multiple-precision integers
700  mpiInit(&m);
701  mpiInit(&c);
702 
703  //Get the length in octets of the modulus n
704  k = mpiGetByteLength(&key->n);
705 
706  //Make sure the modulus is valid
707  if(k == 0)
709 
710  //Point to the buffer where the encoded message EM will be formatted
711  em = ciphertext;
712 
713  //EME-OAEP encoding
714  error = emeOaepEncode(prngAlgo, prngContext, hash, mgfHash, label, labelLen,
715  message, messageLen, em, k);
716  //Any error to report?
717  if(error)
718  return error;
719 
720  //Debug message
721  TRACE_DEBUG(" Encoded message:\r\n");
722  TRACE_DEBUG_ARRAY(" ", em, k);
723 
724  //Start of exception handling block
725  do
726  {
727  //Convert the encoded message EM to an integer message representative m
728  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
729  //Conversion failed?
730  if(error)
731  break;
732 
733  //Apply the RSAEP encryption primitive
734  error = rsaep(key, &m, &c);
735  //Any error to report?
736  if(error)
737  break;
738 
739  //Convert the ciphertext representative c to a ciphertext of length k octets
740  error = mpiExport(&c, ciphertext, k, MPI_FORMAT_BIG_ENDIAN);
741  //Conversion failed?
742  if(error)
743  break;
744 
745  //Length of the resulting ciphertext
746  *ciphertextLen = k;
747 
748  //Debug message
749  TRACE_DEBUG(" Ciphertext:\r\n");
750  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
751 
752  //End of exception handling block
753  } while(0);
754 
755  //Free previously allocated memory
756  mpiFree(&m);
757  mpiFree(&c);
758 
759  //Return status code
760  return error;
761 }
762 
763 
764 /**
765  * @brief RSAES-OAEP decryption operation
766  * @param[in] key Recipient's RSA private key
767  * @param[in] hash Hash function
768  * @param[in] mgfHash MGF hash function
769  * @param[in] label Optional label to be associated with the message
770  * @param[in] labelLen Length of the label, in bytes
771  * @param[in] ciphertext Ciphertext to be decrypted
772  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
773  * @param[out] message Output buffer where to store the decrypted message
774  * @param[in] messageSize Size of the output buffer
775  * @param[out] messageLen Length of the decrypted message
776  * @return Error code
777  **/
778 
779 __weak_func error_t rsaesOaepDecrypt(const RsaPrivateKey *key,
780  const HashAlgo *hash, const HashAlgo *mgfHash, const char_t *label,
781  size_t labelLen, const uint8_t *ciphertext, size_t ciphertextLen,
782  uint8_t *message, size_t messageSize, size_t *messageLen)
783 {
784  error_t error;
785  uint_t k;
786  size_t i;
787  size_t j;
788  size_t n;
789  uint8_t b;
790  uint32_t a;
791  uint32_t badPadding;
792  uint32_t badLength;
793  Mpi c;
794  Mpi m;
795 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
796  uint8_t *em;
797 #else
798  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
799 #endif
800 
801  //Check parameters
802  if(key == NULL || hash == NULL || mgfHash == NULL || ciphertext == NULL ||
803  message == NULL || messageSize == 0 || messageLen == NULL)
804  {
806  }
807 
808  //Debug message
809  TRACE_DEBUG("RSAES-OAEP decryption...\r\n");
810  TRACE_DEBUG(" Modulus:\r\n");
811  TRACE_DEBUG_MPI(" ", &key->n);
812  TRACE_DEBUG(" Public exponent:\r\n");
813  TRACE_DEBUG_MPI(" ", &key->e);
814  TRACE_DEBUG(" Private exponent:\r\n");
815  TRACE_DEBUG_MPI(" ", &key->d);
816  TRACE_DEBUG(" Prime 1:\r\n");
817  TRACE_DEBUG_MPI(" ", &key->p);
818  TRACE_DEBUG(" Prime 2:\r\n");
819  TRACE_DEBUG_MPI(" ", &key->q);
820  TRACE_DEBUG(" Prime exponent 1:\r\n");
821  TRACE_DEBUG_MPI(" ", &key->dp);
822  TRACE_DEBUG(" Prime exponent 2:\r\n");
823  TRACE_DEBUG_MPI(" ", &key->dq);
824  TRACE_DEBUG(" Coefficient:\r\n");
825  TRACE_DEBUG_MPI(" ", &key->qinv);
826  TRACE_DEBUG(" Ciphertext:\r\n");
827  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
828 
829  //Initialize multiple-precision integers
830  mpiInit(&c);
831  mpiInit(&m);
832 
833  //Get the length in octets of the modulus n
834  k = mpiGetByteLength(&key->n);
835 
836  //Check the length of the modulus
837  if(k < (2 * hash->digestSize + 2))
839 
840  //Check the length of the ciphertext
841  if(ciphertextLen != k)
842  return ERROR_INVALID_LENGTH;
843 
844 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
845  //Allocate a buffer to store the encoded message EM
846  em = cryptoAllocMem(k);
847  //Failed to allocate memory?
848  if(em == NULL)
849  return ERROR_OUT_OF_MEMORY;
850 #else
851  //Check the length of the modulus
852  if(k > sizeof(em))
853  return ERROR_BUFFER_OVERFLOW;
854 #endif
855 
856  //Start of exception handling block
857  do
858  {
859  //Convert the ciphertext to an integer ciphertext representative c
860  error = mpiImport(&c, ciphertext, ciphertextLen, MPI_FORMAT_BIG_ENDIAN);
861  //Conversion failed?
862  if(error)
863  break;
864 
865  //Apply the RSADP decryption primitive
866  error = rsadp(key, &c, &m);
867  //Any error to report?
868  if(error)
869  break;
870 
871  //Convert the message representative m to an encoded message EM of
872  //length k octets
873  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
874  //Conversion failed?
875  if(error)
876  break;
877 
878  //Debug message
879  TRACE_DEBUG(" Encoded message:\r\n");
880  TRACE_DEBUG_ARRAY(" ", em, k);
881 
882  //EME-OAEP decoding
883  badPadding = emeOaepDecode(hash, mgfHash, label, labelLen, em, k, &n);
884 
885  //Check whether the output buffer is large enough to hold the decrypted
886  //message
887  badLength = CRYPTO_TEST_LT_32(messageSize, n);
888 
889  //Copy the decrypted message, byte per byte
890  for(i = 0; i < messageSize; i++)
891  {
892  //Read the whole encoded message EM
893  for(b = 0, j = 0; j < k; j++)
894  {
895  //Constant time implementation
896  a = CRYPTO_TEST_EQ_32(j, k - n + i);
897  b = CRYPTO_SELECT_8(b, em[j], a);
898  }
899 
900  //Save the value of the current byte
901  message[i] = b;
902  }
903 
904  //Return the length of the decrypted message
905  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
906 
907  //Check whether the decryption operation is successful
908  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
909  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
910 
911  //Debug message
912  TRACE_DEBUG(" Message:\r\n");
913  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
914 
915  //End of exception handling block
916  } while(0);
917 
918 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
919  //Release the encoded message
920  cryptoFreeMem(em);
921 #endif
922 
923  //Release multiple precision integers
924  mpiFree(&c);
925  mpiFree(&m);
926 
927  //Return status code
928  return error;
929 }
930 
931 
932 /**
933  * @brief RSASSA-PKCS1-v1_5 signature generation operation
934  * @param[in] key Signer's RSA private key
935  * @param[in] hash Hash function used to digest the message
936  * @param[in] digest Digest of the message to be signed
937  * @param[out] signature Resulting signature
938  * @param[out] signatureLen Length of the resulting signature
939  * @return Error code
940  **/
941 
942 __weak_func error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key,
943  const HashAlgo *hash, const uint8_t *digest, uint8_t *signature,
944  size_t *signatureLen)
945 {
946  error_t error;
947  uint_t k;
948  uint8_t *em;
949  Mpi m;
950  Mpi s;
951  Mpi t;
952 
953  //Check parameters
954  if(key == NULL || hash == NULL || digest == NULL || signature == NULL ||
955  signatureLen == NULL)
956  {
958  }
959 
960  //Debug message
961  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature generation...\r\n");
962  TRACE_DEBUG(" Modulus:\r\n");
963  TRACE_DEBUG_MPI(" ", &key->n);
964  TRACE_DEBUG(" Public exponent:\r\n");
965  TRACE_DEBUG_MPI(" ", &key->e);
966  TRACE_DEBUG(" Private exponent:\r\n");
967  TRACE_DEBUG_MPI(" ", &key->d);
968  TRACE_DEBUG(" Prime 1:\r\n");
969  TRACE_DEBUG_MPI(" ", &key->p);
970  TRACE_DEBUG(" Prime 2:\r\n");
971  TRACE_DEBUG_MPI(" ", &key->q);
972  TRACE_DEBUG(" Prime exponent 1:\r\n");
973  TRACE_DEBUG_MPI(" ", &key->dp);
974  TRACE_DEBUG(" Prime exponent 2:\r\n");
975  TRACE_DEBUG_MPI(" ", &key->dq);
976  TRACE_DEBUG(" Coefficient:\r\n");
977  TRACE_DEBUG_MPI(" ", &key->qinv);
978  TRACE_DEBUG(" Message digest:\r\n");
979  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
980 
981  //Initialize multiple-precision integers
982  mpiInit(&m);
983  mpiInit(&s);
984  mpiInit(&t);
985 
986  //Get the length in octets of the modulus n
987  k = mpiGetByteLength(&key->n);
988  //Point to the buffer where the encoded message EM will be formatted
989  em = signature;
990 
991  //Apply the EMSA-PKCS1-v1.5 encoding operation
992  error = emsaPkcs1v15Encode(hash, digest, em, k);
993  //Any error to report?
994  if(error)
995  return error;
996 
997  //Debug message
998  TRACE_DEBUG(" Encoded message:\r\n");
999  TRACE_DEBUG_ARRAY(" ", em, k);
1000 
1001  //Start of exception handling block
1002  do
1003  {
1004  //Convert the encoded message EM to an integer message representative m
1005  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1006  //Conversion failed?
1007  if(error)
1008  break;
1009 
1010  //Apply the RSASP1 signature primitive
1011  error = rsasp1(key, &m, &s);
1012  //Any error to report?
1013  if(error)
1014  break;
1015 
1016  //When unprotected, RSA-CRT is vulnerable to the Bellcore attack
1017  if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->e) > 0 &&
1018  mpiGetLength(&key->p) > 0 && mpiGetLength(&key->q) > 0 &&
1019  mpiGetLength(&key->dp) > 0 && mpiGetLength(&key->dq) > 0 &&
1020  mpiGetLength(&key->qinv) > 0)
1021  {
1022  RsaPublicKey publicKey;
1023 
1024  //The pair of numbers (n, e) form the RSA public key
1025  publicKey.n = key->n;
1026  publicKey.e = key->e;
1027 
1028  //Apply the RSAVP1 verification primitive
1029  error = rsavp1(&publicKey, &s, &t);
1030  //Any error to report?
1031  if(error)
1032  break;
1033 
1034  //Verify the RSA signature in order to protect against RSA-CRT key leak
1035  if(mpiComp(&t, &m) != 0)
1036  {
1037  //A signature fault has been detected
1038  error = ERROR_FAILURE;
1039  break;
1040  }
1041  }
1042 
1043  //Convert the signature representative s to a signature of length k octets
1044  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1045  //Conversion failed?
1046  if(error)
1047  break;
1048 
1049  //Length of the resulting signature
1050  *signatureLen = k;
1051 
1052  //Debug message
1053  TRACE_DEBUG(" Signature:\r\n");
1054  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1055 
1056  //End of exception handling block
1057  } while(0);
1058 
1059  //Free previously allocated memory
1060  mpiFree(&m);
1061  mpiFree(&s);
1062  mpiFree(&t);
1063 
1064  //Return status code
1065  return error;
1066 }
1067 
1068 
1069 /**
1070  * @brief RSASSA-PKCS1-v1_5 signature verification operation
1071  * @param[in] key Signer's RSA public key
1072  * @param[in] hash Hash function used to digest the message
1073  * @param[in] digest Digest of the message whose signature is to be verified
1074  * @param[in] signature Signature to be verified
1075  * @param[in] signatureLen Length of the signature to be verified
1076  * @return Error code
1077  **/
1078 
1080  const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature,
1081  size_t signatureLen)
1082 {
1083  error_t error;
1084  uint_t k;
1085  Mpi s;
1086  Mpi m;
1087 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1088  uint8_t *em;
1089 #else
1090  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1091 #endif
1092 
1093  //Check parameters
1094  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1095  return ERROR_INVALID_PARAMETER;
1096 
1097  //Debug message
1098  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature verification...\r\n");
1099  TRACE_DEBUG(" Modulus:\r\n");
1100  TRACE_DEBUG_MPI(" ", &key->n);
1101  TRACE_DEBUG(" Public exponent:\r\n");
1102  TRACE_DEBUG_MPI(" ", &key->e);
1103  TRACE_DEBUG(" Message digest:\r\n");
1104  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1105  TRACE_DEBUG(" Signature:\r\n");
1106  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1107 
1108  //Initialize multiple-precision integers
1109  mpiInit(&s);
1110  mpiInit(&m);
1111 
1112  //Get the length in octets of the modulus n
1113  k = mpiGetByteLength(&key->n);
1114 
1115  //Make sure the modulus is valid
1116  if(k == 0)
1117  return ERROR_INVALID_PARAMETER;
1118 
1119  //Check the length of the signature
1120  if(signatureLen != k)
1121  return ERROR_INVALID_SIGNATURE;
1122 
1123 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1124  //Allocate a buffer to store the encoded message EM
1125  em = cryptoAllocMem(k);
1126  //Failed to allocate memory?
1127  if(em == NULL)
1128  return ERROR_OUT_OF_MEMORY;
1129 #else
1130  //Check the length of the modulus
1131  if(k > sizeof(em))
1132  return ERROR_BUFFER_OVERFLOW;
1133 #endif
1134 
1135  //Start of exception handling block
1136  do
1137  {
1138  //Convert the signature to an integer signature representative s
1139  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1140  //Conversion failed?
1141  if(error)
1142  break;
1143 
1144  //Apply the RSAVP1 verification primitive
1145  error = rsavp1(key, &s, &m);
1146  //Any error to report?
1147  if(error)
1148  break;
1149 
1150  //Convert the message representative m to an encoded message EM of
1151  //length k octets
1152  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1153  //Conversion failed?
1154  if(error)
1155  break;
1156 
1157  //Debug message
1158  TRACE_DEBUG(" Encoded message:\r\n");
1159  TRACE_DEBUG_ARRAY(" ", em, k);
1160 
1161  //Verify the encoded message EM
1162  error = emsaPkcs1v15Verify(hash, digest, em, k);
1163  //Any error to report?
1164  if(error)
1165  {
1166  //The signature is not valid
1167  error = ERROR_INVALID_SIGNATURE;
1168  break;
1169  }
1170 
1171  //End of exception handling block
1172  } while(0);
1173 
1174 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1175  //Release the encoded message
1176  cryptoFreeMem(em);
1177 #endif
1178 
1179  //Release multiple precision integers
1180  mpiFree(&s);
1181  mpiFree(&m);
1182 
1183  //Return status code
1184  return error;
1185 }
1186 
1187 
1188 /**
1189  * @brief RSASSA-PSS signature generation operation
1190  * @param[in] prngAlgo PRNG algorithm
1191  * @param[in] prngContext Pointer to the PRNG context
1192  * @param[in] key Signer's RSA private key
1193  * @param[in] hash Hash function used to digest the message
1194  * @param[in] mgfHash MGF hash function
1195  * @param[in] saltLen Length of the salt, in bytes
1196  * @param[in] digest Digest of the message to be signed
1197  * @param[out] signature Resulting signature
1198  * @param[out] signatureLen Length of the resulting signature
1199  * @return Error code
1200  **/
1201 
1202 __weak_func error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
1203  const RsaPrivateKey *key, const HashAlgo *hash, const HashAlgo *mgfHash,
1204  size_t saltLen, const uint8_t *digest, uint8_t *signature,
1205  size_t *signatureLen)
1206 {
1207  error_t error;
1208  uint_t k;
1209  uint_t modBits;
1210  uint8_t *em;
1211  Mpi m;
1212  Mpi s;
1213 
1214  //Check parameters
1215  if(prngAlgo == NULL || prngContext == NULL || key == NULL || hash == NULL ||
1216  mgfHash == NULL || digest == NULL || signature == NULL ||
1217  signatureLen == NULL)
1218  {
1219  return ERROR_INVALID_PARAMETER;
1220  }
1221 
1222  //Debug message
1223  TRACE_DEBUG("RSASSA-PSS signature generation...\r\n");
1224  TRACE_DEBUG(" Modulus:\r\n");
1225  TRACE_DEBUG_MPI(" ", &key->n);
1226  TRACE_DEBUG(" Public exponent:\r\n");
1227  TRACE_DEBUG_MPI(" ", &key->e);
1228  TRACE_DEBUG(" Private exponent:\r\n");
1229  TRACE_DEBUG_MPI(" ", &key->d);
1230  TRACE_DEBUG(" Prime 1:\r\n");
1231  TRACE_DEBUG_MPI(" ", &key->p);
1232  TRACE_DEBUG(" Prime 2:\r\n");
1233  TRACE_DEBUG_MPI(" ", &key->q);
1234  TRACE_DEBUG(" Prime exponent 1:\r\n");
1235  TRACE_DEBUG_MPI(" ", &key->dp);
1236  TRACE_DEBUG(" Prime exponent 2:\r\n");
1237  TRACE_DEBUG_MPI(" ", &key->dq);
1238  TRACE_DEBUG(" Coefficient:\r\n");
1239  TRACE_DEBUG_MPI(" ", &key->qinv);
1240  TRACE_DEBUG(" Message digest:\r\n");
1241  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1242 
1243  //Initialize multiple-precision integers
1244  mpiInit(&m);
1245  mpiInit(&s);
1246 
1247  //modBits is the length in bits of the modulus n
1248  modBits = mpiGetBitLength(&key->n);
1249 
1250  //Make sure the modulus is valid
1251  if(modBits == 0)
1252  return ERROR_INVALID_PARAMETER;
1253 
1254  //Calculate the length in octets of the modulus n
1255  k = (modBits + 7) / 8;
1256 
1257  //Point to the buffer where the encoded message EM will be formatted
1258  em = signature;
1259 
1260  //Apply the EMSA-PSS encoding operation to the message M to produce an
1261  //encoded message EM of length ceil((modBits - 1) / 8) octets
1262  error = emsaPssEncode(prngAlgo, prngContext, hash, mgfHash, saltLen, digest,
1263  em, modBits - 1);
1264  //Any error to report?
1265  if(error)
1266  return error;
1267 
1268  //Debug message
1269  TRACE_DEBUG(" Encoded message:\r\n");
1270  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1271 
1272  //Start of exception handling block
1273  do
1274  {
1275  //Convert the encoded message EM to an integer message representative m
1276  error = mpiImport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1277  //Conversion failed?
1278  if(error)
1279  break;
1280 
1281  //Apply the RSASP1 signature primitive
1282  error = rsasp1(key, &m, &s);
1283  //Any error to report?
1284  if(error)
1285  break;
1286 
1287  //Convert the signature representative s to a signature of length k octets
1288  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1289  //Conversion failed?
1290  if(error)
1291  break;
1292 
1293  //Length of the resulting signature
1294  *signatureLen = k;
1295 
1296  //Debug message
1297  TRACE_DEBUG(" Signature:\r\n");
1298  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1299 
1300  //End of exception handling block
1301  } while(0);
1302 
1303  //Free previously allocated memory
1304  mpiFree(&m);
1305  mpiFree(&s);
1306 
1307  //Return status code
1308  return error;
1309 }
1310 
1311 
1312 /**
1313  * @brief RSASSA-PSS signature verification operation
1314  * @param[in] key Signer's RSA public key
1315  * @param[in] hash Hash function used to digest the message
1316  * @param[in] mgfHash MGF hash function
1317  * @param[in] saltLen Length of the salt, in bytes
1318  * @param[in] digest Digest of the message whose signature is to be verified
1319  * @param[in] signature Signature to be verified
1320  * @param[in] signatureLen Length of the signature to be verified
1321  * @return Error code
1322  **/
1323 
1324 __weak_func error_t rsassaPssVerify(const RsaPublicKey *key,
1325  const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen,
1326  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
1327 {
1328  error_t error;
1329  uint_t k;
1330  uint_t modBits;
1331  Mpi s;
1332  Mpi m;
1333 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1334  uint8_t *em;
1335 #else
1336  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1337 #endif
1338 
1339  //Check parameters
1340  if(key == NULL || hash == NULL || mgfHash == NULL || digest == NULL ||
1341  signature == NULL)
1342  {
1343  return ERROR_INVALID_PARAMETER;
1344  }
1345 
1346  //Debug message
1347  TRACE_DEBUG("RSASSA-PSS signature verification...\r\n");
1348  TRACE_DEBUG(" Modulus:\r\n");
1349  TRACE_DEBUG_MPI(" ", &key->n);
1350  TRACE_DEBUG(" Public exponent:\r\n");
1351  TRACE_DEBUG_MPI(" ", &key->e);
1352  TRACE_DEBUG(" Message digest:\r\n");
1353  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1354  TRACE_DEBUG(" Signature:\r\n");
1355  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1356 
1357  //Initialize multiple-precision integers
1358  mpiInit(&s);
1359  mpiInit(&m);
1360 
1361  //modBits is the length in bits of the modulus n
1362  modBits = mpiGetBitLength(&key->n);
1363 
1364  //Make sure the modulus is valid
1365  if(modBits == 0)
1366  return ERROR_INVALID_PARAMETER;
1367 
1368  //Calculate the length in octets of the modulus n
1369  k = (modBits + 7) / 8;
1370 
1371  //Check the length of the signature
1372  if(signatureLen != k)
1373  return ERROR_INVALID_SIGNATURE;
1374 
1375 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1376  //Allocate a buffer to store the encoded message EM
1377  em = cryptoAllocMem(k);
1378  //Failed to allocate memory?
1379  if(em == NULL)
1380  return ERROR_OUT_OF_MEMORY;
1381 #else
1382  //Check the length of the modulus
1383  if(k > sizeof(em))
1384  return ERROR_BUFFER_OVERFLOW;
1385 #endif
1386 
1387  //Start of exception handling block
1388  do
1389  {
1390  //Convert the signature to an integer signature representative s
1391  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1392  //Conversion failed?
1393  if(error)
1394  break;
1395 
1396  //Apply the RSAVP1 verification primitive
1397  error = rsavp1(key, &s, &m);
1398  //Any error to report?
1399  if(error)
1400  break;
1401 
1402  //Convert the message representative m to an encoded message EM of
1403  //length emLen = ceil((modBits - 1) / 8) octets
1404  error = mpiExport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1405  //Conversion failed?
1406  if(error)
1407  break;
1408 
1409  //Debug message
1410  TRACE_DEBUG(" Encoded message:\r\n");
1411  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1412 
1413  //Apply the EMSA-PSS verification operation to the message M and the
1414  //encoded message EM to determine whether they are consistent
1415  error = emsaPssVerify(hash, mgfHash, saltLen, digest, em, modBits - 1);
1416  //Any error to report?
1417  if(error)
1418  {
1419  //The signature is not valid
1420  error = ERROR_INVALID_SIGNATURE;
1421  break;
1422  }
1423 
1424  //End of exception handling block
1425  } while(0);
1426 
1427 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1428  //Release the encoded message
1429  cryptoFreeMem(em);
1430 #endif
1431 
1432  //Release multiple precision integers
1433  mpiFree(&s);
1434  mpiFree(&m);
1435 
1436  //Return status code
1437  return error;
1438 }
1439 
1440 #endif
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
__weak_func 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.
Definition: rsa.c:506
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9]
Definition: rsa.c:82
uint8_t b
Definition: nbns_common.h:122
void rsaFreePublicKey(RsaPublicKey *key)
Release an RSA public key.
Definition: rsa.c:113
#define RSA_MAX_MODULUS_SIZE
Definition: rsa.h:41
#define CRYPTO_TEST_EQ_32(a, b)
Definition: crypto.h:1107
Mpi p
First factor.
Definition: rsa.h:72
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:102
const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:59
const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:69
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
const uint8_t RSASSA_PSS_SHAKE256_OID[8]
Definition: rsa.c:89
#define PrngAlgo
Definition: crypto.h:1140
@ ERROR_DECRYPTION_FAILED
Definition: error.h:243
#define CRYPTO_SELECT_32(a, b, c)
Definition: crypto.h:1131
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9]
Definition: rsa.c:80
__weak_func 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.
Definition: rsa.c:409
error_t emeOaepEncode(const PrngAlgo *prngAlgo, void *prngContext, const HashAlgo *hash, const HashAlgo *mgfHash, const char_t *label, size_t labelLen, const uint8_t *message, size_t messageLen, uint8_t *em, size_t k)
EME-OAEP encoding operation.
Definition: rsa_misc.c:333
uint8_t message[]
Definition: chap.h:154
uint8_t t
Definition: lldp_ext_med.h:212
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9]
Definition: rsa.c:76
size_t digestSize
Definition: crypto.h:1249
error_t rsaGeneratePublicKey(const RsaPrivateKey *privateKey, RsaPublicKey *publicKey)
Derive the public key from an RSA private key.
Definition: rsa.c:364
Mpi n
Modulus.
Definition: rsa.h:69
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t mpiSetBitValue(Mpi *r, uint_t index, uint_t value)
Set the bit value at the specified index.
Definition: mpi.c:296
error_t emsaPssEncode(const PrngAlgo *prngAlgo, void *prngContext, const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest, uint8_t *em, uint_t emBits)
EMSA-PSS encoding operation.
Definition: rsa_misc.c:662
error_t emsaPssVerify(const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest, uint8_t *em, uint_t emBits)
EMSA-PSS verification operation.
Definition: rsa_misc.c:753
Mpi e
Public exponent.
Definition: rsa.h:59
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:85
__weak_func error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, size_t k, uint_t e, RsaPrivateKey *privateKey)
RSA private key generation.
Definition: rsa.c:203
uint32_t emePkcs1v15Decode(uint8_t *em, size_t k, size_t *messageLen)
EME-PKCS1-v1_5 decoding operation.
Definition: rsa_misc.c:277
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:599
error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:1020
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:49
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize an RSA private key.
Definition: rsa.c:126
const uint8_t MGF1_OID[9]
Definition: rsa.c:92
Mpi d
Private exponent.
Definition: rsa.h:71
const uint8_t PKCS1_OID[8]
Definition: rsa.c:52
Mpi n
Modulus.
Definition: rsa.h:58
__weak_func 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.
Definition: rsa.c:779
error_t emePkcs1v15Encode(const PrngAlgo *prngAlgo, void *prngContext, const uint8_t *message, size_t messageLen, uint8_t *em, size_t k)
EME-PKCS1-v1_5 encoding operation.
Definition: rsa_misc.c:209
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9]
Definition: rsa.c:78
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1589
int_t slot
Private key slot.
Definition: rsa.h:77
const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:67
const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:71
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
error_t emsaPkcs1v15Verify(const HashAlgo *hash, const uint8_t *digest, const uint8_t *em, size_t emLen)
EMSA-PKCS1-v1_5 verification operation.
Definition: rsa_misc.c:585
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t emsaPkcs1v15Encode(const HashAlgo *hash, const uint8_t *digest, uint8_t *em, size_t emLen)
EMSA-PKCS1-v1_5 encoding operation.
Definition: rsa_misc.c:521
error_t
Error codes.
Definition: error.h:43
error_t mpiSetValue(Mpi *r, mpi_sword_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:563
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:148
#define MPI_CHECK(f)
Definition: mpi.h:74
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Mpi q
Second factor.
Definition: rsa.h:73
RSA public key.
Definition: rsa.h:57
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:714
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
#define CRYPTO_TEST_LT_32(a, b)
Definition: crypto.h:1115
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
#define CRYPTO_SELECT_8(a, b, c)
Definition: crypto.h:1059
error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
RSA verification primitive.
Definition: rsa_misc.c:189
__weak_func 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.
Definition: rsa.c:670
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:811
uint32_t t2
Mpi e
Public exponent.
Definition: rsa.h:70
error_t mpiCheckProbablePrime(const Mpi *a)
Test whether a number is probable prime.
const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:65
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 mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:517
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:54
#define TRACE_DEBUG(...)
Definition: debug.h:119
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:189
char char_t
Definition: compiler_port.h:55
Helper routines for RSA.
error_t rsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext, size_t k, uint_t e, RsaPrivateKey *privateKey, RsaPublicKey *publicKey)
RSA key pair generation.
Definition: rsa.c:173
__weak_func 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.
Definition: rsa.c:1079
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
uint32_t t1
@ ERROR_INVALID_VALUE
Definition: error.h:116
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
#define cryptoFreeMem(p)
Definition: crypto.h:966
const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
__weak_func 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.
Definition: rsa.c:942
#define cryptoAllocMem(size)
Definition: crypto.h:961
uint8_t s
Definition: igmp_common.h:234
error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
RSA signature primitive.
Definition: rsa_misc.c:168
const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:63
Common interface for hash algorithms.
Definition: crypto.h:1243
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:359
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:430
unsigned int uint_t
Definition: compiler_port.h:57
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
const uint8_t RSASSA_PSS_SHAKE128_OID[8]
Definition: rsa.c:87
__weak_func 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.
Definition: rsa.c:1324
uint32_t emeOaepDecode(const HashAlgo *hash, const HashAlgo *mgfHash, const char_t *label, size_t labelLen, uint8_t *em, size_t k, size_t *messageLen)
EME-OAEP decoding operation.
Definition: rsa_misc.c:424
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:61
uint8_t c
Definition: ndp.h:514
Debugging facilities.
void rsaInitPublicKey(RsaPublicKey *key)
Initialize an RSA public key.
Definition: rsa.c:100
const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:73
__weak_func 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.
Definition: rsa.c:1202
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:65