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-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @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.5.4
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)
422  if(key == NULL || message == NULL)
424  if(ciphertext == NULL || ciphertextLen == NULL)
426 
427  //Debug message
428  TRACE_DEBUG("RSAES-PKCS1-v1_5 encryption...\r\n");
429  TRACE_DEBUG(" Modulus:\r\n");
430  TRACE_DEBUG_MPI(" ", &key->n);
431  TRACE_DEBUG(" Public exponent:\r\n");
432  TRACE_DEBUG_MPI(" ", &key->e);
433  TRACE_DEBUG(" Message:\r\n");
434  TRACE_DEBUG_ARRAY(" ", message, messageLen);
435 
436  //Initialize multiple-precision integers
437  mpiInit(&m);
438  mpiInit(&c);
439 
440  //Get the length in octets of the modulus n
441  k = mpiGetByteLength(&key->n);
442 
443  //Point to the buffer where the encoded message EM will be formatted
444  em = ciphertext;
445 
446  //EME-PKCS1-v1_5 encoding
447  error = emePkcs1v15Encode(prngAlgo, prngContext, message, messageLen, em, k);
448  //Any error to report?
449  if(error)
450  return error;
451 
452  //Debug message
453  TRACE_DEBUG(" Encoded message:\r\n");
454  TRACE_DEBUG_ARRAY(" ", em, k);
455 
456  //Start of exception handling block
457  do
458  {
459  //Convert the encoded message EM to an integer message representative m
460  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
461  //Conversion failed?
462  if(error)
463  break;
464 
465  //Apply the RSAEP encryption primitive
466  error = rsaep(key, &m, &c);
467  //Any error to report?
468  if(error)
469  break;
470 
471  //Convert the ciphertext representative c to a ciphertext of length k octets
472  error = mpiExport(&c, ciphertext, k, MPI_FORMAT_BIG_ENDIAN);
473  //Conversion failed?
474  if(error)
475  break;
476 
477  //Length of the resulting ciphertext
478  *ciphertextLen = k;
479 
480  //Debug message
481  TRACE_DEBUG(" Ciphertext:\r\n");
482  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
483 
484  //End of exception handling block
485  } while(0);
486 
487  //Free previously allocated memory
488  mpiFree(&m);
489  mpiFree(&c);
490 
491  //Return status code
492  return error;
493 }
494 
495 
496 /**
497  * @brief RSAES-PKCS1-v1_5 decryption operation
498  * @param[in] key Recipient's RSA private key
499  * @param[in] ciphertext Ciphertext to be decrypted
500  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
501  * @param[out] message Output buffer where to store the decrypted message
502  * @param[in] messageSize Size of the output buffer
503  * @param[out] messageLen Length of the decrypted message
504  * @return Error code
505  **/
506 
508  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
509  size_t messageSize, size_t *messageLen)
510 {
511  error_t error;
512  uint_t k;
513  size_t i;
514  size_t j;
515  size_t n;
516  uint8_t b;
517  uint32_t a;
518  uint32_t badPadding;
519  uint32_t badLength;
520  Mpi c;
521  Mpi m;
522 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
523  uint8_t *em;
524 #else
525  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
526 #endif
527 
528  //Check parameters
529  if(key == NULL || ciphertext == NULL)
531  if(message == NULL || messageSize == 0 || messageLen == NULL)
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 Underlying hash function
660  * @param[in] label Optional label to be associated with the message
661  * @param[in] message Message to be encrypted
662  * @param[in] messageLen Length of the message to be encrypted
663  * @param[out] ciphertext Ciphertext resulting from the encryption operation
664  * @param[out] ciphertextLen Length of the resulting ciphertext
665  * @return Error code
666  **/
667 
668 __weak_func error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo,
669  void *prngContext, const RsaPublicKey *key, const HashAlgo *hash,
670  const char_t *label, const uint8_t *message, size_t messageLen,
671  uint8_t *ciphertext, size_t *ciphertextLen)
672 {
673  error_t error;
674  uint_t k;
675  uint8_t *em;
676  Mpi m;
677  Mpi c;
678 
679  //Check parameters
680  if(prngAlgo == NULL || prngContext == NULL)
682  if(key == NULL || message == NULL)
684  if(ciphertext == NULL || ciphertextLen == NULL)
686 
687  //Debug message
688  TRACE_DEBUG("RSAES-OAEP encryption...\r\n");
689  TRACE_DEBUG(" Modulus:\r\n");
690  TRACE_DEBUG_MPI(" ", &key->n);
691  TRACE_DEBUG(" Public exponent:\r\n");
692  TRACE_DEBUG_MPI(" ", &key->e);
693  TRACE_DEBUG(" Message:\r\n");
694  TRACE_DEBUG_ARRAY(" ", message, messageLen);
695 
696  //Initialize multiple-precision integers
697  mpiInit(&m);
698  mpiInit(&c);
699 
700  //Get the length in octets of the modulus n
701  k = mpiGetByteLength(&key->n);
702 
703  //Make sure the modulus is valid
704  if(k == 0)
706 
707  //Point to the buffer where the encoded message EM will be formatted
708  em = ciphertext;
709 
710  //EME-OAEP encoding
711  error = emeOaepEncode(prngAlgo, prngContext, hash, label, message,
712  messageLen, em, k);
713  //Any error to report?
714  if(error)
715  return error;
716 
717  //Debug message
718  TRACE_DEBUG(" Encoded message:\r\n");
719  TRACE_DEBUG_ARRAY(" ", em, k);
720 
721  //Start of exception handling block
722  do
723  {
724  //Convert the encoded message EM to an integer message representative m
725  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
726  //Conversion failed?
727  if(error)
728  break;
729 
730  //Apply the RSAEP encryption primitive
731  error = rsaep(key, &m, &c);
732  //Any error to report?
733  if(error)
734  break;
735 
736  //Convert the ciphertext representative c to a ciphertext of length k octets
737  error = mpiExport(&c, ciphertext, k, MPI_FORMAT_BIG_ENDIAN);
738  //Conversion failed?
739  if(error)
740  break;
741 
742  //Length of the resulting ciphertext
743  *ciphertextLen = k;
744 
745  //Debug message
746  TRACE_DEBUG(" Ciphertext:\r\n");
747  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
748 
749  //End of exception handling block
750  } while(0);
751 
752  //Free previously allocated memory
753  mpiFree(&m);
754  mpiFree(&c);
755 
756  //Return status code
757  return error;
758 }
759 
760 
761 /**
762  * @brief RSAES-OAEP decryption operation
763  * @param[in] key Recipient's RSA private key
764  * @param[in] hash Underlying hash function
765  * @param[in] label Optional label to be associated with the message
766  * @param[in] ciphertext Ciphertext to be decrypted
767  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
768  * @param[out] message Output buffer where to store the decrypted message
769  * @param[in] messageSize Size of the output buffer
770  * @param[out] messageLen Length of the decrypted message
771  * @return Error code
772  **/
773 
774 __weak_func error_t rsaesOaepDecrypt(const RsaPrivateKey *key,
775  const HashAlgo *hash, const char_t *label, const uint8_t *ciphertext,
776  size_t ciphertextLen, uint8_t *message, size_t messageSize,
777  size_t *messageLen)
778 {
779  error_t error;
780  uint_t k;
781  size_t i;
782  size_t j;
783  size_t n;
784  uint8_t b;
785  uint32_t a;
786  uint32_t badPadding;
787  uint32_t badLength;
788  Mpi c;
789  Mpi m;
790 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
791  uint8_t *em;
792 #else
793  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
794 #endif
795 
796  //Check parameters
797  if(key == NULL || ciphertext == NULL)
799  if(message == NULL || messageSize == 0 || messageLen == NULL)
801 
802  //Debug message
803  TRACE_DEBUG("RSAES-OAEP decryption...\r\n");
804  TRACE_DEBUG(" Modulus:\r\n");
805  TRACE_DEBUG_MPI(" ", &key->n);
806  TRACE_DEBUG(" Public exponent:\r\n");
807  TRACE_DEBUG_MPI(" ", &key->e);
808  TRACE_DEBUG(" Private exponent:\r\n");
809  TRACE_DEBUG_MPI(" ", &key->d);
810  TRACE_DEBUG(" Prime 1:\r\n");
811  TRACE_DEBUG_MPI(" ", &key->p);
812  TRACE_DEBUG(" Prime 2:\r\n");
813  TRACE_DEBUG_MPI(" ", &key->q);
814  TRACE_DEBUG(" Prime exponent 1:\r\n");
815  TRACE_DEBUG_MPI(" ", &key->dp);
816  TRACE_DEBUG(" Prime exponent 2:\r\n");
817  TRACE_DEBUG_MPI(" ", &key->dq);
818  TRACE_DEBUG(" Coefficient:\r\n");
819  TRACE_DEBUG_MPI(" ", &key->qinv);
820  TRACE_DEBUG(" Ciphertext:\r\n");
821  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
822 
823  //Initialize multiple-precision integers
824  mpiInit(&c);
825  mpiInit(&m);
826 
827  //Get the length in octets of the modulus n
828  k = mpiGetByteLength(&key->n);
829 
830  //Check the length of the modulus
831  if(k < (2 * hash->digestSize + 2))
833 
834  //Check the length of the ciphertext
835  if(ciphertextLen != k)
836  return ERROR_INVALID_LENGTH;
837 
838 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
839  //Allocate a buffer to store the encoded message EM
840  em = cryptoAllocMem(k);
841  //Failed to allocate memory?
842  if(em == NULL)
843  return ERROR_OUT_OF_MEMORY;
844 #else
845  //Check the length of the modulus
846  if(k > sizeof(em))
847  return ERROR_BUFFER_OVERFLOW;
848 #endif
849 
850  //Start of exception handling block
851  do
852  {
853  //Convert the ciphertext to an integer ciphertext representative c
854  error = mpiImport(&c, ciphertext, ciphertextLen, MPI_FORMAT_BIG_ENDIAN);
855  //Conversion failed?
856  if(error)
857  break;
858 
859  //Apply the RSADP decryption primitive
860  error = rsadp(key, &c, &m);
861  //Any error to report?
862  if(error)
863  break;
864 
865  //Convert the message representative m to an encoded message EM of
866  //length k octets
867  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
868  //Conversion failed?
869  if(error)
870  break;
871 
872  //Debug message
873  TRACE_DEBUG(" Encoded message:\r\n");
874  TRACE_DEBUG_ARRAY(" ", em, k);
875 
876  //EME-OAEP decoding
877  badPadding = emeOaepDecode(hash, label, em, k, &n);
878 
879  //Check whether the output buffer is large enough to hold the decrypted
880  //message
881  badLength = CRYPTO_TEST_LT_32(messageSize, n);
882 
883  //Copy the decrypted message, byte per byte
884  for(i = 0; i < messageSize; i++)
885  {
886  //Read the whole encoded message EM
887  for(b = 0, j = 0; j < k; j++)
888  {
889  //Constant time implementation
890  a = CRYPTO_TEST_EQ_32(j, k - n + i);
891  b = CRYPTO_SELECT_8(b, em[j], a);
892  }
893 
894  //Save the value of the current byte
895  message[i] = b;
896  }
897 
898  //Return the length of the decrypted message
899  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
900 
901  //Check whether the decryption operation is successful
902  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
903  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
904 
905  //Debug message
906  TRACE_DEBUG(" Message:\r\n");
907  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
908 
909  //End of exception handling block
910  } while(0);
911 
912 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
913  //Release the encoded message
914  cryptoFreeMem(em);
915 #endif
916 
917  //Release multiple precision integers
918  mpiFree(&c);
919  mpiFree(&m);
920 
921  //Return status code
922  return error;
923 }
924 
925 
926 /**
927  * @brief RSASSA-PKCS1-v1_5 signature generation operation
928  * @param[in] key Signer's RSA private key
929  * @param[in] hash Hash function used to digest the message
930  * @param[in] digest Digest of the message to be signed
931  * @param[out] signature Resulting signature
932  * @param[out] signatureLen Length of the resulting signature
933  * @return Error code
934  **/
935 
936 __weak_func error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key,
937  const HashAlgo *hash, const uint8_t *digest, uint8_t *signature,
938  size_t *signatureLen)
939 {
940  error_t error;
941  uint_t k;
942  uint8_t *em;
943  Mpi m;
944  Mpi s;
945  Mpi t;
946 
947  //Check parameters
948  if(key == NULL || hash == NULL || digest == NULL)
950  if(signature == NULL || signatureLen == NULL)
952 
953  //Debug message
954  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature generation...\r\n");
955  TRACE_DEBUG(" Modulus:\r\n");
956  TRACE_DEBUG_MPI(" ", &key->n);
957  TRACE_DEBUG(" Public exponent:\r\n");
958  TRACE_DEBUG_MPI(" ", &key->e);
959  TRACE_DEBUG(" Private exponent:\r\n");
960  TRACE_DEBUG_MPI(" ", &key->d);
961  TRACE_DEBUG(" Prime 1:\r\n");
962  TRACE_DEBUG_MPI(" ", &key->p);
963  TRACE_DEBUG(" Prime 2:\r\n");
964  TRACE_DEBUG_MPI(" ", &key->q);
965  TRACE_DEBUG(" Prime exponent 1:\r\n");
966  TRACE_DEBUG_MPI(" ", &key->dp);
967  TRACE_DEBUG(" Prime exponent 2:\r\n");
968  TRACE_DEBUG_MPI(" ", &key->dq);
969  TRACE_DEBUG(" Coefficient:\r\n");
970  TRACE_DEBUG_MPI(" ", &key->qinv);
971  TRACE_DEBUG(" Message digest:\r\n");
972  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
973 
974  //Initialize multiple-precision integers
975  mpiInit(&m);
976  mpiInit(&s);
977  mpiInit(&t);
978 
979  //Get the length in octets of the modulus n
980  k = mpiGetByteLength(&key->n);
981  //Point to the buffer where the encoded message EM will be formatted
982  em = signature;
983 
984  //Apply the EMSA-PKCS1-v1.5 encoding operation
985  error = emsaPkcs1v15Encode(hash, digest, em, k);
986  //Any error to report?
987  if(error)
988  return error;
989 
990  //Debug message
991  TRACE_DEBUG(" Encoded message:\r\n");
992  TRACE_DEBUG_ARRAY(" ", em, k);
993 
994  //Start of exception handling block
995  do
996  {
997  //Convert the encoded message EM to an integer message representative m
998  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
999  //Conversion failed?
1000  if(error)
1001  break;
1002 
1003  //Apply the RSASP1 signature primitive
1004  error = rsasp1(key, &m, &s);
1005  //Any error to report?
1006  if(error)
1007  break;
1008 
1009  //When unprotected, RSA-CRT is vulnerable to the Bellcore attack
1010  if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->e) > 0 &&
1011  mpiGetLength(&key->p) > 0 && mpiGetLength(&key->q) > 0 &&
1012  mpiGetLength(&key->dp) > 0 && mpiGetLength(&key->dq) > 0 &&
1013  mpiGetLength(&key->qinv) > 0)
1014  {
1015  RsaPublicKey publicKey;
1016 
1017  //The pair of numbers (n, e) form the RSA public key
1018  publicKey.n = key->n;
1019  publicKey.e = key->e;
1020 
1021  //Apply the RSAVP1 verification primitive
1022  error = rsavp1(&publicKey, &s, &t);
1023  //Any error to report?
1024  if(error)
1025  break;
1026 
1027  //Verify the RSA signature in order to protect against RSA-CRT key leak
1028  if(mpiComp(&t, &m) != 0)
1029  {
1030  //A signature fault has been detected
1031  error = ERROR_FAILURE;
1032  break;
1033  }
1034  }
1035 
1036  //Convert the signature representative s to a signature of length k octets
1037  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1038  //Conversion failed?
1039  if(error)
1040  break;
1041 
1042  //Length of the resulting signature
1043  *signatureLen = k;
1044 
1045  //Debug message
1046  TRACE_DEBUG(" Signature:\r\n");
1047  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1048 
1049  //End of exception handling block
1050  } while(0);
1051 
1052  //Free previously allocated memory
1053  mpiFree(&m);
1054  mpiFree(&s);
1055  mpiFree(&t);
1056 
1057  //Return status code
1058  return error;
1059 }
1060 
1061 
1062 /**
1063  * @brief RSASSA-PKCS1-v1_5 signature verification operation
1064  * @param[in] key Signer's RSA public key
1065  * @param[in] hash Hash function used to digest the message
1066  * @param[in] digest Digest of the message whose signature is to be verified
1067  * @param[in] signature Signature to be verified
1068  * @param[in] signatureLen Length of the signature to be verified
1069  * @return Error code
1070  **/
1071 
1073  const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature,
1074  size_t signatureLen)
1075 {
1076  error_t error;
1077  uint_t k;
1078  Mpi s;
1079  Mpi m;
1080 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1081  uint8_t *em;
1082 #else
1083  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1084 #endif
1085 
1086  //Check parameters
1087  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1088  return ERROR_INVALID_PARAMETER;
1089 
1090  //Debug message
1091  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature verification...\r\n");
1092  TRACE_DEBUG(" Modulus:\r\n");
1093  TRACE_DEBUG_MPI(" ", &key->n);
1094  TRACE_DEBUG(" Public exponent:\r\n");
1095  TRACE_DEBUG_MPI(" ", &key->e);
1096  TRACE_DEBUG(" Message digest:\r\n");
1097  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1098  TRACE_DEBUG(" Signature:\r\n");
1099  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1100 
1101  //Initialize multiple-precision integers
1102  mpiInit(&s);
1103  mpiInit(&m);
1104 
1105  //Get the length in octets of the modulus n
1106  k = mpiGetByteLength(&key->n);
1107 
1108  //Make sure the modulus is valid
1109  if(k == 0)
1110  return ERROR_INVALID_PARAMETER;
1111 
1112  //Check the length of the signature
1113  if(signatureLen != k)
1114  return ERROR_INVALID_SIGNATURE;
1115 
1116 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1117  //Allocate a buffer to store the encoded message EM
1118  em = cryptoAllocMem(k);
1119  //Failed to allocate memory?
1120  if(em == NULL)
1121  return ERROR_OUT_OF_MEMORY;
1122 #else
1123  //Check the length of the modulus
1124  if(k > sizeof(em))
1125  return ERROR_BUFFER_OVERFLOW;
1126 #endif
1127 
1128  //Start of exception handling block
1129  do
1130  {
1131  //Convert the signature to an integer signature representative s
1132  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1133  //Conversion failed?
1134  if(error)
1135  break;
1136 
1137  //Apply the RSAVP1 verification primitive
1138  error = rsavp1(key, &s, &m);
1139  //Any error to report?
1140  if(error)
1141  break;
1142 
1143  //Convert the message representative m to an encoded message EM of
1144  //length k octets
1145  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1146  //Conversion failed?
1147  if(error)
1148  break;
1149 
1150  //Debug message
1151  TRACE_DEBUG(" Encoded message:\r\n");
1152  TRACE_DEBUG_ARRAY(" ", em, k);
1153 
1154  //Verify the encoded message EM
1155  error = emsaPkcs1v15Verify(hash, digest, em, k);
1156  //Any error to report?
1157  if(error)
1158  {
1159  //The signature is not valid
1160  error = ERROR_INVALID_SIGNATURE;
1161  break;
1162  }
1163 
1164  //End of exception handling block
1165  } while(0);
1166 
1167 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1168  //Release the encoded message
1169  cryptoFreeMem(em);
1170 #endif
1171 
1172  //Release multiple precision integers
1173  mpiFree(&s);
1174  mpiFree(&m);
1175 
1176  //Return status code
1177  return error;
1178 }
1179 
1180 
1181 /**
1182  * @brief RSASSA-PSS signature generation operation
1183  * @param[in] prngAlgo PRNG algorithm
1184  * @param[in] prngContext Pointer to the PRNG context
1185  * @param[in] key Signer's RSA private key
1186  * @param[in] hash Hash function used to digest the message
1187  * @param[in] saltLen Length of the salt, in bytes
1188  * @param[in] digest Digest of the message to be signed
1189  * @param[out] signature Resulting signature
1190  * @param[out] signatureLen Length of the resulting signature
1191  * @return Error code
1192  **/
1193 
1194 __weak_func error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
1195  const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen,
1196  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
1197 {
1198  error_t error;
1199  uint_t k;
1200  uint_t modBits;
1201  uint8_t *em;
1202  Mpi m;
1203  Mpi s;
1204 
1205  //Check parameters
1206  if(prngAlgo == NULL || prngContext == NULL)
1207  return ERROR_INVALID_PARAMETER;
1208  if(key == NULL || hash == NULL || digest == NULL)
1209  return ERROR_INVALID_PARAMETER;
1210  if(signature == NULL || signatureLen == NULL)
1211  return ERROR_INVALID_PARAMETER;
1212 
1213  //Debug message
1214  TRACE_DEBUG("RSASSA-PSS signature generation...\r\n");
1215  TRACE_DEBUG(" Modulus:\r\n");
1216  TRACE_DEBUG_MPI(" ", &key->n);
1217  TRACE_DEBUG(" Public exponent:\r\n");
1218  TRACE_DEBUG_MPI(" ", &key->e);
1219  TRACE_DEBUG(" Private exponent:\r\n");
1220  TRACE_DEBUG_MPI(" ", &key->d);
1221  TRACE_DEBUG(" Prime 1:\r\n");
1222  TRACE_DEBUG_MPI(" ", &key->p);
1223  TRACE_DEBUG(" Prime 2:\r\n");
1224  TRACE_DEBUG_MPI(" ", &key->q);
1225  TRACE_DEBUG(" Prime exponent 1:\r\n");
1226  TRACE_DEBUG_MPI(" ", &key->dp);
1227  TRACE_DEBUG(" Prime exponent 2:\r\n");
1228  TRACE_DEBUG_MPI(" ", &key->dq);
1229  TRACE_DEBUG(" Coefficient:\r\n");
1230  TRACE_DEBUG_MPI(" ", &key->qinv);
1231  TRACE_DEBUG(" Message digest:\r\n");
1232  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1233 
1234  //Initialize multiple-precision integers
1235  mpiInit(&m);
1236  mpiInit(&s);
1237 
1238  //modBits is the length in bits of the modulus n
1239  modBits = mpiGetBitLength(&key->n);
1240 
1241  //Make sure the modulus is valid
1242  if(modBits == 0)
1243  return ERROR_INVALID_PARAMETER;
1244 
1245  //Calculate the length in octets of the modulus n
1246  k = (modBits + 7) / 8;
1247 
1248  //Point to the buffer where the encoded message EM will be formatted
1249  em = signature;
1250 
1251  //Apply the EMSA-PSS encoding operation to the message M to produce an
1252  //encoded message EM of length ceil((modBits - 1) / 8) octets
1253  error = emsaPssEncode(prngAlgo, prngContext, hash, saltLen, digest,
1254  em, modBits - 1);
1255  //Any error to report?
1256  if(error)
1257  return error;
1258 
1259  //Debug message
1260  TRACE_DEBUG(" Encoded message:\r\n");
1261  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1262 
1263  //Start of exception handling block
1264  do
1265  {
1266  //Convert the encoded message EM to an integer message representative m
1267  error = mpiImport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1268  //Conversion failed?
1269  if(error)
1270  break;
1271 
1272  //Apply the RSASP1 signature primitive
1273  error = rsasp1(key, &m, &s);
1274  //Any error to report?
1275  if(error)
1276  break;
1277 
1278  //Convert the signature representative s to a signature of length k octets
1279  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1280  //Conversion failed?
1281  if(error)
1282  break;
1283 
1284  //Length of the resulting signature
1285  *signatureLen = k;
1286 
1287  //Debug message
1288  TRACE_DEBUG(" Signature:\r\n");
1289  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1290 
1291  //End of exception handling block
1292  } while(0);
1293 
1294  //Free previously allocated memory
1295  mpiFree(&m);
1296  mpiFree(&s);
1297 
1298  //Return status code
1299  return error;
1300 }
1301 
1302 
1303 /**
1304  * @brief RSASSA-PSS signature verification operation
1305  * @param[in] key Signer's RSA public key
1306  * @param[in] hash Hash function used to digest the message
1307  * @param[in] saltLen Length of the salt, in bytes
1308  * @param[in] digest Digest of the message whose signature is to be verified
1309  * @param[in] signature Signature to be verified
1310  * @param[in] signatureLen Length of the signature to be verified
1311  * @return Error code
1312  **/
1313 
1314 __weak_func error_t rsassaPssVerify(const RsaPublicKey *key,
1315  const HashAlgo *hash, size_t saltLen, const uint8_t *digest,
1316  const uint8_t *signature, size_t signatureLen)
1317 {
1318  error_t error;
1319  uint_t k;
1320  uint_t modBits;
1321  Mpi s;
1322  Mpi m;
1323 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1324  uint8_t *em;
1325 #else
1326  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1327 #endif
1328 
1329  //Check parameters
1330  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1331  return ERROR_INVALID_PARAMETER;
1332 
1333  //Debug message
1334  TRACE_DEBUG("RSASSA-PSS signature verification...\r\n");
1335  TRACE_DEBUG(" Modulus:\r\n");
1336  TRACE_DEBUG_MPI(" ", &key->n);
1337  TRACE_DEBUG(" Public exponent:\r\n");
1338  TRACE_DEBUG_MPI(" ", &key->e);
1339  TRACE_DEBUG(" Message digest:\r\n");
1340  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1341  TRACE_DEBUG(" Signature:\r\n");
1342  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1343 
1344  //Initialize multiple-precision integers
1345  mpiInit(&s);
1346  mpiInit(&m);
1347 
1348  //modBits is the length in bits of the modulus n
1349  modBits = mpiGetBitLength(&key->n);
1350 
1351  //Make sure the modulus is valid
1352  if(modBits == 0)
1353  return ERROR_INVALID_PARAMETER;
1354 
1355  //Calculate the length in octets of the modulus n
1356  k = (modBits + 7) / 8;
1357 
1358  //Check the length of the signature
1359  if(signatureLen != k)
1360  return ERROR_INVALID_SIGNATURE;
1361 
1362 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1363  //Allocate a buffer to store the encoded message EM
1364  em = cryptoAllocMem(k);
1365  //Failed to allocate memory?
1366  if(em == NULL)
1367  return ERROR_OUT_OF_MEMORY;
1368 #else
1369  //Check the length of the modulus
1370  if(k > sizeof(em))
1371  return ERROR_BUFFER_OVERFLOW;
1372 #endif
1373 
1374  //Start of exception handling block
1375  do
1376  {
1377  //Convert the signature to an integer signature representative s
1378  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1379  //Conversion failed?
1380  if(error)
1381  break;
1382 
1383  //Apply the RSAVP1 verification primitive
1384  error = rsavp1(key, &s, &m);
1385  //Any error to report?
1386  if(error)
1387  break;
1388 
1389  //Convert the message representative m to an encoded message EM of
1390  //length emLen = ceil((modBits - 1) / 8) octets
1391  error = mpiExport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1392  //Conversion failed?
1393  if(error)
1394  break;
1395 
1396  //Debug message
1397  TRACE_DEBUG(" Encoded message:\r\n");
1398  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1399 
1400  //Apply the EMSA-PSS verification operation to the message M and the
1401  //encoded message EM to determine whether they are consistent
1402  error = emsaPssVerify(hash, saltLen, digest, em, modBits - 1);
1403  //Any error to report?
1404  if(error)
1405  {
1406  //The signature is not valid
1407  error = ERROR_INVALID_SIGNATURE;
1408  break;
1409  }
1410 
1411  //End of exception handling block
1412  } while(0);
1413 
1414 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1415  //Release the encoded message
1416  cryptoFreeMem(em);
1417 #endif
1418 
1419  //Release multiple precision integers
1420  mpiFree(&s);
1421  mpiFree(&m);
1422 
1423  //Return status code
1424  return error;
1425 }
1426 
1427 #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:507
__weak_func error_t rsaesOaepDecrypt(const RsaPrivateKey *key, const HashAlgo *hash, const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message, size_t messageSize, size_t *messageLen)
RSAES-OAEP decryption operation.
Definition: rsa.c:774
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:975
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:1008
@ ERROR_DECRYPTION_FAILED
Definition: error.h:243
#define CRYPTO_SELECT_32(a, b, c)
Definition: crypto.h:999
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
uint8_t message[]
Definition: chap.h:154
uint8_t t
Definition: lldp_ext_med.h:212
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9]
Definition: rsa.c:76
size_t digestSize
Definition: crypto.h:1130
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
Mpi e
Public exponent.
Definition: rsa.h:59
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
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
error_t emsaPssEncode(const PrngAlgo *prngAlgo, void *prngContext, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *em, uint_t emBits)
EMSA-PSS encoding operation.
Definition: rsa_misc.c:659
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:583
@ 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:519
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:983
@ 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:927
error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
RSA verification primitive.
Definition: rsa_misc.c:189
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
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
error_t emeOaepEncode(const PrngAlgo *prngAlgo, void *prngContext, const HashAlgo *hash, const char_t *label, const uint8_t *message, size_t messageLen, uint8_t *em, size_t k)
EME-OAEP encoding operation.
Definition: rsa_misc.c:331
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
__weak_func error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
Definition: rsa.c:1314
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:1072
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
uint32_t t1
@ ERROR_INVALID_VALUE
Definition: error.h:116
__weak_func error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key, const HashAlgo *hash, const char_t *label, const uint8_t *message, size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
RSAES-OAEP encryption operation.
Definition: rsa.c:668
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
#define cryptoFreeMem(p)
Definition: crypto.h:861
const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
error_t emsaPssVerify(const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *em, uint_t emBits)
EMSA-PSS verification operation.
Definition: rsa_misc.c:749
@ 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:936
#define cryptoAllocMem(size)
Definition: crypto.h:856
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
__weak_func error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
Definition: rsa.c:1194
const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:63
Common interface for hash algorithms.
Definition: crypto.h:1124
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
uint32_t emeOaepDecode(const HashAlgo *hash, const char_t *label, uint8_t *em, size_t k, size_t *messageLen)
EME-OAEP decoding operation.
Definition: rsa_misc.c:421
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
@ 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
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216
error_t mpiCheckProbablePrime(const Mpi *a)
Test whether a number is probable prime.
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:65