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.0
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 error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext,
410  const RsaPublicKey *key, const uint8_t *message, size_t messageLen,
411  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 error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext,
669  const RsaPublicKey *key, const HashAlgo *hash, const char_t *label,
670  const uint8_t *message, size_t messageLen, uint8_t *ciphertext,
671  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 
775  const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen,
776  uint8_t *message, size_t messageSize, size_t *messageLen)
777 {
778  error_t error;
779  uint_t k;
780  size_t i;
781  size_t j;
782  size_t n;
783  uint8_t b;
784  uint32_t a;
785  uint32_t badPadding;
786  uint32_t badLength;
787  Mpi c;
788  Mpi m;
789 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
790  uint8_t *em;
791 #else
792  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
793 #endif
794 
795  //Check parameters
796  if(key == NULL || ciphertext == NULL)
798  if(message == NULL || messageSize == 0 || messageLen == NULL)
800 
801  //Debug message
802  TRACE_DEBUG("RSAES-OAEP decryption...\r\n");
803  TRACE_DEBUG(" Modulus:\r\n");
804  TRACE_DEBUG_MPI(" ", &key->n);
805  TRACE_DEBUG(" Public exponent:\r\n");
806  TRACE_DEBUG_MPI(" ", &key->e);
807  TRACE_DEBUG(" Private exponent:\r\n");
808  TRACE_DEBUG_MPI(" ", &key->d);
809  TRACE_DEBUG(" Prime 1:\r\n");
810  TRACE_DEBUG_MPI(" ", &key->p);
811  TRACE_DEBUG(" Prime 2:\r\n");
812  TRACE_DEBUG_MPI(" ", &key->q);
813  TRACE_DEBUG(" Prime exponent 1:\r\n");
814  TRACE_DEBUG_MPI(" ", &key->dp);
815  TRACE_DEBUG(" Prime exponent 2:\r\n");
816  TRACE_DEBUG_MPI(" ", &key->dq);
817  TRACE_DEBUG(" Coefficient:\r\n");
818  TRACE_DEBUG_MPI(" ", &key->qinv);
819  TRACE_DEBUG(" Ciphertext:\r\n");
820  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
821 
822  //Initialize multiple-precision integers
823  mpiInit(&c);
824  mpiInit(&m);
825 
826  //Get the length in octets of the modulus n
827  k = mpiGetByteLength(&key->n);
828 
829  //Check the length of the modulus
830  if(k < (2 * hash->digestSize + 2))
832 
833  //Check the length of the ciphertext
834  if(ciphertextLen != k)
835  return ERROR_INVALID_LENGTH;
836 
837 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
838  //Allocate a buffer to store the encoded message EM
839  em = cryptoAllocMem(k);
840  //Failed to allocate memory?
841  if(em == NULL)
842  return ERROR_OUT_OF_MEMORY;
843 #else
844  //Check the length of the modulus
845  if(k > sizeof(em))
846  return ERROR_BUFFER_OVERFLOW;
847 #endif
848 
849  //Start of exception handling block
850  do
851  {
852  //Convert the ciphertext to an integer ciphertext representative c
853  error = mpiImport(&c, ciphertext, ciphertextLen, MPI_FORMAT_BIG_ENDIAN);
854  //Conversion failed?
855  if(error)
856  break;
857 
858  //Apply the RSADP decryption primitive
859  error = rsadp(key, &c, &m);
860  //Any error to report?
861  if(error)
862  break;
863 
864  //Convert the message representative m to an encoded message EM of
865  //length k octets
866  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
867  //Conversion failed?
868  if(error)
869  break;
870 
871  //Debug message
872  TRACE_DEBUG(" Encoded message:\r\n");
873  TRACE_DEBUG_ARRAY(" ", em, k);
874 
875  //EME-OAEP decoding
876  badPadding = emeOaepDecode(hash, label, em, k, &n);
877 
878  //Check whether the output buffer is large enough to hold the decrypted
879  //message
880  badLength = CRYPTO_TEST_LT_32(messageSize, n);
881 
882  //Copy the decrypted message, byte per byte
883  for(i = 0; i < messageSize; i++)
884  {
885  //Read the whole encoded message EM
886  for(b = 0, j = 0; j < k; j++)
887  {
888  //Constant time implementation
889  a = CRYPTO_TEST_EQ_32(j, k - n + i);
890  b = CRYPTO_SELECT_8(b, em[j], a);
891  }
892 
893  //Save the value of the current byte
894  message[i] = b;
895  }
896 
897  //Return the length of the decrypted message
898  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
899 
900  //Check whether the decryption operation is successful
901  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
902  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
903 
904  //Debug message
905  TRACE_DEBUG(" Message:\r\n");
906  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
907 
908  //End of exception handling block
909  } while(0);
910 
911 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
912  //Release the encoded message
913  cryptoFreeMem(em);
914 #endif
915 
916  //Release multiple precision integers
917  mpiFree(&c);
918  mpiFree(&m);
919 
920  //Return status code
921  return error;
922 }
923 
924 
925 /**
926  * @brief RSASSA-PKCS1-v1_5 signature generation operation
927  * @param[in] key Signer's RSA private key
928  * @param[in] hash Hash function used to digest the message
929  * @param[in] digest Digest of the message to be signed
930  * @param[out] signature Resulting signature
931  * @param[out] signatureLen Length of the resulting signature
932  * @return Error code
933  **/
934 
936  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
937 {
938  error_t error;
939  uint_t k;
940  uint8_t *em;
941  Mpi m;
942  Mpi s;
943  Mpi t;
944 
945  //Check parameters
946  if(key == NULL || hash == NULL || digest == NULL)
948  if(signature == NULL || signatureLen == NULL)
950 
951  //Debug message
952  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature generation...\r\n");
953  TRACE_DEBUG(" Modulus:\r\n");
954  TRACE_DEBUG_MPI(" ", &key->n);
955  TRACE_DEBUG(" Public exponent:\r\n");
956  TRACE_DEBUG_MPI(" ", &key->e);
957  TRACE_DEBUG(" Private exponent:\r\n");
958  TRACE_DEBUG_MPI(" ", &key->d);
959  TRACE_DEBUG(" Prime 1:\r\n");
960  TRACE_DEBUG_MPI(" ", &key->p);
961  TRACE_DEBUG(" Prime 2:\r\n");
962  TRACE_DEBUG_MPI(" ", &key->q);
963  TRACE_DEBUG(" Prime exponent 1:\r\n");
964  TRACE_DEBUG_MPI(" ", &key->dp);
965  TRACE_DEBUG(" Prime exponent 2:\r\n");
966  TRACE_DEBUG_MPI(" ", &key->dq);
967  TRACE_DEBUG(" Coefficient:\r\n");
968  TRACE_DEBUG_MPI(" ", &key->qinv);
969  TRACE_DEBUG(" Message digest:\r\n");
970  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
971 
972  //Initialize multiple-precision integers
973  mpiInit(&m);
974  mpiInit(&s);
975  mpiInit(&t);
976 
977  //Get the length in octets of the modulus n
978  k = mpiGetByteLength(&key->n);
979  //Point to the buffer where the encoded message EM will be formatted
980  em = signature;
981 
982  //Apply the EMSA-PKCS1-v1.5 encoding operation
983  error = emsaPkcs1v15Encode(hash, digest, em, k);
984  //Any error to report?
985  if(error)
986  return error;
987 
988  //Debug message
989  TRACE_DEBUG(" Encoded message:\r\n");
990  TRACE_DEBUG_ARRAY(" ", em, k);
991 
992  //Start of exception handling block
993  do
994  {
995  //Convert the encoded message EM to an integer message representative m
996  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
997  //Conversion failed?
998  if(error)
999  break;
1000 
1001  //Apply the RSASP1 signature primitive
1002  error = rsasp1(key, &m, &s);
1003  //Any error to report?
1004  if(error)
1005  break;
1006 
1007  //When unprotected, RSA-CRT is vulnerable to the Bellcore attack
1008  if(key->n.size && key->e.size && key->p.size && key->q.size &&
1009  key->dp.size && key->dq.size && key->qinv.size)
1010  {
1011  RsaPublicKey publicKey;
1012 
1013  //The pair of numbers (n, e) form the RSA public key
1014  publicKey.n = key->n;
1015  publicKey.e = key->e;
1016 
1017  //Apply the RSAVP1 verification primitive
1018  error = rsavp1(&publicKey, &s, &t);
1019  //Any error to report?
1020  if(error)
1021  break;
1022 
1023  //Verify the RSA signature in order to protect against RSA-CRT key leak
1024  if(mpiComp(&t, &m) != 0)
1025  {
1026  //A signature fault has been detected
1027  error = ERROR_FAILURE;
1028  break;
1029  }
1030  }
1031 
1032  //Convert the signature representative s to a signature of length k octets
1033  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1034  //Conversion failed?
1035  if(error)
1036  break;
1037 
1038  //Length of the resulting signature
1039  *signatureLen = k;
1040 
1041  //Debug message
1042  TRACE_DEBUG(" Signature:\r\n");
1043  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1044 
1045  //End of exception handling block
1046  } while(0);
1047 
1048  //Free previously allocated memory
1049  mpiFree(&m);
1050  mpiFree(&s);
1051  mpiFree(&t);
1052 
1053  //Return status code
1054  return error;
1055 }
1056 
1057 
1058 /**
1059  * @brief RSASSA-PKCS1-v1_5 signature verification operation
1060  * @param[in] key Signer's RSA public key
1061  * @param[in] hash Hash function used to digest the message
1062  * @param[in] digest Digest of the message whose signature is to be verified
1063  * @param[in] signature Signature to be verified
1064  * @param[in] signatureLen Length of the signature to be verified
1065  * @return Error code
1066  **/
1067 
1069  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
1070 {
1071  error_t error;
1072  uint_t k;
1073  Mpi s;
1074  Mpi m;
1075 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1076  uint8_t *em;
1077 #else
1078  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1079 #endif
1080 
1081  //Check parameters
1082  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1083  return ERROR_INVALID_PARAMETER;
1084 
1085  //Debug message
1086  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature verification...\r\n");
1087  TRACE_DEBUG(" Modulus:\r\n");
1088  TRACE_DEBUG_MPI(" ", &key->n);
1089  TRACE_DEBUG(" Public exponent:\r\n");
1090  TRACE_DEBUG_MPI(" ", &key->e);
1091  TRACE_DEBUG(" Message digest:\r\n");
1092  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1093  TRACE_DEBUG(" Signature:\r\n");
1094  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1095 
1096  //Initialize multiple-precision integers
1097  mpiInit(&s);
1098  mpiInit(&m);
1099 
1100  //Get the length in octets of the modulus n
1101  k = mpiGetByteLength(&key->n);
1102 
1103  //Make sure the modulus is valid
1104  if(k == 0)
1105  return ERROR_INVALID_PARAMETER;
1106 
1107  //Check the length of the signature
1108  if(signatureLen != k)
1109  return ERROR_INVALID_SIGNATURE;
1110 
1111 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1112  //Allocate a buffer to store the encoded message EM
1113  em = cryptoAllocMem(k);
1114  //Failed to allocate memory?
1115  if(em == NULL)
1116  return ERROR_OUT_OF_MEMORY;
1117 #else
1118  //Check the length of the modulus
1119  if(k > sizeof(em))
1120  return ERROR_BUFFER_OVERFLOW;
1121 #endif
1122 
1123  //Start of exception handling block
1124  do
1125  {
1126  //Convert the signature to an integer signature representative s
1127  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1128  //Conversion failed?
1129  if(error)
1130  break;
1131 
1132  //Apply the RSAVP1 verification primitive
1133  error = rsavp1(key, &s, &m);
1134  //Any error to report?
1135  if(error)
1136  break;
1137 
1138  //Convert the message representative m to an encoded message EM of
1139  //length k octets
1140  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1141  //Conversion failed?
1142  if(error)
1143  break;
1144 
1145  //Debug message
1146  TRACE_DEBUG(" Encoded message:\r\n");
1147  TRACE_DEBUG_ARRAY(" ", em, k);
1148 
1149  //Verify the encoded message EM
1150  error = emsaPkcs1v15Verify(hash, digest, em, k);
1151  //Any error to report?
1152  if(error)
1153  {
1154  //The signature is not valid
1155  error = ERROR_INVALID_SIGNATURE;
1156  break;
1157  }
1158 
1159  //End of exception handling block
1160  } while(0);
1161 
1162 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1163  //Release the encoded message
1164  cryptoFreeMem(em);
1165 #endif
1166 
1167  //Release multiple precision integers
1168  mpiFree(&s);
1169  mpiFree(&m);
1170 
1171  //Return status code
1172  return error;
1173 }
1174 
1175 
1176 /**
1177  * @brief RSASSA-PSS signature generation operation
1178  * @param[in] prngAlgo PRNG algorithm
1179  * @param[in] prngContext Pointer to the PRNG context
1180  * @param[in] key Signer's RSA private key
1181  * @param[in] hash Hash function used to digest the message
1182  * @param[in] saltLen Length of the salt, in bytes
1183  * @param[in] digest Digest of the message to be signed
1184  * @param[out] signature Resulting signature
1185  * @param[out] signatureLen Length of the resulting signature
1186  * @return Error code
1187  **/
1188 
1189 error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
1190  const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen,
1191  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
1192 {
1193  error_t error;
1194  uint_t k;
1195  uint_t modBits;
1196  uint8_t *em;
1197  Mpi m;
1198  Mpi s;
1199 
1200  //Check parameters
1201  if(prngAlgo == NULL || prngContext == NULL)
1202  return ERROR_INVALID_PARAMETER;
1203  if(key == NULL || hash == NULL || digest == NULL)
1204  return ERROR_INVALID_PARAMETER;
1205  if(signature == NULL || signatureLen == NULL)
1206  return ERROR_INVALID_PARAMETER;
1207 
1208  //Debug message
1209  TRACE_DEBUG("RSASSA-PSS signature generation...\r\n");
1210  TRACE_DEBUG(" Modulus:\r\n");
1211  TRACE_DEBUG_MPI(" ", &key->n);
1212  TRACE_DEBUG(" Public exponent:\r\n");
1213  TRACE_DEBUG_MPI(" ", &key->e);
1214  TRACE_DEBUG(" Private exponent:\r\n");
1215  TRACE_DEBUG_MPI(" ", &key->d);
1216  TRACE_DEBUG(" Prime 1:\r\n");
1217  TRACE_DEBUG_MPI(" ", &key->p);
1218  TRACE_DEBUG(" Prime 2:\r\n");
1219  TRACE_DEBUG_MPI(" ", &key->q);
1220  TRACE_DEBUG(" Prime exponent 1:\r\n");
1221  TRACE_DEBUG_MPI(" ", &key->dp);
1222  TRACE_DEBUG(" Prime exponent 2:\r\n");
1223  TRACE_DEBUG_MPI(" ", &key->dq);
1224  TRACE_DEBUG(" Coefficient:\r\n");
1225  TRACE_DEBUG_MPI(" ", &key->qinv);
1226  TRACE_DEBUG(" Message digest:\r\n");
1227  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1228 
1229  //Initialize multiple-precision integers
1230  mpiInit(&m);
1231  mpiInit(&s);
1232 
1233  //modBits is the length in bits of the modulus n
1234  modBits = mpiGetBitLength(&key->n);
1235 
1236  //Make sure the modulus is valid
1237  if(modBits == 0)
1238  return ERROR_INVALID_PARAMETER;
1239 
1240  //Calculate the length in octets of the modulus n
1241  k = (modBits + 7) / 8;
1242 
1243  //Point to the buffer where the encoded message EM will be formatted
1244  em = signature;
1245 
1246  //Apply the EMSA-PSS encoding operation to the message M to produce an
1247  //encoded message EM of length ceil((modBits - 1) / 8) octets
1248  error = emsaPssEncode(prngAlgo, prngContext, hash, saltLen, digest,
1249  em, modBits - 1);
1250  //Any error to report?
1251  if(error)
1252  return error;
1253 
1254  //Debug message
1255  TRACE_DEBUG(" Encoded message:\r\n");
1256  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1257 
1258  //Start of exception handling block
1259  do
1260  {
1261  //Convert the encoded message EM to an integer message representative m
1262  error = mpiImport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1263  //Conversion failed?
1264  if(error)
1265  break;
1266 
1267  //Apply the RSASP1 signature primitive
1268  error = rsasp1(key, &m, &s);
1269  //Any error to report?
1270  if(error)
1271  break;
1272 
1273  //Convert the signature representative s to a signature of length k octets
1274  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1275  //Conversion failed?
1276  if(error)
1277  break;
1278 
1279  //Length of the resulting signature
1280  *signatureLen = k;
1281 
1282  //Debug message
1283  TRACE_DEBUG(" Signature:\r\n");
1284  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1285 
1286  //End of exception handling block
1287  } while(0);
1288 
1289  //Free previously allocated memory
1290  mpiFree(&m);
1291  mpiFree(&s);
1292 
1293  //Return status code
1294  return error;
1295 }
1296 
1297 
1298 /**
1299  * @brief RSASSA-PSS signature verification operation
1300  * @param[in] key Signer's RSA public key
1301  * @param[in] hash Hash function used to digest the message
1302  * @param[in] saltLen Length of the salt, in bytes
1303  * @param[in] digest Digest of the message whose signature is to be verified
1304  * @param[in] signature Signature to be verified
1305  * @param[in] signatureLen Length of the signature to be verified
1306  * @return Error code
1307  **/
1308 
1310  size_t saltLen, const uint8_t *digest, const uint8_t *signature,
1311  size_t signatureLen)
1312 {
1313  error_t error;
1314  uint_t k;
1315  uint_t modBits;
1316  Mpi s;
1317  Mpi m;
1318 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1319  uint8_t *em;
1320 #else
1321  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1322 #endif
1323 
1324  //Check parameters
1325  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1326  return ERROR_INVALID_PARAMETER;
1327 
1328  //Debug message
1329  TRACE_DEBUG("RSASSA-PSS signature verification...\r\n");
1330  TRACE_DEBUG(" Modulus:\r\n");
1331  TRACE_DEBUG_MPI(" ", &key->n);
1332  TRACE_DEBUG(" Public exponent:\r\n");
1333  TRACE_DEBUG_MPI(" ", &key->e);
1334  TRACE_DEBUG(" Message digest:\r\n");
1335  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1336  TRACE_DEBUG(" Signature:\r\n");
1337  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1338 
1339  //Initialize multiple-precision integers
1340  mpiInit(&s);
1341  mpiInit(&m);
1342 
1343  //modBits is the length in bits of the modulus n
1344  modBits = mpiGetBitLength(&key->n);
1345 
1346  //Make sure the modulus is valid
1347  if(modBits == 0)
1348  return ERROR_INVALID_PARAMETER;
1349 
1350  //Calculate the length in octets of the modulus n
1351  k = (modBits + 7) / 8;
1352 
1353  //Check the length of the signature
1354  if(signatureLen != k)
1355  return ERROR_INVALID_SIGNATURE;
1356 
1357 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1358  //Allocate a buffer to store the encoded message EM
1359  em = cryptoAllocMem(k);
1360  //Failed to allocate memory?
1361  if(em == NULL)
1362  return ERROR_OUT_OF_MEMORY;
1363 #else
1364  //Check the length of the modulus
1365  if(k > sizeof(em))
1366  return ERROR_BUFFER_OVERFLOW;
1367 #endif
1368 
1369  //Start of exception handling block
1370  do
1371  {
1372  //Convert the signature to an integer signature representative s
1373  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1374  //Conversion failed?
1375  if(error)
1376  break;
1377 
1378  //Apply the RSAVP1 verification primitive
1379  error = rsavp1(key, &s, &m);
1380  //Any error to report?
1381  if(error)
1382  break;
1383 
1384  //Convert the message representative m to an encoded message EM of
1385  //length emLen = ceil((modBits - 1) / 8) octets
1386  error = mpiExport(&m, em, (modBits + 6) / 8, MPI_FORMAT_BIG_ENDIAN);
1387  //Conversion failed?
1388  if(error)
1389  break;
1390 
1391  //Debug message
1392  TRACE_DEBUG(" Encoded message:\r\n");
1393  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1394 
1395  //Apply the EMSA-PSS verification operation to the message M and the
1396  //encoded message EM to determine whether they are consistent
1397  error = emsaPssVerify(hash, saltLen, digest, em, modBits - 1);
1398  //Any error to report?
1399  if(error)
1400  {
1401  //The signature is not valid
1402  error = ERROR_INVALID_SIGNATURE;
1403  break;
1404  }
1405 
1406  //End of exception handling block
1407  } while(0);
1408 
1409 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1410  //Release the encoded message
1411  cryptoFreeMem(em);
1412 #endif
1413 
1414  //Release multiple precision integers
1415  mpiFree(&s);
1416  mpiFree(&m);
1417 
1418  //Return status code
1419  return error;
1420 }
1421 
1422 #endif
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9]
Definition: rsa.c:82
uint8_t b
Definition: nbns_common.h:104
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:940
Mpi p
First factor.
Definition: rsa.h:72
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
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
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
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:973
@ ERROR_DECRYPTION_FAILED
Definition: error.h:243
#define CRYPTO_SELECT_32(a, b, c)
Definition: crypto.h:964
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9]
Definition: rsa.c:80
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:1088
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:295
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:598
error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:1018
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
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
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:1587
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:562
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:148
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
#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
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:1189
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:712
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
#define CRYPTO_TEST_LT_32(a, b)
Definition: crypto.h:948
@ 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:892
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:809
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:254
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:516
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:54
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
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:1068
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
#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
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:1309
uint_t size
Definition: mpi.h:104
#define cryptoFreeMem(p)
Definition: crypto.h:826
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
#define cryptoAllocMem(size)
Definition: crypto.h:821
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:1082
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:935
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:358
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:429
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:215
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:64