blob: e99e4af583c37e67e7de7025f40fb1d554fe26f8 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * The RSA public-key cryptosystem
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
Tom Van Eyckc1633172024-04-09 18:44:13 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Jens Wiklander817466c2018-05-22 13:49:31 +02006 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01007
Jens Wiklander817466c2018-05-22 13:49:31 +02008/*
9 * The following sources were referenced in the design of this implementation
10 * of the RSA algorithm:
11 *
12 * [1] A method for obtaining digital signatures and public-key cryptosystems
13 * R Rivest, A Shamir, and L Adleman
14 * http://people.csail.mit.edu/rivest/pubs.html#RSA78
15 *
16 * [2] Handbook of Applied Cryptography - 1997, Chapter 8
17 * Menezes, van Oorschot and Vanstone
18 *
19 * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
20 * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
21 * Stefan Mangard
22 * https://arxiv.org/abs/1702.08719v2
23 *
24 */
25
Jerome Forissier79013242021-07-28 10:24:04 +020026#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020027
28#if defined(MBEDTLS_RSA_C)
29
30#include "mbedtls/rsa.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020031#include "bignum_core.h"
Jens Wiklander32b31802023-10-06 16:59:46 +020032#include "rsa_alt_helpers.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020033#include "rsa_internal.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020034#include "mbedtls/oid.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020035#include "mbedtls/asn1write.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020037#include "mbedtls/error.h"
Jerome Forissier039e02d2022-08-09 17:10:15 +020038#include "constant_time_internal.h"
39#include "mbedtls/constant_time.h"
Tom Van Eyckc1633172024-04-09 18:44:13 +020040#include "md_psa.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020041
42#include <string.h>
43
Jerome Forissier79013242021-07-28 10:24:04 +020044#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
Jens Wiklander817466c2018-05-22 13:49:31 +020045#include <stdlib.h>
46#endif
47
Jens Wiklander817466c2018-05-22 13:49:31 +020048#include "mbedtls/platform.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020049
Jens Wiklander30bdb1b2022-04-01 17:45:55 +020050#include <fault_mitigation.h>
51
Tom Van Eyckc1633172024-04-09 18:44:13 +020052/*
53 * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
54 *
55 * The value zero is:
56 * - never a valid value for an RSA parameter
57 * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
58 *
59 * Since values can't be omitted in PKCS#1, passing a zero value to
60 * rsa_complete() would be incorrect, so reject zero values early.
61 */
62static int asn1_get_nonzero_mpi(unsigned char **p,
63 const unsigned char *end,
64 mbedtls_mpi *X)
65{
66 int ret;
67
68 ret = mbedtls_asn1_get_mpi(p, end, X);
69 if (ret != 0) {
70 return ret;
71 }
72
73 if (mbedtls_mpi_cmp_int(X, 0) == 0) {
74 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
75 }
76
77 return 0;
78}
79
80int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
81{
82 int ret, version;
83 size_t len;
84 unsigned char *p, *end;
85
86 mbedtls_mpi T;
87 mbedtls_mpi_init(&T);
88
89 p = (unsigned char *) key;
90 end = p + keylen;
91
92 /*
93 * This function parses the RSAPrivateKey (PKCS#1)
94 *
95 * RSAPrivateKey ::= SEQUENCE {
96 * version Version,
97 * modulus INTEGER, -- n
98 * publicExponent INTEGER, -- e
99 * privateExponent INTEGER, -- d
100 * prime1 INTEGER, -- p
101 * prime2 INTEGER, -- q
102 * exponent1 INTEGER, -- d mod (p-1)
103 * exponent2 INTEGER, -- d mod (q-1)
104 * coefficient INTEGER, -- (inverse of q) mod p
105 * otherPrimeInfos OtherPrimeInfos OPTIONAL
106 * }
107 */
108 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
109 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
110 return ret;
111 }
112
113 if (end != p + len) {
114 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
115 }
116
117 if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
118 return ret;
119 }
120
121 if (version != 0) {
122 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
123 }
124
125 /* Import N */
126 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
127 (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
128 NULL, NULL)) != 0) {
129 goto cleanup;
130 }
131
132 /* Import E */
133 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
134 (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
135 NULL, &T)) != 0) {
136 goto cleanup;
137 }
138
139 /* Import D */
140 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
141 (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
142 &T, NULL)) != 0) {
143 goto cleanup;
144 }
145
146 /* Import P */
147 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
148 (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
149 NULL, NULL)) != 0) {
150 goto cleanup;
151 }
152
153 /* Import Q */
154 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
155 (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
156 NULL, NULL)) != 0) {
157 goto cleanup;
158 }
159
160#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
161 /*
162 * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
163 * that they can be easily recomputed from D, P and Q. However by
164 * parsing them from the PKCS1 structure it is possible to avoid
165 * recalculating them which both reduces the overhead of loading
166 * RSA private keys into memory and also avoids side channels which
167 * can arise when computing those values, since all of D, P, and Q
168 * are secret. See https://eprint.iacr.org/2020/055 for a
169 * description of one such attack.
170 */
171
172 /* Import DP */
173 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
174 (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
175 goto cleanup;
176 }
177
178 /* Import DQ */
179 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
180 (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
181 goto cleanup;
182 }
183
184 /* Import QP */
185 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
186 (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
187 goto cleanup;
188 }
189
190#else
191 /* Verify existence of the CRT params */
192 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
193 (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
194 (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
195 goto cleanup;
196 }
197#endif
198
199 /* rsa_complete() doesn't complete anything with the default
200 * implementation but is still called:
201 * - for the benefit of alternative implementation that may want to
202 * pre-compute stuff beyond what's provided (eg Montgomery factors)
203 * - as is also sanity-checks the key
204 *
205 * Furthermore, we also check the public part for consistency with
206 * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
207 */
208 if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
209 (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
210 goto cleanup;
211 }
212
213 if (p != end) {
214 ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
215 }
216
217cleanup:
218
219 mbedtls_mpi_free(&T);
220
221 if (ret != 0) {
222 mbedtls_rsa_free(rsa);
223 }
224
225 return ret;
226}
227
228int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
229{
230 unsigned char *p = (unsigned char *) key;
231 unsigned char *end = (unsigned char *) (key + keylen);
232 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
233 size_t len;
234
235 /*
236 * RSAPublicKey ::= SEQUENCE {
237 * modulus INTEGER, -- n
238 * publicExponent INTEGER -- e
239 * }
240 */
241
242 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
243 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
244 return ret;
245 }
246
247 if (end != p + len) {
248 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
249 }
250
251 /* Import N */
252 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
253 return ret;
254 }
255
256 if ((ret = mbedtls_rsa_import_raw(rsa, p, len, NULL, 0, NULL, 0,
257 NULL, 0, NULL, 0)) != 0) {
258 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
259 }
260
261 p += len;
262
263 /* Import E */
264 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
265 return ret;
266 }
267
268 if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
269 NULL, 0, p, len)) != 0) {
270 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
271 }
272
273 p += len;
274
275 if (mbedtls_rsa_complete(rsa) != 0 ||
276 mbedtls_rsa_check_pubkey(rsa) != 0) {
277 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
278 }
279
280 if (p != end) {
281 return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
282 }
283
284 return 0;
285}
286
287int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
288 unsigned char **p)
289{
290 size_t len = 0;
291 int ret;
292
293 mbedtls_mpi T; /* Temporary holding the exported parameters */
294
295 /*
296 * Export the parameters one after another to avoid simultaneous copies.
297 */
298
299 mbedtls_mpi_init(&T);
300
301 /* Export QP */
302 if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
303 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
304 goto end_of_export;
305 }
306 len += ret;
307
308 /* Export DQ */
309 if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
310 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
311 goto end_of_export;
312 }
313 len += ret;
314
315 /* Export DP */
316 if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
317 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
318 goto end_of_export;
319 }
320 len += ret;
321
322 /* Export Q */
323 if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, &T, NULL, NULL)) != 0 ||
324 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
325 goto end_of_export;
326 }
327 len += ret;
328
329 /* Export P */
330 if ((ret = mbedtls_rsa_export(rsa, NULL, &T, NULL, NULL, NULL)) != 0 ||
331 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
332 goto end_of_export;
333 }
334 len += ret;
335
336 /* Export D */
337 if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, &T, NULL)) != 0 ||
338 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
339 goto end_of_export;
340 }
341 len += ret;
342
343 /* Export E */
344 if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
345 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
346 goto end_of_export;
347 }
348 len += ret;
349
350 /* Export N */
351 if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
352 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
353 goto end_of_export;
354 }
355 len += ret;
356
357end_of_export:
358
359 mbedtls_mpi_free(&T);
360 if (ret < 0) {
361 return ret;
362 }
363
364 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, start, 0));
365 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
366 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
367 MBEDTLS_ASN1_CONSTRUCTED |
368 MBEDTLS_ASN1_SEQUENCE));
369
370 return (int) len;
371}
372
373/*
374 * RSAPublicKey ::= SEQUENCE {
375 * modulus INTEGER, -- n
376 * publicExponent INTEGER -- e
377 * }
378 */
379int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
380 unsigned char **p)
381{
382 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
383 size_t len = 0;
384 mbedtls_mpi T;
385
386 mbedtls_mpi_init(&T);
387
388 /* Export E */
389 if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
390 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
391 goto end_of_export;
392 }
393 len += ret;
394
395 /* Export N */
396 if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
397 (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
398 goto end_of_export;
399 }
400 len += ret;
401
402end_of_export:
403
404 mbedtls_mpi_free(&T);
405 if (ret < 0) {
406 return ret;
407 }
408
409 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
410 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
411 MBEDTLS_ASN1_SEQUENCE));
412
413 return (int) len;
414}
415
416#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
417
418/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
419 * operation (EME-PKCS1-v1_5 decoding).
420 *
421 * \note The return value from this function is a sensitive value
422 * (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
423 * in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
424 * is often a situation that an attacker can provoke and leaking which
425 * one is the result is precisely the information the attacker wants.
426 *
427 * \param input The input buffer which is the payload inside PKCS#1v1.5
428 * encryption padding, called the "encoded message EM"
429 * by the terminology.
430 * \param ilen The length of the payload in the \p input buffer.
431 * \param output The buffer for the payload, called "message M" by the
432 * PKCS#1 terminology. This must be a writable buffer of
433 * length \p output_max_len bytes.
434 * \param olen The address at which to store the length of
435 * the payload. This must not be \c NULL.
436 * \param output_max_len The length in bytes of the output buffer \p output.
437 *
438 * \return \c 0 on success.
439 * \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
440 * The output buffer is too small for the unpadded payload.
441 * \return #MBEDTLS_ERR_RSA_INVALID_PADDING
442 * The input doesn't contain properly formatted padding.
443 */
444static int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
445 size_t ilen,
446 unsigned char *output,
447 size_t output_max_len,
448 size_t *olen)
449{
450 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
451 size_t i, plaintext_max_size;
452
453 /* The following variables take sensitive values: their value must
454 * not leak into the observable behavior of the function other than
455 * the designated outputs (output, olen, return value). Otherwise
456 * this would open the execution of the function to
457 * side-channel-based variants of the Bleichenbacher padding oracle
458 * attack. Potential side channels include overall timing, memory
459 * access patterns (especially visible to an adversary who has access
460 * to a shared memory cache), and branches (especially visible to
461 * an adversary who has access to a shared code cache or to a shared
462 * branch predictor). */
463 size_t pad_count = 0;
464 mbedtls_ct_condition_t bad;
465 mbedtls_ct_condition_t pad_done;
466 size_t plaintext_size = 0;
467 mbedtls_ct_condition_t output_too_large;
468
469 plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11
470 : output_max_len;
471
472 /* Check and get padding length in constant time and constant
473 * memory trace. The first byte must be 0. */
474 bad = mbedtls_ct_bool(input[0]);
475
476
477 /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
478 * where PS must be at least 8 nonzero bytes. */
479 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(input[1], MBEDTLS_RSA_CRYPT));
480
481 /* Read the whole buffer. Set pad_done to nonzero if we find
482 * the 0x00 byte and remember the padding length in pad_count. */
483 pad_done = MBEDTLS_CT_FALSE;
484 for (i = 2; i < ilen; i++) {
485 mbedtls_ct_condition_t found = mbedtls_ct_uint_eq(input[i], 0);
486 pad_done = mbedtls_ct_bool_or(pad_done, found);
487 pad_count += mbedtls_ct_uint_if_else_0(mbedtls_ct_bool_not(pad_done), 1);
488 }
489
490 /* If pad_done is still zero, there's no data, only unfinished padding. */
491 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_not(pad_done));
492
493 /* There must be at least 8 bytes of padding. */
494 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_gt(8, pad_count));
495
496 /* If the padding is valid, set plaintext_size to the number of
497 * remaining bytes after stripping the padding. If the padding
498 * is invalid, avoid leaking this fact through the size of the
499 * output: use the maximum message size that fits in the output
500 * buffer. Do it without branches to avoid leaking the padding
501 * validity through timing. RSA keys are small enough that all the
502 * size_t values involved fit in unsigned int. */
503 plaintext_size = mbedtls_ct_uint_if(
504 bad, (unsigned) plaintext_max_size,
505 (unsigned) (ilen - pad_count - 3));
506
507 /* Set output_too_large to 0 if the plaintext fits in the output
508 * buffer and to 1 otherwise. */
509 output_too_large = mbedtls_ct_uint_gt(plaintext_size,
510 plaintext_max_size);
511
512 /* Set ret without branches to avoid timing attacks. Return:
513 * - INVALID_PADDING if the padding is bad (bad != 0).
514 * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
515 * plaintext does not fit in the output buffer.
516 * - 0 if the padding is correct. */
517 ret = mbedtls_ct_error_if(
518 bad,
519 MBEDTLS_ERR_RSA_INVALID_PADDING,
520 mbedtls_ct_error_if_else_0(output_too_large, MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE)
521 );
522
523 /* If the padding is bad or the plaintext is too large, zero the
524 * data that we're about to copy to the output buffer.
525 * We need to copy the same amount of data
526 * from the same buffer whether the padding is good or not to
527 * avoid leaking the padding validity through overall timing or
528 * through memory or cache access patterns. */
529 mbedtls_ct_zeroize_if(mbedtls_ct_bool_or(bad, output_too_large), input + 11, ilen - 11);
530
531 /* If the plaintext is too large, truncate it to the buffer size.
532 * Copy anyway to avoid revealing the length through timing, because
533 * revealing the length is as bad as revealing the padding validity
534 * for a Bleichenbacher attack. */
535 plaintext_size = mbedtls_ct_uint_if(output_too_large,
536 (unsigned) plaintext_max_size,
537 (unsigned) plaintext_size);
538
539 /* Move the plaintext to the leftmost position where it can start in
540 * the working buffer, i.e. make it start plaintext_max_size from
541 * the end of the buffer. Do this with a memory access trace that
542 * does not depend on the plaintext size. After this move, the
543 * starting location of the plaintext is no longer sensitive
544 * information. */
545 mbedtls_ct_memmove_left(input + ilen - plaintext_max_size,
546 plaintext_max_size,
547 plaintext_max_size - plaintext_size);
548
549 /* Finally copy the decrypted plaintext plus trailing zeros into the output
550 * buffer. If output_max_len is 0, then output may be an invalid pointer
551 * and the result of memcpy() would be undefined; prevent undefined
552 * behavior making sure to depend only on output_max_len (the size of the
553 * user-provided output buffer), which is independent from plaintext
554 * length, validity of padding, success of the decryption, and other
555 * secrets. */
556 if (output_max_len != 0) {
557 memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size);
558 }
559
560 /* Report the amount of data we copied to the output buffer. In case
561 * of errors (bad padding or output too large), the value of *olen
562 * when this function returns is not specified. Making it equivalent
563 * to the good case limits the risks of leaking the padding validity. */
564 *olen = plaintext_size;
565
566 return ret;
567}
568
569#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
Jens Wiklandera8466302022-04-01 17:45:55 +0200570
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100571#if !defined(MBEDTLS_RSA_ALT)
572
Jens Wiklander32b31802023-10-06 16:59:46 +0200573int mbedtls_rsa_import(mbedtls_rsa_context *ctx,
574 const mbedtls_mpi *N,
575 const mbedtls_mpi *P, const mbedtls_mpi *Q,
576 const mbedtls_mpi *D, const mbedtls_mpi *E)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100577{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200578 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100579
Jens Wiklander32b31802023-10-06 16:59:46 +0200580 if ((N != NULL && (ret = mbedtls_mpi_copy(&ctx->N, N)) != 0) ||
581 (P != NULL && (ret = mbedtls_mpi_copy(&ctx->P, P)) != 0) ||
582 (Q != NULL && (ret = mbedtls_mpi_copy(&ctx->Q, Q)) != 0) ||
583 (D != NULL && (ret = mbedtls_mpi_copy(&ctx->D, D)) != 0) ||
584 (E != NULL && (ret = mbedtls_mpi_copy(&ctx->E, E)) != 0)) {
585 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100586 }
587
Jens Wiklander32b31802023-10-06 16:59:46 +0200588 if (N != NULL) {
589 ctx->len = mbedtls_mpi_size(&ctx->N);
590 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100591
Jens Wiklander32b31802023-10-06 16:59:46 +0200592 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100593}
594
Jens Wiklander32b31802023-10-06 16:59:46 +0200595int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx,
596 unsigned char const *N, size_t N_len,
597 unsigned char const *P, size_t P_len,
598 unsigned char const *Q, size_t Q_len,
599 unsigned char const *D, size_t D_len,
600 unsigned char const *E, size_t E_len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100601{
602 int ret = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100603
Jens Wiklander32b31802023-10-06 16:59:46 +0200604 if (N != NULL) {
605 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->N, N, N_len));
606 ctx->len = mbedtls_mpi_size(&ctx->N);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100607 }
608
Jens Wiklander32b31802023-10-06 16:59:46 +0200609 if (P != NULL) {
610 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->P, P, P_len));
611 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100612
Jens Wiklander32b31802023-10-06 16:59:46 +0200613 if (Q != NULL) {
614 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->Q, Q, Q_len));
615 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100616
Jens Wiklander32b31802023-10-06 16:59:46 +0200617 if (D != NULL) {
618 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->D, D, D_len));
619 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100620
Jens Wiklander32b31802023-10-06 16:59:46 +0200621 if (E != NULL) {
622 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->E, E, E_len));
623 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100624
625cleanup:
626
Jens Wiklander32b31802023-10-06 16:59:46 +0200627 if (ret != 0) {
628 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
629 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100630
Jens Wiklander32b31802023-10-06 16:59:46 +0200631 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100632}
633
634/*
635 * Checks whether the context fields are set in such a way
636 * that the RSA primitives will be able to execute without error.
637 * It does *not* make guarantees for consistency of the parameters.
638 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200639static int rsa_check_context(mbedtls_rsa_context const *ctx, int is_priv,
640 int blinding_needed)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100641{
642#if !defined(MBEDTLS_RSA_NO_CRT)
643 /* blinding_needed is only used for NO_CRT to decide whether
644 * P,Q need to be present or not. */
645 ((void) blinding_needed);
646#endif
647
Jens Wiklander32b31802023-10-06 16:59:46 +0200648 if (ctx->len != mbedtls_mpi_size(&ctx->N) ||
649 ctx->len > MBEDTLS_MPI_MAX_SIZE) {
650 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100651 }
652
653 /*
654 * 1. Modular exponentiation needs positive, odd moduli.
655 */
656
657 /* Modular exponentiation wrt. N is always used for
658 * RSA public key operations. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200659 if (mbedtls_mpi_cmp_int(&ctx->N, 0) <= 0 ||
660 mbedtls_mpi_get_bit(&ctx->N, 0) == 0) {
661 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100662 }
663
664#if !defined(MBEDTLS_RSA_NO_CRT)
665 /* Modular exponentiation for P and Q is only
666 * used for private key operations and if CRT
667 * is used. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200668 if (is_priv &&
669 (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 ||
670 mbedtls_mpi_get_bit(&ctx->P, 0) == 0 ||
671 mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0 ||
672 mbedtls_mpi_get_bit(&ctx->Q, 0) == 0)) {
673 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100674 }
675#endif /* !MBEDTLS_RSA_NO_CRT */
676
677 /*
678 * 2. Exponents must be positive
679 */
680
681 /* Always need E for public key operations */
Jens Wiklander32b31802023-10-06 16:59:46 +0200682 if (mbedtls_mpi_cmp_int(&ctx->E, 0) <= 0) {
683 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
684 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100685
686#if defined(MBEDTLS_RSA_NO_CRT)
687 /* For private key operations, use D or DP & DQ
688 * as (unblinded) exponents. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200689 if (is_priv && mbedtls_mpi_cmp_int(&ctx->D, 0) <= 0) {
690 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
691 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100692#else
Jens Wiklander32b31802023-10-06 16:59:46 +0200693 if (is_priv &&
694 (mbedtls_mpi_cmp_int(&ctx->DP, 0) <= 0 ||
695 mbedtls_mpi_cmp_int(&ctx->DQ, 0) <= 0)) {
696 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100697 }
698#endif /* MBEDTLS_RSA_NO_CRT */
699
700 /* Blinding shouldn't make exponents negative either,
701 * so check that P, Q >= 1 if that hasn't yet been
702 * done as part of 1. */
703#if defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200704 if (is_priv && blinding_needed &&
705 (mbedtls_mpi_cmp_int(&ctx->P, 0) <= 0 ||
706 mbedtls_mpi_cmp_int(&ctx->Q, 0) <= 0)) {
707 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100708 }
709#endif
710
711 /* It wouldn't lead to an error if it wasn't satisfied,
712 * but check for QP >= 1 nonetheless. */
713#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200714 if (is_priv &&
715 mbedtls_mpi_cmp_int(&ctx->QP, 0) <= 0) {
716 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100717 }
718#endif
719
Jens Wiklander32b31802023-10-06 16:59:46 +0200720 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100721}
722
Jens Wiklander32b31802023-10-06 16:59:46 +0200723int mbedtls_rsa_complete(mbedtls_rsa_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100724{
725 int ret = 0;
726 int have_N, have_P, have_Q, have_D, have_E;
Jerome Forissier5b25c762020-04-07 11:18:49 +0200727#if !defined(MBEDTLS_RSA_NO_CRT)
728 int have_DP, have_DQ, have_QP;
729#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100730 int n_missing, pq_missing, d_missing, is_pub, is_priv;
731
Jens Wiklander32b31802023-10-06 16:59:46 +0200732 have_N = (mbedtls_mpi_cmp_int(&ctx->N, 0) != 0);
733 have_P = (mbedtls_mpi_cmp_int(&ctx->P, 0) != 0);
734 have_Q = (mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0);
735 have_D = (mbedtls_mpi_cmp_int(&ctx->D, 0) != 0);
736 have_E = (mbedtls_mpi_cmp_int(&ctx->E, 0) != 0);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100737
Jerome Forissier5b25c762020-04-07 11:18:49 +0200738#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200739 have_DP = (mbedtls_mpi_cmp_int(&ctx->DP, 0) != 0);
740 have_DQ = (mbedtls_mpi_cmp_int(&ctx->DQ, 0) != 0);
741 have_QP = (mbedtls_mpi_cmp_int(&ctx->QP, 0) != 0);
Jerome Forissier5b25c762020-04-07 11:18:49 +0200742#endif
743
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100744 /*
745 * Check whether provided parameters are enough
746 * to deduce all others. The following incomplete
747 * parameter sets for private keys are supported:
748 *
749 * (1) P, Q missing.
750 * (2) D and potentially N missing.
751 *
752 */
753
754 n_missing = have_P && have_Q && have_D && have_E;
755 pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
756 d_missing = have_P && have_Q && !have_D && have_E;
757 is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
758
759 /* These three alternatives are mutually exclusive */
760 is_priv = n_missing || pq_missing || d_missing;
761
Jens Wiklander32b31802023-10-06 16:59:46 +0200762 if (!is_priv && !is_pub) {
763 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
764 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100765
766 /*
767 * Step 1: Deduce N if P, Q are provided.
768 */
769
Jens Wiklander32b31802023-10-06 16:59:46 +0200770 if (!have_N && have_P && have_Q) {
771 if ((ret = mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P,
772 &ctx->Q)) != 0) {
773 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100774 }
775
Jens Wiklander32b31802023-10-06 16:59:46 +0200776 ctx->len = mbedtls_mpi_size(&ctx->N);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100777 }
778
779 /*
780 * Step 2: Deduce and verify all remaining core parameters.
781 */
782
Jens Wiklander32b31802023-10-06 16:59:46 +0200783 if (pq_missing) {
784 ret = mbedtls_rsa_deduce_primes(&ctx->N, &ctx->E, &ctx->D,
785 &ctx->P, &ctx->Q);
786 if (ret != 0) {
787 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
788 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100789
Jens Wiklander32b31802023-10-06 16:59:46 +0200790 } else if (d_missing) {
791 if ((ret = mbedtls_rsa_deduce_private_exponent(&ctx->P,
792 &ctx->Q,
793 &ctx->E,
794 &ctx->D)) != 0) {
795 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100796 }
797 }
798
799 /*
800 * Step 3: Deduce all additional parameters specific
801 * to our current RSA implementation.
802 */
803
804#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +0200805 if (is_priv && !(have_DP && have_DQ && have_QP)) {
806 ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
807 &ctx->DP, &ctx->DQ, &ctx->QP);
808 if (ret != 0) {
809 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
810 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100811 }
812#endif /* MBEDTLS_RSA_NO_CRT */
813
814 /*
815 * Step 3: Basic sanity checks
816 */
817
Jens Wiklander32b31802023-10-06 16:59:46 +0200818 return rsa_check_context(ctx, is_priv, 1);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100819}
820
Jens Wiklander32b31802023-10-06 16:59:46 +0200821int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx,
822 unsigned char *N, size_t N_len,
823 unsigned char *P, size_t P_len,
824 unsigned char *Q, size_t Q_len,
825 unsigned char *D, size_t D_len,
826 unsigned char *E, size_t E_len)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100827{
828 int ret = 0;
829 int is_priv;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100830
831 /* Check if key is private or public */
832 is_priv =
Jens Wiklander32b31802023-10-06 16:59:46 +0200833 mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
834 mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
835 mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
836 mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
837 mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100838
Jens Wiklander32b31802023-10-06 16:59:46 +0200839 if (!is_priv) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100840 /* If we're trying to export private parameters for a public key,
841 * something must be wrong. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200842 if (P != NULL || Q != NULL || D != NULL) {
843 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
844 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100845
846 }
847
Jens Wiklander32b31802023-10-06 16:59:46 +0200848 if (N != NULL) {
849 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->N, N, N_len));
850 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100851
Jens Wiklander32b31802023-10-06 16:59:46 +0200852 if (P != NULL) {
853 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->P, P, P_len));
854 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100855
Jens Wiklander32b31802023-10-06 16:59:46 +0200856 if (Q != NULL) {
857 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->Q, Q, Q_len));
858 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100859
Jens Wiklander32b31802023-10-06 16:59:46 +0200860 if (D != NULL) {
861 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->D, D, D_len));
862 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100863
Jens Wiklander32b31802023-10-06 16:59:46 +0200864 if (E != NULL) {
865 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->E, E, E_len));
866 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100867
868cleanup:
869
Jens Wiklander32b31802023-10-06 16:59:46 +0200870 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100871}
872
Jens Wiklander32b31802023-10-06 16:59:46 +0200873int mbedtls_rsa_export(const mbedtls_rsa_context *ctx,
874 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
875 mbedtls_mpi *D, mbedtls_mpi *E)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100876{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200877 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100878 int is_priv;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100879
880 /* Check if key is private or public */
881 is_priv =
Jens Wiklander32b31802023-10-06 16:59:46 +0200882 mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
883 mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
884 mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
885 mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
886 mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100887
Jens Wiklander32b31802023-10-06 16:59:46 +0200888 if (!is_priv) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100889 /* If we're trying to export private parameters for a public key,
890 * something must be wrong. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200891 if (P != NULL || Q != NULL || D != NULL) {
892 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
893 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100894
895 }
896
897 /* Export all requested core parameters. */
898
Jens Wiklander32b31802023-10-06 16:59:46 +0200899 if ((N != NULL && (ret = mbedtls_mpi_copy(N, &ctx->N)) != 0) ||
900 (P != NULL && (ret = mbedtls_mpi_copy(P, &ctx->P)) != 0) ||
901 (Q != NULL && (ret = mbedtls_mpi_copy(Q, &ctx->Q)) != 0) ||
902 (D != NULL && (ret = mbedtls_mpi_copy(D, &ctx->D)) != 0) ||
903 (E != NULL && (ret = mbedtls_mpi_copy(E, &ctx->E)) != 0)) {
904 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100905 }
906
Jens Wiklander32b31802023-10-06 16:59:46 +0200907 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100908}
909
910/*
911 * Export CRT parameters
912 * This must also be implemented if CRT is not used, for being able to
913 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
914 * can be used in this case.
915 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200916int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx,
917 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP)
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100918{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200919 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100920 int is_priv;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100921
922 /* Check if key is private or public */
923 is_priv =
Jens Wiklander32b31802023-10-06 16:59:46 +0200924 mbedtls_mpi_cmp_int(&ctx->N, 0) != 0 &&
925 mbedtls_mpi_cmp_int(&ctx->P, 0) != 0 &&
926 mbedtls_mpi_cmp_int(&ctx->Q, 0) != 0 &&
927 mbedtls_mpi_cmp_int(&ctx->D, 0) != 0 &&
928 mbedtls_mpi_cmp_int(&ctx->E, 0) != 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100929
Jens Wiklander32b31802023-10-06 16:59:46 +0200930 if (!is_priv) {
931 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
932 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100933
934#if !defined(MBEDTLS_RSA_NO_CRT)
935 /* Export all requested blinding parameters. */
Jens Wiklander32b31802023-10-06 16:59:46 +0200936 if ((DP != NULL && (ret = mbedtls_mpi_copy(DP, &ctx->DP)) != 0) ||
937 (DQ != NULL && (ret = mbedtls_mpi_copy(DQ, &ctx->DQ)) != 0) ||
938 (QP != NULL && (ret = mbedtls_mpi_copy(QP, &ctx->QP)) != 0)) {
939 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100940 }
941#else
Jens Wiklander32b31802023-10-06 16:59:46 +0200942 if ((ret = mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
943 DP, DQ, QP)) != 0) {
944 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret);
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100945 }
946#endif
947
Jens Wiklander32b31802023-10-06 16:59:46 +0200948 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200949}
950
951/*
952 * Initialize an RSA context
953 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200954void mbedtls_rsa_init(mbedtls_rsa_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +0200955{
Jens Wiklander32b31802023-10-06 16:59:46 +0200956 memset(ctx, 0, sizeof(mbedtls_rsa_context));
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100957
Jens Wiklander32b31802023-10-06 16:59:46 +0200958 ctx->padding = MBEDTLS_RSA_PKCS_V15;
959 ctx->hash_id = MBEDTLS_MD_NONE;
Jens Wiklander817466c2018-05-22 13:49:31 +0200960
961#if defined(MBEDTLS_THREADING_C)
Jerome Forissier79013242021-07-28 10:24:04 +0200962 /* Set ctx->ver to nonzero to indicate that the mutex has been
963 * initialized and will need to be freed. */
964 ctx->ver = 1;
Jens Wiklander32b31802023-10-06 16:59:46 +0200965 mbedtls_mutex_init(&ctx->mutex);
Jens Wiklander817466c2018-05-22 13:49:31 +0200966#endif
967}
968
969/*
970 * Set padding for an existing RSA context
971 */
Jens Wiklander32b31802023-10-06 16:59:46 +0200972int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding,
973 mbedtls_md_type_t hash_id)
Jens Wiklander817466c2018-05-22 13:49:31 +0200974{
Jens Wiklander32b31802023-10-06 16:59:46 +0200975 switch (padding) {
976#if defined(MBEDTLS_PKCS1_V15)
977 case MBEDTLS_RSA_PKCS_V15:
978 break;
979#endif
980
981#if defined(MBEDTLS_PKCS1_V21)
982 case MBEDTLS_RSA_PKCS_V21:
983 break;
984#endif
985 default:
986 return MBEDTLS_ERR_RSA_INVALID_PADDING;
987 }
988
989#if defined(MBEDTLS_PKCS1_V21)
990 if ((padding == MBEDTLS_RSA_PKCS_V21) &&
991 (hash_id != MBEDTLS_MD_NONE)) {
992 /* Just make sure this hash is supported in this build. */
Tom Van Eyckc1633172024-04-09 18:44:13 +0200993 if (mbedtls_md_info_from_type(hash_id) == NULL) {
Jens Wiklander32b31802023-10-06 16:59:46 +0200994 return MBEDTLS_ERR_RSA_INVALID_PADDING;
995 }
996 }
997#endif /* MBEDTLS_PKCS1_V21 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100998
Jens Wiklander817466c2018-05-22 13:49:31 +0200999 ctx->padding = padding;
1000 ctx->hash_id = hash_id;
Jens Wiklander32b31802023-10-06 16:59:46 +02001001
1002 return 0;
1003}
1004
1005/*
1006 * Get padding mode of initialized RSA context
1007 */
1008int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx)
1009{
1010 return ctx->padding;
1011}
1012
1013/*
1014 * Get hash identifier of mbedtls_md_type_t type
1015 */
1016int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx)
1017{
1018 return ctx->hash_id;
Jens Wiklander817466c2018-05-22 13:49:31 +02001019}
1020
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001021/*
Tom Van Eyckc1633172024-04-09 18:44:13 +02001022 * Get length in bits of RSA modulus
1023 */
1024size_t mbedtls_rsa_get_bitlen(const mbedtls_rsa_context *ctx)
1025{
1026 return mbedtls_mpi_bitlen(&ctx->N);
1027}
1028
1029/*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001030 * Get length in bytes of RSA modulus
1031 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001032size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx)
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001033{
Jens Wiklander32b31802023-10-06 16:59:46 +02001034 return ctx->len;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001035}
1036
Jens Wiklander817466c2018-05-22 13:49:31 +02001037#if defined(MBEDTLS_GENPRIME)
1038
1039/*
1040 * Generate an RSA keypair
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001041 *
1042 * This generation method follows the RSA key pair generation procedure of
1043 * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
Jens Wiklander817466c2018-05-22 13:49:31 +02001044 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001045int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx,
1046 int (*f_rng)(void *, unsigned char *, size_t),
1047 void *p_rng,
1048 unsigned int nbits, int exponent)
Jens Wiklander817466c2018-05-22 13:49:31 +02001049{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001050 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001051 mbedtls_mpi H, G, L;
1052 int prime_quality = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001053
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001054 /*
1055 * If the modulus is 1024 bit long or shorter, then the security strength of
1056 * the RSA algorithm is less than or equal to 80 bits and therefore an error
1057 * rate of 2^-80 is sufficient.
1058 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001059 if (nbits > 1024) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001060 prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
Jens Wiklander32b31802023-10-06 16:59:46 +02001061 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001062
Jens Wiklander32b31802023-10-06 16:59:46 +02001063 mbedtls_mpi_init(&H);
1064 mbedtls_mpi_init(&G);
1065 mbedtls_mpi_init(&L);
Jens Wiklander817466c2018-05-22 13:49:31 +02001066
Tom Van Eyckc1633172024-04-09 18:44:13 +02001067 if (exponent < 3 || nbits % 2 != 0) {
1068 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1069 goto cleanup;
1070 }
1071
1072 if (nbits < MBEDTLS_RSA_GEN_KEY_MIN_BITS) {
Jerome Forissier79013242021-07-28 10:24:04 +02001073 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1074 goto cleanup;
1075 }
1076
Jens Wiklander817466c2018-05-22 13:49:31 +02001077 /*
1078 * find primes P and Q with Q < P so that:
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001079 * 1. |P-Q| > 2^( nbits / 2 - 100 )
1080 * 2. GCD( E, (P-1)*(Q-1) ) == 1
1081 * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001082 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001083 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->E, exponent));
Jens Wiklander817466c2018-05-22 13:49:31 +02001084
Jens Wiklander32b31802023-10-06 16:59:46 +02001085 do {
1086 MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->P, nbits >> 1,
1087 prime_quality, f_rng, p_rng));
Jens Wiklander817466c2018-05-22 13:49:31 +02001088
Jens Wiklander32b31802023-10-06 16:59:46 +02001089 MBEDTLS_MPI_CHK(mbedtls_mpi_gen_prime(&ctx->Q, nbits >> 1,
1090 prime_quality, f_rng, p_rng));
Jens Wiklander817466c2018-05-22 13:49:31 +02001091
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001092 /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
Jens Wiklander32b31802023-10-06 16:59:46 +02001093 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&H, &ctx->P, &ctx->Q));
1094 if (mbedtls_mpi_bitlen(&H) <= ((nbits >= 200) ? ((nbits >> 1) - 99) : 0)) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001095 continue;
Jens Wiklander32b31802023-10-06 16:59:46 +02001096 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001097
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001098 /* not required by any standards, but some users rely on the fact that P > Q */
Jens Wiklander32b31802023-10-06 16:59:46 +02001099 if (H.s < 0) {
1100 mbedtls_mpi_swap(&ctx->P, &ctx->Q);
1101 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001102
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001103 /* Temporarily replace P,Q by P-1, Q-1 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001104 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->P, &ctx->P, 1));
1105 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&ctx->Q, &ctx->Q, 1));
1106 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&H, &ctx->P, &ctx->Q));
Jens Wiklander817466c2018-05-22 13:49:31 +02001107
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001108 /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
Jens Wiklander32b31802023-10-06 16:59:46 +02001109 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->E, &H));
1110 if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001111 continue;
Jens Wiklander32b31802023-10-06 16:59:46 +02001112 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001113
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001114 /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
Jens Wiklander32b31802023-10-06 16:59:46 +02001115 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, &ctx->P, &ctx->Q));
1116 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&L, NULL, &H, &G));
1117 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->D, &ctx->E, &L));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001118
Jens Wiklander32b31802023-10-06 16:59:46 +02001119 if (mbedtls_mpi_bitlen(&ctx->D) <= ((nbits + 1) / 2)) { // (FIPS 186-4 §B.3.1 criterion 3(a))
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001120 continue;
Jens Wiklander32b31802023-10-06 16:59:46 +02001121 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001122
1123 break;
Jens Wiklander32b31802023-10-06 16:59:46 +02001124 } while (1);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001125
1126 /* Restore P,Q */
Jens Wiklander32b31802023-10-06 16:59:46 +02001127 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->P, &ctx->P, 1));
1128 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&ctx->Q, &ctx->Q, 1));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001129
Jens Wiklander32b31802023-10-06 16:59:46 +02001130 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->N, &ctx->P, &ctx->Q));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001131
Jens Wiklander32b31802023-10-06 16:59:46 +02001132 ctx->len = mbedtls_mpi_size(&ctx->N);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001133
1134#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander817466c2018-05-22 13:49:31 +02001135 /*
Jens Wiklander817466c2018-05-22 13:49:31 +02001136 * DP = D mod (P - 1)
1137 * DQ = D mod (Q - 1)
1138 * QP = Q^-1 mod P
1139 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001140 MBEDTLS_MPI_CHK(mbedtls_rsa_deduce_crt(&ctx->P, &ctx->Q, &ctx->D,
1141 &ctx->DP, &ctx->DQ, &ctx->QP));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001142#endif /* MBEDTLS_RSA_NO_CRT */
Jens Wiklander817466c2018-05-22 13:49:31 +02001143
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001144 /* Double-check */
Jens Wiklander32b31802023-10-06 16:59:46 +02001145 MBEDTLS_MPI_CHK(mbedtls_rsa_check_privkey(ctx));
Jens Wiklander817466c2018-05-22 13:49:31 +02001146
1147cleanup:
1148
Jens Wiklander32b31802023-10-06 16:59:46 +02001149 mbedtls_mpi_free(&H);
1150 mbedtls_mpi_free(&G);
1151 mbedtls_mpi_free(&L);
Jens Wiklander817466c2018-05-22 13:49:31 +02001152
Jens Wiklander32b31802023-10-06 16:59:46 +02001153 if (ret != 0) {
1154 mbedtls_rsa_free(ctx);
Jerome Forissier79013242021-07-28 10:24:04 +02001155
Jens Wiklander32b31802023-10-06 16:59:46 +02001156 if ((-ret & ~0x7f) == 0) {
1157 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret);
1158 }
1159 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001160 }
1161
Jens Wiklander32b31802023-10-06 16:59:46 +02001162 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001163}
1164
1165#endif /* MBEDTLS_GENPRIME */
1166
1167/*
1168 * Check a public RSA key
1169 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001170int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +02001171{
Jens Wiklander32b31802023-10-06 16:59:46 +02001172 if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */) != 0) {
1173 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001174 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001175
Jens Wiklander32b31802023-10-06 16:59:46 +02001176 if (mbedtls_mpi_bitlen(&ctx->N) < 128) {
1177 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001178 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001179
Jens Wiklander32b31802023-10-06 16:59:46 +02001180 if (mbedtls_mpi_get_bit(&ctx->E, 0) == 0 ||
1181 mbedtls_mpi_bitlen(&ctx->E) < 2 ||
1182 mbedtls_mpi_cmp_mpi(&ctx->E, &ctx->N) >= 0) {
1183 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
1184 }
1185
1186 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001187}
1188
1189/*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001190 * Check for the consistency of all fields in an RSA private key context
Jens Wiklander817466c2018-05-22 13:49:31 +02001191 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001192int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +02001193{
Jens Wiklander32b31802023-10-06 16:59:46 +02001194 if (mbedtls_rsa_check_pubkey(ctx) != 0 ||
1195 rsa_check_context(ctx, 1 /* private */, 1 /* blinding */) != 0) {
1196 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001197 }
1198
Jens Wiklander32b31802023-10-06 16:59:46 +02001199 if (mbedtls_rsa_validate_params(&ctx->N, &ctx->P, &ctx->Q,
1200 &ctx->D, &ctx->E, NULL, NULL) != 0) {
1201 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001202 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001203
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001204#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02001205 else if (mbedtls_rsa_validate_crt(&ctx->P, &ctx->Q, &ctx->D,
1206 &ctx->DP, &ctx->DQ, &ctx->QP) != 0) {
1207 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001208 }
1209#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001210
Jens Wiklander32b31802023-10-06 16:59:46 +02001211 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001212}
1213
1214/*
1215 * Check if contexts holding a public and private key match
1216 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001217int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub,
1218 const mbedtls_rsa_context *prv)
Jens Wiklander817466c2018-05-22 13:49:31 +02001219{
Jens Wiklander32b31802023-10-06 16:59:46 +02001220 if (mbedtls_rsa_check_pubkey(pub) != 0 ||
1221 mbedtls_rsa_check_privkey(prv) != 0) {
1222 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001223 }
1224
Jens Wiklander32b31802023-10-06 16:59:46 +02001225 if (mbedtls_mpi_cmp_mpi(&pub->N, &prv->N) != 0 ||
1226 mbedtls_mpi_cmp_mpi(&pub->E, &prv->E) != 0) {
1227 return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001228 }
1229
Jens Wiklander32b31802023-10-06 16:59:46 +02001230 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001231}
1232
1233/*
1234 * Do an RSA public key operation
1235 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001236int mbedtls_rsa_public(mbedtls_rsa_context *ctx,
1237 const unsigned char *input,
1238 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +02001239{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001240 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001241 size_t olen;
1242 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001243
Jens Wiklander32b31802023-10-06 16:59:46 +02001244 if (rsa_check_context(ctx, 0 /* public */, 0 /* no blinding */)) {
1245 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1246 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001247
Jens Wiklander32b31802023-10-06 16:59:46 +02001248 mbedtls_mpi_init(&T);
Jens Wiklander817466c2018-05-22 13:49:31 +02001249
1250#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +02001251 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
1252 return ret;
1253 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001254#endif
1255
Jens Wiklander32b31802023-10-06 16:59:46 +02001256 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
Jens Wiklander817466c2018-05-22 13:49:31 +02001257
Jens Wiklander32b31802023-10-06 16:59:46 +02001258 if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001259 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1260 goto cleanup;
1261 }
1262
1263 olen = ctx->len;
Jens Wiklander32b31802023-10-06 16:59:46 +02001264 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
1265 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
Jens Wiklander817466c2018-05-22 13:49:31 +02001266
1267cleanup:
1268#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +02001269 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
1270 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
1271 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001272#endif
1273
Jens Wiklander32b31802023-10-06 16:59:46 +02001274 mbedtls_mpi_free(&T);
Jens Wiklander817466c2018-05-22 13:49:31 +02001275
Jens Wiklander32b31802023-10-06 16:59:46 +02001276 if (ret != 0) {
1277 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret);
1278 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001279
Jens Wiklander32b31802023-10-06 16:59:46 +02001280 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02001281}
1282
1283/*
1284 * Generate or update blinding values, see section 10 of:
1285 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
1286 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
1287 * Berlin Heidelberg, 1996. p. 104-113.
1288 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001289static int rsa_prepare_blinding(mbedtls_rsa_context *ctx,
1290 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Jens Wiklander817466c2018-05-22 13:49:31 +02001291{
1292 int ret, count = 0;
Jerome Forissier79013242021-07-28 10:24:04 +02001293 mbedtls_mpi R;
1294
Jens Wiklander32b31802023-10-06 16:59:46 +02001295 mbedtls_mpi_init(&R);
Jens Wiklander817466c2018-05-22 13:49:31 +02001296
Jens Wiklander32b31802023-10-06 16:59:46 +02001297 if (ctx->Vf.p != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001298 /* We already have blinding values, just update them by squaring */
Jens Wiklander32b31802023-10-06 16:59:46 +02001299 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
1300 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
1301 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
1302 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->N));
Jens Wiklander817466c2018-05-22 13:49:31 +02001303
1304 goto cleanup;
1305 }
1306
1307 /* Unblinding value: Vf = random number, invertible mod N */
1308 do {
Jens Wiklander32b31802023-10-06 16:59:46 +02001309 if (count++ > 10) {
Jerome Forissier79013242021-07-28 10:24:04 +02001310 ret = MBEDTLS_ERR_RSA_RNG_FAILED;
1311 goto cleanup;
1312 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001313
Jens Wiklander32b31802023-10-06 16:59:46 +02001314 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->Vf, ctx->len - 1, f_rng, p_rng));
Jens Wiklander817466c2018-05-22 13:49:31 +02001315
Jerome Forissier79013242021-07-28 10:24:04 +02001316 /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
Jens Wiklander32b31802023-10-06 16:59:46 +02001317 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, ctx->len - 1, f_rng, p_rng));
1318 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vf, &R));
1319 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
Jerome Forissier79013242021-07-28 10:24:04 +02001320
1321 /* At this point, Vi is invertible mod N if and only if both Vf and R
1322 * are invertible mod N. If one of them isn't, we don't need to know
1323 * which one, we just loop and choose new values for both of them.
1324 * (Each iteration succeeds with overwhelming probability.) */
Jens Wiklander32b31802023-10-06 16:59:46 +02001325 ret = mbedtls_mpi_inv_mod(&ctx->Vi, &ctx->Vi, &ctx->N);
1326 if (ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
Jerome Forissier79013242021-07-28 10:24:04 +02001327 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02001328 }
Jerome Forissier79013242021-07-28 10:24:04 +02001329
Jens Wiklander32b31802023-10-06 16:59:46 +02001330 } while (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Jerome Forissier79013242021-07-28 10:24:04 +02001331
1332 /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001333 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &R));
1334 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->N));
Jerome Forissier79013242021-07-28 10:24:04 +02001335
1336 /* Blinding value: Vi = Vf^(-e) mod N
1337 * (Vi already contains Vf^-1 at this point) */
Jens Wiklander32b31802023-10-06 16:59:46 +02001338 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN));
Jens Wiklander817466c2018-05-22 13:49:31 +02001339
1340
1341cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +02001342 mbedtls_mpi_free(&R);
Jerome Forissier79013242021-07-28 10:24:04 +02001343
Jens Wiklander32b31802023-10-06 16:59:46 +02001344 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001345}
1346
1347/*
Tom Van Eyckc1633172024-04-09 18:44:13 +02001348 * Unblind
1349 * T = T * Vf mod N
1350 */
1351static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N)
1352{
1353 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1354 const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
1355 const size_t nlimbs = N->n;
1356 const size_t tlimbs = mbedtls_mpi_core_montmul_working_limbs(nlimbs);
1357 mbedtls_mpi RR, M_T;
1358
1359 mbedtls_mpi_init(&RR);
1360 mbedtls_mpi_init(&M_T);
1361
1362 MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
1363 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs));
1364
1365 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs));
1366 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs));
1367
1368 /* T = T * Vf mod N
1369 * Reminder: montmul(A, B, N) = A * B * R^-1 mod N
1370 * Usually both operands are multiplied by R mod N beforehand (by calling
1371 * `to_mont_rep()` on them), yielding a result that's also * R mod N (aka
1372 * "in the Montgomery domain"). Here we only multiply one operand by R mod
1373 * N, so the result is directly what we want - no need to call
1374 * `from_mont_rep()` on it. */
1375 mbedtls_mpi_core_to_mont_rep(T->p, T->p, N->p, nlimbs, mm, RR.p, M_T.p);
1376 mbedtls_mpi_core_montmul(T->p, T->p, Vf->p, nlimbs, N->p, nlimbs, mm, M_T.p);
1377
1378cleanup:
1379
1380 mbedtls_mpi_free(&RR);
1381 mbedtls_mpi_free(&M_T);
1382
1383 return ret;
1384}
1385
1386/*
Jens Wiklander817466c2018-05-22 13:49:31 +02001387 * Exponent blinding supposed to prevent side-channel attacks using multiple
1388 * traces of measurements to recover the RSA key. The more collisions are there,
1389 * the more bits of the key can be recovered. See [3].
1390 *
1391 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
Jerome Forissier039e02d2022-08-09 17:10:15 +02001392 * observations on average.
Jens Wiklander817466c2018-05-22 13:49:31 +02001393 *
1394 * For example with 28 byte blinding to achieve 2 collisions the adversary has
Jerome Forissier039e02d2022-08-09 17:10:15 +02001395 * to make 2^112 observations on average.
Jens Wiklander817466c2018-05-22 13:49:31 +02001396 *
1397 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1398 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1399 * Thus in this sense with 28 byte blinding the security is not reduced by
1400 * side-channel attacks like the one in [3])
1401 *
1402 * This countermeasure does not help if the key recovery is possible with a
1403 * single trace.
1404 */
1405#define RSA_EXPONENT_BLINDING 28
1406
1407/*
1408 * Do an RSA private key operation
1409 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001410int mbedtls_rsa_private(mbedtls_rsa_context *ctx,
1411 int (*f_rng)(void *, unsigned char *, size_t),
1412 void *p_rng,
1413 const unsigned char *input,
1414 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +02001415{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001417 size_t olen;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001418
1419 /* Temporary holding the result */
1420 mbedtls_mpi T;
1421
1422 /* Temporaries holding P-1, Q-1 and the
1423 * exponent blinding factor, respectively. */
Jens Wiklander817466c2018-05-22 13:49:31 +02001424 mbedtls_mpi P1, Q1, R;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001425
1426#if !defined(MBEDTLS_RSA_NO_CRT)
1427 /* Temporaries holding the results mod p resp. mod q. */
1428 mbedtls_mpi TP, TQ;
1429
1430 /* Temporaries holding the blinded exponents for
1431 * the mod p resp. mod q computation (if used). */
Jens Wiklander817466c2018-05-22 13:49:31 +02001432 mbedtls_mpi DP_blind, DQ_blind;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001433#else
1434 /* Temporary holding the blinded exponent (if used). */
1435 mbedtls_mpi D_blind;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001436#endif /* MBEDTLS_RSA_NO_CRT */
1437
1438 /* Temporaries holding the initial input and the double
1439 * checked result; should be the same in the end. */
Tom Van Eyckc1633172024-04-09 18:44:13 +02001440 mbedtls_mpi input_blinded, check_result_blinded;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001441
Jens Wiklander32b31802023-10-06 16:59:46 +02001442 if (f_rng == NULL) {
1443 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1444 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001445
Jens Wiklander32b31802023-10-06 16:59:46 +02001446 if (rsa_check_context(ctx, 1 /* private key checks */,
1447 1 /* blinding on */) != 0) {
1448 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001449 }
1450
1451#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +02001452 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
1453 return ret;
1454 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001455#endif
1456
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001457 /* MPI Initialization */
Jens Wiklander32b31802023-10-06 16:59:46 +02001458 mbedtls_mpi_init(&T);
Jens Wiklander817466c2018-05-22 13:49:31 +02001459
Jens Wiklander32b31802023-10-06 16:59:46 +02001460 mbedtls_mpi_init(&P1);
1461 mbedtls_mpi_init(&Q1);
1462 mbedtls_mpi_init(&R);
Jens Wiklander817466c2018-05-22 13:49:31 +02001463
Jens Wiklander817466c2018-05-22 13:49:31 +02001464#if defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02001465 mbedtls_mpi_init(&D_blind);
Jens Wiklander817466c2018-05-22 13:49:31 +02001466#else
Jens Wiklander32b31802023-10-06 16:59:46 +02001467 mbedtls_mpi_init(&DP_blind);
1468 mbedtls_mpi_init(&DQ_blind);
Jens Wiklander817466c2018-05-22 13:49:31 +02001469#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001470
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001471#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02001472 mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ);
Jens Wiklander817466c2018-05-22 13:49:31 +02001473#endif
1474
Tom Van Eyckc1633172024-04-09 18:44:13 +02001475 mbedtls_mpi_init(&input_blinded);
1476 mbedtls_mpi_init(&check_result_blinded);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001477
1478 /* End of MPI initialization */
1479
Jens Wiklander32b31802023-10-06 16:59:46 +02001480 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
1481 if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001482 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1483 goto cleanup;
1484 }
1485
Jens Wiklander32b31802023-10-06 16:59:46 +02001486 /*
1487 * Blinding
1488 * T = T * Vi mod N
1489 */
1490 MBEDTLS_MPI_CHK(rsa_prepare_blinding(ctx, f_rng, p_rng));
1491 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vi));
1492 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N));
Jens Wiklander817466c2018-05-22 13:49:31 +02001493
Tom Van Eyckc1633172024-04-09 18:44:13 +02001494 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T));
1495
Jens Wiklander32b31802023-10-06 16:59:46 +02001496 /*
1497 * Exponent blinding
1498 */
1499 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&P1, &ctx->P, 1));
1500 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&Q1, &ctx->Q, 1));
Jens Wiklander817466c2018-05-22 13:49:31 +02001501
1502#if defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02001503 /*
1504 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1505 */
1506 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1507 f_rng, p_rng));
1508 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &P1, &Q1));
1509 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&D_blind, &D_blind, &R));
1510 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&D_blind, &D_blind, &ctx->D));
Jens Wiklander817466c2018-05-22 13:49:31 +02001511#else
Jens Wiklander32b31802023-10-06 16:59:46 +02001512 /*
1513 * DP_blind = ( P - 1 ) * R + DP
1514 */
1515 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1516 f_rng, p_rng));
1517 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DP_blind, &P1, &R));
1518 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DP_blind, &DP_blind,
1519 &ctx->DP));
Jens Wiklander817466c2018-05-22 13:49:31 +02001520
Jens Wiklander32b31802023-10-06 16:59:46 +02001521 /*
1522 * DQ_blind = ( Q - 1 ) * R + DQ
1523 */
1524 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&R, RSA_EXPONENT_BLINDING,
1525 f_rng, p_rng));
1526 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&DQ_blind, &Q1, &R));
1527 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&DQ_blind, &DQ_blind,
1528 &ctx->DQ));
Jens Wiklander817466c2018-05-22 13:49:31 +02001529#endif /* MBEDTLS_RSA_NO_CRT */
Jens Wiklander817466c2018-05-22 13:49:31 +02001530
1531#if defined(MBEDTLS_RSA_NO_CRT)
Tom Van Eyckc1633172024-04-09 18:44:13 +02001532 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &D_blind, &ctx->N, &ctx->RN));
Jens Wiklander817466c2018-05-22 13:49:31 +02001533#else
1534 /*
1535 * Faster decryption using the CRT
1536 *
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001537 * TP = input ^ dP mod P
1538 * TQ = input ^ dQ mod Q
Jens Wiklander817466c2018-05-22 13:49:31 +02001539 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001540
Tom Van Eyckc1633172024-04-09 18:44:13 +02001541 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TP, &T, &DP_blind, &ctx->P, &ctx->RP));
1542 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&TQ, &T, &DQ_blind, &ctx->Q, &ctx->RQ));
Jens Wiklander817466c2018-05-22 13:49:31 +02001543
1544 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001545 * T = (TP - TQ) * (Q^-1 mod P) mod P
Jens Wiklander817466c2018-05-22 13:49:31 +02001546 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001547 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&T, &TP, &TQ));
1548 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->QP));
1549 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &TP, &ctx->P));
Jens Wiklander817466c2018-05-22 13:49:31 +02001550
1551 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001552 * T = TQ + T * Q
Jens Wiklander817466c2018-05-22 13:49:31 +02001553 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001554 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&TP, &T, &ctx->Q));
1555 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP));
Jens Wiklander817466c2018-05-22 13:49:31 +02001556#endif /* MBEDTLS_RSA_NO_CRT */
1557
Tom Van Eyckc1633172024-04-09 18:44:13 +02001558 /* Verify the result to prevent glitching attacks. */
1559 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E,
1560 &ctx->N, &ctx->RN));
1561 if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) {
1562 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
1563 goto cleanup;
1564 }
1565
Jens Wiklander32b31802023-10-06 16:59:46 +02001566 /*
1567 * Unblind
1568 * T = T * Vf mod N
1569 */
Tom Van Eyckc1633172024-04-09 18:44:13 +02001570 MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001571
Jens Wiklander817466c2018-05-22 13:49:31 +02001572 olen = ctx->len;
Jens Wiklander32b31802023-10-06 16:59:46 +02001573 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
Jens Wiklander817466c2018-05-22 13:49:31 +02001574
1575cleanup:
1576#if defined(MBEDTLS_THREADING_C)
Jens Wiklander32b31802023-10-06 16:59:46 +02001577 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
1578 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
Jens Wiklander817466c2018-05-22 13:49:31 +02001579 }
Jens Wiklander32b31802023-10-06 16:59:46 +02001580#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001581
Jens Wiklander32b31802023-10-06 16:59:46 +02001582 mbedtls_mpi_free(&P1);
1583 mbedtls_mpi_free(&Q1);
1584 mbedtls_mpi_free(&R);
1585
1586#if defined(MBEDTLS_RSA_NO_CRT)
1587 mbedtls_mpi_free(&D_blind);
1588#else
1589 mbedtls_mpi_free(&DP_blind);
1590 mbedtls_mpi_free(&DQ_blind);
1591#endif
1592
1593 mbedtls_mpi_free(&T);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001594
1595#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02001596 mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001597#endif
1598
Tom Van Eyckc1633172024-04-09 18:44:13 +02001599 mbedtls_mpi_free(&check_result_blinded);
1600 mbedtls_mpi_free(&input_blinded);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001601
Jens Wiklander32b31802023-10-06 16:59:46 +02001602 if (ret != 0 && ret >= -0x007f) {
1603 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret);
1604 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001605
Jens Wiklander32b31802023-10-06 16:59:46 +02001606 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02001607}
1608
1609#if defined(MBEDTLS_PKCS1_V21)
1610/**
1611 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1612 *
1613 * \param dst buffer to mask
1614 * \param dlen length of destination buffer
1615 * \param src source of the mask generation
1616 * \param slen length of the source buffer
Jens Wiklander32b31802023-10-06 16:59:46 +02001617 * \param md_alg message digest to use
Jens Wiklander817466c2018-05-22 13:49:31 +02001618 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001619static int mgf_mask(unsigned char *dst, size_t dlen, unsigned char *src,
1620 size_t slen, mbedtls_md_type_t md_alg)
Jens Wiklander817466c2018-05-22 13:49:31 +02001621{
Jens Wiklander817466c2018-05-22 13:49:31 +02001622 unsigned char counter[4];
1623 unsigned char *p;
1624 unsigned int hlen;
1625 size_t i, use_len;
Tom Van Eyckc1633172024-04-09 18:44:13 +02001626 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001627 int ret = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +02001628 const mbedtls_md_info_t *md_info;
1629 mbedtls_md_context_t md_ctx;
Jens Wiklander817466c2018-05-22 13:49:31 +02001630
Jens Wiklander32b31802023-10-06 16:59:46 +02001631 mbedtls_md_init(&md_ctx);
1632 md_info = mbedtls_md_info_from_type(md_alg);
1633 if (md_info == NULL) {
1634 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1635 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001636
Jens Wiklander32b31802023-10-06 16:59:46 +02001637 mbedtls_md_init(&md_ctx);
1638 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
1639 goto exit;
1640 }
1641
1642 hlen = mbedtls_md_get_size(md_info);
Jens Wiklander32b31802023-10-06 16:59:46 +02001643
1644 memset(mask, 0, sizeof(mask));
1645 memset(counter, 0, 4);
Jens Wiklander817466c2018-05-22 13:49:31 +02001646
1647 /* Generate and apply dbMask */
1648 p = dst;
1649
Jens Wiklander32b31802023-10-06 16:59:46 +02001650 while (dlen > 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001651 use_len = hlen;
Jens Wiklander32b31802023-10-06 16:59:46 +02001652 if (dlen < hlen) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001653 use_len = dlen;
Jens Wiklander32b31802023-10-06 16:59:46 +02001654 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001655
Jens Wiklander32b31802023-10-06 16:59:46 +02001656 if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001657 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +02001658 }
1659 if ((ret = mbedtls_md_update(&md_ctx, src, slen)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001660 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +02001661 }
1662 if ((ret = mbedtls_md_update(&md_ctx, counter, 4)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001663 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +02001664 }
1665 if ((ret = mbedtls_md_finish(&md_ctx, mask)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001666 goto exit;
Jens Wiklander32b31802023-10-06 16:59:46 +02001667 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001668
Jens Wiklander32b31802023-10-06 16:59:46 +02001669 for (i = 0; i < use_len; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001670 *p++ ^= mask[i];
Jens Wiklander32b31802023-10-06 16:59:46 +02001671 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001672
1673 counter[3]++;
1674
1675 dlen -= use_len;
1676 }
1677
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001678exit:
Jens Wiklander32b31802023-10-06 16:59:46 +02001679 mbedtls_platform_zeroize(mask, sizeof(mask));
Jens Wiklander32b31802023-10-06 16:59:46 +02001680 mbedtls_md_free(&md_ctx);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001681
Jens Wiklander32b31802023-10-06 16:59:46 +02001682 return ret;
Jens Wiklander32b31802023-10-06 16:59:46 +02001683}
1684
1685/**
1686 * Generate Hash(M') as in RFC 8017 page 43 points 5 and 6.
1687 *
1688 * \param hash the input hash
1689 * \param hlen length of the input hash
1690 * \param salt the input salt
1691 * \param slen length of the input salt
1692 * \param out the output buffer - must be large enough for \p md_alg
1693 * \param md_alg message digest to use
1694 */
1695static int hash_mprime(const unsigned char *hash, size_t hlen,
1696 const unsigned char *salt, size_t slen,
1697 unsigned char *out, mbedtls_md_type_t md_alg)
1698{
1699 const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1700
Jens Wiklander32b31802023-10-06 16:59:46 +02001701 mbedtls_md_context_t md_ctx;
1702 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1703
1704 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md_alg);
1705 if (md_info == NULL) {
1706 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1707 }
1708
1709 mbedtls_md_init(&md_ctx);
1710 if ((ret = mbedtls_md_setup(&md_ctx, md_info, 0)) != 0) {
1711 goto exit;
1712 }
1713 if ((ret = mbedtls_md_starts(&md_ctx)) != 0) {
1714 goto exit;
1715 }
1716 if ((ret = mbedtls_md_update(&md_ctx, zeros, sizeof(zeros))) != 0) {
1717 goto exit;
1718 }
1719 if ((ret = mbedtls_md_update(&md_ctx, hash, hlen)) != 0) {
1720 goto exit;
1721 }
1722 if ((ret = mbedtls_md_update(&md_ctx, salt, slen)) != 0) {
1723 goto exit;
1724 }
1725 if ((ret = mbedtls_md_finish(&md_ctx, out)) != 0) {
1726 goto exit;
1727 }
1728
1729exit:
1730 mbedtls_md_free(&md_ctx);
1731
1732 return ret;
Jens Wiklander32b31802023-10-06 16:59:46 +02001733}
1734
1735/**
1736 * Compute a hash.
1737 *
1738 * \param md_alg algorithm to use
1739 * \param input input message to hash
1740 * \param ilen input length
1741 * \param output the output buffer - must be large enough for \p md_alg
1742 */
1743static int compute_hash(mbedtls_md_type_t md_alg,
1744 const unsigned char *input, size_t ilen,
1745 unsigned char *output)
1746{
Jens Wiklander32b31802023-10-06 16:59:46 +02001747 const mbedtls_md_info_t *md_info;
1748
1749 md_info = mbedtls_md_info_from_type(md_alg);
1750 if (md_info == NULL) {
1751 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1752 }
1753
1754 return mbedtls_md(md_info, input, ilen, output);
Jens Wiklander817466c2018-05-22 13:49:31 +02001755}
1756#endif /* MBEDTLS_PKCS1_V21 */
1757
1758#if defined(MBEDTLS_PKCS1_V21)
1759/*
1760 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1761 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001762int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx,
1763 int (*f_rng)(void *, unsigned char *, size_t),
1764 void *p_rng,
1765 const unsigned char *label, size_t label_len,
1766 size_t ilen,
1767 const unsigned char *input,
1768 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +02001769{
1770 size_t olen;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001771 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001772 unsigned char *p = output;
1773 unsigned int hlen;
Jens Wiklander817466c2018-05-22 13:49:31 +02001774
Jens Wiklander32b31802023-10-06 16:59:46 +02001775 if (f_rng == NULL) {
1776 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1777 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001778
Tom Van Eyckc1633172024-04-09 18:44:13 +02001779 hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02001780 if (hlen == 0) {
1781 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1782 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001783
1784 olen = ctx->len;
Jens Wiklander817466c2018-05-22 13:49:31 +02001785
1786 /* first comparison checks for overflow */
Jens Wiklander32b31802023-10-06 16:59:46 +02001787 if (ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2) {
1788 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1789 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001790
Jens Wiklander32b31802023-10-06 16:59:46 +02001791 memset(output, 0, olen);
Jens Wiklander817466c2018-05-22 13:49:31 +02001792
1793 *p++ = 0;
1794
1795 /* Generate a random octet string seed */
Jens Wiklander32b31802023-10-06 16:59:46 +02001796 if ((ret = f_rng(p_rng, p, hlen)) != 0) {
1797 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
1798 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001799
1800 p += hlen;
1801
1802 /* Construct DB */
Jens Wiklander32b31802023-10-06 16:59:46 +02001803 ret = compute_hash((mbedtls_md_type_t) ctx->hash_id, label, label_len, p);
1804 if (ret != 0) {
1805 return ret;
1806 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001807 p += hlen;
1808 p += olen - 2 * hlen - 2 - ilen;
1809 *p++ = 1;
Jens Wiklander32b31802023-10-06 16:59:46 +02001810 if (ilen != 0) {
1811 memcpy(p, input, ilen);
1812 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001813
1814 /* maskedDB: Apply dbMask to DB */
Jens Wiklander32b31802023-10-06 16:59:46 +02001815 if ((ret = mgf_mask(output + hlen + 1, olen - hlen - 1, output + 1, hlen,
Tom Van Eyckc1633172024-04-09 18:44:13 +02001816 (mbedtls_md_type_t) ctx->hash_id)) != 0) {
Jens Wiklander32b31802023-10-06 16:59:46 +02001817 return ret;
1818 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001819
1820 /* maskedSeed: Apply seedMask to seed */
Jens Wiklander32b31802023-10-06 16:59:46 +02001821 if ((ret = mgf_mask(output + 1, hlen, output + hlen + 1, olen - hlen - 1,
Tom Van Eyckc1633172024-04-09 18:44:13 +02001822 (mbedtls_md_type_t) ctx->hash_id)) != 0) {
Jens Wiklander32b31802023-10-06 16:59:46 +02001823 return ret;
1824 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001825
Jens Wiklander32b31802023-10-06 16:59:46 +02001826 return mbedtls_rsa_public(ctx, output, output);
Jens Wiklander817466c2018-05-22 13:49:31 +02001827}
1828#endif /* MBEDTLS_PKCS1_V21 */
1829
1830#if defined(MBEDTLS_PKCS1_V15)
1831/*
1832 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1833 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001834int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx,
1835 int (*f_rng)(void *, unsigned char *, size_t),
1836 void *p_rng, size_t ilen,
1837 const unsigned char *input,
1838 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +02001839{
1840 size_t nb_pad, olen;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001841 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001842 unsigned char *p = output;
1843
Jens Wiklander817466c2018-05-22 13:49:31 +02001844 olen = ctx->len;
1845
1846 /* first comparison checks for overflow */
Jens Wiklander32b31802023-10-06 16:59:46 +02001847 if (ilen + 11 < ilen || olen < ilen + 11) {
1848 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1849 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001850
1851 nb_pad = olen - 3 - ilen;
1852
1853 *p++ = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001854
Jens Wiklander32b31802023-10-06 16:59:46 +02001855 if (f_rng == NULL) {
1856 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander817466c2018-05-22 13:49:31 +02001857 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001858
Jens Wiklander32b31802023-10-06 16:59:46 +02001859 *p++ = MBEDTLS_RSA_CRYPT;
1860
1861 while (nb_pad-- > 0) {
1862 int rng_dl = 100;
1863
1864 do {
1865 ret = f_rng(p_rng, p, 1);
1866 } while (*p == 0 && --rng_dl && ret == 0);
1867
1868 /* Check if RNG failed to generate data */
1869 if (rng_dl == 0 || ret != 0) {
1870 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
1871 }
1872
1873 p++;
Jens Wiklander817466c2018-05-22 13:49:31 +02001874 }
1875
1876 *p++ = 0;
Jens Wiklander32b31802023-10-06 16:59:46 +02001877 if (ilen != 0) {
1878 memcpy(p, input, ilen);
1879 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001880
Jens Wiklander32b31802023-10-06 16:59:46 +02001881 return mbedtls_rsa_public(ctx, output, output);
Jens Wiklander817466c2018-05-22 13:49:31 +02001882}
1883#endif /* MBEDTLS_PKCS1_V15 */
1884
1885/*
1886 * Add the message padding, then do an RSA operation
1887 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001888int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx,
1889 int (*f_rng)(void *, unsigned char *, size_t),
1890 void *p_rng,
1891 size_t ilen,
1892 const unsigned char *input,
1893 unsigned char *output)
Jens Wiklander817466c2018-05-22 13:49:31 +02001894{
Jens Wiklander32b31802023-10-06 16:59:46 +02001895 switch (ctx->padding) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001896#if defined(MBEDTLS_PKCS1_V15)
1897 case MBEDTLS_RSA_PKCS_V15:
Jens Wiklander32b31802023-10-06 16:59:46 +02001898 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx, f_rng, p_rng,
1899 ilen, input, output);
Jens Wiklander817466c2018-05-22 13:49:31 +02001900#endif
1901
1902#if defined(MBEDTLS_PKCS1_V21)
1903 case MBEDTLS_RSA_PKCS_V21:
Jens Wiklander32b31802023-10-06 16:59:46 +02001904 return mbedtls_rsa_rsaes_oaep_encrypt(ctx, f_rng, p_rng, NULL, 0,
1905 ilen, input, output);
Jens Wiklander817466c2018-05-22 13:49:31 +02001906#endif
1907
1908 default:
Jens Wiklander32b31802023-10-06 16:59:46 +02001909 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02001910 }
1911}
1912
1913#if defined(MBEDTLS_PKCS1_V21)
1914/*
1915 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
1916 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001917int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx,
1918 int (*f_rng)(void *, unsigned char *, size_t),
1919 void *p_rng,
1920 const unsigned char *label, size_t label_len,
1921 size_t *olen,
1922 const unsigned char *input,
1923 unsigned char *output,
1924 size_t output_max_len)
Jens Wiklander817466c2018-05-22 13:49:31 +02001925{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001926 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001927 size_t ilen, i, pad_len;
Tom Van Eyckc1633172024-04-09 18:44:13 +02001928 unsigned char *p;
1929 mbedtls_ct_condition_t bad, in_padding;
Jens Wiklander817466c2018-05-22 13:49:31 +02001930 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Tom Van Eyckc1633172024-04-09 18:44:13 +02001931 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Jens Wiklander817466c2018-05-22 13:49:31 +02001932 unsigned int hlen;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001933
Jens Wiklander817466c2018-05-22 13:49:31 +02001934 /*
1935 * Parameters sanity checks
1936 */
Jens Wiklander32b31802023-10-06 16:59:46 +02001937 if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
1938 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1939 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001940
1941 ilen = ctx->len;
1942
Jens Wiklander32b31802023-10-06 16:59:46 +02001943 if (ilen < 16 || ilen > sizeof(buf)) {
1944 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1945 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001946
Tom Van Eyckc1633172024-04-09 18:44:13 +02001947 hlen = mbedtls_md_get_size_from_type((mbedtls_md_type_t) ctx->hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02001948 if (hlen == 0) {
1949 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1950 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001951
1952 // checking for integer underflow
Jens Wiklander32b31802023-10-06 16:59:46 +02001953 if (2 * hlen + 2 > ilen) {
1954 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
1955 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001956
1957 /*
1958 * RSA operation
1959 */
Summer Qind2fda4f2017-12-15 11:27:56 +08001960 if( ctx->P.n == 0 )
1961 ret = mbedtls_rsa_private( ctx, NULL, NULL, input, buf );
1962 else
1963 ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02001964
Jens Wiklander32b31802023-10-06 16:59:46 +02001965 if (ret != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02001966 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02001967 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001968
1969 /*
1970 * Unmask data and generate lHash
1971 */
Jens Wiklander817466c2018-05-22 13:49:31 +02001972 /* seed: Apply seedMask to maskedSeed */
Jens Wiklander32b31802023-10-06 16:59:46 +02001973 if ((ret = mgf_mask(buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
Tom Van Eyckc1633172024-04-09 18:44:13 +02001974 (mbedtls_md_type_t) ctx->hash_id)) != 0 ||
Jens Wiklander32b31802023-10-06 16:59:46 +02001975 /* DB: Apply dbMask to maskedDB */
1976 (ret = mgf_mask(buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
Tom Van Eyckc1633172024-04-09 18:44:13 +02001977 (mbedtls_md_type_t) ctx->hash_id)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001978 goto cleanup;
1979 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001980
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001981 /* Generate lHash */
Jens Wiklander32b31802023-10-06 16:59:46 +02001982 ret = compute_hash((mbedtls_md_type_t) ctx->hash_id,
1983 label, label_len, lhash);
1984 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001985 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02001986 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001987
Jens Wiklander817466c2018-05-22 13:49:31 +02001988 /*
1989 * Check contents, in "constant-time"
1990 */
1991 p = buf;
Jens Wiklander817466c2018-05-22 13:49:31 +02001992
Tom Van Eyckc1633172024-04-09 18:44:13 +02001993 bad = mbedtls_ct_bool(*p++); /* First byte must be 0 */
Jens Wiklander817466c2018-05-22 13:49:31 +02001994
1995 p += hlen; /* Skip seed */
1996
1997 /* Check lHash */
Tom Van Eyckc1633172024-04-09 18:44:13 +02001998 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool(mbedtls_ct_memcmp(lhash, p, hlen)));
1999 p += hlen;
Jens Wiklander817466c2018-05-22 13:49:31 +02002000
2001 /* Get zero-padding len, but always read till end of buffer
2002 * (minus one, for the 01 byte) */
2003 pad_len = 0;
Tom Van Eyckc1633172024-04-09 18:44:13 +02002004 in_padding = MBEDTLS_CT_TRUE;
Jens Wiklander32b31802023-10-06 16:59:46 +02002005 for (i = 0; i < ilen - 2 * hlen - 2; i++) {
Tom Van Eyckc1633172024-04-09 18:44:13 +02002006 in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_uint_eq(p[i], 0));
2007 pad_len += mbedtls_ct_uint_if_else_0(in_padding, 1);
Jens Wiklander817466c2018-05-22 13:49:31 +02002008 }
2009
2010 p += pad_len;
Tom Van Eyckc1633172024-04-09 18:44:13 +02002011 bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_ne(*p++, 0x01));
Jens Wiklander817466c2018-05-22 13:49:31 +02002012
2013 /*
2014 * The only information "leaked" is whether the padding was correct or not
2015 * (eg, no data is copied if it was not correct). This meets the
2016 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
2017 * the different error conditions.
2018 */
Tom Van Eyckc1633172024-04-09 18:44:13 +02002019 if (bad != MBEDTLS_CT_FALSE) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002020 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
2021 goto cleanup;
2022 }
2023
Tom Van Eyckc1633172024-04-09 18:44:13 +02002024 if (ilen - ((size_t) (p - buf)) > output_max_len) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002025 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
2026 goto cleanup;
2027 }
2028
Tom Van Eyckc1633172024-04-09 18:44:13 +02002029 *olen = ilen - ((size_t) (p - buf));
Jens Wiklander32b31802023-10-06 16:59:46 +02002030 if (*olen != 0) {
2031 memcpy(output, p, *olen);
2032 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002033 ret = 0;
2034
2035cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +02002036 mbedtls_platform_zeroize(buf, sizeof(buf));
2037 mbedtls_platform_zeroize(lhash, sizeof(lhash));
Jens Wiklander817466c2018-05-22 13:49:31 +02002038
Jens Wiklander32b31802023-10-06 16:59:46 +02002039 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02002040}
2041#endif /* MBEDTLS_PKCS1_V21 */
2042
2043#if defined(MBEDTLS_PKCS1_V15)
2044/*
2045 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
2046 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002047int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx,
2048 int (*f_rng)(void *, unsigned char *, size_t),
2049 void *p_rng,
2050 size_t *olen,
2051 const unsigned char *input,
2052 unsigned char *output,
2053 size_t output_max_len)
Jens Wiklander817466c2018-05-22 13:49:31 +02002054{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jerome Forissier039e02d2022-08-09 17:10:15 +02002056 size_t ilen;
Jens Wiklander817466c2018-05-22 13:49:31 +02002057 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002058
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002059 ilen = ctx->len;
Jens Wiklander817466c2018-05-22 13:49:31 +02002060
Jens Wiklander32b31802023-10-06 16:59:46 +02002061 if (ctx->padding != MBEDTLS_RSA_PKCS_V15) {
2062 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2063 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002064
Jens Wiklander32b31802023-10-06 16:59:46 +02002065 if (ilen < 16 || ilen > sizeof(buf)) {
2066 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2067 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002068
Jens Wiklander32b31802023-10-06 16:59:46 +02002069 ret = mbedtls_rsa_private(ctx, f_rng, p_rng, input, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02002070
Jens Wiklander32b31802023-10-06 16:59:46 +02002071 if (ret != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002072 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02002073 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002074
Jens Wiklander32b31802023-10-06 16:59:46 +02002075 ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding(buf, ilen,
2076 output, output_max_len, olen);
Jens Wiklander817466c2018-05-22 13:49:31 +02002077
2078cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +02002079 mbedtls_platform_zeroize(buf, sizeof(buf));
Jens Wiklander817466c2018-05-22 13:49:31 +02002080
Jens Wiklander32b31802023-10-06 16:59:46 +02002081 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02002082}
2083#endif /* MBEDTLS_PKCS1_V15 */
2084
2085/*
2086 * Do an RSA operation, then remove the message padding
2087 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002088int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx,
2089 int (*f_rng)(void *, unsigned char *, size_t),
2090 void *p_rng,
2091 size_t *olen,
2092 const unsigned char *input,
2093 unsigned char *output,
2094 size_t output_max_len)
Jens Wiklander817466c2018-05-22 13:49:31 +02002095{
Jens Wiklander32b31802023-10-06 16:59:46 +02002096 switch (ctx->padding) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002097#if defined(MBEDTLS_PKCS1_V15)
2098 case MBEDTLS_RSA_PKCS_V15:
Jens Wiklander32b31802023-10-06 16:59:46 +02002099 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx, f_rng, p_rng, olen,
2100 input, output, output_max_len);
Jens Wiklander817466c2018-05-22 13:49:31 +02002101#endif
2102
2103#if defined(MBEDTLS_PKCS1_V21)
2104 case MBEDTLS_RSA_PKCS_V21:
Jens Wiklander32b31802023-10-06 16:59:46 +02002105 return mbedtls_rsa_rsaes_oaep_decrypt(ctx, f_rng, p_rng, NULL, 0,
2106 olen, input, output,
2107 output_max_len);
Jens Wiklander817466c2018-05-22 13:49:31 +02002108#endif
2109
2110 default:
Jens Wiklander32b31802023-10-06 16:59:46 +02002111 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002112 }
2113}
2114
2115#if defined(MBEDTLS_PKCS1_V21)
Tom Van Eyckc1633172024-04-09 18:44:13 +02002116static int rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx,
2117 int (*f_rng)(void *, unsigned char *, size_t),
2118 void *p_rng,
2119 mbedtls_md_type_t md_alg,
2120 unsigned int hashlen,
2121 const unsigned char *hash,
2122 int saltlen,
2123 unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002124{
2125 size_t olen;
2126 unsigned char *p = sig;
Jerome Forissier79013242021-07-28 10:24:04 +02002127 unsigned char *salt = NULL;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002128 size_t slen, min_slen, hlen, offset = 0;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002129 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002130 size_t msb;
Tom Van Eyckc1633172024-04-09 18:44:13 +02002131 mbedtls_md_type_t hash_id;
Jens Wiklander817466c2018-05-22 13:49:31 +02002132
Jens Wiklander32b31802023-10-06 16:59:46 +02002133 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2134 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2135 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002136
Jens Wiklander32b31802023-10-06 16:59:46 +02002137 if (f_rng == NULL) {
2138 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2139 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002140
2141 olen = ctx->len;
2142
Jens Wiklander32b31802023-10-06 16:59:46 +02002143 if (md_alg != MBEDTLS_MD_NONE) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002144 /* Gather length of hash to sign */
Tom Van Eyckc1633172024-04-09 18:44:13 +02002145 size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
Jens Wiklander32b31802023-10-06 16:59:46 +02002146 if (exp_hashlen == 0) {
2147 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2148 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002149
Jens Wiklander32b31802023-10-06 16:59:46 +02002150 if (hashlen != exp_hashlen) {
2151 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2152 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002153 }
2154
Tom Van Eyckc1633172024-04-09 18:44:13 +02002155 hash_id = (mbedtls_md_type_t) ctx->hash_id;
2156 if (hash_id == MBEDTLS_MD_NONE) {
2157 hash_id = md_alg;
2158 }
2159 hlen = mbedtls_md_get_size_from_type(hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02002160 if (hlen == 0) {
2161 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2162 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002163
Jens Wiklander32b31802023-10-06 16:59:46 +02002164 if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) {
2165 /* Calculate the largest possible salt length, up to the hash size.
2166 * Normally this is the hash length, which is the maximum salt length
2167 * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
2168 * enough room, use the maximum salt length that fits. The constraint is
2169 * that the hash length plus the salt length plus 2 bytes must be at most
2170 * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
2171 * (PKCS#1 v2.2) §9.1.1 step 3. */
Jerome Forissier79013242021-07-28 10:24:04 +02002172 min_slen = hlen - 2;
Jens Wiklander32b31802023-10-06 16:59:46 +02002173 if (olen < hlen + min_slen + 2) {
2174 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2175 } else if (olen >= hlen + hlen + 2) {
Jerome Forissier79013242021-07-28 10:24:04 +02002176 slen = hlen;
Jens Wiklander32b31802023-10-06 16:59:46 +02002177 } else {
Jerome Forissier79013242021-07-28 10:24:04 +02002178 slen = olen - hlen - 2;
Jens Wiklander32b31802023-10-06 16:59:46 +02002179 }
2180 } else if ((saltlen < 0) || (saltlen + hlen + 2 > olen)) {
2181 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2182 } else {
Jerome Forissier79013242021-07-28 10:24:04 +02002183 slen = (size_t) saltlen;
2184 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002185
Jens Wiklander32b31802023-10-06 16:59:46 +02002186 memset(sig, 0, olen);
Jens Wiklander817466c2018-05-22 13:49:31 +02002187
Jens Wiklander817466c2018-05-22 13:49:31 +02002188 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Jens Wiklander32b31802023-10-06 16:59:46 +02002189 msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002190 p += olen - hlen - slen - 2;
Jens Wiklander817466c2018-05-22 13:49:31 +02002191 *p++ = 0x01;
Jerome Forissier79013242021-07-28 10:24:04 +02002192
2193 /* Generate salt of length slen in place in the encoded message */
2194 salt = p;
Jens Wiklander32b31802023-10-06 16:59:46 +02002195 if ((ret = f_rng(p_rng, salt, slen)) != 0) {
2196 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_RNG_FAILED, ret);
2197 }
Jerome Forissier79013242021-07-28 10:24:04 +02002198
Jens Wiklander817466c2018-05-22 13:49:31 +02002199 p += slen;
2200
Jens Wiklander817466c2018-05-22 13:49:31 +02002201 /* Generate H = Hash( M' ) */
Tom Van Eyckc1633172024-04-09 18:44:13 +02002202 ret = hash_mprime(hash, hashlen, salt, slen, p, hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02002203 if (ret != 0) {
2204 return ret;
2205 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002206
2207 /* Compensate for boundary condition when applying mask */
Jens Wiklander32b31802023-10-06 16:59:46 +02002208 if (msb % 8 == 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002209 offset = 1;
Jens Wiklander32b31802023-10-06 16:59:46 +02002210 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002211
2212 /* maskedDB: Apply dbMask to DB */
Tom Van Eyckc1633172024-04-09 18:44:13 +02002213 ret = mgf_mask(sig + offset, olen - hlen - 1 - offset, p, hlen, hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02002214 if (ret != 0) {
2215 return ret;
2216 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002217
Jens Wiklander32b31802023-10-06 16:59:46 +02002218 msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
2219 sig[0] &= 0xFF >> (olen * 8 - msb);
Jens Wiklander817466c2018-05-22 13:49:31 +02002220
2221 p += hlen;
2222 *p++ = 0xBC;
2223
Summer Qind2fda4f2017-12-15 11:27:56 +08002224 if (ctx->P.n == 0)
2225 return mbedtls_rsa_private(ctx, NULL, NULL, sig, sig);
2226
Jens Wiklander32b31802023-10-06 16:59:46 +02002227 return mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002228}
Jerome Forissier79013242021-07-28 10:24:04 +02002229
Tom Van Eyckc1633172024-04-09 18:44:13 +02002230static int rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
2231 int (*f_rng)(void *, unsigned char *, size_t),
2232 void *p_rng,
2233 mbedtls_md_type_t md_alg,
2234 unsigned int hashlen,
2235 const unsigned char *hash,
2236 int saltlen,
2237 unsigned char *sig)
2238{
2239 if (ctx->padding != MBEDTLS_RSA_PKCS_V21) {
2240 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2241 }
2242 if ((ctx->hash_id == MBEDTLS_MD_NONE) && (md_alg == MBEDTLS_MD_NONE)) {
2243 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2244 }
2245 return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg, hashlen, hash, saltlen,
2246 sig);
2247}
2248
2249int mbedtls_rsa_rsassa_pss_sign_no_mode_check(mbedtls_rsa_context *ctx,
2250 int (*f_rng)(void *, unsigned char *, size_t),
2251 void *p_rng,
2252 mbedtls_md_type_t md_alg,
2253 unsigned int hashlen,
2254 const unsigned char *hash,
2255 unsigned char *sig)
2256{
2257 return rsa_rsassa_pss_sign_no_mode_check(ctx, f_rng, p_rng, md_alg,
2258 hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig);
2259}
2260
Jerome Forissier79013242021-07-28 10:24:04 +02002261/*
2262 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
2263 * the option to pass in the salt length.
2264 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002265int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx,
2266 int (*f_rng)(void *, unsigned char *, size_t),
2267 void *p_rng,
2268 mbedtls_md_type_t md_alg,
2269 unsigned int hashlen,
2270 const unsigned char *hash,
2271 int saltlen,
2272 unsigned char *sig)
Jerome Forissier79013242021-07-28 10:24:04 +02002273{
Jens Wiklander32b31802023-10-06 16:59:46 +02002274 return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
2275 hashlen, hash, saltlen, sig);
Jerome Forissier79013242021-07-28 10:24:04 +02002276}
2277
Jerome Forissier79013242021-07-28 10:24:04 +02002278/*
2279 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
2280 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002281int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx,
2282 int (*f_rng)(void *, unsigned char *, size_t),
2283 void *p_rng,
2284 mbedtls_md_type_t md_alg,
2285 unsigned int hashlen,
2286 const unsigned char *hash,
2287 unsigned char *sig)
Jerome Forissier79013242021-07-28 10:24:04 +02002288{
Jens Wiklander32b31802023-10-06 16:59:46 +02002289 return rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
2290 hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig);
Jerome Forissier79013242021-07-28 10:24:04 +02002291}
Jens Wiklander817466c2018-05-22 13:49:31 +02002292#endif /* MBEDTLS_PKCS1_V21 */
2293
2294#if defined(MBEDTLS_PKCS1_V15)
2295/*
2296 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
2297 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002298
2299/* Construct a PKCS v1.5 encoding of a hashed message
2300 *
2301 * This is used both for signature generation and verification.
2302 *
2303 * Parameters:
2304 * - md_alg: Identifies the hash algorithm used to generate the given hash;
2305 * MBEDTLS_MD_NONE if raw data is signed.
Jens Wiklander32b31802023-10-06 16:59:46 +02002306 * - hashlen: Length of hash. Must match md_alg if that's not NONE.
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002307 * - hash: Buffer containing the hashed message or the raw data.
2308 * - dst_len: Length of the encoded message.
2309 * - dst: Buffer to hold the encoded message.
2310 *
2311 * Assumptions:
Jens Wiklander32b31802023-10-06 16:59:46 +02002312 * - hash has size hashlen.
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002313 * - dst points to a buffer of size at least dst_len.
2314 *
2315 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002316static int rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg,
2317 unsigned int hashlen,
2318 const unsigned char *hash,
2319 size_t dst_len,
2320 unsigned char *dst)
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002321{
2322 size_t oid_size = 0;
2323 size_t nb_pad = dst_len;
2324 unsigned char *p = dst;
2325 const char *oid = NULL;
2326
2327 /* Are we signing hashed or raw data? */
Jens Wiklander32b31802023-10-06 16:59:46 +02002328 if (md_alg != MBEDTLS_MD_NONE) {
Tom Van Eyckc1633172024-04-09 18:44:13 +02002329 unsigned char md_size = mbedtls_md_get_size_from_type(md_alg);
Jens Wiklander32b31802023-10-06 16:59:46 +02002330 if (md_size == 0) {
2331 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2332 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002333
Jens Wiklander32b31802023-10-06 16:59:46 +02002334 if (mbedtls_oid_get_oid_by_md(md_alg, &oid, &oid_size) != 0) {
2335 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2336 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002337
Jens Wiklander32b31802023-10-06 16:59:46 +02002338 if (hashlen != md_size) {
2339 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2340 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002341
2342 /* Double-check that 8 + hashlen + oid_size can be used as a
2343 * 1-byte ASN.1 length encoding and that there's no overflow. */
Jens Wiklander32b31802023-10-06 16:59:46 +02002344 if (8 + hashlen + oid_size >= 0x80 ||
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002345 10 + hashlen < hashlen ||
Jens Wiklander32b31802023-10-06 16:59:46 +02002346 10 + hashlen + oid_size < 10 + hashlen) {
2347 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2348 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002349
2350 /*
2351 * Static bounds check:
2352 * - Need 10 bytes for five tag-length pairs.
2353 * (Insist on 1-byte length encodings to protect against variants of
2354 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
2355 * - Need hashlen bytes for hash
2356 * - Need oid_size bytes for hash alg OID.
2357 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002358 if (nb_pad < 10 + hashlen + oid_size) {
2359 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2360 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002361 nb_pad -= 10 + hashlen + oid_size;
Jens Wiklander32b31802023-10-06 16:59:46 +02002362 } else {
2363 if (nb_pad < hashlen) {
2364 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2365 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002366
2367 nb_pad -= hashlen;
2368 }
2369
2370 /* Need space for signature header and padding delimiter (3 bytes),
2371 * and 8 bytes for the minimal padding */
Jens Wiklander32b31802023-10-06 16:59:46 +02002372 if (nb_pad < 3 + 8) {
2373 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2374 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002375 nb_pad -= 3;
2376
2377 /* Now nb_pad is the amount of memory to be filled
2378 * with padding, and at least 8 bytes long. */
2379
2380 /* Write signature header and padding */
2381 *p++ = 0;
2382 *p++ = MBEDTLS_RSA_SIGN;
Jens Wiklander32b31802023-10-06 16:59:46 +02002383 memset(p, 0xFF, nb_pad);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002384 p += nb_pad;
2385 *p++ = 0;
2386
2387 /* Are we signing raw data? */
Jens Wiklander32b31802023-10-06 16:59:46 +02002388 if (md_alg == MBEDTLS_MD_NONE) {
2389 memcpy(p, hash, hashlen);
2390 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002391 }
2392
2393 /* Signing hashed data, add corresponding ASN.1 structure
2394 *
2395 * DigestInfo ::= SEQUENCE {
2396 * digestAlgorithm DigestAlgorithmIdentifier,
2397 * digest Digest }
2398 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
2399 * Digest ::= OCTET STRING
2400 *
2401 * Schematic:
2402 * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
2403 * TAG-NULL + LEN [ NULL ] ]
2404 * TAG-OCTET + LEN [ HASH ] ]
2405 */
2406 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Jens Wiklander32b31802023-10-06 16:59:46 +02002407 *p++ = (unsigned char) (0x08 + oid_size + hashlen);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002408 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Jens Wiklander32b31802023-10-06 16:59:46 +02002409 *p++ = (unsigned char) (0x04 + oid_size);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002410 *p++ = MBEDTLS_ASN1_OID;
2411 *p++ = (unsigned char) oid_size;
Jens Wiklander32b31802023-10-06 16:59:46 +02002412 memcpy(p, oid, oid_size);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002413 p += oid_size;
2414 *p++ = MBEDTLS_ASN1_NULL;
2415 *p++ = 0x00;
2416 *p++ = MBEDTLS_ASN1_OCTET_STRING;
2417 *p++ = (unsigned char) hashlen;
Jens Wiklander32b31802023-10-06 16:59:46 +02002418 memcpy(p, hash, hashlen);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002419 p += hashlen;
2420
2421 /* Just a sanity-check, should be automatic
2422 * after the initial bounds check. */
Jens Wiklander32b31802023-10-06 16:59:46 +02002423 if (p != dst + dst_len) {
2424 mbedtls_platform_zeroize(dst, dst_len);
2425 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002426 }
2427
Jens Wiklander32b31802023-10-06 16:59:46 +02002428 return 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002429}
2430
Jens Wiklander817466c2018-05-22 13:49:31 +02002431/*
2432 * Do an RSA operation to sign the message digest
2433 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002434int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx,
2435 int (*f_rng)(void *, unsigned char *, size_t),
2436 void *p_rng,
2437 mbedtls_md_type_t md_alg,
2438 unsigned int hashlen,
2439 const unsigned char *hash,
2440 unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002441{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002442 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002443 unsigned char *sig_try = NULL, *verif = NULL;
2444
Jens Wiklander32b31802023-10-06 16:59:46 +02002445 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2446 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2447 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002448
Jens Wiklander32b31802023-10-06 16:59:46 +02002449 if (ctx->padding != MBEDTLS_RSA_PKCS_V15) {
2450 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2451 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002452
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002453 /*
2454 * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
2455 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002456
Jens Wiklander32b31802023-10-06 16:59:46 +02002457 if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash,
2458 ctx->len, sig)) != 0) {
2459 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002460 }
2461
2462 /* Private key operation
2463 *
Jens Wiklander817466c2018-05-22 13:49:31 +02002464 * In order to prevent Lenstra's attack, make the signature in a
2465 * temporary buffer and check it before returning it.
2466 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002467
Jens Wiklander32b31802023-10-06 16:59:46 +02002468 sig_try = mbedtls_calloc(1, ctx->len);
2469 if (sig_try == NULL) {
2470 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002471 }
2472
Jens Wiklander32b31802023-10-06 16:59:46 +02002473 verif = mbedtls_calloc(1, ctx->len);
2474 if (verif == NULL) {
2475 mbedtls_free(sig_try);
2476 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
2477 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002478
Jens Wiklander32b31802023-10-06 16:59:46 +02002479 MBEDTLS_MPI_CHK(mbedtls_rsa_private(ctx, f_rng, p_rng, sig, sig_try));
2480 MBEDTLS_MPI_CHK(mbedtls_rsa_public(ctx, sig_try, verif));
2481
2482 if (mbedtls_ct_memcmp(verif, sig, ctx->len) != 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002483 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2484 goto cleanup;
2485 }
2486
Jens Wiklander32b31802023-10-06 16:59:46 +02002487 memcpy(sig, sig_try, ctx->len);
Jens Wiklander817466c2018-05-22 13:49:31 +02002488
2489cleanup:
Tom Van Eyckc1633172024-04-09 18:44:13 +02002490 mbedtls_zeroize_and_free(sig_try, ctx->len);
2491 mbedtls_zeroize_and_free(verif, ctx->len);
Jens Wiklander817466c2018-05-22 13:49:31 +02002492
Jens Wiklander32b31802023-10-06 16:59:46 +02002493 if (ret != 0) {
2494 memset(sig, '!', ctx->len);
2495 }
2496 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02002497}
2498#endif /* MBEDTLS_PKCS1_V15 */
2499
2500/*
2501 * Do an RSA operation to sign the message digest
2502 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002503int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx,
2504 int (*f_rng)(void *, unsigned char *, size_t),
2505 void *p_rng,
2506 mbedtls_md_type_t md_alg,
2507 unsigned int hashlen,
2508 const unsigned char *hash,
2509 unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002510{
Jens Wiklander32b31802023-10-06 16:59:46 +02002511 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2512 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2513 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002514
Jens Wiklander32b31802023-10-06 16:59:46 +02002515 switch (ctx->padding) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002516#if defined(MBEDTLS_PKCS1_V15)
2517 case MBEDTLS_RSA_PKCS_V15:
Jens Wiklander32b31802023-10-06 16:59:46 +02002518 return mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx, f_rng, p_rng,
2519 md_alg, hashlen, hash, sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002520#endif
2521
2522#if defined(MBEDTLS_PKCS1_V21)
2523 case MBEDTLS_RSA_PKCS_V21:
Jens Wiklander32b31802023-10-06 16:59:46 +02002524 return mbedtls_rsa_rsassa_pss_sign(ctx, f_rng, p_rng, md_alg,
2525 hashlen, hash, sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002526#endif
2527
2528 default:
Jens Wiklander32b31802023-10-06 16:59:46 +02002529 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002530 }
2531}
2532
2533#if defined(MBEDTLS_PKCS1_V21)
2534/*
2535 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2536 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002537int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx,
2538 mbedtls_md_type_t md_alg,
2539 unsigned int hashlen,
2540 const unsigned char *hash,
2541 mbedtls_md_type_t mgf1_hash_id,
2542 int expected_salt_len,
2543 const unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002544{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002545 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002546 size_t siglen;
2547 unsigned char *p;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002548 unsigned char *hash_start;
Tom Van Eyckc1633172024-04-09 18:44:13 +02002549 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Jens Wiklander817466c2018-05-22 13:49:31 +02002550 unsigned int hlen;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002551 size_t observed_salt_len, msb;
Jens Wiklander32b31802023-10-06 16:59:46 +02002552 unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = { 0 };
Jens Wiklander817466c2018-05-22 13:49:31 +02002553
Jens Wiklander32b31802023-10-06 16:59:46 +02002554 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2555 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2556 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002557
2558 siglen = ctx->len;
2559
Jens Wiklander32b31802023-10-06 16:59:46 +02002560 if (siglen < 16 || siglen > sizeof(buf)) {
2561 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2562 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002563
Jens Wiklander32b31802023-10-06 16:59:46 +02002564 ret = mbedtls_rsa_public(ctx, sig, buf);
Jens Wiklander817466c2018-05-22 13:49:31 +02002565
Jens Wiklander32b31802023-10-06 16:59:46 +02002566 if (ret != 0) {
2567 return ret;
2568 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002569
2570 p = buf;
2571
Jens Wiklander32b31802023-10-06 16:59:46 +02002572 if (buf[siglen - 1] != 0xBC) {
2573 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002574 }
2575
Jens Wiklander32b31802023-10-06 16:59:46 +02002576 if (md_alg != MBEDTLS_MD_NONE) {
2577 /* Gather length of hash to sign */
Tom Van Eyckc1633172024-04-09 18:44:13 +02002578 size_t exp_hashlen = mbedtls_md_get_size_from_type(md_alg);
Jens Wiklander32b31802023-10-06 16:59:46 +02002579 if (exp_hashlen == 0) {
2580 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2581 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002582
Jens Wiklander32b31802023-10-06 16:59:46 +02002583 if (hashlen != exp_hashlen) {
2584 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2585 }
2586 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002587
Tom Van Eyckc1633172024-04-09 18:44:13 +02002588 hlen = mbedtls_md_get_size_from_type(mgf1_hash_id);
Jens Wiklander32b31802023-10-06 16:59:46 +02002589 if (hlen == 0) {
2590 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2591 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002592
2593 /*
2594 * Note: EMSA-PSS verification is over the length of N - 1 bits
2595 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002596 msb = mbedtls_mpi_bitlen(&ctx->N) - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002597
Jens Wiklander32b31802023-10-06 16:59:46 +02002598 if (buf[0] >> (8 - siglen * 8 + msb)) {
2599 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2600 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002601
Jens Wiklander817466c2018-05-22 13:49:31 +02002602 /* Compensate for boundary condition when applying mask */
Jens Wiklander32b31802023-10-06 16:59:46 +02002603 if (msb % 8 == 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002604 p++;
2605 siglen -= 1;
2606 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002607
Jens Wiklander32b31802023-10-06 16:59:46 +02002608 if (siglen < hlen + 2) {
2609 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2610 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002611 hash_start = p + siglen - hlen - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002612
Jens Wiklander32b31802023-10-06 16:59:46 +02002613 ret = mgf_mask(p, siglen - hlen - 1, hash_start, hlen, mgf1_hash_id);
2614 if (ret != 0) {
2615 return ret;
2616 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002617
Jens Wiklander32b31802023-10-06 16:59:46 +02002618 buf[0] &= 0xFF >> (siglen * 8 - msb);
Jens Wiklander817466c2018-05-22 13:49:31 +02002619
Jens Wiklander32b31802023-10-06 16:59:46 +02002620 while (p < hash_start - 1 && *p == 0) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002621 p++;
Jens Wiklander32b31802023-10-06 16:59:46 +02002622 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002623
Jens Wiklander32b31802023-10-06 16:59:46 +02002624 if (*p++ != 0x01) {
2625 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002626 }
2627
Tom Van Eyckc1633172024-04-09 18:44:13 +02002628 observed_salt_len = (size_t) (hash_start - p);
Jens Wiklander817466c2018-05-22 13:49:31 +02002629
Jens Wiklander32b31802023-10-06 16:59:46 +02002630 if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
2631 observed_salt_len != (size_t) expected_salt_len) {
2632 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002633 }
2634
2635 /*
2636 * Generate H = Hash( M' )
2637 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002638 ret = hash_mprime(hash, hashlen, p, observed_salt_len,
2639 result, mgf1_hash_id);
2640 if (ret != 0) {
2641 return ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002642 }
2643
Jens Wiklander30bdb1b2022-04-01 17:45:55 +02002644 if (FTMN_CALLEE_DONE_MEMCMP(memcmp, hash_start, result, hlen) != 0) {
Jens Wiklander32b31802023-10-06 16:59:46 +02002645 return MBEDTLS_ERR_RSA_VERIFY_FAILED;
2646 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002647
Jens Wiklander32b31802023-10-06 16:59:46 +02002648 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02002649}
2650
2651/*
2652 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2653 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002654int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx,
2655 mbedtls_md_type_t md_alg,
2656 unsigned int hashlen,
2657 const unsigned char *hash,
2658 const unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002659{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002660 mbedtls_md_type_t mgf1_hash_id;
Jens Wiklander32b31802023-10-06 16:59:46 +02002661 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2662 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2663 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002664
Jens Wiklander32b31802023-10-06 16:59:46 +02002665 mgf1_hash_id = (ctx->hash_id != MBEDTLS_MD_NONE)
Jens Wiklander817466c2018-05-22 13:49:31 +02002666 ? (mbedtls_md_type_t) ctx->hash_id
2667 : md_alg;
2668
Jens Wiklander32b31802023-10-06 16:59:46 +02002669 return mbedtls_rsa_rsassa_pss_verify_ext(ctx,
2670 md_alg, hashlen, hash,
2671 mgf1_hash_id,
2672 MBEDTLS_RSA_SALT_LEN_ANY,
2673 sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002674
2675}
2676#endif /* MBEDTLS_PKCS1_V21 */
2677
2678#if defined(MBEDTLS_PKCS1_V15)
2679/*
2680 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2681 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002682int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx,
2683 mbedtls_md_type_t md_alg,
2684 unsigned int hashlen,
2685 const unsigned char *hash,
2686 const unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002687{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002688 int ret = 0;
2689 size_t sig_len;
2690 unsigned char *encoded = NULL, *encoded_expected = NULL;
2691
Jens Wiklander32b31802023-10-06 16:59:46 +02002692 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2693 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2694 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002695
2696 sig_len = ctx->len;
Jens Wiklander817466c2018-05-22 13:49:31 +02002697
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002698 /*
2699 * Prepare expected PKCS1 v1.5 encoding of hash.
2700 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002701
Jens Wiklander32b31802023-10-06 16:59:46 +02002702 if ((encoded = mbedtls_calloc(1, sig_len)) == NULL ||
2703 (encoded_expected = mbedtls_calloc(1, sig_len)) == NULL) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002704 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2705 goto cleanup;
2706 }
2707
Jens Wiklander32b31802023-10-06 16:59:46 +02002708 if ((ret = rsa_rsassa_pkcs1_v15_encode(md_alg, hashlen, hash, sig_len,
2709 encoded_expected)) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002710 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02002711 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002712
2713 /*
2714 * Apply RSA primitive to get what should be PKCS1 encoded hash.
2715 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002716
Jens Wiklander32b31802023-10-06 16:59:46 +02002717 ret = mbedtls_rsa_public(ctx, sig, encoded);
2718 if (ret != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002719 goto cleanup;
Jens Wiklander32b31802023-10-06 16:59:46 +02002720 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002721
2722 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002723 * Compare
Jens Wiklander817466c2018-05-22 13:49:31 +02002724 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002725
Jens Wiklander523ae952022-04-01 17:45:56 +02002726 if ((ret = FTMN_CALLEE_DONE_MEMCMP(mbedtls_ct_memcmp, encoded,
2727 encoded_expected, sig_len )) != 0) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002728 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2729 goto cleanup;
2730 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002731
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002732cleanup:
Jens Wiklander817466c2018-05-22 13:49:31 +02002733
Jens Wiklander32b31802023-10-06 16:59:46 +02002734 if (encoded != NULL) {
Tom Van Eyckc1633172024-04-09 18:44:13 +02002735 mbedtls_zeroize_and_free(encoded, sig_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002736 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002737
Jens Wiklander32b31802023-10-06 16:59:46 +02002738 if (encoded_expected != NULL) {
Tom Van Eyckc1633172024-04-09 18:44:13 +02002739 mbedtls_zeroize_and_free(encoded_expected, sig_len);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002740 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002741
Jens Wiklander32b31802023-10-06 16:59:46 +02002742 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02002743}
2744#endif /* MBEDTLS_PKCS1_V15 */
2745
2746/*
2747 * Do an RSA operation and check the message digest
2748 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002749int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx,
2750 mbedtls_md_type_t md_alg,
2751 unsigned int hashlen,
2752 const unsigned char *hash,
2753 const unsigned char *sig)
Jens Wiklander817466c2018-05-22 13:49:31 +02002754{
Jens Wiklander32b31802023-10-06 16:59:46 +02002755 if ((md_alg != MBEDTLS_MD_NONE || hashlen != 0) && hash == NULL) {
2756 return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
2757 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002758
Jens Wiklander32b31802023-10-06 16:59:46 +02002759 switch (ctx->padding) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002760#if defined(MBEDTLS_PKCS1_V15)
2761 case MBEDTLS_RSA_PKCS_V15:
Jens Wiklander32b31802023-10-06 16:59:46 +02002762 return mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx, md_alg,
2763 hashlen, hash, sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002764#endif
2765
2766#if defined(MBEDTLS_PKCS1_V21)
2767 case MBEDTLS_RSA_PKCS_V21:
Jens Wiklander32b31802023-10-06 16:59:46 +02002768 return mbedtls_rsa_rsassa_pss_verify(ctx, md_alg,
2769 hashlen, hash, sig);
Jens Wiklander817466c2018-05-22 13:49:31 +02002770#endif
2771
2772 default:
Jens Wiklander32b31802023-10-06 16:59:46 +02002773 return MBEDTLS_ERR_RSA_INVALID_PADDING;
Jens Wiklander817466c2018-05-22 13:49:31 +02002774 }
2775}
2776
2777/*
2778 * Copy the components of an RSA key
2779 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002780int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src)
Jens Wiklander817466c2018-05-22 13:49:31 +02002781{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002782 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002783
Jens Wiklander817466c2018-05-22 13:49:31 +02002784 dst->len = src->len;
2785
Jens Wiklander32b31802023-10-06 16:59:46 +02002786 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->N, &src->N));
2787 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->E, &src->E));
Jens Wiklander817466c2018-05-22 13:49:31 +02002788
Jens Wiklander32b31802023-10-06 16:59:46 +02002789 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->D, &src->D));
2790 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->P, &src->P));
2791 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Q, &src->Q));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002792
2793#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02002794 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DP, &src->DP));
2795 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->DQ, &src->DQ));
2796 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->QP, &src->QP));
2797 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RP, &src->RP));
2798 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RQ, &src->RQ));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002799#endif
2800
Jens Wiklander32b31802023-10-06 16:59:46 +02002801 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->RN, &src->RN));
Jens Wiklander817466c2018-05-22 13:49:31 +02002802
Jens Wiklander32b31802023-10-06 16:59:46 +02002803 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vi, &src->Vi));
2804 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&dst->Vf, &src->Vf));
Jens Wiklander817466c2018-05-22 13:49:31 +02002805
2806 dst->padding = src->padding;
2807 dst->hash_id = src->hash_id;
2808
2809cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +02002810 if (ret != 0) {
2811 mbedtls_rsa_free(dst);
2812 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002813
Jens Wiklander32b31802023-10-06 16:59:46 +02002814 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02002815}
2816
2817/*
2818 * Free the components of an RSA key
2819 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002820void mbedtls_rsa_free(mbedtls_rsa_context *ctx)
Jens Wiklander817466c2018-05-22 13:49:31 +02002821{
Jens Wiklander32b31802023-10-06 16:59:46 +02002822 if (ctx == NULL) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002823 return;
Jens Wiklander32b31802023-10-06 16:59:46 +02002824 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002825
Jens Wiklander32b31802023-10-06 16:59:46 +02002826 mbedtls_mpi_free(&ctx->Vi);
2827 mbedtls_mpi_free(&ctx->Vf);
2828 mbedtls_mpi_free(&ctx->RN);
2829 mbedtls_mpi_free(&ctx->D);
2830 mbedtls_mpi_free(&ctx->Q);
2831 mbedtls_mpi_free(&ctx->P);
2832 mbedtls_mpi_free(&ctx->E);
2833 mbedtls_mpi_free(&ctx->N);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002834
2835#if !defined(MBEDTLS_RSA_NO_CRT)
Jens Wiklander32b31802023-10-06 16:59:46 +02002836 mbedtls_mpi_free(&ctx->RQ);
2837 mbedtls_mpi_free(&ctx->RP);
2838 mbedtls_mpi_free(&ctx->QP);
2839 mbedtls_mpi_free(&ctx->DQ);
2840 mbedtls_mpi_free(&ctx->DP);
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002841#endif /* MBEDTLS_RSA_NO_CRT */
Jens Wiklander817466c2018-05-22 13:49:31 +02002842
2843#if defined(MBEDTLS_THREADING_C)
Jerome Forissier79013242021-07-28 10:24:04 +02002844 /* Free the mutex, but only if it hasn't been freed already. */
Jens Wiklander32b31802023-10-06 16:59:46 +02002845 if (ctx->ver != 0) {
2846 mbedtls_mutex_free(&ctx->mutex);
Jerome Forissier79013242021-07-28 10:24:04 +02002847 ctx->ver = 0;
2848 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002849#endif
2850}
2851
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002852#endif /* !MBEDTLS_RSA_ALT */
2853
Jens Wiklander817466c2018-05-22 13:49:31 +02002854#if defined(MBEDTLS_SELF_TEST)
2855
Jens Wiklander817466c2018-05-22 13:49:31 +02002856
2857/*
2858 * Example RSA-1024 keypair, for test purposes
2859 */
2860#define KEY_LEN 128
2861
2862#define RSA_N "9292758453063D803DD603D5E777D788" \
2863 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2864 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2865 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2866 "93A89813FBF3C4F8066D2D800F7C38A8" \
2867 "1AE31942917403FF4946B0A83D3D3E05" \
2868 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2869 "5E94BB77B07507233A0BC7BAC8F90F79"
2870
2871#define RSA_E "10001"
2872
2873#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2874 "66CA472BC44D253102F8B4A9D3BFA750" \
2875 "91386C0077937FE33FA3252D28855837" \
2876 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2877 "DF79C5CE07EE72C7F123142198164234" \
2878 "CABB724CF78B8173B9F880FC86322407" \
2879 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2880 "071513A1E85B5DFA031F21ECAE91A34D"
2881
2882#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2883 "2C01CAD19EA484A87EA4377637E75500" \
2884 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2885 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2886
2887#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2888 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2889 "910E4168387E3C30AA1E00C339A79508" \
2890 "8452DD96A9A5EA5D9DCA68DA636032AF"
2891
Jens Wiklander817466c2018-05-22 13:49:31 +02002892#define PT_LEN 24
2893#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2894 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2895
2896#if defined(MBEDTLS_PKCS1_V15)
Jens Wiklander32b31802023-10-06 16:59:46 +02002897static int myrand(void *rng_state, unsigned char *output, size_t len)
Jens Wiklander817466c2018-05-22 13:49:31 +02002898{
Jerome Forissier79013242021-07-28 10:24:04 +02002899#if !defined(__OpenBSD__) && !defined(__NetBSD__)
Jens Wiklander817466c2018-05-22 13:49:31 +02002900 size_t i;
2901
Jens Wiklander32b31802023-10-06 16:59:46 +02002902 if (rng_state != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002903 rng_state = NULL;
Jens Wiklander32b31802023-10-06 16:59:46 +02002904 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002905
Jens Wiklander32b31802023-10-06 16:59:46 +02002906 for (i = 0; i < len; ++i) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002907 output[i] = rand();
Jens Wiklander32b31802023-10-06 16:59:46 +02002908 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002909#else
Jens Wiklander32b31802023-10-06 16:59:46 +02002910 if (rng_state != NULL) {
Jens Wiklander817466c2018-05-22 13:49:31 +02002911 rng_state = NULL;
Jens Wiklander32b31802023-10-06 16:59:46 +02002912 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002913
Jens Wiklander32b31802023-10-06 16:59:46 +02002914 arc4random_buf(output, len);
Jerome Forissier79013242021-07-28 10:24:04 +02002915#endif /* !OpenBSD && !NetBSD */
Jens Wiklander817466c2018-05-22 13:49:31 +02002916
Jens Wiklander32b31802023-10-06 16:59:46 +02002917 return 0;
Jens Wiklander817466c2018-05-22 13:49:31 +02002918}
2919#endif /* MBEDTLS_PKCS1_V15 */
2920
2921/*
2922 * Checkup routine
2923 */
Jens Wiklander32b31802023-10-06 16:59:46 +02002924int mbedtls_rsa_self_test(int verbose)
Jens Wiklander817466c2018-05-22 13:49:31 +02002925{
2926 int ret = 0;
2927#if defined(MBEDTLS_PKCS1_V15)
2928 size_t len;
2929 mbedtls_rsa_context rsa;
2930 unsigned char rsa_plaintext[PT_LEN];
2931 unsigned char rsa_decrypted[PT_LEN];
2932 unsigned char rsa_ciphertext[KEY_LEN];
Tom Van Eyckc1633172024-04-09 18:44:13 +02002933#if defined(MBEDTLS_MD_CAN_SHA1)
Jens Wiklander817466c2018-05-22 13:49:31 +02002934 unsigned char sha1sum[20];
2935#endif
2936
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002937 mbedtls_mpi K;
2938
Jens Wiklander32b31802023-10-06 16:59:46 +02002939 mbedtls_mpi_init(&K);
2940 mbedtls_rsa_init(&rsa);
Jens Wiklander817466c2018-05-22 13:49:31 +02002941
Jens Wiklander32b31802023-10-06 16:59:46 +02002942 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_N));
2943 MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, &K, NULL, NULL, NULL, NULL));
2944 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_P));
2945 MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, &K, NULL, NULL, NULL));
2946 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_Q));
2947 MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, &K, NULL, NULL));
2948 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_D));
2949 MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, &K, NULL));
2950 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&K, 16, RSA_E));
2951 MBEDTLS_MPI_CHK(mbedtls_rsa_import(&rsa, NULL, NULL, NULL, NULL, &K));
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002952
Jens Wiklander32b31802023-10-06 16:59:46 +02002953 MBEDTLS_MPI_CHK(mbedtls_rsa_complete(&rsa));
Jens Wiklander817466c2018-05-22 13:49:31 +02002954
Jens Wiklander32b31802023-10-06 16:59:46 +02002955 if (verbose != 0) {
2956 mbedtls_printf(" RSA key validation: ");
2957 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002958
Jens Wiklander32b31802023-10-06 16:59:46 +02002959 if (mbedtls_rsa_check_pubkey(&rsa) != 0 ||
2960 mbedtls_rsa_check_privkey(&rsa) != 0) {
2961 if (verbose != 0) {
2962 mbedtls_printf("failed\n");
2963 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002964
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002965 ret = 1;
2966 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02002967 }
2968
Jens Wiklander32b31802023-10-06 16:59:46 +02002969 if (verbose != 0) {
2970 mbedtls_printf("passed\n PKCS#1 encryption : ");
2971 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002972
Jens Wiklander32b31802023-10-06 16:59:46 +02002973 memcpy(rsa_plaintext, RSA_PT, PT_LEN);
Jens Wiklander817466c2018-05-22 13:49:31 +02002974
Jens Wiklander32b31802023-10-06 16:59:46 +02002975 if (mbedtls_rsa_pkcs1_encrypt(&rsa, myrand, NULL,
2976 PT_LEN, rsa_plaintext,
2977 rsa_ciphertext) != 0) {
2978 if (verbose != 0) {
2979 mbedtls_printf("failed\n");
2980 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002981
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002982 ret = 1;
2983 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02002984 }
2985
Jens Wiklander32b31802023-10-06 16:59:46 +02002986 if (verbose != 0) {
2987 mbedtls_printf("passed\n PKCS#1 decryption : ");
2988 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002989
Jens Wiklander32b31802023-10-06 16:59:46 +02002990 if (mbedtls_rsa_pkcs1_decrypt(&rsa, myrand, NULL,
2991 &len, rsa_ciphertext, rsa_decrypted,
2992 sizeof(rsa_decrypted)) != 0) {
2993 if (verbose != 0) {
2994 mbedtls_printf("failed\n");
2995 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002996
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002997 ret = 1;
2998 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02002999 }
3000
Jens Wiklander32b31802023-10-06 16:59:46 +02003001 if (memcmp(rsa_decrypted, rsa_plaintext, len) != 0) {
3002 if (verbose != 0) {
3003 mbedtls_printf("failed\n");
3004 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003005
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003006 ret = 1;
3007 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02003008 }
3009
Jens Wiklander32b31802023-10-06 16:59:46 +02003010 if (verbose != 0) {
3011 mbedtls_printf("passed\n");
3012 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003013
Tom Van Eyckc1633172024-04-09 18:44:13 +02003014#if defined(MBEDTLS_MD_CAN_SHA1)
Jens Wiklander32b31802023-10-06 16:59:46 +02003015 if (verbose != 0) {
3016 mbedtls_printf(" PKCS#1 data sign : ");
Jens Wiklander817466c2018-05-22 13:49:31 +02003017 }
3018
Jens Wiklander32b31802023-10-06 16:59:46 +02003019 if (mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
3020 rsa_plaintext, PT_LEN, sha1sum) != 0) {
3021 if (verbose != 0) {
3022 mbedtls_printf("failed\n");
3023 }
3024
3025 return 1;
3026 }
3027
3028 if (mbedtls_rsa_pkcs1_sign(&rsa, myrand, NULL,
3029 MBEDTLS_MD_SHA1, 20,
3030 sha1sum, rsa_ciphertext) != 0) {
3031 if (verbose != 0) {
3032 mbedtls_printf("failed\n");
3033 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003034
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003035 ret = 1;
3036 goto cleanup;
3037 }
3038
Jens Wiklander32b31802023-10-06 16:59:46 +02003039 if (verbose != 0) {
3040 mbedtls_printf("passed\n PKCS#1 sig. verify: ");
3041 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003042
Jens Wiklander32b31802023-10-06 16:59:46 +02003043 if (mbedtls_rsa_pkcs1_verify(&rsa, MBEDTLS_MD_SHA1, 20,
3044 sha1sum, rsa_ciphertext) != 0) {
3045 if (verbose != 0) {
3046 mbedtls_printf("failed\n");
3047 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003048
3049 ret = 1;
3050 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02003051 }
3052
Jens Wiklander32b31802023-10-06 16:59:46 +02003053 if (verbose != 0) {
3054 mbedtls_printf("passed\n");
3055 }
Tom Van Eyckc1633172024-04-09 18:44:13 +02003056#endif /* MBEDTLS_MD_CAN_SHA1 */
Jens Wiklander817466c2018-05-22 13:49:31 +02003057
Jens Wiklander32b31802023-10-06 16:59:46 +02003058 if (verbose != 0) {
3059 mbedtls_printf("\n");
3060 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003061
3062cleanup:
Jens Wiklander32b31802023-10-06 16:59:46 +02003063 mbedtls_mpi_free(&K);
3064 mbedtls_rsa_free(&rsa);
Jens Wiklander817466c2018-05-22 13:49:31 +02003065#else /* MBEDTLS_PKCS1_V15 */
3066 ((void) verbose);
3067#endif /* MBEDTLS_PKCS1_V15 */
Jens Wiklander32b31802023-10-06 16:59:46 +02003068 return ret;
Jens Wiklander817466c2018-05-22 13:49:31 +02003069}
3070
3071#endif /* MBEDTLS_SELF_TEST */
3072
3073#endif /* MBEDTLS_RSA_C */