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  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @section Description
26  *
27  * RSA is an algorithm for public-key cryptography which is suitable for signing
28  * as well as encryption. Refer to the following RFCs for complete details:
29  * - RFC 2313: PKCS #1: RSA Encryption Version 1.5
30  * - RFC 3447: PKCS #1: RSA Cryptography Specifications Version 2.1
31  * - RFC 8017: PKCS #1: RSA Cryptography Specifications Version 2.2
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 1.9.0
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
39 
40 //Dependencies
41 #include "core/crypto.h"
42 #include "mac/hmac.h"
43 #include "pkc/rsa.h"
44 #include "mpi/mpi.h"
45 #include "encoding/asn1.h"
46 #include "encoding/oid.h"
47 #include "debug.h"
48 
49 //Check crypto library configuration
50 #if (RSA_SUPPORT == ENABLED)
51 
52 //PKCS #1 OID (1.2.840.113549.1.1)
53 const uint8_t PKCS1_OID[8] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01};
54 //RSA encryption OID (1.2.840.113549.1.1.1)
55 const uint8_t RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01};
56 
57 //MD2 with RSA encryption OID (1.2.840.113549.1.1.2)
58 const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02};
59 //MD5 with RSA encryption OID (1.2.840.113549.1.1.4)
60 const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04};
61 //SHA-1 with RSA encryption OID (1.2.840.113549.1.1.5)
62 const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05};
63 //SHA-224 with RSA encryption OID (1.2.840.113549.1.1.14)
64 const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E};
65 //SHA-256 with RSA encryption OID (1.2.840.113549.1.1.11)
66 const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B};
67 //SHA-384 with RSA encryption OID (1.2.840.113549.1.1.12)
68 const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C};
69 //SHA-512 with RSA encryption OID (1.2.840.113549.1.1.13)
70 const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D};
71 //SHA-512/224 with RSA encryption OID (1.2.840.113549.1.1.15)
72 const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0F};
73 //SHA-512/256 with RSA encryption OID (1.2.840.113549.1.1.16)
74 const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x10};
75 
76 //RSASSA-PKCS1-v1_5 signature with SHA-3-224 OID (2.16.840.1.101.3.4.3.13)
77 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0D};
78 //RSASSA-PKCS1-v1_5 signature with SHA-3-256 OID (2.16.840.1.101.3.4.3.14)
79 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0E};
80 //RSASSA-PKCS1-v1_5 signature with SHA-3-384 OID (2.16.840.1.101.3.4.3.15)
81 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0F};
82 //RSASSA-PKCS1-v1_5 signature with SHA-3-512 OID (2.16.840.1.101.3.4.3.16)
83 const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x10};
84 
85 //RSASSA-PSS OID (1.2.840.113549.1.1.10)
86 const uint8_t RSASSA_PSS_OID[9] = {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A};
87 
88 //Padding string
89 static const uint8_t padding[] =
90 {
91  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
92 };
93 
94 
95 /**
96  * @brief Initialize a 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 a 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 a 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 
139 
140 /**
141  * @brief Release a RSA private key
142  * @param[in] key Pointer to the RSA private key to free
143  **/
144 
146 {
147  //Free multiple precision integers
148  mpiFree(&key->n);
149  mpiFree(&key->e);
150  mpiFree(&key->d);
151  mpiFree(&key->p);
152  mpiFree(&key->q);
153  mpiFree(&key->dp);
154  mpiFree(&key->dq);
155  mpiFree(&key->qinv);
156 }
157 
158 
159 /**
160  * @brief RSAES-PKCS1-v1_5 encryption operation
161  * @param[in] prngAlgo PRNG algorithm
162  * @param[in] prngContext Pointer to the PRNG context
163  * @param[in] key Recipient's RSA public key
164  * @param[in] message Message to be encrypted
165  * @param[in] messageLen Length of the message to be encrypted
166  * @param[out] ciphertext Ciphertext resulting from the encryption operation
167  * @param[out] ciphertextLen Length of the resulting ciphertext
168  * @return Error code
169  **/
170 
171 error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext,
172  const RsaPublicKey *key, const uint8_t *message, size_t messageLen,
173  uint8_t *ciphertext, size_t *ciphertextLen)
174 {
175  error_t error;
176  uint_t k;
177  uint8_t *em;
178  Mpi m;
179  Mpi c;
180 
181  //Check parameters
182  if(prngAlgo == NULL || prngContext == NULL)
184  if(key == NULL || message == NULL)
186  if(ciphertext == NULL || ciphertextLen == NULL)
188 
189  //Debug message
190  TRACE_DEBUG("RSAES-PKCS1-v1_5 encryption...\r\n");
191  TRACE_DEBUG(" Modulus:\r\n");
192  TRACE_DEBUG_MPI(" ", &key->n);
193  TRACE_DEBUG(" Public exponent:\r\n");
194  TRACE_DEBUG_MPI(" ", &key->e);
195  TRACE_DEBUG(" Message:\r\n");
196  TRACE_DEBUG_ARRAY(" ", message, messageLen);
197 
198  //Initialize multiple-precision integers
199  mpiInit(&m);
200  mpiInit(&c);
201 
202  //Get the length in octets of the modulus n
203  k = mpiGetByteLength(&key->n);
204 
205  //Point to the buffer where the encoded message EM will be formatted
206  em = ciphertext;
207 
208  //EME-PKCS1-v1_5 encoding
209  error = emePkcs1v15Encode(prngAlgo, prngContext, message, messageLen, em, k);
210  //Any error to report?
211  if(error)
212  return error;
213 
214  //Debug message
215  TRACE_DEBUG(" Encoded message:\r\n");
216  TRACE_DEBUG_ARRAY(" ", em, k);
217 
218  //Start of exception handling block
219  do
220  {
221  //Convert the encoded message EM to an integer message representative m
222  error = mpiReadRaw(&m, em, k);
223  //Conversion failed?
224  if(error)
225  break;
226 
227  //Apply the RSAEP encryption primitive
228  error = rsaep(key, &m, &c);
229  //Any error to report?
230  if(error)
231  break;
232 
233  //Convert the ciphertext representative c to a ciphertext of length k octets
234  error = mpiWriteRaw(&c, ciphertext, k);
235  //Conversion failed?
236  if(error)
237  break;
238 
239  //Length of the resulting ciphertext
240  *ciphertextLen = k;
241 
242  //Debug message
243  TRACE_DEBUG(" Ciphertext:\r\n");
244  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
245 
246  //End of exception handling block
247  } while(0);
248 
249  //Free previously allocated memory
250  mpiFree(&m);
251  mpiFree(&c);
252 
253  //Return status code
254  return error;
255 }
256 
257 
258 /**
259  * @brief RSAES-PKCS1-v1_5 decryption operation
260  * @param[in] key Recipient's RSA private key
261  * @param[in] ciphertext Ciphertext to be decrypted
262  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
263  * @param[out] message Output buffer where to store the decrypted message
264  * @param[in] messageSize Size of the output buffer
265  * @param[out] messageLen Length of the decrypted message
266  * @return Error code
267  **/
268 
269 error_t rsaesPkcs1v15Decrypt(const RsaPrivateKey *key, const uint8_t *ciphertext,
270  size_t ciphertextLen, uint8_t *message, size_t messageSize, size_t *messageLen)
271 {
272  error_t error;
273  uint_t k;
274  size_t n;
275  uint8_t *p;
276  uint8_t *em;
277  Mpi c;
278  Mpi m;
279 
280  //Check parameters
281  if(key == NULL || ciphertext == NULL)
283  if(message == NULL || messageLen == NULL)
285 
286  //Debug message
287  TRACE_DEBUG("RSAES-PKCS1-v1_5 decryption...\r\n");
288  TRACE_DEBUG(" Modulus:\r\n");
289  TRACE_DEBUG_MPI(" ", &key->n);
290  TRACE_DEBUG(" Public exponent:\r\n");
291  TRACE_DEBUG_MPI(" ", &key->e);
292  TRACE_DEBUG(" Private exponent:\r\n");
293  TRACE_DEBUG_MPI(" ", &key->d);
294  TRACE_DEBUG(" Prime 1:\r\n");
295  TRACE_DEBUG_MPI(" ", &key->p);
296  TRACE_DEBUG(" Prime 2:\r\n");
297  TRACE_DEBUG_MPI(" ", &key->q);
298  TRACE_DEBUG(" Prime exponent 1:\r\n");
299  TRACE_DEBUG_MPI(" ", &key->dp);
300  TRACE_DEBUG(" Prime exponent 2:\r\n");
301  TRACE_DEBUG_MPI(" ", &key->dq);
302  TRACE_DEBUG(" Coefficient:\r\n");
303  TRACE_DEBUG_MPI(" ", &key->qinv);
304  TRACE_DEBUG(" Ciphertext:\r\n");
305  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
306 
307  //Initialize multiple-precision integers
308  mpiInit(&c);
309  mpiInit(&m);
310 
311  //Get the length in octets of the modulus n
312  k = mpiGetByteLength(&key->n);
313 
314  //Check the length of the ciphertext
315  if(ciphertextLen != k || ciphertextLen < 11)
316  return ERROR_INVALID_LENGTH;
317 
318  //Allocate a buffer to store the encoded message EM
319  em = cryptoAllocMem(k);
320  //Failed to allocate memory?
321  if(em == NULL)
322  return ERROR_OUT_OF_MEMORY;
323 
324  //Start of exception handling block
325  do
326  {
327  //Convert the ciphertext to an integer ciphertext representative c
328  error = mpiReadRaw(&c, ciphertext, ciphertextLen);
329  //Conversion failed?
330  if(error)
331  break;
332 
333  //Apply the RSADP decryption primitive
334  error = rsadp(key, &c, &m);
335  //Any error to report?
336  if(error)
337  break;
338 
339  //Convert the message representative m to an encoded message EM of
340  //length k octets
341  error = mpiWriteRaw(&m, em, k);
342  //Conversion failed?
343  if(error)
344  break;
345 
346  //Debug message
347  TRACE_DEBUG(" Encoded message:\r\n");
348  TRACE_DEBUG_ARRAY(" ", em, k);
349 
350  //EME-PKCS1-v1_5 decoding
351  error = emePkcs1v15Decode(em, k, &p, &n);
352  //Any error to report?
353  if(error)
354  break;
355 
356  //Ensure that the output buffer is large enough
357  if(messageSize < n)
358  {
359  //Report an error
360  error = ERROR_INVALID_LENGTH;
361  break;
362  }
363 
364  //Recover the length of the message
365  *messageLen = n;
366  //Copy the message contents
367  cryptoMemcpy(message, p, n);
368 
369  //Debug message
370  TRACE_DEBUG(" Message:\r\n");
371  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
372 
373  //End of exception handling block
374  } while(0);
375 
376  //Release the encoded message
377  cryptoFreeMem(em);
378 
379  //Release multiple precision integers
380  mpiFree(&c);
381  mpiFree(&m);
382 
383  //Return status code
384  return error;
385 }
386 
387 
388 /**
389  * @brief RSAES-OAEP encryption operation
390  * @param[in] prngAlgo PRNG algorithm
391  * @param[in] prngContext Pointer to the PRNG context
392  * @param[in] key Recipient's RSA public key
393  * @param[in] hash Underlying hash function
394  * @param[in] label Optional label to be associated with the message
395  * @param[in] message Message to be encrypted
396  * @param[in] messageLen Length of the message to be encrypted
397  * @param[out] ciphertext Ciphertext resulting from the encryption operation
398  * @param[out] ciphertextLen Length of the resulting ciphertext
399  * @return Error code
400  **/
401 
402 error_t rsaesOaepEncrypt(const PrngAlgo *prngAlgo, void *prngContext,
403  const RsaPublicKey *key, const HashAlgo *hash, const char_t *label,
404  const uint8_t *message, size_t messageLen, uint8_t *ciphertext,
405  size_t *ciphertextLen)
406 {
407  error_t error;
408  uint_t k;
409  uint8_t *em;
410  Mpi m;
411  Mpi c;
412 
413  //Check parameters
414  if(prngAlgo == NULL || prngContext == NULL)
416  if(key == NULL || message == NULL)
418  if(ciphertext == NULL || ciphertextLen == NULL)
420 
421  //Debug message
422  TRACE_DEBUG("RSAES-OAEP encryption...\r\n");
423  TRACE_DEBUG(" Modulus:\r\n");
424  TRACE_DEBUG_MPI(" ", &key->n);
425  TRACE_DEBUG(" Public exponent:\r\n");
426  TRACE_DEBUG_MPI(" ", &key->e);
427  TRACE_DEBUG(" Message:\r\n");
428  TRACE_DEBUG_ARRAY(" ", message, messageLen);
429 
430  //Initialize multiple-precision integers
431  mpiInit(&m);
432  mpiInit(&c);
433 
434  //Get the length in octets of the modulus n
435  k = mpiGetByteLength(&key->n);
436 
437  //Make sure the modulus is valid
438  if(k == 0)
440 
441  //Point to the buffer where the encoded message EM will be formatted
442  em = ciphertext;
443 
444  //EME-OAEP encoding
445  error = emeOaepEncode(prngAlgo, prngContext, hash, label, message,
446  messageLen, em, k);
447  //Any error to report?
448  if(error)
449  return error;
450 
451  //Debug message
452  TRACE_DEBUG(" Encoded message:\r\n");
453  TRACE_DEBUG_ARRAY(" ", em, k);
454 
455  //Start of exception handling block
456  do
457  {
458  //Convert the encoded message EM to an integer message representative m
459  error = mpiReadRaw(&m, em, k);
460  //Conversion failed?
461  if(error)
462  break;
463 
464  //Apply the RSAEP encryption primitive
465  error = rsaep(key, &m, &c);
466  //Any error to report?
467  if(error)
468  break;
469 
470  //Convert the ciphertext representative c to a ciphertext of length k octets
471  error = mpiWriteRaw(&c, ciphertext, k);
472  //Conversion failed?
473  if(error)
474  break;
475 
476  //Length of the resulting ciphertext
477  *ciphertextLen = k;
478 
479  //Debug message
480  TRACE_DEBUG(" Ciphertext:\r\n");
481  TRACE_DEBUG_ARRAY(" ", ciphertext, *ciphertextLen);
482 
483  //End of exception handling block
484  } while(0);
485 
486  //Free previously allocated memory
487  mpiFree(&m);
488  mpiFree(&c);
489 
490  //Return status code
491  return error;
492 }
493 
494 
495 /**
496  * @brief RSAES-OAEP decryption operation
497  * @param[in] key Recipient's RSA private key
498  * @param[in] hash Underlying hash function
499  * @param[in] label Optional label to be associated with the message
500  * @param[in] ciphertext Ciphertext to be decrypted
501  * @param[in] ciphertextLen Length of the ciphertext to be decrypted
502  * @param[out] message Output buffer where to store the decrypted message
503  * @param[in] messageSize Size of the output buffer
504  * @param[out] messageLen Length of the decrypted message
505  * @return Error code
506  **/
507 
509  const char_t *label, const uint8_t *ciphertext, size_t ciphertextLen,
510  uint8_t *message, size_t messageSize, size_t *messageLen)
511 {
512  error_t error;
513  uint_t k;
514  size_t n;
515  uint8_t *p;
516  uint8_t *em;
517  Mpi c;
518  Mpi m;
519 
520  //Check parameters
521  if(key == NULL || ciphertext == NULL)
523  if(message == NULL || messageLen == NULL)
525 
526  //Debug message
527  TRACE_DEBUG("RSAES-OAEP decryption...\r\n");
528  TRACE_DEBUG(" Modulus:\r\n");
529  TRACE_DEBUG_MPI(" ", &key->n);
530  TRACE_DEBUG(" Public exponent:\r\n");
531  TRACE_DEBUG_MPI(" ", &key->e);
532  TRACE_DEBUG(" Private exponent:\r\n");
533  TRACE_DEBUG_MPI(" ", &key->d);
534  TRACE_DEBUG(" Prime 1:\r\n");
535  TRACE_DEBUG_MPI(" ", &key->p);
536  TRACE_DEBUG(" Prime 2:\r\n");
537  TRACE_DEBUG_MPI(" ", &key->q);
538  TRACE_DEBUG(" Prime exponent 1:\r\n");
539  TRACE_DEBUG_MPI(" ", &key->dp);
540  TRACE_DEBUG(" Prime exponent 2:\r\n");
541  TRACE_DEBUG_MPI(" ", &key->dq);
542  TRACE_DEBUG(" Coefficient:\r\n");
543  TRACE_DEBUG_MPI(" ", &key->qinv);
544  TRACE_DEBUG(" Ciphertext:\r\n");
545  TRACE_DEBUG_ARRAY(" ", ciphertext, ciphertextLen);
546 
547  //Initialize multiple-precision integers
548  mpiInit(&c);
549  mpiInit(&m);
550 
551  //Get the length in octets of the modulus n
552  k = mpiGetByteLength(&key->n);
553 
554  //Check the length of the modulus
555  if(k < (2 * hash->digestSize + 2))
557 
558  //Check the length of the ciphertext
559  if(ciphertextLen != k)
560  return ERROR_INVALID_LENGTH;
561 
562  //Allocate a buffer to store the encoded message EM
563  em = cryptoAllocMem(k);
564  //Failed to allocate memory?
565  if(em == NULL)
566  return ERROR_OUT_OF_MEMORY;
567 
568  //Start of exception handling block
569  do
570  {
571  //Convert the ciphertext to an integer ciphertext representative c
572  error = mpiReadRaw(&c, ciphertext, ciphertextLen);
573  //Conversion failed?
574  if(error)
575  break;
576 
577  //Apply the RSADP decryption primitive
578  error = rsadp(key, &c, &m);
579  //Any error to report?
580  if(error)
581  break;
582 
583  //Convert the message representative m to an encoded message EM of
584  //length k octets
585  error = mpiWriteRaw(&m, em, k);
586  //Conversion failed?
587  if(error)
588  break;
589 
590  //Debug message
591  TRACE_DEBUG(" Encoded message:\r\n");
592  TRACE_DEBUG_ARRAY(" ", em, k);
593 
594  //EME-OAEP decoding
595  error = emeOaepDecode(hash, label, em, k, &p, &n);
596  //Any error to report?
597  if(error)
598  break;
599 
600  //Ensure that the output buffer is large enough
601  if(messageSize < n)
602  {
603  //Report an error
604  error = ERROR_INVALID_LENGTH;
605  break;
606  }
607 
608  //Recover the length of the message
609  *messageLen = n;
610  //Copy the message contents
611  cryptoMemcpy(message, p, n);
612 
613  //Debug message
614  TRACE_DEBUG(" Message:\r\n");
615  TRACE_DEBUG_ARRAY(" ", message, *messageLen);
616 
617  //End of exception handling block
618  } while(0);
619 
620  //Release the encoded message
621  cryptoFreeMem(em);
622 
623  //Release multiple precision integers
624  mpiFree(&c);
625  mpiFree(&m);
626 
627  //Return status code
628  return error;
629 }
630 
631 
632 /**
633  * @brief RSASSA-PKCS1-v1_5 signature generation operation
634  * @param[in] key Signer's RSA private key
635  * @param[in] hash Hash function used to digest the message
636  * @param[in] digest Digest of the message to be signed
637  * @param[out] signature Resulting signature
638  * @param[out] signatureLen Length of the resulting signature
639  * @return Error code
640  **/
641 
643  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
644 {
645  error_t error;
646  uint_t k;
647  uint8_t *em;
648  Mpi m;
649  Mpi s;
650  Mpi t;
651 
652  //Check parameters
653  if(key == NULL || hash == NULL || digest == NULL)
655  if(signature == NULL || signatureLen == NULL)
657 
658  //Debug message
659  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature generation...\r\n");
660  TRACE_DEBUG(" Modulus:\r\n");
661  TRACE_DEBUG_MPI(" ", &key->n);
662  TRACE_DEBUG(" Public exponent:\r\n");
663  TRACE_DEBUG_MPI(" ", &key->e);
664  TRACE_DEBUG(" Private exponent:\r\n");
665  TRACE_DEBUG_MPI(" ", &key->d);
666  TRACE_DEBUG(" Prime 1:\r\n");
667  TRACE_DEBUG_MPI(" ", &key->p);
668  TRACE_DEBUG(" Prime 2:\r\n");
669  TRACE_DEBUG_MPI(" ", &key->q);
670  TRACE_DEBUG(" Prime exponent 1:\r\n");
671  TRACE_DEBUG_MPI(" ", &key->dp);
672  TRACE_DEBUG(" Prime exponent 2:\r\n");
673  TRACE_DEBUG_MPI(" ", &key->dq);
674  TRACE_DEBUG(" Coefficient:\r\n");
675  TRACE_DEBUG_MPI(" ", &key->qinv);
676  TRACE_DEBUG(" Message digest:\r\n");
677  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
678 
679  //Initialize multiple-precision integers
680  mpiInit(&m);
681  mpiInit(&s);
682  mpiInit(&t);
683 
684  //Get the length in octets of the modulus n
685  k = mpiGetByteLength(&key->n);
686  //Point to the buffer where the encoded message EM will be formatted
687  em = signature;
688 
689  //Apply the EMSA-PKCS1-v1.5 encoding operation
690  error = emsaPkcs1v15Encode(hash, digest, em, k);
691  //Any error to report?
692  if(error)
693  return error;
694 
695  //Debug message
696  TRACE_DEBUG(" Encoded message:\r\n");
697  TRACE_DEBUG_ARRAY(" ", em, k);
698 
699  //Start of exception handling block
700  do
701  {
702  //Convert the encoded message EM to an integer message representative m
703  error = mpiReadRaw(&m, em, k);
704  //Conversion failed?
705  if(error)
706  break;
707 
708  //Apply the RSASP1 signature primitive
709  error = rsasp1(key, &m, &s);
710  //Any error to report?
711  if(error)
712  break;
713 
714  //When unprotected, RSA–CRT is vulnerable to the Bellcore attack
715  if(key->n.size && key->e.size && key->p.size && key->q.size &&
716  key->dp.size && key->dq.size && key->qinv.size)
717  {
718  RsaPublicKey publicKey;
719 
720  //Retrieve modulus and public exponent
721  publicKey.n = key->n;
722  publicKey.e = key->e;
723 
724  //Apply the RSAVP1 verification primitive
725  error = rsavp1(&publicKey, &s, &t);
726  //Any error to report?
727  if(error)
728  break;
729 
730  //Verify the RSA signature in order to protect against RSA-CRT key leak
731  if(mpiComp(&t, &m) != 0)
732  {
733  //A signature fault has been detected
734  error = ERROR_FAILURE;
735  break;
736  }
737  }
738 
739  //Convert the signature representative s to a signature of length k octets
740  error = mpiWriteRaw(&s, signature, k);
741  //Conversion failed?
742  if(error)
743  break;
744 
745  //Length of the resulting signature
746  *signatureLen = k;
747 
748  //Debug message
749  TRACE_DEBUG(" Signature:\r\n");
750  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
751 
752  //End of exception handling block
753  } while(0);
754 
755  //Free previously allocated memory
756  mpiFree(&m);
757  mpiFree(&s);
758  mpiFree(&t);
759 
760  //Return status code
761  return error;
762 }
763 
764 
765 /**
766  * @brief RSASSA-PKCS1-v1_5 signature verification operation
767  * @param[in] key Signer's RSA public key
768  * @param[in] hash Hash function used to digest the message
769  * @param[in] digest Digest of the message whose signature is to be verified
770  * @param[in] signature Signature to be verified
771  * @param[in] signatureLen Length of the signature to be verified
772  * @return Error code
773  **/
774 
776  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
777 {
778  error_t error;
779  uint_t k;
780  uint8_t *em;
781  Mpi s;
782  Mpi m;
783 
784  //Check parameters
785  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
787 
788  //Debug message
789  TRACE_DEBUG("RSASSA-PKCS1-v1_5 signature verification...\r\n");
790  TRACE_DEBUG(" Modulus:\r\n");
791  TRACE_DEBUG_MPI(" ", &key->n);
792  TRACE_DEBUG(" Public exponent:\r\n");
793  TRACE_DEBUG_MPI(" ", &key->e);
794  TRACE_DEBUG(" Message digest:\r\n");
795  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
796  TRACE_DEBUG(" Signature:\r\n");
797  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
798 
799  //Initialize multiple-precision integers
800  mpiInit(&s);
801  mpiInit(&m);
802 
803  //Get the length in octets of the modulus n
804  k = mpiGetByteLength(&key->n);
805 
806  //Make sure the modulus is valid
807  if(k == 0)
809 
810  //Check the length of the signature
811  if(signatureLen != k)
813 
814  //Allocate a memory buffer to hold the encoded message
815  em = cryptoAllocMem(k);
816  //Failed to allocate memory?
817  if(em == NULL)
818  return ERROR_OUT_OF_MEMORY;
819 
820  //Start of exception handling block
821  do
822  {
823  //Convert the signature to an integer signature representative s
824  error = mpiReadRaw(&s, signature, signatureLen);
825  //Conversion failed?
826  if(error)
827  break;
828 
829  //Apply the RSAVP1 verification primitive
830  error = rsavp1(key, &s, &m);
831  //Any error to report?
832  if(error)
833  break;
834 
835  //Convert the message representative m to an encoded message EM of
836  //length k octets
837  error = mpiWriteRaw(&m, em, k);
838  //Conversion failed?
839  if(error)
840  break;
841 
842  //Debug message
843  TRACE_DEBUG(" Encoded message:\r\n");
844  TRACE_DEBUG_ARRAY(" ", em, k);
845 
846  //Verify the encoded message EM
847  error = emsaPkcs1v15Verify(hash, digest, em, k);
848  //Any error to report?
849  if(error)
850  {
851  //The signature is not valid
852  error = ERROR_INVALID_SIGNATURE;
853  break;
854  }
855 
856  //End of exception handling block
857  } while(0);
858 
859  //Release the encoded message
860  cryptoFreeMem(em);
861 
862  //Release multiple precision integers
863  mpiFree(&s);
864  mpiFree(&m);
865 
866  //Return status code
867  return error;
868 }
869 
870 
871 /**
872  * @brief RSASSA-PSS signature generation operation
873  * @param[in] prngAlgo PRNG algorithm
874  * @param[in] prngContext Pointer to the PRNG context
875  * @param[in] key Signer's RSA private key
876  * @param[in] hash Hash function used to digest the message
877  * @param[in] saltLen Length of the salt, in bytes
878  * @param[in] digest Digest of the message to be signed
879  * @param[out] signature Resulting signature
880  * @param[out] signatureLen Length of the resulting signature
881  * @return Error code
882  **/
883 
884 error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext,
885  const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen,
886  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
887 {
888  error_t error;
889  uint_t k;
890  uint_t modBits;
891  uint8_t *em;
892  Mpi m;
893  Mpi s;
894 
895  //Check parameters
896  if(prngAlgo == NULL || prngContext == NULL)
898  if(key == NULL || hash == NULL || digest == NULL)
900  if(signature == NULL || signatureLen == NULL)
902 
903  //Debug message
904  TRACE_DEBUG("RSASSA-PSS signature generation...\r\n");
905  TRACE_DEBUG(" Modulus:\r\n");
906  TRACE_DEBUG_MPI(" ", &key->n);
907  TRACE_DEBUG(" Public exponent:\r\n");
908  TRACE_DEBUG_MPI(" ", &key->e);
909  TRACE_DEBUG(" Private exponent:\r\n");
910  TRACE_DEBUG_MPI(" ", &key->d);
911  TRACE_DEBUG(" Prime 1:\r\n");
912  TRACE_DEBUG_MPI(" ", &key->p);
913  TRACE_DEBUG(" Prime 2:\r\n");
914  TRACE_DEBUG_MPI(" ", &key->q);
915  TRACE_DEBUG(" Prime exponent 1:\r\n");
916  TRACE_DEBUG_MPI(" ", &key->dp);
917  TRACE_DEBUG(" Prime exponent 2:\r\n");
918  TRACE_DEBUG_MPI(" ", &key->dq);
919  TRACE_DEBUG(" Coefficient:\r\n");
920  TRACE_DEBUG_MPI(" ", &key->qinv);
921  TRACE_DEBUG(" Message digest:\r\n");
922  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
923 
924  //Initialize multiple-precision integers
925  mpiInit(&m);
926  mpiInit(&s);
927 
928  //modBits is the length in bits of the modulus n
929  modBits = mpiGetBitLength(&key->n);
930 
931  //Make sure the modulus is valid
932  if(modBits == 0)
934 
935  //Calculate the length in octets of the modulus n
936  k = (modBits + 7) / 8;
937 
938  //Point to the buffer where the encoded message EM will be formatted
939  em = signature;
940 
941  //Apply the EMSA-PSS encoding operation to the message M to produce an
942  //encoded message EM of length ceil((modBits - 1) / 8) octets
943  error = emsaPssEncode(prngAlgo, prngContext, hash, saltLen, digest,
944  em, modBits - 1);
945  //Any error to report?
946  if(error)
947  return error;
948 
949  //Debug message
950  TRACE_DEBUG(" Encoded message:\r\n");
951  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
952 
953  //Start of exception handling block
954  do
955  {
956  //Convert the encoded message EM to an integer message representative m
957  error = mpiReadRaw(&m, em, (modBits + 6) / 8);
958  //Conversion failed?
959  if(error)
960  break;
961 
962  //Apply the RSASP1 signature primitive
963  error = rsasp1(key, &m, &s);
964  //Any error to report?
965  if(error)
966  break;
967 
968  //Convert the signature representative s to a signature of length k octets
969  error = mpiWriteRaw(&s, signature, k);
970  //Conversion failed?
971  if(error)
972  break;
973 
974  //Length of the resulting signature
975  *signatureLen = k;
976 
977  //Debug message
978  TRACE_DEBUG(" Signature:\r\n");
979  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
980 
981  //End of exception handling block
982  } while(0);
983 
984  //Free previously allocated memory
985  mpiFree(&m);
986  mpiFree(&s);
987 
988  //Return status code
989  return error;
990 }
991 
992 
993 /**
994  * @brief RSASSA-PSS signature verification operation
995  * @param[in] key Signer's RSA public key
996  * @param[in] hash Hash function used to digest the message
997  * @param[in] saltLen Length of the salt, in bytes
998  * @param[in] digest Digest of the message whose signature is to be verified
999  * @param[in] signature Signature to be verified
1000  * @param[in] signatureLen Length of the signature to be verified
1001  * @return Error code
1002  **/
1003 
1005  size_t saltLen, const uint8_t *digest, const uint8_t *signature,
1006  size_t signatureLen)
1007 {
1008  error_t error;
1009  uint_t k;
1010  uint_t modBits;
1011  uint8_t *em;
1012  Mpi s;
1013  Mpi m;
1014 
1015  //Check parameters
1016  if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
1017  return ERROR_INVALID_PARAMETER;
1018 
1019  //Debug message
1020  TRACE_DEBUG("RSASSA-PSS signature verification...\r\n");
1021  TRACE_DEBUG(" Modulus:\r\n");
1022  TRACE_DEBUG_MPI(" ", &key->n);
1023  TRACE_DEBUG(" Public exponent:\r\n");
1024  TRACE_DEBUG_MPI(" ", &key->e);
1025  TRACE_DEBUG(" Message digest:\r\n");
1026  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
1027  TRACE_DEBUG(" Signature:\r\n");
1028  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1029 
1030  //Initialize multiple-precision integers
1031  mpiInit(&s);
1032  mpiInit(&m);
1033 
1034  //modBits is the length in bits of the modulus n
1035  modBits = mpiGetBitLength(&key->n);
1036 
1037  //Make sure the modulus is valid
1038  if(modBits == 0)
1039  return ERROR_INVALID_PARAMETER;
1040 
1041  //Calculate the length in octets of the modulus n
1042  k = (modBits + 7) / 8;
1043 
1044  //Check the length of the signature
1045  if(signatureLen != k)
1046  return ERROR_INVALID_SIGNATURE;
1047 
1048  //Allocate a memory buffer to hold the encoded message
1049  em = cryptoAllocMem(k);
1050  //Failed to allocate memory?
1051  if(em == NULL)
1052  return ERROR_OUT_OF_MEMORY;
1053 
1054  //Start of exception handling block
1055  do
1056  {
1057  //Convert the signature to an integer signature representative s
1058  error = mpiReadRaw(&s, signature, signatureLen);
1059  //Conversion failed?
1060  if(error)
1061  break;
1062 
1063  //Apply the RSAVP1 verification primitive
1064  error = rsavp1(key, &s, &m);
1065  //Any error to report?
1066  if(error)
1067  break;
1068 
1069  //Convert the message representative m to an encoded message EM of
1070  //length emLen = ceil((modBits - 1) / 8) octets
1071  error = mpiWriteRaw(&m, em, (modBits + 6) / 8);
1072  //Conversion failed?
1073  if(error)
1074  break;
1075 
1076  //Debug message
1077  TRACE_DEBUG(" Encoded message:\r\n");
1078  TRACE_DEBUG_ARRAY(" ", em, (modBits + 6) / 8);
1079 
1080  //Apply the EMSA-PSS verification operation to the message M and the
1081  //encoded message EM to determine whether they are consistent
1082  error = emsaPssVerify(hash, saltLen, digest, em, modBits - 1);
1083  //Any error to report?
1084  if(error)
1085  {
1086  //The signature is not valid
1087  error = ERROR_INVALID_SIGNATURE;
1088  break;
1089  }
1090 
1091  //End of exception handling block
1092  } while(0);
1093 
1094  //Release the encoded message
1095  cryptoFreeMem(em);
1096 
1097  //Release multiple precision integers
1098  mpiFree(&s);
1099  mpiFree(&m);
1100 
1101  //Return status code
1102  return error;
1103 }
1104 
1105 
1106  /**
1107  * @brief RSA encryption primitive
1108  *
1109  * The RSA encryption primitive produces a ciphertext representative from
1110  * a message representative under the control of a public key
1111  *
1112  * @param[in] key RSA public key
1113  * @param[in] m Message representative
1114  * @param[out] c Ciphertext representative
1115  * @return Error code
1116  **/
1117 
1118 error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
1119 {
1120  //Ensure the RSA public key is valid
1121  if(!key->n.size || !key->e.size)
1122  return ERROR_INVALID_PARAMETER;
1123 
1124  //The message representative m shall be between 0 and n - 1
1125  if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
1126  return ERROR_OUT_OF_RANGE;
1127 
1128  //Perform modular exponentiation (c = m ^ e mod n)
1129  return mpiExpMod(c, m, &key->e, &key->n);
1130 }
1131 
1132 
1133 /**
1134  * @brief RSA decryption primitive
1135  *
1136  * The RSA decryption primitive recovers the message representative from
1137  * the ciphertext representative under the control of a private key
1138  *
1139  * @param[in] key RSA private key
1140  * @param[in] c Ciphertext representative
1141  * @param[out] m Message representative
1142  * @return Error code
1143  **/
1144 
1145 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
1146 {
1147  error_t error;
1148  Mpi m1;
1149  Mpi m2;
1150  Mpi h;
1151 
1152  //The ciphertext representative c shall be between 0 and n - 1
1153  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
1154  return ERROR_OUT_OF_RANGE;
1155 
1156  //Initialize multiple-precision integers
1157  mpiInit(&m1);
1158  mpiInit(&m2);
1159  mpiInit(&h);
1160 
1161  //Use the Chinese remainder algorithm?
1162  if(key->n.size && key->p.size && key->q.size &&
1163  key->dp.size && key->dq.size && key->qinv.size)
1164  {
1165  //Compute m1 = c ^ dP mod p
1166  MPI_CHECK(mpiExpMod(&m1, c, &key->dp, &key->p));
1167  //Compute m2 = c ^ dQ mod q
1168  MPI_CHECK(mpiExpMod(&m2, c, &key->dq, &key->q));
1169  //Let h = (m1 - m2) * qInv mod p
1170  MPI_CHECK(mpiSub(&h, &m1, &m2));
1171  MPI_CHECK(mpiMulMod(&h, &h, &key->qinv, &key->p));
1172  //Let m = m2 + q * h
1173  MPI_CHECK(mpiMul(m, &key->q, &h));
1174  MPI_CHECK(mpiAdd(m, m, &m2));
1175  }
1176  //Use modular exponentiation?
1177  else if(key->n.size && key->d.size)
1178  {
1179  //Let m = c ^ d mod n
1180  error = mpiExpMod(m, c, &key->d, &key->n);
1181  }
1182  //Invalid parameters?
1183  else
1184  {
1185  //Report an error
1186  error = ERROR_INVALID_PARAMETER;
1187  }
1188 
1189 end:
1190  //Free previously allocated memory
1191  mpiFree(&m1);
1192  mpiFree(&m2);
1193  mpiFree(&h);
1194 
1195  //Return status code
1196  return error;
1197 }
1198 
1199 
1200 /**
1201  * @brief RSA signature primitive
1202  *
1203  * The RSA signature primitive produces a signature representative from
1204  * a message representative under the control of a private key
1205  *
1206  * @param[in] key RSA private key
1207  * @param[in] m Message representative
1208  * @param[out] s Signature representative
1209  * @return Error code
1210  **/
1211 
1212 error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
1213 {
1214  //RSASP1 primitive is the same as RSADP except for the names of its input
1215  //and output arguments. They are distinguished as they are intended for
1216  //different purposes
1217  return rsadp(key, m, s);
1218 }
1219 
1220 
1221 /**
1222  * @brief RSA verification primitive
1223  *
1224  * The RSA verification primitive recovers the message representative from
1225  * the signature representative under the control of a public key
1226  *
1227  * @param[in] key RSA public key
1228  * @param[in] s Signature representative
1229  * @param[out] m Message representative
1230  * @return Error code
1231  **/
1232 
1233 error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
1234 {
1235  //RSAVP1 primitive is the same as RSAEP except for the names of its input
1236  //and output arguments. They are distinguished as they are intended for
1237  //different purposes
1238  return rsaep(key, s, m);
1239 }
1240 
1241 
1242 /**
1243  * @brief EME-PKCS1-v1_5 encoding operation
1244  * @param[in] prngAlgo PRNG algorithm
1245  * @param[in] prngContext Pointer to the PRNG context
1246  * @param[in] message Message to be encrypted
1247  * @param[in] messageLen Length of the message to be encrypted
1248  * @param[out] em Encoded message
1249  * @param[in] k Length of the encoded message
1250  * @return Error code
1251  **/
1252 
1253 error_t emePkcs1v15Encode(const PrngAlgo *prngAlgo, void *prngContext,
1254  const uint8_t *message, size_t messageLen, uint8_t *em, size_t k)
1255 {
1256  error_t error;
1257  size_t i;
1258  size_t j;
1259  size_t n;
1260  uint8_t *p;
1261 
1262  //Check the length of the message
1263  if((messageLen + 11) > k)
1264  return ERROR_INVALID_LENGTH;
1265 
1266  //The leading 0x00 octet ensures that the encoded message, converted to
1267  //an integer, is less than the modulus
1268  em[0] = 0x00;
1269  //For a public-key operation, the block type BT shall be 0x02
1270  em[1] = 0x02;
1271 
1272  //Point to the buffer where to format the padding string PS
1273  p = em + 2;
1274  //Determine the length of the padding string
1275  n = k - messageLen - 3;
1276 
1277  //Generate an octet string PS of length k - mLen - 3 consisting of
1278  //pseudo-randomly generated nonzero octets
1279  while(n > 0)
1280  {
1281  //Generate random data
1282  error = prngAlgo->read(prngContext, p, n);
1283  //Any error to report?
1284  if(error)
1285  return error;
1286 
1287  //Parse the resulting octet string
1288  for(i = 0, j = 0; j < n; j++)
1289  {
1290  //Strip any byte with a value of zero
1291  if(p[j] != 0)
1292  {
1293  p[i++] = p[j];
1294  }
1295  }
1296 
1297  //Advance data pointer
1298  p += i;
1299  n -= i;
1300  }
1301 
1302  //Append a 0x00 octet to the padding string
1303  *p = 0x00;
1304 
1305  //Copy the message to be encrypted
1306  cryptoMemcpy(p + 1, message, messageLen);
1307 
1308  //Successful processing
1309  return NO_ERROR;
1310 }
1311 
1312 
1313 /**
1314  * @brief EME-PKCS1-v1_5 decoding operation
1315  * @param[in] em Encoded message
1316  * @param[in] k Length of the encoded message
1317  * @param[out] message Pointer to the decrypted message
1318  * @param[out] messageLen Length of the decrypted message
1319  * @return Error code
1320  **/
1321 
1322 error_t emePkcs1v15Decode(uint8_t *em, size_t k, uint8_t **message,
1323  size_t *messageLen)
1324 {
1325  size_t i;
1326  size_t m;
1327  uint32_t c;
1328  uint32_t bad;
1329 
1330  //Separate the encoded message EM into an octet string PS consisting of
1331  //nonzero octets and a message M
1332  for(m = 0, i = 2; i < k; i++)
1333  {
1334  //Constant time implementation
1335  c = CRYPTO_TEST_Z_8(em[i]);
1336  c &= CRYPTO_TEST_Z_32(m);
1337  m = CRYPTO_SELECT_32(m, i, c);
1338  }
1339 
1340  //Point to the first byte of the message
1341  *message = em + m + 1;
1342  //Retrieve the length of the message
1343  *messageLen = k - m - 1;
1344 
1345  //If the first octet of EM does not have hexadecimal value 0x00, then
1346  //report a decryption error
1347  bad = em[0];
1348 
1349  //If the second octet of EM does not have hexadecimal value 0x02, then
1350  //report a decryption error
1351  bad |= em[1] ^ 0x02;
1352 
1353  //If there is no octet with hexadecimal value 0x00 to separate PS from M,
1354  //then report a decryption error
1355  bad |= CRYPTO_TEST_Z_32(m);
1356 
1357  //If the length of PS is less than 8 octets, then report a decryption error
1358  bad |= CRYPTO_TEST_LT_32(m, 10);
1359 
1360  //Care must be taken to ensure that an opponent cannot distinguish the
1361  //different error conditions, whether by error message or timing
1362  return (bad != 0) ? ERROR_DECRYPTION_FAILED : NO_ERROR;
1363 }
1364 
1365 
1366 /**
1367  * @brief EME-OAEP encoding operation
1368  * @param[in] prngAlgo PRNG algorithm
1369  * @param[in] prngContext Pointer to the PRNG context
1370  * @param[in] hash Underlying hash function
1371  * @param[in] label Optional label to be associated with the message
1372  * @param[in] message Message to be encrypted
1373  * @param[in] messageLen Length of the message to be encrypted
1374  * @param[out] em Encoded message
1375  * @param[in] k Length of the encoded message
1376  * @return Error code
1377  **/
1378 
1379 error_t emeOaepEncode(const PrngAlgo *prngAlgo, void *prngContext,
1380  const HashAlgo *hash, const char_t *label, const uint8_t *message,
1381  size_t messageLen, uint8_t *em, size_t k)
1382 {
1383  error_t error;
1384  size_t n;
1385  uint8_t *db;
1386  uint8_t *seed;
1387  HashContext *hashContext;
1388 
1389  //Check the length of the message
1390  if(messageLen > (k - 2 * hash->digestSize - 2))
1391  return ERROR_INVALID_LENGTH;
1392 
1393  //Point to the buffer where to format the seed
1394  seed = em + 1;
1395  //Point to the buffer where to format the data block
1396  db = em + hash->digestSize + 1;
1397 
1398  //Generate a random octet string seed of length hLen
1399  error = prngAlgo->read(prngContext, seed, hash->digestSize);
1400  //Any error to report?
1401  if(error)
1402  return error;
1403 
1404  //Allocate a memory buffer to hold the hash context
1405  hashContext = cryptoAllocMem(hash->contextSize);
1406  //Failed to allocate memory?
1407  if(hashContext == NULL)
1408  return ERROR_OUT_OF_MEMORY;
1409 
1410  //If the label L is not provided, let L be the empty string
1411  if(label == NULL)
1412  label = "";
1413 
1414  //Let lHash = Hash(L)
1415  hash->init(hashContext);
1416  hash->update(hashContext, label, strlen(label));
1417  hash->final(hashContext, db);
1418 
1419  //The padding string PS consists of k - mLen - 2hLen - 2 zero octets
1420  n = k - messageLen - 2 * hash->digestSize - 2;
1421  //Generate the padding string
1422  memset(db + hash->digestSize, 0, n);
1423 
1424  //Concatenate lHash, PS, a single octet with hexadecimal value 0x01, and
1425  //the message M to form a data block DB of length k - hLen - 1 octets
1426  db[hash->digestSize + n] = 0x01;
1427  cryptoMemcpy(db + hash->digestSize + n + 1, message, messageLen);
1428 
1429  //Calculate the length of the data block
1430  n = k - hash->digestSize - 1;
1431 
1432  //Let maskedDB = DB xor MGF(seed, k - hLen - 1)
1433  mgf1(hash, hashContext, seed, hash->digestSize, db, n);
1434  //Let maskedSeed = seed xor MGF(maskedDB, hLen)
1435  mgf1(hash, hashContext, db, n, seed, hash->digestSize);
1436 
1437  //Concatenate a single octet with hexadecimal value 0x00, maskedSeed, and
1438  //maskedDB to form an encoded message EM of length k octets
1439  em[0] = 0x00;
1440 
1441  //Release hash context
1442  cryptoFreeMem(hashContext);
1443 
1444  //Successful processing
1445  return NO_ERROR;
1446 }
1447 
1448 
1449 /**
1450  * @brief EME-OAEP decoding operation
1451  * @param[in] hash Underlying hash function
1452  * @param[in] label Optional label to be associated with the message
1453  * @param[in] em Encoded message
1454  * @param[in] k Length of the encoded message
1455  * @param[out] message Pointer to the decrypted message
1456  * @param[out] messageLen Length of the decrypted message
1457  * @return Error code
1458  **/
1459 
1460 error_t emeOaepDecode(const HashAlgo *hash, const char_t *label, uint8_t *em,
1461  size_t k, uint8_t **message, size_t *messageLen)
1462 {
1463  size_t i;
1464  size_t m;
1465  size_t n;
1466  uint32_t c;
1467  uint32_t bad;
1468  uint8_t *db;
1469  uint8_t *seed;
1470  uint8_t lHash[MAX_HASH_DIGEST_SIZE];
1471  HashContext *hashContext;
1472 
1473  //Allocate a memory buffer to hold the hash context
1474  hashContext = cryptoAllocMem(hash->contextSize);
1475  //Failed to allocate memory?
1476  if(hashContext == NULL)
1477  return ERROR_OUT_OF_MEMORY;
1478 
1479  //If the label L is not provided, let L be the empty string
1480  if(label == NULL)
1481  label = "";
1482 
1483  //Let lHash = Hash(L)
1484  hash->init(hashContext);
1485  hash->update(hashContext, label, strlen(label));
1486  hash->final(hashContext, lHash);
1487 
1488  //Separate the encoded message EM into a single octet Y, an octet string
1489  //maskedSeed of length hLen, and an octet string maskedDB of length k - hLen - 1
1490  seed = em + 1;
1491  db = em + hash->digestSize + 1;
1492 
1493  //Calculate the length of the data block
1494  n = k - hash->digestSize - 1;
1495 
1496  //Let seed = maskedSeed xor MGF(maskedDB, hLen)
1497  mgf1(hash, hashContext, db, n, seed, hash->digestSize);
1498  //Let DB = maskedDB xor MGF(seed, k - hLen - 1)
1499  mgf1(hash, hashContext, seed, hash->digestSize, db, n);
1500 
1501  //Release hash context
1502  cryptoFreeMem(hashContext);
1503 
1504  //Separate DB into an octet string lHash' of length hLen, a padding string
1505  //PS consisting of octets with hexadecimal value 0x00, and a message M
1506  for(m = 0, i = hash->digestSize; i < n; i++)
1507  {
1508  //Constant time implementation
1509  c = CRYPTO_TEST_NZ_8(db[i]);
1510  c &= CRYPTO_TEST_Z_32(m);
1511  m = CRYPTO_SELECT_32(m, i, c);
1512  }
1513 
1514  //Point to the first byte of the message
1515  *message = db + m + 1;
1516  //Retrieve the length of the message
1517  *messageLen = n - m - 1;
1518 
1519  //Make sure the padding string PS is terminated
1520  bad = CRYPTO_TEST_Z_32(m);
1521 
1522  //If there is no octet with hexadecimal value 0x01 to separate PS from M,
1523  //then report a decryption error
1524  bad |= db[m] ^ 0x01;
1525 
1526  //If lHash does not equal lHash', then report a decryption error
1527  for(i = 0; i < hash->digestSize; i++)
1528  {
1529  bad |= db[i] ^ lHash[i];
1530  }
1531 
1532  //If Y is nonzero, then report a decryption error
1533  bad |= em[0];
1534 
1535  //Care must be taken to ensure that an opponent cannot distinguish the
1536  //different error conditions, whether by error message or timing
1537  return (bad != 0) ? ERROR_DECRYPTION_FAILED : NO_ERROR;
1538 }
1539 
1540 
1541 /**
1542  * @brief EMSA-PKCS1-v1_5 encoding operation
1543  * @param[in] hash Hash function used to digest the message
1544  * @param[in] digest Digest of the message to be signed
1545  * @param[out] em Encoded message
1546  * @param[in] emLen Intended length of the encoded message
1547  * @return Error code
1548  **/
1549 
1551  const uint8_t *digest, uint8_t *em, size_t emLen)
1552 {
1553  size_t i;
1554  size_t n;
1555 
1556  //Check the intended length of the encoded message
1557  if(emLen < (hash->oidSize + hash->digestSize + 21))
1558  return ERROR_INVALID_LENGTH;
1559 
1560  //Point to the first byte of the encoded message
1561  i = 0;
1562 
1563  //The leading 0x00 octet ensures that the encoded message, converted to
1564  //an integer, is less than the modulus
1565  em[i++] = 0x00;
1566  //Block type 0x01 is used for private-key operations
1567  em[i++] = 0x01;
1568 
1569  //Determine the length of the padding string PS
1570  n = emLen - hash->oidSize - hash->digestSize - 13;
1571 
1572  //Each byte of PS must be set to 0xFF when the block type is 0x01
1573  cryptoMemset(em + i, 0xFF, n);
1574  i += n;
1575 
1576  //Append a 0x00 octet to the padding string
1577  em[i++] = 0x00;
1578 
1579  //Encode the DigestInfo structure using ASN.1
1580  em[i++] = (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1581  em[i++] = (uint8_t) (hash->oidSize + hash->digestSize + 8);
1582  em[i++] = (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1583  em[i++] = (uint8_t) (hash->oidSize + 4);
1584  em[i++] = (uint8_t) ASN1_TYPE_OBJECT_IDENTIFIER;
1585  em[i++] = (uint8_t) hash->oidSize;
1586 
1587  //Copy the hash algorithm OID
1588  cryptoMemcpy(em + i, hash->oid, hash->oidSize);
1589  i += hash->oidSize;
1590 
1591  //Encode the rest of the ASN.1 structure
1592  em[i++] = (uint8_t) ASN1_TYPE_NULL;
1593  em[i++] = 0;
1594  em[i++] = (uint8_t) ASN1_TYPE_OCTET_STRING;
1595  em[i++] = (uint8_t) hash->digestSize;
1596 
1597  //Append the hash value
1598  cryptoMemcpy(em + i, digest, hash->digestSize);
1599 
1600  //Successful processing
1601  return NO_ERROR;
1602 }
1603 
1604 
1605 /**
1606  * @brief EMSA-PKCS1-v1_5 verification operation
1607  * @param[in] hash Hash function
1608  * @param[in] digest Digest value
1609  * @param[in] em Encoded message
1610  * @param[in] emLen Length of the encoded message
1611  * @return Error code
1612  **/
1613 
1614 error_t emsaPkcs1v15Verify(const HashAlgo *hash, const uint8_t *digest,
1615  const uint8_t *em, size_t emLen)
1616 {
1617  size_t i;
1618  size_t j;
1619  size_t n;
1620  uint8_t bad;
1621 
1622  //Check the length of the encoded message
1623  if(emLen < (hash->oidSize + hash->digestSize + 21))
1624  return ERROR_INVALID_LENGTH;
1625 
1626  //Point to the first byte of the encoded message
1627  i = 0;
1628 
1629  //The first octet of EM must have hexadecimal value 0x00
1630  bad = em[i++];
1631  //The second octet of EM must have hexadecimal value 0x01
1632  bad |= em[i++] ^ 0x01;
1633 
1634  //Determine the length of the padding string PS
1635  n = emLen - hash->oidSize - hash->digestSize - 13;
1636 
1637  //Each byte of PS must be set to 0xFF when the block type is 0x01
1638  for(j = 0 ; j < n; j++)
1639  {
1640  bad |= em[i++] ^ 0xFF;
1641  }
1642 
1643  //The padding string must be followed by a 0x00 octet
1644  bad |= em[i++];
1645 
1646  //Check the ASN.1 syntax of the DigestInfo structure
1647  bad |= em[i++] ^ (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1648  bad |= em[i++] ^ (uint8_t) (hash->oidSize + hash->digestSize + 8);
1649  bad |= em[i++] ^ (uint8_t) (ASN1_ENCODING_CONSTRUCTED | ASN1_TYPE_SEQUENCE);
1650  bad |= em[i++] ^ (uint8_t) (hash->oidSize + 4);
1651  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_OBJECT_IDENTIFIER;
1652  bad |= em[i++] ^ (uint8_t) hash->oidSize;
1653 
1654  //Verify the hash algorithm OID
1655  for(j = 0; j < hash->oidSize; j++)
1656  {
1657  bad |= em[i++] ^ hash->oid[j];
1658  }
1659 
1660  //Check the rest of the ASN.1 structure
1661  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_NULL;
1662  bad |= em[i++];
1663  bad |= em[i++] ^ (uint8_t) ASN1_TYPE_OCTET_STRING;
1664  bad |= em[i++] ^ (uint8_t) hash->digestSize;
1665 
1666  //Recover the underlying hash value, and then compare it to a newly
1667  //computed hash value
1668  for(j = 0; j < hash->digestSize; j++)
1669  {
1670  bad |= em[i++] ^ digest[j];
1671  }
1672 
1673  //Verification result
1674  return (bad != 0) ? ERROR_INCONSISTENT_VALUE : NO_ERROR;
1675 }
1676 
1677 
1678 /**
1679  * @brief EMSA-PSS encoding operation
1680  * @param[in] prngAlgo PRNG algorithm
1681  * @param[in] prngContext Pointer to the PRNG context
1682  * @param[in] hash Underlying hash function
1683  * @param[in] saltLen Length of the salt, in bytes
1684  * @param[in] digest Digest of the message to be signed
1685  * @param[out] em Encoded message
1686  * @param[in] emBits Maximal bit length of the integer OS2IP(EM)
1687  * @return Error code
1688  **/
1689 
1690 error_t emsaPssEncode(const PrngAlgo *prngAlgo, void *prngContext,
1691  const HashAlgo *hash, size_t saltLen, const uint8_t *digest,
1692  uint8_t *em, uint_t emBits)
1693 {
1694  error_t error;
1695  size_t n;
1696  size_t emLen;
1697  uint8_t *db;
1698  uint8_t h[MAX_HASH_DIGEST_SIZE];
1699  uint8_t salt[MAX_HASH_DIGEST_SIZE];
1700  HashContext *hashContext;
1701 
1702  //The encoded message is an octet string of length emLen = ceil(emBits / 8)
1703  emLen = (emBits + 7) / 8;
1704 
1705  //If emLen < hLen + sLen + 2, output "encoding error" and stop
1706  if(emLen < (hash->digestSize + saltLen + 2))
1707  return ERROR_INVALID_LENGTH;
1708 
1709  //Generate a random octet string salt of length sLen
1710  error = prngAlgo->read(prngContext, salt, saltLen);
1711  //Any error to report?
1712  if(error)
1713  return error;
1714 
1715  //Allocate a memory buffer to hold the hash context
1716  hashContext = cryptoAllocMem(hash->contextSize);
1717  //Failed to allocate memory?
1718  if(hashContext == NULL)
1719  return ERROR_OUT_OF_MEMORY;
1720 
1721  //Let H = Hash(00 00 00 00 00 00 00 00 || mHash || salt)
1722  hash->init(hashContext);
1723  hash->update(hashContext, padding, sizeof(padding));
1724  hash->update(hashContext, digest, hash->digestSize);
1725  hash->update(hashContext, salt, saltLen);
1726  hash->final(hashContext, h);
1727 
1728  //Point to the buffer where to format the data block DB
1729  db = em;
1730 
1731  //The padding string PS consists of emLen - sLen - hLen - 2 zero octets
1732  n = emLen - saltLen - hash->digestSize - 2;
1733 
1734  //Let DB = PS || 0x01 || salt
1735  cryptoMemset(db, 0, n);
1736  db[n] = 0x01;
1737  cryptoMemcpy(db + n + 1, salt, saltLen);
1738 
1739  //Calculate the length of the data block
1740  n += saltLen + 1;
1741 
1742  //Let maskedDB = DB xor MGF(H, emLen - hLen - 1)
1743  mgf1(hash, hashContext, h, hash->digestSize, db, n);
1744 
1745  //Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB
1746  //to zero
1747  db[0] &= 0xFF >> (8 * emLen - emBits);
1748 
1749  //Let EM = maskedDB || H || 0xbc
1750  cryptoMemcpy(em + n, h, hash->digestSize);
1751  em[n + hash->digestSize] = 0xBC;
1752 
1753  //Release hash context
1754  cryptoFreeMem(hashContext);
1755 
1756  //Successful processing
1757  return NO_ERROR;
1758 }
1759 
1760 
1761 /**
1762  * @brief EMSA-PSS verification operation
1763  * @param[in] hash Underlying hash function
1764  * @param[in] saltLen Length of the salt, in bytes
1765  * @param[in] digest Digest of the message to be signed
1766  * @param[out] em Encoded message
1767  * @param[in] emBits Maximal bit length of the integer OS2IP(EM)
1768  * @return Error code
1769  **/
1770 
1771 error_t emsaPssVerify(const HashAlgo *hash, size_t saltLen,
1772  const uint8_t *digest, uint8_t *em, uint_t emBits)
1773 {
1774  size_t i;
1775  size_t n;
1776  size_t emLen;
1777  uint8_t bad;
1778  uint8_t mask;
1779  uint8_t *h;
1780  uint8_t *db;
1781  uint8_t *salt;
1782  HashContext *hashContext;
1783 
1784  //The encoded message is an octet string of length emLen = ceil(emBits / 8)
1785  emLen = (emBits + 7) / 8;
1786 
1787  //Check the length of the encoded message EM
1788  if(emLen < (hash->digestSize + saltLen + 2))
1789  return ERROR_INVALID_LENGTH;
1790 
1791  //Allocate a memory buffer to hold the hash context
1792  hashContext = cryptoAllocMem(hash->contextSize);
1793  //Failed to allocate memory?
1794  if(hashContext == NULL)
1795  return ERROR_OUT_OF_MEMORY;
1796 
1797  //If the rightmost octet of EM does not have hexadecimal value 0xbc, output
1798  //"inconsistent" and stop
1799  bad = em[emLen - 1] ^ 0xBC;
1800 
1801  //Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and let H be
1802  //the next hLen octets
1803  db = em;
1804  n = emLen - hash->digestSize - 1;
1805  h = em + n;
1806 
1807  //Form a mask
1808  mask = 0xFF >> (8 * emLen - emBits);
1809 
1810  //If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are
1811  //not all equal to zero, output "inconsistent" and stop
1812  bad |= db[0] & ~mask;
1813 
1814  //Let DB = maskedDB xor MGF(H, emLen - hLen - 1)
1815  mgf1(hash, hashContext, h, hash->digestSize, db, n);
1816 
1817  //Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero
1818  db[0] &= mask;
1819 
1820  //The padding string PS consists of emLen - sLen - hLen - 2 octets
1821  n = emLen - hash->digestSize - saltLen - 2;
1822 
1823  //If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero, output
1824  //"inconsistent" and stop
1825  for(i = 0; i < n; i++)
1826  {
1827  bad |= db[i];
1828  }
1829 
1830  //If the octet at position emLen - hLen - sLen - 1 does not have hexadecimal
1831  //value 0x01, output "inconsistent" and stop
1832  bad |= db[n] ^ 0x01;
1833 
1834  //Let salt be the last sLen octets of DB
1835  salt = db + n + 1;
1836 
1837  //Let H' = Hash(00 00 00 00 00 00 00 00 || mHash || salt)
1838  hash->init(hashContext);
1839  hash->update(hashContext, padding, sizeof(padding));
1840  hash->update(hashContext, digest, hash->digestSize);
1841  hash->update(hashContext, salt, saltLen);
1842  hash->final(hashContext, NULL);
1843 
1844  //If H = H', output "consistent". Otherwise, output "inconsistent"
1845  for(i = 0; i < hash->digestSize; i++)
1846  {
1847  bad |= h[i] ^ hashContext->digest[i];
1848  }
1849 
1850  //Release hash context
1851  cryptoFreeMem(hashContext);
1852 
1853  //Verification result
1854  return (bad != 0) ? ERROR_INCONSISTENT_VALUE : NO_ERROR;
1855 }
1856 
1857 
1858 /**
1859  * @brief MGF1 mask generation function
1860  * @param[in] hash Hash function
1861  * @param[in] hashContext Hash function context
1862  * @param[in] seed Seed from which the mask is generated
1863  * @param[in] seedLen Length of the seed in bytes
1864  * @param[in,out] data Data block to be masked
1865  * @param[in] dataLen Length of the data block in bytes
1866  **/
1867 
1868 void mgf1(const HashAlgo *hash, HashContext *hashContext, const uint8_t *seed,
1869  size_t seedLen, uint8_t *data, size_t dataLen)
1870 {
1871  size_t i;
1872  size_t n;
1873  uint32_t counter;
1874  uint8_t c[4];
1875 
1876  //The data is processed block by block
1877  for(counter = 0; dataLen > 0; counter++)
1878  {
1879  //Limit the number of bytes to process at a time
1880  n = MIN(dataLen, hash->digestSize);
1881 
1882  //Convert counter to an octet string C of length 4 octets
1883  STORE32BE(counter, c);
1884 
1885  //Calculate Hash(mgfSeed || C)
1886  hash->init(hashContext);
1887  hash->update(hashContext, seed, seedLen);
1888  hash->update(hashContext, c, sizeof(c));
1889  hash->final(hashContext, NULL);
1890 
1891  //Apply the mask
1892  for(i = 0; i < n; i++)
1893  {
1894  data[i] ^= hashContext->digest[i];
1895  }
1896 
1897  //Advance data pointer
1898  data += n;
1899  dataLen -= n;
1900  }
1901 }
1902 
1903 #endif
#define CRYPTO_TEST_NZ_8(a)
Definition: crypto.h:880
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:269
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:1550
const uint8_t SHA512_256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:74
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:34
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:747
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize a RSA private key.
Definition: rsa.c:126
error_t emeOaepDecode(const HashAlgo *hash, const char_t *label, uint8_t *em, size_t k, uint8_t **message, size_t *messageLen)
EME-OAEP decoding operation.
Definition: rsa.c:1460
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:60
Arbitrary precision integer.
Definition: mpi.h:67
char char_t
Definition: compiler_port.h:41
uint8_t digest[1]
Definition: crypto.h:1046
uint8_t c
Definition: ndp.h:510
#define cryptoMemcpy(dest, src, length)
Definition: crypto.h:590
Mpi p
First factor.
Definition: rsa.h:62
#define cryptoFreeMem(p)
Definition: crypto.h:578
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:1253
#define CRYPTO_TEST_LT_32(a, b)
Definition: crypto.h:964
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
Definition: mpi.c:1394
Debugging facilities.
Mpi n
Modulus.
Definition: rsa.h:48
uint8_t hash
Definition: tls.h:1363
uint8_t p
Definition: ndp.h:295
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:402
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
Definition: mpi.c:1492
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
Definition: rsa.c:1145
Mpi d
Private exponent.
Definition: rsa.h:61
Generic error code.
Definition: error.h:43
#define cryptoAllocMem(size)
Definition: crypto.h:573
error_t emePkcs1v15Decode(uint8_t *em, size_t k, uint8_t **message, size_t *messageLen)
EME-PKCS1-v1_5 decoding operation.
Definition: rsa.c:1322
uint8_t message[]
Definition: chap.h:150
const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:68
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:86
General definitions for cryptographic algorithms.
Invalid parameter.
Definition: error.h:45
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:287
void rsaFreePublicKey(RsaPublicKey *key)
Release a RSA public key.
Definition: rsa.c:113
#define MAX_HASH_DIGEST_SIZE
Definition: crypto.h:747
#define MPI_CHECK(f)
Definition: mpi.h:40
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:1771
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
Generic hash algorithm context.
Definition: crypto.h:1044
Mpi e
Public exponent.
Definition: rsa.h:49
uint8_t m
Definition: ndp.h:299
OID (Object Identifier)
error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
RSA signature primitive.
Definition: rsa.c:1212
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_384_OID[9]
Definition: rsa.c:81
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:101
Mpi n
Modulus.
Definition: rsa.h:59
Mpi q
Second factor.
Definition: rsa.h:63
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_512_OID[9]
Definition: rsa.c:83
#define CRYPTO_SELECT_32(a, b, c)
Definition: crypto.h:980
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_224_OID[9]
Definition: rsa.c:77
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:884
HMAC (Keyed-Hashing for Message Authentication)
uint8_t mask
Definition: web_socket.h:315
ASN.1 (Abstract Syntax Notation One)
#define STORE32BE(a, p)
Definition: cpu_endian.h:268
const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:70
Mpi e
Public exponent.
Definition: rsa.h:60
const uint8_t PKCS1_OID[8]
Definition: rsa.c:53
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:33
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:190
RSA public key.
Definition: rsa.h:46
#define ASN1_ENCODING_CONSTRUCTED
Definition: asn1.h:41
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:171
#define MIN(a, b)
Definition: os_port.h:60
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:674
uint8_t signature
Definition: tls.h:1364
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:1868
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:1690
const uint8_t MD2_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:58
const uint8_t SHA224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:64
const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:62
uint8_t s
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:1379
void rsaFreePrivateKey(RsaPrivateKey *key)
Release a RSA private key.
Definition: rsa.c:145
Mpi dq
second factor&#39;s CRT exponent
Definition: rsa.h:65
error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
RSA verification primitive.
Definition: rsa.c:1233
Success.
Definition: error.h:42
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:55
const uint8_t SHA512_224_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:72
#define CRYPTO_TEST_Z_32(a)
Definition: crypto.h:948
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
Definition: rsa.c:1118
error_t
Error codes.
Definition: error.h:40
MPI (Multiple Precision Integer Arithmetic)
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:331
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:642
RSA public-key cryptography standard.
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:775
unsigned int uint_t
Definition: compiler_port.h:43
Mpi qinv
CRT coefficient.
Definition: rsa.h:66
uint8_t data[]
Definition: dtls_misc.h:167
const uint8_t MD5_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:60
Common interface for pseudo-random number generators.
Definition: crypto.h:1091
Mpi dp
First factor&#39;s CRT exponent.
Definition: rsa.h:64
const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:66
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:1004
#define cryptoMemset(p, value, length)
Definition: crypto.h:584
uint_t size
Definition: mpi.h:70
#define CRYPTO_TEST_Z_8(a)
Definition: crypto.h:876
Common interface for hash algorithms.
Definition: crypto.h:1054
uint8_t n
uint8_t h
Definition: ndp.h:297
void rsaInitPublicKey(RsaPublicKey *key)
Initialize a RSA public key.
Definition: rsa.c:100
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:1614
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:508
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:46
RSA private key.
Definition: rsa.h:57
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
Definition: mpi.c:1094
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:154
PrngAlgoRead read
Definition: crypto.h:1099
const uint8_t RSASSA_PKCS1_V1_5_WITH_SHA3_256_OID[9]
Definition: rsa.c:79
#define TRACE_DEBUG(...)
Definition: debug.h:98