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-2024 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.4.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 "mac/hmac.h"
45 #include "pkc/rsa.h"
46 #include "mpi/mpi.h"
47 #include "encoding/asn1.h"
48 #include "encoding/oid.h"
49 #include "debug.h"
50 
51 //Check crypto library configuration
52 #if (RSA_SUPPORT == ENABLED)
53 
54 //PKCS #1 OID (1.2.840.113549.1.1)
55 const uint8_t PKCS1_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01};
56 //RSA encryption OID (1.2.840.113549.1.1.1)
57 const uint8_t RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01};
58 
59 //MD2 with RSA encryption OID (1.2.840.113549.1.1.2)
60 const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02};
61 //MD5 with RSA encryption OID (1.2.840.113549.1.1.4)
62 const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04};
63 //SHA-1 with RSA encryption OID (1.2.840.113549.1.1.5)
64 const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05};
65 //SHA-224 with RSA encryption OID (1.2.840.113549.1.1.14)
66 const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E};
67 //SHA-256 with RSA encryption OID (1.2.840.113549.1.1.11)
68 const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B};
69 //SHA-384 with RSA encryption OID (1.2.840.113549.1.1.12)
70 const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C};
71 //SHA-512 with RSA encryption OID (1.2.840.113549.1.1.13)
72 const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D};
73 //SHA-512/224 with RSA encryption OID (1.2.840.113549.1.1.15)
74 const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0F};
75 //SHA-512/256 with RSA encryption OID (1.2.840.113549.1.1.16)
76 const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x10};
77 
78 //RSASSA-PKCS1-v1_5 signature with SHA-3-224 OID (2.16.840.1.101.3.4.3.13)
79 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0D};
80 //RSASSA-PKCS1-v1_5 signature with SHA-3-256 OID (2.16.840.1.101.3.4.3.14)
81 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0E};
82 //RSASSA-PKCS1-v1_5 signature with SHA-3-384 OID (2.16.840.1.101.3.4.3.15)
83 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0F};
84 //RSASSA-PKCS1-v1_5 signature with SHA-3-512 OID (2.16.840.1.101.3.4.3.16)
85 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x10};
86 
87 //RSASSA-PSS OID (1.2.840.113549.1.1.10)
88 const uint8_t RSASSA_PSS_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A};
89 
90 //MGF1 OID (1.2.840.113549.1.1.8)
91 const uint8_t MGF1_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x08};
92 
93 //Padding string
94 static const uint8_t padding[] =
95 {
96  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
97 };
98 
99 
100 /**
101  * @brief Initialize an RSA public key
102  * @param[in] key Pointer to the RSA public key to initialize
103  **/
104 
106 {
107  //Initialize multiple precision integers
108  mpiInit(&key->n);
109  mpiInit(&key->e);
110 }
111 
112 
113 /**
114  * @brief Release an RSA public key
115  * @param[in] key Pointer to the RSA public key to free
116  **/
117 
119 {
120  //Free multiple precision integers
121  mpiFree(&key->n);
122  mpiFree(&key->e);
123 }
124 
125 
126 /**
127  * @brief Initialize an RSA private key
128  * @param[in] key Pointer to the RSA private key to initialize
129  **/
130 
132 {
133  //Initialize multiple precision integers
134  mpiInit(&key->n);
135  mpiInit(&key->e);
136  mpiInit(&key->d);
137  mpiInit(&key->p);
138  mpiInit(&key->q);
139  mpiInit(&key->dp);
140  mpiInit(&key->dq);
141  mpiInit(&key->qinv);
142 
143  //Initialize private key slot
144  key->slot = -1;
145 }
146 
147 
148 /**
149  * @brief Release an RSA private key
150  * @param[in] key Pointer to the RSA private key to free
151  **/
152 
154 {
155  //Free multiple precision integers
156  mpiFree(&key->n);
157  mpiFree(&key->e);
158  mpiFree(&key->d);
159  mpiFree(&key->p);
160  mpiFree(&key->q);
161  mpiFree(&key->dp);
162  mpiFree(&key->dq);
163  mpiFree(&key->qinv);
164 }
165 
166 
167 /**
168  * @brief RSAES-PKCS1-v1_5 encryption operation
169  * @param[in] prngAlgo PRNG algorithm
170  * @param[in] prngContext Pointer to the PRNG context
171  * @param[in] key Recipient's RSA public key
172  * @param[in] message Message to be encrypted
173  * @param[in] messageLen Length of the message to be encrypted
174  * @param[out] ciphertext Ciphertext resulting from the encryption operation
175  * @param[out] ciphertextLen Length of the resulting ciphertext
176  * @return Error code
177  **/
178 
179 error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext,
180  const RsaPublicKey *key, const uint8_t *message, size_t messageLen,
181  uint8_t *ciphertext, size_t *ciphertextLen)
182 {
183  error_t error;
184  uint_t k;
185  uint8_t *em;
186  Mpi m;
187  Mpi c;
188 
189  //Check parameters
190  if(prngAlgo == NULL || prngContext == NULL)
192  if(key == NULL || message == NULL)
194  if(ciphertext == NULL || ciphertextLen == NULL)
196 
197  //Debug message
198  TRACE_DEBUG("RSAES-PKCS1-v1_5 encryption...\r\n");
199  TRACE_DEBUG(" Modulus:\r\n");
200  TRACE_DEBUG_MPI(" ", &key->n);
201  TRACE_DEBUG(" Public exponent:\r\n");
202  TRACE_DEBUG_MPI(" ", &key->e);
203  TRACE_DEBUG(" Message:\r\n");
204  TRACE_DEBUG_ARRAY(" ", message, messageLen);
205 
206  //Initialize multiple-precision integers
207  mpiInit(&m);
208  mpiInit(&c);
209 
210  //Get the length in octets of the modulus n
211  k = mpiGetByteLength(&key->n);
212 
213  //Point to the buffer where the encoded message EM will be formatted
214  em = ciphertext;
215 
216  //EME-PKCS1-v1_5 encoding
217  error = emePkcs1v15Encode(prngAlgo, prngContext, message, messageLen, em, k);
218  //Any error to report?
219  if(error)
220  return error;
221 
222  //Debug message
223  TRACE_DEBUG(" Encoded message:\r\n");
224  TRACE_DEBUG_ARRAY(" ", em, k);
225 
226  //Start of exception handling block
227  do
228  {
229  //Convert the encoded message EM to an integer message representative m
230  error = mpiReadRaw(&m, em, k);
231  //Conversion failed?
232  if(error)
233  break;
234 
235  //Apply the RSAEP encryption primitive
236  error = rsaep(key, &m, &c);
237  //Any error to report?
238  if(error)
239  break;
240 
241  //Convert the ciphertext representative c to a ciphertext of length k octets
242  error = mpiWriteRaw(&c, ciphertext, k);
243  //Conversion failed?
244  if(error)
245  break;
246 
247  //Length of the resulting ciphertext
248  *ciphertextLen = k;
249 
250  //Debug message
251  TRACE_DEBUG(" Ciphertext:\r\n");
252  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
253 
254  //End of exception handling block
255  } while(0);
256 
257  //Free previously allocated memory
258  mpiFree(&m);
259  mpiFree(&c);
260 
261  //Return status code
262  return error;
263 }
264 
265 
266 /**
267  * @brief RSAES-PKCS1-v1_5 decryption operation
268  * @param[in] key Recipient's RSA private key
269  * @param[in] ciphertext Ciphertext to be decrypted
270  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
271  * @param[out] message Output buffer where to store the decrypted message
272  * @param[in] messageSize Size of the output buffer
273  * @param[out] messageLen Length of the decrypted message
274  * @return Error code
275  **/
276 
278  const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *message,
279  size_t messageSize, size_t *messageLen)
280 {
281  error_t error;
282  uint_t k;
283  size_t i;
284  size_t j;
285  size_t n;
286  uint8_t b;
287  uint32_t a;
288  uint32_t badPadding;
289  uint32_t badLength;
290  Mpi c;
291  Mpi m;
292 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
293  uint8_t *em;
294 #else
295  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
296 #endif
297 
298  //Check parameters
299  if(key == NULL || ciphertext == NULL)
301  if(message == NULL || messageSize == 0 || messageLen == NULL)
303 
304  //Debug message
305  TRACE_DEBUG("RSAES-PKCS1-v1_5 decryption...\r\n");
306  TRACE_DEBUG(" Modulus:\r\n");
307  TRACE_DEBUG_MPI(" ", &key->n);
308  TRACE_DEBUG(" Public exponent:\r\n");
309  TRACE_DEBUG_MPI(" ", &key->e);
310  TRACE_DEBUG(" Private exponent:\r\n");
311  TRACE_DEBUG_MPI(" ", &key->d);
312  TRACE_DEBUG(" Prime 1:\r\n");
313  TRACE_DEBUG_MPI(" ", &key->p);
314  TRACE_DEBUG(" Prime 2:\r\n");
315  TRACE_DEBUG_MPI(" ", &key->q);
316  TRACE_DEBUG(" Prime exponent 1:\r\n");
317  TRACE_DEBUG_MPI(" ", &key->dp);
318  TRACE_DEBUG(" Prime exponent 2:\r\n");
319  TRACE_DEBUG_MPI(" ", &key->dq);
320  TRACE_DEBUG(" Coefficient:\r\n");
321  TRACE_DEBUG_MPI(" ", &key->qinv);
322  TRACE_DEBUG(" Ciphertext:\r\n");
323  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
324 
325  //Initialize multiple-precision integers
326  mpiInit(&c);
327  mpiInit(&m);
328 
329  //Get the length in octets of the modulus n
330  k = mpiGetByteLength(&key->n);
331 
332  //Check the length of the ciphertext
333  if(ciphertextLen != k || ciphertextLen < 11)
334  return ERROR_INVALID_LENGTH;
335 
336 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
337  //Allocate a buffer to store the encoded message EM
338  em = cryptoAllocMem(k);
339  //Failed to allocate memory?
340  if(em == NULL)
341  return ERROR_OUT_OF_MEMORY;
342 #else
343  //Check the length of the modulus
344  if(k > sizeof(em))
345  return ERROR_BUFFER_OVERFLOW;
346 #endif
347 
348  //Start of exception handling block
349  do
350  {
351  //Convert the ciphertext to an integer ciphertext representative c
352  error = mpiReadRaw(&c, ciphertext, ciphertextLen);
353  //Conversion failed?
354  if(error)
355  break;
356 
357  //Apply the RSADP decryption primitive
358  error = rsadp(key, &c, &m);
359  //Any error to report?
360  if(error)
361  break;
362 
363  //Convert the message representative m to an encoded message EM of
364  //length k octets
365  error = mpiWriteRaw(&m, em, k);
366  //Conversion failed?
367  if(error)
368  break;
369 
370  //Debug message
371  TRACE_DEBUG(" Encoded message:\r\n");
372  TRACE_DEBUG_ARRAY(" ", em, k);
373 
374  //EME-PKCS1-v1_5 decoding
375  badPadding = emePkcs1v15Decode(em, k, &n);
376 
377  //Check whether the output buffer is large enough to hold the decrypted
378  //message
379  badLength = CRYPTO_TEST_LT_32(messageSize, n);
380 
381  //Copy the decrypted message, byte per byte
382  for(i = 0; i < messageSize; i++)
383  {
384  //Read the whole encoded message EM
385  for(b = 0, j = 0; j < k; j++)
386  {
387  //Constant time implementation
388  a = CRYPTO_TEST_EQ_32(j, k - n + i);
389  b = CRYPTO_SELECT_8(b, em[j], a);
390  }
391 
392  //Save the value of the current byte
393  message[i] = b;
394  }
395 
396  //Return the length of the decrypted message
397  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
398 
399  //Check whether the decryption operation is successful
400  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
401  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
402 
403  //Debug message
404  TRACE_DEBUG(" Message:\r\n");
405  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
406 
407  //End of exception handling block
408  } while(0);
409 
410 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
411  //Release the encoded message
412  cryptoFreeMem(em);
413 #endif
414 
415  //Release multiple precision integers
416  mpiFree(&c);
417  mpiFree(&m);
418 
419  //Return status code
420  return error;
421 }
422 
423 
424 /**
425  * @brief RSAES-OAEP encryption operation
426  * @param[in] prngAlgo PRNG algorithm
427  * @param[in] prngContext Pointer to the PRNG context
428  * @param[in] key Recipient's RSA public key
429  * @param[in] hash Underlying hash function
430  * @param[in] label Optional label to be associated with the message
431  * @param[in] message Message to be encrypted
432  * @param[in] messageLen Length of the message to be encrypted
433  * @param[out] ciphertext Ciphertext resulting from the encryption operation
434  * @param[out] ciphertextLen Length of the resulting ciphertext
435  * @return Error code
436  **/
437 
438 error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext,
439  const RsaPublicKey *key, const HashAlgo *hash, const char_t *label,
440  const uint8_t *message, size_t messageLen, uint8_t *ciphertext,
441  size_t *ciphertextLen)
442 {
443  error_t error;
444  uint_t k;
445  uint8_t *em;
446  Mpi m;
447  Mpi c;
448 
449  //Check parameters
450  if(prngAlgo == NULL || prngContext == NULL)
452  if(key == NULL || message == NULL)
454  if(ciphertext == NULL || ciphertextLen == NULL)
456 
457  //Debug message
458  TRACE_DEBUG("RSAES-OAEP encryption...\r\n");
459  TRACE_DEBUG(" Modulus:\r\n");
460  TRACE_DEBUG_MPI(" ", &key->n);
461  TRACE_DEBUG(" Public exponent:\r\n");
462  TRACE_DEBUG_MPI(" ", &key->e);
463  TRACE_DEBUG(" Message:\r\n");
464  TRACE_DEBUG_ARRAY(" ", message, messageLen);
465 
466  //Initialize multiple-precision integers
467  mpiInit(&m);
468  mpiInit(&c);
469 
470  //Get the length in octets of the modulus n
471  k = mpiGetByteLength(&key->n);
472 
473  //Make sure the modulus is valid
474  if(k == 0)
476 
477  //Point to the buffer where the encoded message EM will be formatted
478  em = ciphertext;
479 
480  //EME-OAEP encoding
481  error = emeOaepEncode(prngAlgo, prngContext, hash, label, message,
482  messageLen, em, k);
483  //Any error to report?
484  if(error)
485  return error;
486 
487  //Debug message
488  TRACE_DEBUG(" Encoded message:\r\n");
489  TRACE_DEBUG_ARRAY(" ", em, k);
490 
491  //Start of exception handling block
492  do
493  {
494  //Convert the encoded message EM to an integer message representative m
495  error = mpiReadRaw(&m, em, k);
496  //Conversion failed?
497  if(error)
498  break;
499 
500  //Apply the RSAEP encryption primitive
501  error = rsaep(key, &m, &c);
502  //Any error to report?
503  if(error)
504  break;
505 
506  //Convert the ciphertext representative c to a ciphertext of length k octets
507  error = mpiWriteRaw(&c, ciphertext, k);
508  //Conversion failed?
509  if(error)
510  break;
511 
512  //Length of the resulting ciphertext
513  *ciphertextLen = k;
514 
515  //Debug message
516  TRACE_DEBUG(" Ciphertext:\r\n");
517  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
518 
519  //End of exception handling block
520  } while(0);
521 
522  //Free previously allocated memory
523  mpiFree(&m);
524  mpiFree(&c);
525 
526  //Return status code
527  return error;
528 }
529 
530 
531 /**
532  * @brief RSAES-OAEP decryption operation
533  * @param[in] key Recipient's RSA private key
534  * @param[in] hash Underlying hash function
535  * @param[in] label Optional label to be associated with the message
536  * @param[in] ciphertext Ciphertext to be decrypted
537  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
538  * @param[out] message Output buffer where to store the decrypted message
539  * @param[in] messageSize Size of the output buffer
540  * @param[out] messageLen Length of the decrypted message
541  * @return Error code
542  **/
543 
545  const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen,
546  uint8_t *message, size_t messageSize, size_t *messageLen)
547 {
548  error_t error;
549  uint_t k;
550  size_t i;
551  size_t j;
552  size_t n;
553  uint8_t b;
554  uint32_t a;
555  uint32_t badPadding;
556  uint32_t badLength;
557  Mpi c;
558  Mpi m;
559 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
560  uint8_t *em;
561 #else
562  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
563 #endif
564 
565  //Check parameters
566  if(key == NULL || ciphertext == NULL)
568  if(message == NULL || messageSize == 0 || messageLen == NULL)
570 
571  //Debug message
572  TRACE_DEBUG("RSAES-OAEP decryption...\r\n");
573  TRACE_DEBUG(" Modulus:\r\n");
574  TRACE_DEBUG_MPI(" ", &key->n);
575  TRACE_DEBUG(" Public exponent:\r\n");
576  TRACE_DEBUG_MPI(" ", &key->e);
577  TRACE_DEBUG(" Private exponent:\r\n");
578  TRACE_DEBUG_MPI(" ", &key->d);
579  TRACE_DEBUG(" Prime 1:\r\n");
580  TRACE_DEBUG_MPI(" ", &key->p);
581  TRACE_DEBUG(" Prime 2:\r\n");
582  TRACE_DEBUG_MPI(" ", &key->q);
583  TRACE_DEBUG(" Prime exponent 1:\r\n");
584  TRACE_DEBUG_MPI(" ", &key->dp);
585  TRACE_DEBUG(" Prime exponent 2:\r\n");
586  TRACE_DEBUG_MPI(" ", &key->dq);
587  TRACE_DEBUG(" Coefficient:\r\n");
588  TRACE_DEBUG_MPI(" ", &key->qinv);
589  TRACE_DEBUG(" Ciphertext:\r\n");
590  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
591 
592  //Initialize multiple-precision integers
593  mpiInit(&c);
594  mpiInit(&m);
595 
596  //Get the length in octets of the modulus n
597  k = mpiGetByteLength(&key->n);
598 
599  //Check the length of the modulus
600  if(k < (2 * hash->digestSize + 2))
602 
603  //Check the length of the ciphertext
604  if(ciphertextLen != k)
605  return ERROR_INVALID_LENGTH;
606 
607 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
608  //Allocate a buffer to store the encoded message EM
609  em = cryptoAllocMem(k);
610  //Failed to allocate memory?
611  if(em == NULL)
612  return ERROR_OUT_OF_MEMORY;
613 #else
614  //Check the length of the modulus
615  if(k > sizeof(em))
616  return ERROR_BUFFER_OVERFLOW;
617 #endif
618 
619  //Start of exception handling block
620  do
621  {
622  //Convert the ciphertext to an integer ciphertext representative c
623  error = mpiReadRaw(&c, ciphertext, ciphertextLen);
624  //Conversion failed?
625  if(error)
626  break;
627 
628  //Apply the RSADP decryption primitive
629  error = rsadp(key, &c, &m);
630  //Any error to report?
631  if(error)
632  break;
633 
634  //Convert the message representative m to an encoded message EM of
635  //length k octets
636  error = mpiWriteRaw(&m, em, k);
637  //Conversion failed?
638  if(error)
639  break;
640 
641  //Debug message
642  TRACE_DEBUG(" Encoded message:\r\n");
643  TRACE_DEBUG_ARRAY(" ", em, k);
644 
645  //EME-OAEP decoding
646  badPadding = emeOaepDecode(hash, label, em, k, &n);
647 
648  //Check whether the output buffer is large enough to hold the decrypted
649  //message
650  badLength = CRYPTO_TEST_LT_32(messageSize, n);
651 
652  //Copy the decrypted message, byte per byte
653  for(i = 0; i < messageSize; i++)
654  {
655  //Read the whole encoded message EM
656  for(b = 0, j = 0; j < k; j++)
657  {
658  //Constant time implementation
659  a = CRYPTO_TEST_EQ_32(j, k - n + i);
660  b = CRYPTO_SELECT_8(b, em[j], a);
661  }
662 
663  //Save the value of the current byte
664  message[i] = b;
665  }
666 
667  //Return the length of the decrypted message
668  *messageLen = CRYPTO_SELECT_32(n, messageSize, badLength);
669 
670  //Check whether the decryption operation is successful
671  error = (error_t) CRYPTO_SELECT_32(error, ERROR_BUFFER_OVERFLOW, badLength);
672  error = (error_t) CRYPTO_SELECT_32(error, ERROR_DECRYPTION_FAILED, badPadding);
673 
674  //Debug message
675  TRACE_DEBUG(" Message:\r\n");
676  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
677 
678  //End of exception handling block
679  } while(0);
680 
681 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
682  //Release the encoded message
683  cryptoFreeMem(em);
684 #endif
685 
686  //Release multiple precision integers
687  mpiFree(&c);
688  mpiFree(&m);
689 
690  //Return status code
691  return error;
692 }
693 
694 
695 /**
696  * @brief RSASSA-PKCS1-v1_5 signature generation operation
697  * @param[in] key Signer's RSA private key
698  * @param[in] hash Hash function used to digest the message
699  * @param[in] digest Digest of the message to be signed
700  * @param[out] signature Resulting signature
701  * @param[out] signatureLen Length of the resulting signature
702  * @return Error code
703  **/
704 
706  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
707 {
708  error_t error;
709  uint_t k;
710  uint8_t *em;
711  Mpi m;
712  Mpi s;
713  Mpi t;
714 
715  //Check parameters
716  if(key == NULL || hash == NULL || digest == NULL)
718  if(signature == NULL || signatureLen == NULL)
720 
721  //Debug message
722  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature generation...\r\n");
723  TRACE_DEBUG(" Modulus:\r\n");
724  TRACE_DEBUG_MPI(" ", &key->n);
725  TRACE_DEBUG(" Public exponent:\r\n");
726  TRACE_DEBUG_MPI(" ", &key->e);
727  TRACE_DEBUG(" Private exponent:\r\n");
728  TRACE_DEBUG_MPI(" ", &key->d);
729  TRACE_DEBUG(" Prime 1:\r\n");
730  TRACE_DEBUG_MPI(" ", &key->p);
731  TRACE_DEBUG(" Prime 2:\r\n");
732  TRACE_DEBUG_MPI(" ", &key->q);
733  TRACE_DEBUG(" Prime exponent 1:\r\n");
734  TRACE_DEBUG_MPI(" ", &key->dp);
735  TRACE_DEBUG(" Prime exponent 2:\r\n");
736  TRACE_DEBUG_MPI(" ", &key->dq);
737  TRACE_DEBUG(" Coefficient:\r\n");
738  TRACE_DEBUG_MPI(" ", &key->qinv);
739  TRACE_DEBUG(" Message digest:\r\n");
740  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
741 
742  //Initialize multiple-precision integers
743  mpiInit(&m);
744  mpiInit(&s);
745  mpiInit(&t);
746 
747  //Get the length in octets of the modulus n
748  k = mpiGetByteLength(&key->n);
749  //Point to the buffer where the encoded message EM will be formatted
750  em = signature;
751 
752  //Apply the EMSA-PKCS1-v1.5 encoding operation
753  error = emsaPkcs1v15Encode(hash, digest, em, k);
754  //Any error to report?
755  if(error)
756  return error;
757 
758  //Debug message
759  TRACE_DEBUG(" Encoded message:\r\n");
760  TRACE_DEBUG_ARRAY(" ", em, k);
761 
762  //Start of exception handling block
763  do
764  {
765  //Convert the encoded message EM to an integer message representative m
766  error = mpiReadRaw(&m, em, k);
767  //Conversion failed?
768  if(error)
769  break;
770 
771  //Apply the RSASP1 signature primitive
772  error = rsasp1(key, &m, &s);
773  //Any error to report?
774  if(error)
775  break;
776 
777  //When unprotected, RSA-CRT is vulnerable to the Bellcore attack
778  if(key->n.size && key->e.size && key->p.size && key->q.size &&
779  key->dp.size && key->dq.size && key->qinv.size)
780  {
781  RsaPublicKey publicKey;
782 
783  //Retrieve modulus and public exponent
784  publicKey.n = key->n;
785  publicKey.e = key->e;
786 
787  //Apply the RSAVP1 verification primitive
788  error = rsavp1(&publicKey, &s, &t);
789  //Any error to report?
790  if(error)
791  break;
792 
793  //Verify the RSA signature in order to protect against RSA-CRT key leak
794  if(mpiComp(&t, &m) != 0)
795  {
796  //A signature fault has been detected
797  error = ERROR_FAILURE;
798  break;
799  }
800  }
801 
802  //Convert the signature representative s to a signature of length k octets
803  error = mpiWriteRaw(&s, signature, k);
804  //Conversion failed?
805  if(error)
806  break;
807 
808  //Length of the resulting signature
809  *signatureLen = k;
810 
811  //Debug message
812  TRACE_DEBUG(" Signature:\r\n");
813  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
814 
815  //End of exception handling block
816  } while(0);
817 
818  //Free previously allocated memory
819  mpiFree(&m);
820  mpiFree(&s);
821  mpiFree(&t);
822 
823  //Return status code
824  return error;
825 }
826 
827 
828 /**
829  * @brief RSASSA-PKCS1-v1_5 signature verification operation
830  * @param[in] key Signer's RSA public key
831  * @param[in] hash Hash function used to digest the message
832  * @param[in] digest Digest of the message whose signature is to be verified
833  * @param[in] signature Signature to be verified
834  * @param[in] signatureLen Length of the signature to be verified
835  * @return Error code
836  **/
837 
839  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
840 {
841  error_t error;
842  uint_t k;
843  Mpi s;
844  Mpi m;
845 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
846  uint8_t *em;
847 #else
848  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
849 #endif
850 
851  //Check parameters
852  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
854 
855  //Debug message
856  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature verification...\r\n");
857  TRACE_DEBUG(" Modulus:\r\n");
858  TRACE_DEBUG_MPI(" ", &key->n);
859  TRACE_DEBUG(" Public exponent:\r\n");
860  TRACE_DEBUG_MPI(" ", &key->e);
861  TRACE_DEBUG(" Message digest:\r\n");
862  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
863  TRACE_DEBUG(" Signature:\r\n");
864  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
865 
866  //Initialize multiple-precision integers
867  mpiInit(&s);
868  mpiInit(&m);
869 
870  //Get the length in octets of the modulus n
871  k = mpiGetByteLength(&key->n);
872 
873  //Make sure the modulus is valid
874  if(k == 0)
876 
877  //Check the length of the signature
878  if(signatureLen != k)
880 
881 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
882  //Allocate a buffer to store the encoded message EM
883  em = cryptoAllocMem(k);
884  //Failed to allocate memory?
885  if(em == NULL)
886  return ERROR_OUT_OF_MEMORY;
887 #else
888  //Check the length of the modulus
889  if(k > sizeof(em))
890  return ERROR_BUFFER_OVERFLOW;
891 #endif
892 
893  //Start of exception handling block
894  do
895  {
896  //Convert the signature to an integer signature representative s
897  error = mpiReadRaw(&s, signature, signatureLen);
898  //Conversion failed?
899  if(error)
900  break;
901 
902  //Apply the RSAVP1 verification primitive
903  error = rsavp1(key, &s, &m);
904  //Any error to report?
905  if(error)
906  break;
907 
908  //Convert the message representative m to an encoded message EM of
909  //length k octets
910  error = mpiWriteRaw(&m, em, k);
911  //Conversion failed?
912  if(error)
913  break;
914 
915  //Debug message
916  TRACE_DEBUG(" Encoded message:\r\n");
917  TRACE_DEBUG_ARRAY(" ", em, k);
918 
919  //Verify the encoded message EM
920  error = emsaPkcs1v15Verify(hash, digest, em, k);
921  //Any error to report?
922  if(error)
923  {
924  //The signature is not valid
925  error = ERROR_INVALID_SIGNATURE;
926  break;
927  }
928 
929  //End of exception handling block
930  } while(0);
931 
932 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
933  //Release the encoded message
934  cryptoFreeMem(em);
935 #endif
936 
937  //Release multiple precision integers
938  mpiFree(&s);
939  mpiFree(&m);
940 
941  //Return status code
942  return error;
943 }
944 
945 
946 /**
947  * @brief RSASSA-PSS signature generation operation
948  * @param[in] prngAlgo PRNG algorithm
949  * @param[in] prngContext Pointer to the PRNG context
950  * @param[in] key Signer's RSA private key
951  * @param[in] hash Hash function used to digest the message
952  * @param[in] saltLen Length of the salt, in bytes
953  * @param[in] digest Digest of the message to be signed
954  * @param[out] signature Resulting signature
955  * @param[out] signatureLen Length of the resulting signature
956  * @return Error code
957  **/
958 
959 error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
960  const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen,
961  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
962 {
963  error_t error;
964  uint_t k;
965  uint_t modBits;
966  uint8_t *em;
967  Mpi m;
968  Mpi s;
969 
970  //Check parameters
971  if(prngAlgo == NULL || prngContext == NULL)
973  if(key == NULL || hash == NULL || digest == NULL)
975  if(signature == NULL || signatureLen == NULL)
977 
978  //Debug message
979  TRACE_DEBUG("RSASSA-PSS signature generation...\r\n");
980  TRACE_DEBUG(" Modulus:\r\n");
981  TRACE_DEBUG_MPI(" ", &key->n);
982  TRACE_DEBUG(" Public exponent:\r\n");
983  TRACE_DEBUG_MPI(" ", &key->e);
984  TRACE_DEBUG(" Private exponent:\r\n");
985  TRACE_DEBUG_MPI(" ", &key->d);
986  TRACE_DEBUG(" Prime 1:\r\n");
987  TRACE_DEBUG_MPI(" ", &key->p);
988  TRACE_DEBUG(" Prime 2:\r\n");
989  TRACE_DEBUG_MPI(" ", &key->q);
990  TRACE_DEBUG(" Prime exponent 1:\r\n");
991  TRACE_DEBUG_MPI(" ", &key->dp);
992  TRACE_DEBUG(" Prime exponent 2:\r\n");
993  TRACE_DEBUG_MPI(" ", &key->dq);
994  TRACE_DEBUG(" Coefficient:\r\n");
995  TRACE_DEBUG_MPI(" ", &key->qinv);
996  TRACE_DEBUG(" Message digest:\r\n");
997  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
998 
999  //Initialize multiple-precision integers
1000  mpiInit(&m);
1001  mpiInit(&s);
1002 
1003  //modBits is the length in bits of the modulus n
1004  modBits = mpiGetBitLength(&key->n);
1005 
1006  //Make sure the modulus is valid
1007  if(modBits == 0)
1008  return ERROR_INVALID_PARAMETER;
1009 
1010  //Calculate the length in octets of the modulus n
1011  k = (modBits + 7) / 8;
1012 
1013  //Point to the buffer where the encoded message EM will be formatted
1014  em = signature;
1015 
1016  //Apply the EMSA-PSS encoding operation to the message M to produce an
1017  //encoded message EM of length ceil((modBits - 1) / 8) octets
1018  error = emsaPssEncode(prngAlgo, prngContext, hash, saltLen, digest,
1019  em, modBits - 1);
1020  //Any error to report?
1021  if(error)
1022  return error;
1023 
1024  //Debug message
1025  TRACE_DEBUG(" Encoded message:\r\n");
1026  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1027 
1028  //Start of exception handling block
1029  do
1030  {
1031  //Convert the encoded message EM to an integer message representative m
1032  error = mpiReadRaw(&m, em, (modBits + 6) / 8);
1033  //Conversion failed?
1034  if(error)
1035  break;
1036 
1037  //Apply the RSASP1 signature primitive
1038  error = rsasp1(key, &m, &s);
1039  //Any error to report?
1040  if(error)
1041  break;
1042 
1043  //Convert the signature representative s to a signature of length k octets
1044  error = mpiWriteRaw(&s, signature, k);
1045  //Conversion failed?
1046  if(error)
1047  break;
1048 
1049  //Length of the resulting signature
1050  *signatureLen = k;
1051 
1052  //Debug message
1053  TRACE_DEBUG(" Signature:\r\n");
1054  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1055 
1056  //End of exception handling block
1057  } while(0);
1058 
1059  //Free previously allocated memory
1060  mpiFree(&m);
1061  mpiFree(&s);
1062 
1063  //Return status code
1064  return error;
1065 }
1066 
1067 
1068 /**
1069  * @brief RSASSA-PSS signature verification operation
1070  * @param[in] key Signer's RSA public key
1071  * @param[in] hash Hash function used to digest the message
1072  * @param[in] saltLen Length of the salt, in bytes
1073  * @param[in] digest Digest of the message whose signature is to be verified
1074  * @param[in] signature Signature to be verified
1075  * @param[in] signatureLen Length of the signature to be verified
1076  * @return Error code
1077  **/
1078 
1080  size_t saltLen, const uint8_t *digest, const uint8_t *signature,
1081  size_t signatureLen)
1082 {
1083  error_t error;
1084  uint_t k;
1085  uint_t modBits;
1086  Mpi s;
1087  Mpi m;
1088 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1089  uint8_t *em;
1090 #else
1091  uint8_t em[RSA_MAX_MODULUS_SIZE / 8];
1092 #endif
1093 
1094  //Check parameters
1095  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1096  return ERROR_INVALID_PARAMETER;
1097 
1098  //Debug message
1099  TRACE_DEBUG("RSASSA-PSS signature verification...\r\n");
1100  TRACE_DEBUG(" Modulus:\r\n");
1101  TRACE_DEBUG_MPI(" ", &key->n);
1102  TRACE_DEBUG(" Public exponent:\r\n");
1103  TRACE_DEBUG_MPI(" ", &key->e);
1104  TRACE_DEBUG(" Message digest:\r\n");
1105  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1106  TRACE_DEBUG(" Signature:\r\n");
1107  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1108 
1109  //Initialize multiple-precision integers
1110  mpiInit(&s);
1111  mpiInit(&m);
1112 
1113  //modBits is the length in bits of the modulus n
1114  modBits = mpiGetBitLength(&key->n);
1115 
1116  //Make sure the modulus is valid
1117  if(modBits == 0)
1118  return ERROR_INVALID_PARAMETER;
1119 
1120  //Calculate the length in octets of the modulus n
1121  k = (modBits + 7) / 8;
1122 
1123  //Check the length of the signature
1124  if(signatureLen != k)
1125  return ERROR_INVALID_SIGNATURE;
1126 
1127 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1128  //Allocate a buffer to store the encoded message EM
1129  em = cryptoAllocMem(k);
1130  //Failed to allocate memory?
1131  if(em == NULL)
1132  return ERROR_OUT_OF_MEMORY;
1133 #else
1134  //Check the length of the modulus
1135  if(k > sizeof(em))
1136  return ERROR_BUFFER_OVERFLOW;
1137 #endif
1138 
1139  //Start of exception handling block
1140  do
1141  {
1142  //Convert the signature to an integer signature representative s
1143  error = mpiReadRaw(&s, signature, signatureLen);
1144  //Conversion failed?
1145  if(error)
1146  break;
1147 
1148  //Apply the RSAVP1 verification primitive
1149  error = rsavp1(key, &s, &m);
1150  //Any error to report?
1151  if(error)
1152  break;
1153 
1154  //Convert the message representative m to an encoded message EM of
1155  //length emLen = ceil((modBits - 1) / 8) octets
1156  error = mpiWriteRaw(&m, em, (modBits + 6) / 8);
1157  //Conversion failed?
1158  if(error)
1159  break;
1160 
1161  //Debug message
1162  TRACE_DEBUG(" Encoded message:\r\n");
1163  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1164 
1165  //Apply the EMSA-PSS verification operation to the message M and the
1166  //encoded message EM to determine whether they are consistent
1167  error = emsaPssVerify(hash, saltLen, digest, em, modBits - 1);
1168  //Any error to report?
1169  if(error)
1170  {
1171  //The signature is not valid
1172  error = ERROR_INVALID_SIGNATURE;
1173  break;
1174  }
1175 
1176  //End of exception handling block
1177  } while(0);
1178 
1179 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1180  //Release the encoded message
1181  cryptoFreeMem(em);
1182 #endif
1183 
1184  //Release multiple precision integers
1185  mpiFree(&s);
1186  mpiFree(&m);
1187 
1188  //Return status code
1189  return error;
1190 }
1191 
1192 
1193 /**
1194  * @brief RSA encryption primitive
1195  *
1196  * The RSA encryption primitive produces a ciphertext representative from
1197  * a message representative under the control of a public key
1198  *
1199  * @param[in] key RSA public key
1200  * @param[in] m Message representative
1201  * @param[out] c Ciphertext representative
1202  * @return Error code
1203  **/
1204 
1205 __weak_func error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
1206 {
1207  //Ensure the RSA public key is valid
1208  if(!key->n.size || !key->e.size)
1209  return ERROR_INVALID_PARAMETER;
1210 
1211  //The message representative m shall be between 0 and n - 1
1212  if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
1213  return ERROR_OUT_OF_RANGE;
1214 
1215  //Perform modular exponentiation (c = m ^ e mod n)
1216  return mpiExpModFast(c, m, &key->e, &key->n);
1217 }
1218 
1219 
1220 /**
1221  * @brief RSA decryption primitive
1222  *
1223  * The RSA decryption primitive recovers the message representative from
1224  * the ciphertext representative under the control of a private key
1225  *
1226  * @param[in] key RSA private key
1227  * @param[in] c Ciphertext representative
1228  * @param[out] m Message representative
1229  * @return Error code
1230  **/
1231 
1232 __weak_func error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
1233 {
1234  error_t error;
1235  Mpi m1;
1236  Mpi m2;
1237  Mpi h;
1238 
1239  //The ciphertext representative c shall be between 0 and n - 1
1240  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
1241  return ERROR_OUT_OF_RANGE;
1242 
1243  //Initialize multiple-precision integers
1244  mpiInit(&m1);
1245  mpiInit(&m2);
1246  mpiInit(&h);
1247 
1248  //Use the Chinese remainder algorithm?
1249  if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->p) > 0 &&
1250  mpiGetLength(&key->q) > 0 && mpiGetLength(&key->dp) > 0 &&
1251  mpiGetLength(&key->dq) > 0 && mpiGetLength(&key->qinv) > 0)
1252  {
1253  //Compute m1 = c ^ dP mod p
1254  MPI_CHECK(mpiMod(&m1, c, &key->p));
1255  MPI_CHECK(mpiExpModRegular(&m1, &m1, &key->dp, &key->p));
1256  //Compute m2 = c ^ dQ mod q
1257  MPI_CHECK(mpiMod(&m2, c, &key->q));
1258  MPI_CHECK(mpiExpModRegular(&m2, &m2, &key->dq, &key->q));
1259  //Let h = (m1 - m2) * qInv mod p
1260  MPI_CHECK(mpiSub(&h, &m1, &m2));
1261  MPI_CHECK(mpiMulMod(&h, &h, &key->qinv, &key->p));
1262  //Let m = m2 + q * h
1263  MPI_CHECK(mpiMul(m, &key->q, &h));
1264  MPI_CHECK(mpiAdd(m, m, &m2));
1265  }
1266  //Use modular exponentiation?
1267  else if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->d) > 0)
1268  {
1269  //Let m = c ^ d mod n
1270  error = mpiExpModRegular(m, c, &key->d, &key->n);
1271  }
1272  //Invalid parameters?
1273  else
1274  {
1275  //Report an error
1276  error = ERROR_INVALID_PARAMETER;
1277  }
1278 
1279 end:
1280  //Free previously allocated memory
1281  mpiFree(&m1);
1282  mpiFree(&m2);
1283  mpiFree(&h);
1284 
1285  //Return status code
1286  return error;
1287 }
1288 
1289 
1290 /**
1291  * @brief RSA signature primitive
1292  *
1293  * The RSA signature primitive produces a signature representative from
1294  * a message representative under the control of a private key
1295  *
1296  * @param[in] key RSA private key
1297  * @param[in] m Message representative
1298  * @param[out] s Signature representative
1299  * @return Error code
1300  **/
1301 
1302 error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
1303 {
1304  //RSASP1 primitive is the same as RSADP except for the names of its input
1305  //and output arguments. They are distinguished as they are intended for
1306  //different purposes
1307  return rsadp(key, m, s);
1308 }
1309 
1310 
1311 /**
1312  * @brief RSA verification primitive
1313  *
1314  * The RSA verification primitive recovers the message representative from
1315  * the signature representative under the control of a public key
1316  *
1317  * @param[in] key RSA public key
1318  * @param[in] s Signature representative
1319  * @param[out] m Message representative
1320  * @return Error code
1321  **/
1322 
1323 error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
1324 {
1325  //RSAVP1 primitive is the same as RSAEP except for the names of its input
1326  //and output arguments. They are distinguished as they are intended for
1327  //different purposes
1328  return rsaep(key, s, m);
1329 }
1330 
1331 
1332 /**
1333  * @brief EME-PKCS1-v1_5 encoding operation
1334  * @param[in] prngAlgo PRNG algorithm
1335  * @param[in] prngContext Pointer to the PRNG context
1336  * @param[in] message Message to be encrypted
1337  * @param[in] messageLen Length of the message to be encrypted
1338  * @param[out] em Encoded message
1339  * @param[in] k Length of the encoded message
1340  * @return Error code
1341  **/
1342 
1343 error_t emePkcs1v15Encode(const PrngAlgo *prngAlgo, void *prngContext,
1344  const uint8_t *message, size_t messageLen, uint8_t *em, size_t k)
1345 {
1346  error_t error;
1347  size_t i;
1348  size_t j;
1349  size_t n;
1350  uint8_t *p;
1351 
1352  //Check the length of the message
1353  if((messageLen + 11) > k)
1354  return ERROR_INVALID_LENGTH;
1355 
1356  //The leading 0x00 octet ensures that the encoded message, converted to
1357  //an integer, is less than the modulus
1358  em[0] = 0x00;
1359  //For a public-key operation, the block type BT shall be 0x02
1360  em[1] = 0x02;
1361 
1362  //Point to the buffer where to format the padding string PS
1363  p = em + 2;
1364  //Determine the length of the padding string
1365  n = k - messageLen - 3;
1366 
1367  //Generate an octet string PS of length k - mLen - 3 consisting of
1368  //pseudo-randomly generated nonzero octets
1369  while(n > 0)
1370  {
1371  //Generate random data
1372  error = prngAlgo->read(prngContext, p, n);
1373  //Any error to report?
1374  if(error)
1375  return error;
1376 
1377  //Parse the resulting octet string
1378  for(i = 0, j = 0; j < n; j++)
1379  {
1380  //Strip any byte with a value of zero
1381  if(p[j] != 0)
1382  {
1383  p[i++] = p[j];
1384  }
1385  }
1386 
1387  //Advance data pointer
1388  p += i;
1389  n -= i;
1390  }
1391 
1392  //Append a 0x00 octet to the padding string
1393  *p = 0x00;
1394 
1395  //Copy the message to be encrypted
1396  osMemcpy(p + 1, message, messageLen);
1397 
1398  //Successful processing
1399  return NO_ERROR;
1400 }
1401 
1402 
1403 /**
1404  * @brief EME-PKCS1-v1_5 decoding operation
1405  * @param[in] em Encoded message
1406  * @param[in] k Length of the encoded message
1407  * @param[out] messageLen Length of the decrypted message
1408  * @return The function returns 0 on success, 1 on failure
1409  **/
1410 
1411 uint32_t emePkcs1v15Decode(uint8_t *em, size_t k, size_t *messageLen)
1412 {
1413  size_t i;
1414  size_t m;
1415  uint32_t c;
1416  uint32_t bad;
1417 
1418  //Separate the encoded message EM into an octet string PS consisting of
1419  //nonzero octets and a message M
1420  for(m = 0, i = 2; i < k; i++)
1421  {
1422  //Constant time implementation
1423  c = CRYPTO_TEST_Z_8(em[i]);
1424  c &= CRYPTO_TEST_Z_32(m);
1425  m = CRYPTO_SELECT_32(m, i, c);
1426  }
1427 
1428  //If the first octet of EM does not have hexadecimal value 0x00, then
1429  //report a decryption error
1430  bad = CRYPTO_TEST_NEQ_8(em[0], 0x00);
1431 
1432  //If the second octet of EM does not have hexadecimal value 0x02, then
1433  //report a decryption error
1434  bad |= CRYPTO_TEST_NEQ_8(em[1], 0x02);
1435 
1436  //If there is no octet with hexadecimal value 0x00 to separate PS from M,
1437  //then report a decryption error
1438  bad |= CRYPTO_TEST_Z_32(m);
1439 
1440  //If the length of PS is less than 8 octets, then report a decryption error
1441  bad |= CRYPTO_TEST_LT_32(m, 10);
1442 
1443  //Return the length of the decrypted message
1444  *messageLen = CRYPTO_SELECT_32(k - m - 1, 0, bad);
1445 
1446  //Care must be taken to ensure that an opponent cannot distinguish the
1447  //different error conditions, whether by error message or timing
1448  return bad;
1449 }
1450 
1451 
1452 /**
1453  * @brief EME-OAEP encoding operation
1454  * @param[in] prngAlgo PRNG algorithm
1455  * @param[in] prngContext Pointer to the PRNG context
1456  * @param[in] hash Underlying hash function
1457  * @param[in] label Optional label to be associated with the message
1458  * @param[in] message Message to be encrypted
1459  * @param[in] messageLen Length of the message to be encrypted
1460  * @param[out] em Encoded message
1461  * @param[in] k Length of the encoded message
1462  * @return Error code
1463  **/
1464 
1465 error_t emeOaepEncode(const PrngAlgo *prngAlgo, void *prngContext,
1466  const HashAlgo *hash, const char_t *label, const uint8_t *message,
1467  size_t messageLen, uint8_t *em, size_t k)
1468 {
1469  error_t error;
1470  size_t n;
1471  uint8_t *db;
1472  uint8_t *seed;
1473 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1474  HashContext *hashContext;
1475 #else
1476  HashContext hashContext[1];
1477 #endif
1478 
1479  //Check the length of the message
1480  if(messageLen > (k - 2 * hash->digestSize - 2))
1481  return ERROR_INVALID_LENGTH;
1482 
1483  //Point to the buffer where to format the seed
1484  seed = em + 1;
1485  //Point to the buffer where to format the data block
1486  db = em + hash->digestSize + 1;
1487 
1488  //Generate a random octet string seed of length hLen
1489  error = prngAlgo->read(prngContext, seed, hash->digestSize);
1490  //Any error to report?
1491  if(error)
1492  return error;
1493 
1494 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1495  //Allocate a memory buffer to hold the hash context
1496  hashContext = cryptoAllocMem(hash->contextSize);
1497  //Failed to allocate memory?
1498  if(hashContext == NULL)
1499  return ERROR_OUT_OF_MEMORY;
1500 #endif
1501 
1502  //If the label L is not provided, let L be the empty string
1503  if(label == NULL)
1504  {
1505  label = "";
1506  }
1507 
1508  //Let lHash = Hash(L)
1509  hash->init(hashContext);
1510  hash->update(hashContext, label, osStrlen(label));
1511  hash->final(hashContext, db);
1512 
1513  //The padding string PS consists of k - mLen - 2hLen - 2 zero octets
1514  n = k - messageLen - 2 * hash->digestSize - 2;
1515  //Generate the padding string
1516  osMemset(db + hash->digestSize, 0, n);
1517 
1518  //Concatenate lHash, PS, a single octet with hexadecimal value 0x01, and
1519  //the message M to form a data block DB of length k - hLen - 1 octets
1520  db[hash->digestSize + n] = 0x01;
1521  osMemcpy(db + hash->digestSize + n + 1, message, messageLen);
1522 
1523  //Calculate the length of the data block
1524  n = k - hash->digestSize - 1;
1525 
1526  //Let maskedDB = DB xor MGF(seed, k - hLen - 1)
1527  mgf1(hash, hashContext, seed, hash->digestSize, db, n);
1528  //Let maskedSeed = seed xor MGF(maskedDB, hLen)
1529  mgf1(hash, hashContext, db, n, seed, hash->digestSize);
1530 
1531  //Concatenate a single octet with hexadecimal value 0x00, maskedSeed, and
1532  //maskedDB to form an encoded message EM of length k octets
1533  em[0] = 0x00;
1534 
1535 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1536  //Release hash context
1537  cryptoFreeMem(hashContext);
1538 #endif
1539 
1540  //Successful processing
1541  return NO_ERROR;
1542 }
1543 
1544 
1545 /**
1546  * @brief EME-OAEP decoding operation
1547  * @param[in] hash Underlying hash function
1548  * @param[in] label Optional label to be associated with the message
1549  * @param[in] em Encoded message
1550  * @param[in] k Length of the encoded message
1551  * @param[out] messageLen Length of the decrypted message
1552  * @return The function returns 0 on success, 1 on failure
1553  **/
1554 
1555 uint32_t emeOaepDecode(const HashAlgo *hash, const char_t *label, uint8_t *em,
1556  size_t k, size_t *messageLen)
1557 {
1558  size_t i;
1559  size_t m;
1560  size_t n;
1561  uint32_t c;
1562  uint32_t bad;
1563  uint8_t *db;
1564  uint8_t *seed;
1565  uint8_t lHash[MAX_HASH_DIGEST_SIZE];
1566 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1567  HashContext *hashContext;
1568 #else
1569  HashContext hashContext[1];
1570 #endif
1571 
1572 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1573  //Allocate a memory buffer to hold the hash context
1574  hashContext = cryptoAllocMem(hash->contextSize);
1575  //Failed to allocate memory?
1576  if(hashContext == NULL)
1577  return TRUE;
1578 #endif
1579 
1580  //If the label L is not provided, let L be the empty string
1581  if(label == NULL)
1582  {
1583  label = "";
1584  }
1585 
1586  //Let lHash = Hash(L)
1587  hash->init(hashContext);
1588  hash->update(hashContext, label, osStrlen(label));
1589  hash->final(hashContext, lHash);
1590 
1591  //Separate the encoded message EM into a single octet Y, an octet string
1592  //maskedSeed of length hLen, and an octet string maskedDB of length k - hLen - 1
1593  seed = em + 1;
1594  db = em + hash->digestSize + 1;
1595 
1596  //Calculate the length of the data block
1597  n = k - hash->digestSize - 1;
1598 
1599  //Let seed = maskedSeed xor MGF(maskedDB, hLen)
1600  mgf1(hash, hashContext, db, n, seed, hash->digestSize);
1601  //Let DB = maskedDB xor MGF(seed, k - hLen - 1)
1602  mgf1(hash, hashContext, seed, hash->digestSize, db, n);
1603 
1604 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1605  //Release hash context
1606  cryptoFreeMem(hashContext);
1607 #endif
1608 
1609  //Separate DB into an octet string lHash' of length hLen, a padding string
1610  //PS consisting of octets with hexadecimal value 0x00, and a message M
1611  for(m = 0, i = hash->digestSize; i < n; i++)
1612  {
1613  //Constant time implementation
1614  c = CRYPTO_TEST_NZ_8(db[i]);
1615  c &= CRYPTO_TEST_Z_32(m);
1616  m = CRYPTO_SELECT_32(m, i, c);
1617  }
1618 
1619  //Make sure the padding string PS is terminated
1620  bad = CRYPTO_TEST_Z_32(m);
1621 
1622  //If there is no octet with hexadecimal value 0x01 to separate PS from M,
1623  //then report a decryption error
1624  bad |= CRYPTO_TEST_NEQ_8(db[m], 0x01);
1625 
1626  //If lHash does not equal lHash', then report a decryption error
1627  for(i = 0; i < hash->digestSize; i++)
1628  {
1629  bad |= CRYPTO_TEST_NEQ_8(db[i], lHash[i]);
1630  }
1631 
1632  //If Y is nonzero, then report a decryption error
1633  bad |= CRYPTO_TEST_NEQ_8(em[0], 0x00);
1634 
1635  //Return the length of the decrypted message
1636  *messageLen = CRYPTO_SELECT_32(n - m - 1, 0, bad);
1637 
1638  //Care must be taken to ensure that an opponent cannot distinguish the
1639  //different error conditions, whether by error message or timing
1640  return bad;
1641 }
1642 
1643 
1644 /**
1645  * @brief EMSA-PKCS1-v1_5 encoding operation
1646  * @param[in] hash Hash function used to digest the message
1647  * @param[in] digest Digest of the message to be signed
1648  * @param[out] em Encoded message
1649  * @param[in] emLen Intended length of the encoded message
1650  * @return Error code
1651  **/
1652 
1654  const uint8_t *digest, uint8_t *em, size_t emLen)
1655 {
1656  size_t i;
1657  size_t n;
1658 
1659  //Check the intended length of the encoded message
1660  if(emLen < (hash->oidSize + hash->digestSize + 21))
1661  return ERROR_INVALID_LENGTH;
1662 
1663  //Point to the first byte of the encoded message
1664  i = 0;
1665 
1666  //The leading 0x00 octet ensures that the encoded message, converted to
1667  //an integer, is less than the modulus
1668  em[i++] = 0x00;
1669  //Block type 0x01 is used for private-key operations
1670  em[i++] = 0x01;
1671 
1672  //Determine the length of the padding string PS
1673  n = emLen - hash->oidSize - hash->digestSize - 13;
1674 
1675  //Each byte of PS must be set to 0xFF when the block type is 0x01
1676  osMemset(em + i, 0xFF, n);
1677  i += n;
1678 
1679  //Append a 0x00 octet to the padding string
1680  em[i++] = 0x00;
1681 
1682  //Encode the DigestInfo structure using ASN.1
1683  em[i++] = (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1684  em[i++] = (uint8_t) (hash->oidSize + hash->digestSize + 8);
1685  em[i++] = (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1686  em[i++] = (uint8_t) (hash->oidSize + 4);
1687  em[i++] = (uint8_t) ASN1_TYPE_OBJECT_IDENTIFIER;
1688  em[i++] = (uint8_t) hash->oidSize;
1689 
1690  //Copy the hash algorithm OID
1691  osMemcpy(em + i, hash->oid, hash->oidSize);
1692  i += hash->oidSize;
1693 
1694  //Encode the rest of the ASN.1 structure
1695  em[i++] = (uint8_t) ASN1_TYPE_NULL;
1696  em[i++] = 0;
1697  em[i++] = (uint8_t) ASN1_TYPE_OCTET_STRING;
1698  em[i++] = (uint8_t) hash->digestSize;
1699 
1700  //Append the hash value
1701  osMemcpy(em + i, digest, hash->digestSize);
1702 
1703  //Successful processing
1704  return NO_ERROR;
1705 }
1706 
1707 
1708 /**
1709  * @brief EMSA-PKCS1-v1_5 verification operation
1710  * @param[in] hash Hash function
1711  * @param[in] digest Digest value
1712  * @param[in] em Encoded message
1713  * @param[in] emLen Length of the encoded message
1714  * @return Error code
1715  **/
1716 
1717 error_t emsaPkcs1v15Verify(const HashAlgo *hash, const uint8_t *digest,
1718  const uint8_t *em, size_t emLen)
1719 {
1720  size_t i;
1721  size_t j;
1722  size_t n;
1723  uint8_t bad;
1724 
1725  //Check the length of the encoded message
1726  if(emLen < (hash->oidSize + hash->digestSize + 21))
1727  return ERROR_INVALID_LENGTH;
1728 
1729  //Point to the first byte of the encoded message
1730  i = 0;
1731 
1732  //The first octet of EM must have hexadecimal value 0x00
1733  bad = em[i++];
1734  //The second octet of EM must have hexadecimal value 0x01
1735  bad |= em[i++] ^ 0x01;
1736 
1737  //Determine the length of the padding string PS
1738  n = emLen - hash->oidSize - hash->digestSize - 13;
1739 
1740  //Each byte of PS must be set to 0xFF when the block type is 0x01
1741  for(j = 0; j < n; j++)
1742  {
1743  bad |= em[i++] ^ 0xFF;
1744  }
1745 
1746  //The padding string must be followed by a 0x00 octet
1747  bad |= em[i++];
1748 
1749  //Check the ASN.1 syntax of the DigestInfo structure
1750  bad |= em[i++] ^ (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1751  bad |= em[i++] ^ (uint8_t) (hash->oidSize + hash->digestSize + 8);
1752  bad |= em[i++] ^ (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1753  bad |= em[i++] ^ (uint8_t) (hash->oidSize + 4);
1754  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_OBJECT_IDENTIFIER;
1755  bad |= em[i++] ^ (uint8_t) hash->oidSize;
1756 
1757  //Verify the hash algorithm OID
1758  for(j = 0; j < hash->oidSize; j++)
1759  {
1760  bad |= em[i++] ^ hash->oid[j];
1761  }
1762 
1763  //Check the rest of the ASN.1 structure
1764  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_NULL;
1765  bad |= em[i++];
1766  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_OCTET_STRING;
1767  bad |= em[i++] ^ (uint8_t) hash->digestSize;
1768 
1769  //Recover the underlying hash value, and then compare it to the newly
1770  //computed hash value
1771  for(j = 0; j < hash->digestSize; j++)
1772  {
1773  bad |= em[i++] ^ digest[j];
1774  }
1775 
1776  //Verification result
1777  return (bad != 0) ? ERROR_INCONSISTENT_VALUE : NO_ERROR;
1778 }
1779 
1780 
1781 /**
1782  * @brief EMSA-PSS encoding operation
1783  * @param[in] prngAlgo PRNG algorithm
1784  * @param[in] prngContext Pointer to the PRNG context
1785  * @param[in] hash Underlying hash function
1786  * @param[in] saltLen Length of the salt, in bytes
1787  * @param[in] digest Digest of the message to be signed
1788  * @param[out] em Encoded message
1789  * @param[in] emBits Maximal bit length of the integer OS2IP(EM)
1790  * @return Error code
1791  **/
1792 
1793 error_t emsaPssEncode(const PrngAlgo *prngAlgo, void *prngContext,
1794  const HashAlgo *hash, size_t saltLen, const uint8_t *digest,
1795  uint8_t *em, uint_t emBits)
1796 {
1797  error_t error;
1798  size_t n;
1799  size_t emLen;
1800  uint8_t *db;
1801  uint8_t *salt;
1802  uint8_t h[MAX_HASH_DIGEST_SIZE];
1803 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1804  HashContext *hashContext;
1805 #else
1806  HashContext hashContext[1];
1807 #endif
1808 
1809  //The encoded message is an octet string of length emLen = ceil(emBits / 8)
1810  emLen = (emBits + 7) / 8;
1811 
1812  //If emLen < hLen + sLen + 2, output "encoding error" and stop
1813  if(emLen < (hash->digestSize + saltLen + 2))
1814  return ERROR_INVALID_LENGTH;
1815 
1816  //The padding string PS consists of emLen - sLen - hLen - 2 zero octets
1817  n = emLen - saltLen - hash->digestSize - 2;
1818 
1819  //Point to the buffer where to format the data block DB
1820  db = em;
1821  //Point to the buffer where to generate the salt
1822  salt = db + n + 1;
1823 
1824  //Generate a random octet string salt of length sLen
1825  error = prngAlgo->read(prngContext, salt, saltLen);
1826  //Any error to report?
1827  if(error)
1828  return error;
1829 
1830 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1831  //Allocate a memory buffer to hold the hash context
1832  hashContext = cryptoAllocMem(hash->contextSize);
1833  //Failed to allocate memory?
1834  if(hashContext == NULL)
1835  return ERROR_OUT_OF_MEMORY;
1836 #endif
1837 
1838  //Let H = Hash(00 00 00 00 00 00 00 00 || mHash || salt)
1839  hash->init(hashContext);
1840  hash->update(hashContext, padding, sizeof(padding));
1841  hash->update(hashContext, digest, hash->digestSize);
1842  hash->update(hashContext, salt, saltLen);
1843  hash->final(hashContext, h);
1844 
1845  //Let DB = PS || 0x01 || salt
1846  osMemset(db, 0, n);
1847  db[n] = 0x01;
1848 
1849  //Calculate the length of the data block
1850  n += saltLen + 1;
1851 
1852  //Let maskedDB = DB xor MGF(H, emLen - hLen - 1)
1853  mgf1(hash, hashContext, h, hash->digestSize, db, n);
1854 
1855  //Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB
1856  //to zero
1857  db[0] &= 0xFF >> (8 * emLen - emBits);
1858 
1859  //Let EM = maskedDB || H || 0xbc
1860  osMemcpy(em + n, h, hash->digestSize);
1861  em[n + hash->digestSize] = 0xBC;
1862 
1863 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1864  //Release hash context
1865  cryptoFreeMem(hashContext);
1866 #endif
1867 
1868  //Successful processing
1869  return NO_ERROR;
1870 }
1871 
1872 
1873 /**
1874  * @brief EMSA-PSS verification operation
1875  * @param[in] hash Underlying hash function
1876  * @param[in] saltLen Length of the salt, in bytes
1877  * @param[in] digest Digest of the message to be signed
1878  * @param[out] em Encoded message
1879  * @param[in] emBits Maximal bit length of the integer OS2IP(EM)
1880  * @return Error code
1881  **/
1882 
1883 error_t emsaPssVerify(const HashAlgo *hash, size_t saltLen,
1884  const uint8_t *digest, uint8_t *em, uint_t emBits)
1885 {
1886  size_t i;
1887  size_t n;
1888  size_t emLen;
1889  uint8_t bad;
1890  uint8_t mask;
1891  uint8_t *h;
1892  uint8_t *db;
1893  uint8_t *salt;
1894 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1895  HashContext *hashContext;
1896 #else
1897  HashContext hashContext[1];
1898 #endif
1899 
1900  //The encoded message is an octet string of length emLen = ceil(emBits / 8)
1901  emLen = (emBits + 7) / 8;
1902 
1903  //Check the length of the encoded message EM
1904  if(emLen < (hash->digestSize + saltLen + 2))
1905  return ERROR_INVALID_LENGTH;
1906 
1907 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1908  //Allocate a memory buffer to hold the hash context
1909  hashContext = cryptoAllocMem(hash->contextSize);
1910  //Failed to allocate memory?
1911  if(hashContext == NULL)
1912  return ERROR_OUT_OF_MEMORY;
1913 #endif
1914 
1915  //If the rightmost octet of EM does not have hexadecimal value 0xbc, output
1916  //"inconsistent" and stop
1917  bad = em[emLen - 1] ^ 0xBC;
1918 
1919  //Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and let H be
1920  //the next hLen octets
1921  db = em;
1922  n = emLen - hash->digestSize - 1;
1923  h = em + n;
1924 
1925  //Form a mask
1926  mask = 0xFF >> (8 * emLen - emBits);
1927 
1928  //If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are
1929  //not all equal to zero, output "inconsistent" and stop
1930  bad |= db[0] & ~mask;
1931 
1932  //Let DB = maskedDB xor MGF(H, emLen - hLen - 1)
1933  mgf1(hash, hashContext, h, hash->digestSize, db, n);
1934 
1935  //Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero
1936  db[0] &= mask;
1937 
1938  //The padding string PS consists of emLen - sLen - hLen - 2 octets
1939  n = emLen - hash->digestSize - saltLen - 2;
1940 
1941  //If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero, output
1942  //"inconsistent" and stop
1943  for(i = 0; i < n; i++)
1944  {
1945  bad |= db[i];
1946  }
1947 
1948  //If the octet at position emLen - hLen - sLen - 1 does not have hexadecimal
1949  //value 0x01, output "inconsistent" and stop
1950  bad |= db[n] ^ 0x01;
1951 
1952  //Let salt be the last sLen octets of DB
1953  salt = db + n + 1;
1954 
1955  //Let H' = Hash(00 00 00 00 00 00 00 00 || mHash || salt)
1956  hash->init(hashContext);
1957  hash->update(hashContext, padding, sizeof(padding));
1958  hash->update(hashContext, digest, hash->digestSize);
1959  hash->update(hashContext, salt, saltLen);
1960  hash->final(hashContext, NULL);
1961 
1962  //If H = H', output "consistent". Otherwise, output "inconsistent"
1963  for(i = 0; i < hash->digestSize; i++)
1964  {
1965  bad |= h[i] ^ hashContext->digest[i];
1966  }
1967 
1968 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1969  //Release hash context
1970  cryptoFreeMem(hashContext);
1971 #endif
1972 
1973  //Verification result
1974  return (bad != 0) ? ERROR_INCONSISTENT_VALUE : NO_ERROR;
1975 }
1976 
1977 
1978 /**
1979  * @brief MGF1 mask generation function
1980  * @param[in] hash Hash function
1981  * @param[in] hashContext Hash function context
1982  * @param[in] seed Seed from which the mask is generated
1983  * @param[in] seedLen Length of the seed in bytes
1984  * @param[in,out] data Data block to be masked
1985  * @param[in] dataLen Length of the data block in bytes
1986  **/
1987 
1988 void mgf1(const HashAlgo *hash, HashContext *hashContext, const uint8_t *seed,
1989  size_t seedLen, uint8_t *data, size_t dataLen)
1990 {
1991  size_t i;
1992  size_t n;
1993  uint32_t counter;
1994  uint8_t c[4];
1995 
1996  //The data is processed block by block
1997  for(counter = 0; dataLen > 0; counter++)
1998  {
1999  //Limit the number of bytes to process at a time
2000  n = MIN(dataLen, hash->digestSize);
2001 
2002  //Convert counter to an octet string C of length 4 octets
2003  STORE32BE(counter, c);
2004 
2005  //Calculate Hash(mgfSeed || C)
2006  hash->init(hashContext);
2007  hash->update(hashContext, seed, seedLen);
2008  hash->update(hashContext, c, sizeof(c));
2009  hash->final(hashContext, NULL);
2010 
2011  //Apply the mask
2012  for(i = 0; i < n; i++)
2013  {
2014  data[i] ^= hashContext->digest[i];
2015  }
2016 
2017  //Advance data pointer
2018  data += n;
2019  dataLen -= n;
2020  }
2021 }
2022 
2023 
2024 /**
2025  * @brief RSA key pair generation
2026  * @param[in] prngAlgo PRNG algorithm
2027  * @param[in] prngContext Pointer to the PRNG context
2028  * @param[in] k Required bit length of the modulus n
2029  * @param[in] e Public exponent (3, 5, 17, 257 or 65537)
2030  * @param[out] privateKey RSA private key
2031  * @param[out] publicKey RSA public key
2032  * @return Error code
2033  **/
2034 
2035 error_t rsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext,
2036  size_t k, uint_t e, RsaPrivateKey *privateKey, RsaPublicKey *publicKey)
2037 {
2038  error_t error;
2039 
2040  //Generate a private key
2041  error = rsaGeneratePrivateKey(prngAlgo, prngContext, k, e, privateKey);
2042 
2043  //Check status code
2044  if(!error)
2045  {
2046  //Derive the public key from the private key
2047  error = rsaGeneratePublicKey(privateKey, publicKey);
2048  }
2049 
2050  //Return status code
2051  return error;
2052 }
2053 
2054 
2055 /**
2056  * @brief RSA private key generation
2057  * @param[in] prngAlgo PRNG algorithm
2058  * @param[in] prngContext Pointer to the PRNG context
2059  * @param[in] k Required bit length of the modulus n
2060  * @param[in] e Public exponent (3, 5, 17, 257 or 65537)
2061  * @param[out] privateKey RSA private key
2062  * @return Error code
2063  **/
2064 
2065 __weak_func error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext,
2066  size_t k, uint_t e, RsaPrivateKey *privateKey)
2067 {
2068  error_t error;
2069  Mpi t1;
2070  Mpi t2;
2071  Mpi phy;
2072 
2073  //Check parameters
2074  if(prngAlgo == NULL || prngContext == NULL || privateKey == NULL)
2075  return ERROR_INVALID_PARAMETER;
2076 
2077  //Check the length of the modulus
2078  if(k < 8)
2079  return ERROR_INVALID_PARAMETER;
2080 
2081  //Check the value of the public exponent
2082  if(e != 3 && e != 5 && e != 17 && e != 257 && e != 65537)
2083  return ERROR_INVALID_PARAMETER;
2084 
2085  //Initialize multiple precision integers
2086  mpiInit(&t1);
2087  mpiInit(&t2);
2088  mpiInit(&phy);
2089 
2090  //Save public exponent
2091  MPI_CHECK(mpiSetValue(&privateKey->e, e));
2092 
2093  //Generate a large random prime p
2094  do
2095  {
2096  do
2097  {
2098  //Generate a random number of bit length k/2
2099  MPI_CHECK(mpiRand(&privateKey->p, k / 2, prngAlgo, prngContext));
2100  //Set the low bit (this ensures the number is odd)
2101  MPI_CHECK(mpiSetBitValue(&privateKey->p, 0, 1));
2102  //Set the two highest bits (this ensures that the high bit of n is also set)
2103  MPI_CHECK(mpiSetBitValue(&privateKey->p, k / 2 - 1, 1));
2104  MPI_CHECK(mpiSetBitValue(&privateKey->p, k / 2 - 2, 1));
2105 
2106  //Test whether p is a probable prime
2107  error = mpiCheckProbablePrime(&privateKey->p);
2108 
2109  //Repeat until an acceptable value is found
2110  } while(error == ERROR_INVALID_VALUE);
2111 
2112  //Check status code
2113  MPI_CHECK(error);
2114 
2115  //Compute p mod e
2116  MPI_CHECK(mpiMod(&t1, &privateKey->p, &privateKey->e));
2117 
2118  //Repeat as long as p mod e = 1
2119  } while(mpiCompInt(&t1, 1) == 0);
2120 
2121  //Generate a large random prime q
2122  do
2123  {
2124  do
2125  {
2126  //Generate random number of bit length k - k/2
2127  MPI_CHECK(mpiRand(&privateKey->q, k - (k / 2), prngAlgo, prngContext));
2128  //Set the low bit (this ensures the number is odd)
2129  MPI_CHECK(mpiSetBitValue(&privateKey->q, 0, 1));
2130  //Set the two highest bits (this ensures that the high bit of n is also set)
2131  MPI_CHECK(mpiSetBitValue(&privateKey->q, k - (k / 2) - 1, 1));
2132  MPI_CHECK(mpiSetBitValue(&privateKey->q, k - (k / 2) - 2, 1));
2133 
2134  //Test whether q is a probable prime
2135  error = mpiCheckProbablePrime(&privateKey->q);
2136 
2137  //Repeat until an acceptable value is found
2138  } while(error == ERROR_INVALID_VALUE);
2139 
2140  //Check status code
2141  MPI_CHECK(error);
2142 
2143  //Compute q mod e
2144  MPI_CHECK(mpiMod(&t2, &privateKey->q, &privateKey->e));
2145 
2146  //Repeat as long as p mod e = 1
2147  } while(mpiCompInt(&t2, 1) == 0);
2148 
2149  //Make sure p an q are distinct
2150  if(mpiComp(&privateKey->p, &privateKey->q) == 0)
2151  {
2153  }
2154 
2155  //If p < q, then swap p and q (this only matters if the CRT form of
2156  //the private key is used)
2157  if(mpiComp(&privateKey->p, &privateKey->q) < 0)
2158  {
2159  //Swap primes
2160  mpiCopy(&t1, &privateKey->p);
2161  mpiCopy(&privateKey->p, &privateKey->q);
2162  mpiCopy(&privateKey->q, &t1);
2163  }
2164 
2165  //Compute the modulus n = pq
2166  MPI_CHECK(mpiMul(&privateKey->n, &privateKey->p, &privateKey->q));
2167 
2168  //Compute phy = (p-1)(q-1)
2169  MPI_CHECK(mpiSubInt(&t1, &privateKey->p, 1));
2170  MPI_CHECK(mpiSubInt(&t2, &privateKey->q, 1));
2171  MPI_CHECK(mpiMul(&phy, &t1, &t2));
2172 
2173  //Compute d = e^-1 mod phy
2174  MPI_CHECK(mpiInvMod(&privateKey->d, &privateKey->e, &phy));
2175  //Compute dP = d mod (p-1)
2176  MPI_CHECK(mpiMod(&privateKey->dp, &privateKey->d, &t1));
2177  //Compute dQ = d mod (q-1)
2178  MPI_CHECK(mpiMod(&privateKey->dq, &privateKey->d, &t2));
2179  //Compute qInv = q^-1 mod p
2180  MPI_CHECK(mpiInvMod(&privateKey->qinv, &privateKey->q, &privateKey->p));
2181 
2182  //Debug message
2183  TRACE_DEBUG("RSA private key:\r\n");
2184  TRACE_DEBUG(" Modulus:\r\n");
2185  TRACE_DEBUG_MPI(" ", &privateKey->n);
2186  TRACE_DEBUG(" Public exponent:\r\n");
2187  TRACE_DEBUG_MPI(" ", &privateKey->e);
2188  TRACE_DEBUG(" Private exponent:\r\n");
2189  TRACE_DEBUG_MPI(" ", &privateKey->d);
2190  TRACE_DEBUG(" Prime 1:\r\n");
2191  TRACE_DEBUG_MPI(" ", &privateKey->p);
2192  TRACE_DEBUG(" Prime 2:\r\n");
2193  TRACE_DEBUG_MPI(" ", &privateKey->q);
2194  TRACE_DEBUG(" Prime exponent 1:\r\n");
2195  TRACE_DEBUG_MPI(" ", &privateKey->dp);
2196  TRACE_DEBUG(" Prime exponent 2:\r\n");
2197  TRACE_DEBUG_MPI(" ", &privateKey->dq);
2198  TRACE_DEBUG(" Coefficient:\r\n");
2199  TRACE_DEBUG_MPI(" ", &privateKey->qinv);
2200 
2201 end:
2202  //Release multiple precision integers
2203  mpiFree(&t1);
2204  mpiFree(&t2);
2205  mpiFree(&phy);
2206 
2207  //Any error to report?
2208  if(error)
2209  {
2210  //Release RSA private key
2211  rsaFreePrivateKey(privateKey);
2212  }
2213 
2214  //Return status code
2215  return error;
2216 }
2217 
2218 
2219 /**
2220  * @brief Derive the public key from an RSA private key
2221  * @param[in] privateKey RSA private key
2222  * @param[out] publicKey RSA public key
2223  * @return Error code
2224  **/
2225 
2227  RsaPublicKey *publicKey)
2228 {
2229  error_t error;
2230 
2231  //Check parameters
2232  if(privateKey == NULL || publicKey == NULL)
2233  return ERROR_INVALID_PARAMETER;
2234 
2235  //The public key is (n, e)
2236  MPI_CHECK(mpiCopy(&publicKey->n, &privateKey->n));
2237  MPI_CHECK(mpiCopy(&publicKey->e, &privateKey->e));
2238 
2239  //Debug message
2240  TRACE_DEBUG("RSA public key:\r\n");
2241  TRACE_DEBUG(" Modulus:\r\n");
2242  TRACE_DEBUG_MPI(" ", &publicKey->n);
2243  TRACE_DEBUG(" Public exponent:\r\n");
2244  TRACE_DEBUG_MPI(" ", &publicKey->e);
2245 
2246 end:
2247  //Any error to report?
2248  if(error)
2249  {
2250  //Release RSA public key
2251  rsaFreePublicKey(publicKey);
2252  }
2253 
2254  //Return status code
2255  return error;
2256 }
2257 
2258 #endif
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:74
@ ASN1_TYPE_NULL
Definition: asn1.h:73
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:72
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
#define ASN1_ENCODING_CONSTRUCTED
Definition: asn1.h:48
uint8_t message[]
Definition: chap.h:154
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
General definitions for cryptographic algorithms.
#define CRYPTO_TEST_EQ_32(a, b)
Definition: crypto.h:884
#define CRYPTO_SELECT_32(a, b, c)
Definition: crypto.h:908
#define CRYPTO_TEST_Z_8(a)
Definition: crypto.h:804
#define CRYPTO_TEST_NEQ_8(a, b)
Definition: crypto.h:816
#define CRYPTO_TEST_NZ_8(a)
Definition: crypto.h:808
#define cryptoAllocMem(size)
Definition: crypto.h:765
#define CRYPTO_TEST_Z_32(a)
Definition: crypto.h:876
#define CRYPTO_TEST_LT_32(a, b)
Definition: crypto.h:892
#define CRYPTO_SELECT_8(a, b, c)
Definition: crypto.h:836
#define cryptoFreeMem(p)
Definition: crypto.h:770
#define PrngAlgo
Definition: crypto.h:917
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:110
uint8_t n
uint32_t t1
uint32_t t2
error_t
Error codes.
Definition: error.h:43
@ ERROR_DECRYPTION_FAILED
Definition: error.h:241
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_OUT_OF_RANGE
Definition: error.h:137
@ ERROR_INVALID_VALUE
Definition: error.h:116
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ ERROR_INCONSISTENT_VALUE
Definition: error.h:124
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
uint8_t data[]
Definition: ethernet.h:222
#define MAX_HASH_DIGEST_SIZE
HMAC (Keyed-Hashing for Message Authentication)
uint8_t t
Definition: lldp_ext_med.h:212
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:168
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
error_t mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:447
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:864
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:382
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:338
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
error_t mpiSetBitValue(Mpi *r, uint_t index, uint_t value)
Set the bit value at the specified index.
Definition: mpi.c:275
error_t mpiSubInt(Mpi *r, const Mpi *a, int_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:913
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:515
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:787
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
MPI (Multiple Precision Integer Arithmetic)
#define MPI_CHECK(f)
Definition: mpi.h:52
uint8_t b
Definition: nbns_common.h:104
uint8_t h
Definition: ndp.h:302
uint8_t c
Definition: ndp.h:514
uint8_t s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
uint8_t a
Definition: ndp.h:411
OID (Object Identifier)
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
#define osStrlen(s)
Definition: os_port.h:165
#define TRUE
Definition: os_port.h:50
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
error_t mpiCheckProbablePrime(const Mpi *a)
Test whether a number is probable prime.
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t MGF1_OID[9]
Definition: rsa.c:91
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9]
Definition: rsa.c:83
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:153
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.c:1343
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:179
__weak_func error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
Definition: rsa.c:1232
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:277
const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:76
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:959
__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:2065
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:1079
error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
RSA signature primitive.
Definition: rsa.c:1302
const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:70
const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:68
uint32_t emePkcs1v15Decode(uint8_t *em, size_t k, size_t *messageLen)
EME-PKCS1-v1_5 decoding operation.
Definition: rsa.c:1411
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9]
Definition: rsa.c:79
const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:60
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:2035
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.c:1555
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.c:1465
void rsaFreePublicKey(RsaPublicKey *key)
Release an RSA public key.
Definition: rsa.c:118
const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:64
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.c:1883
const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:74
error_t emsaPkcs1v15Encode(const HashAlgo *hash, const uint8_t *digest, uint8_t *em, size_t emLen)
EMSA-PKCS1-v1_5 encoding operation.
Definition: rsa.c:1653
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9]
Definition: rsa.c:85
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:438
void mgf1(const HashAlgo *hash, HashContext *hashContext, const uint8_t *seed, size_t seedLen, uint8_t *data, size_t dataLen)
MGF1 mask generation function.
Definition: rsa.c:1988
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:544
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:705
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9]
Definition: rsa.c:81
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:66
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:838
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize an RSA private key.
Definition: rsa.c:131
const uint8_t PKCS1_OID[8]
Definition: rsa.c:55
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.c:1717
const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:72
error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
RSA verification primitive.
Definition: rsa.c:1323
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.c:1793
const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:62
void rsaInitPublicKey(RsaPublicKey *key)
Initialize an RSA public key.
Definition: rsa.c:105
error_t rsaGeneratePublicKey(const RsaPrivateKey *privateKey, RsaPublicKey *publicKey)
Derive the public key from an RSA private key.
Definition: rsa.c:2226
__weak_func error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
Definition: rsa.c:1205
RSA public-key cryptography standard.
#define RSA_MAX_MODULUS_SIZE
Definition: rsa.h:41
uint32_t dataLen
Definition: sftp_common.h:229
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoFinal final
Definition: crypto.h:1026
size_t contextSize
Definition: crypto.h:1018
HashAlgoUpdate update
Definition: crypto.h:1025
size_t oidSize
Definition: crypto.h:1017
size_t digestSize
Definition: crypto.h:1020
HashAlgoInit init
Definition: crypto.h:1024
const uint8_t * oid
Definition: crypto.h:1016
Arbitrary precision integer.
Definition: mpi.h:80
uint_t size
Definition: mpi.h:82
RSA private key.
Definition: rsa.h:68
Mpi p
First factor.
Definition: rsa.h:72
int_t slot
Private key slot.
Definition: rsa.h:77
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Mpi e
Public exponent.
Definition: rsa.h:70
Mpi q
Second factor.
Definition: rsa.h:73
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi n
Modulus.
Definition: rsa.h:69
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
Generic hash algorithm context.
uint8_t digest[MAX_HASH_DIGEST_SIZE]
uint8_t mask
Definition: web_socket.h:319