blob: 2ff51c34b71b35dbfdc537c5b2e455a110526040 [file] [log] [blame]
Hanno Beckera565f542017-10-11 11:00:19 +01001/*
2 * Helper functions for the RSA module
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Hanno Beckera565f542017-10-11 11:00:19 +01005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
Hanno Beckera565f542017-10-11 11:00:19 +010019 */
20
Gilles Peskinedb09ef62020-06-03 01:43:33 +020021#include "common.h"
Hanno Beckera565f542017-10-11 11:00:19 +010022
23#if defined(MBEDTLS_RSA_C)
24
25#include "mbedtls/rsa.h"
26#include "mbedtls/bignum.h"
27#include "mbedtls/rsa_internal.h"
28
29/*
30 * Compute RSA prime factors from public and private exponents
31 *
32 * Summary of algorithm:
33 * Setting F := lcm(P-1,Q-1), the idea is as follows:
34 *
35 * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
36 * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
37 * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
38 * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
39 * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
40 * factors of N.
41 *
42 * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
43 * construction still applies since (-)^K is the identity on the set of
44 * roots of 1 in Z/NZ.
45 *
46 * The public and private key primitives (-)^E and (-)^D are mutually inverse
47 * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
48 * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
49 * Splitting L = 2^t * K with K odd, we have
50 *
51 * DE - 1 = FL = (F/2) * (2^(t+1)) * K,
52 *
53 * so (F / 2) * K is among the numbers
54 *
55 * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
56 *
57 * where ord is the order of 2 in (DE - 1).
58 * We can therefore iterate through these numbers apply the construction
59 * of (a) and (b) above to attempt to factor N.
60 *
61 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N,
63 mbedtls_mpi const *E, mbedtls_mpi const *D,
64 mbedtls_mpi *P, mbedtls_mpi *Q)
Hanno Beckera565f542017-10-11 11:00:19 +010065{
66 int ret = 0;
67
68 uint16_t attempt; /* Number of current attempt */
69 uint16_t iter; /* Number of squares computed in the current attempt */
70
71 uint16_t order; /* Order of 2 in DE - 1 */
72
73 mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */
74 mbedtls_mpi K; /* Temporary holding the current candidate */
75
Hanno Becker4055a3a2017-10-17 09:15:26 +010076 const unsigned char primes[] = { 2,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010077 3, 5, 7, 11, 13, 17, 19, 23,
78 29, 31, 37, 41, 43, 47, 53, 59,
79 61, 67, 71, 73, 79, 83, 89, 97,
80 101, 103, 107, 109, 113, 127, 131, 137,
81 139, 149, 151, 157, 163, 167, 173, 179,
82 181, 191, 193, 197, 199, 211, 223, 227,
83 229, 233, 239, 241, 251 };
Hanno Beckera565f542017-10-11 11:00:19 +010084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010085 const size_t num_primes = sizeof(primes) / sizeof(*primes);
Hanno Beckera565f542017-10-11 11:00:19 +010086
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010087 if (P == NULL || Q == NULL || P->p != NULL || Q->p != NULL) {
88 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
89 }
Hanno Beckera565f542017-10-11 11:00:19 +010090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010091 if (mbedtls_mpi_cmp_int(N, 0) <= 0 ||
92 mbedtls_mpi_cmp_int(D, 1) <= 0 ||
93 mbedtls_mpi_cmp_mpi(D, N) >= 0 ||
94 mbedtls_mpi_cmp_int(E, 1) <= 0 ||
95 mbedtls_mpi_cmp_mpi(E, N) >= 0) {
96 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
Hanno Beckera565f542017-10-11 11:00:19 +010097 }
98
99 /*
100 * Initializations and temporary changes
101 */
102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 mbedtls_mpi_init(&K);
104 mbedtls_mpi_init(&T);
Hanno Beckera565f542017-10-11 11:00:19 +0100105
106 /* T := DE - 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, D, E));
108 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&T, &T, 1));
Hanno Beckera565f542017-10-11 11:00:19 +0100109
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 if ((order = (uint16_t) mbedtls_mpi_lsb(&T)) == 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100111 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
112 goto cleanup;
113 }
114
115 /* After this operation, T holds the largest odd divisor of DE - 1. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100116 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&T, order));
Hanno Beckera565f542017-10-11 11:00:19 +0100117
118 /*
119 * Actual work
120 */
121
122 /* Skip trying 2 if N == 1 mod 8 */
123 attempt = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 if (N->p[0] % 8 == 1) {
Hanno Beckera565f542017-10-11 11:00:19 +0100125 attempt = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 }
Hanno Beckera565f542017-10-11 11:00:19 +0100127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100128 for (; attempt < num_primes; ++attempt) {
129 mbedtls_mpi_lset(&K, primes[attempt]);
Hanno Beckera565f542017-10-11 11:00:19 +0100130
131 /* Check if gcd(K,N) = 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100132 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
133 if (mbedtls_mpi_cmp_int(P, 1) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100134 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135 }
Hanno Beckera565f542017-10-11 11:00:19 +0100136
137 /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ...
138 * and check whether they have nontrivial GCD with N. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &K, &T, N,
140 Q /* temporarily use Q for storing Montgomery
141 * multiplication helper values */));
Hanno Beckera565f542017-10-11 11:00:19 +0100142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143 for (iter = 1; iter <= order; ++iter) {
Hanno Becker5d42b532017-10-11 15:58:00 +0100144 /* If we reach 1 prematurely, there's no point
145 * in continuing to square K */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100146 if (mbedtls_mpi_cmp_int(&K, 1) == 0) {
Hanno Becker5d42b532017-10-11 15:58:00 +0100147 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100148 }
Hanno Becker5d42b532017-10-11 15:58:00 +0100149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100150 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&K, &K, 1));
151 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(P, &K, N));
Hanno Beckera565f542017-10-11 11:00:19 +0100152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153 if (mbedtls_mpi_cmp_int(P, 1) == 1 &&
154 mbedtls_mpi_cmp_mpi(P, N) == -1) {
Hanno Beckera565f542017-10-11 11:00:19 +0100155 /*
156 * Have found a nontrivial divisor P of N.
157 * Set Q := N / P.
158 */
159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(Q, NULL, N, P));
Hanno Beckera565f542017-10-11 11:00:19 +0100161 goto cleanup;
162 }
163
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100164 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
165 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &K));
166 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, N));
Hanno Beckera565f542017-10-11 11:00:19 +0100167 }
Hanno Becker14a00c02017-10-11 12:58:23 +0100168
Hanno Becker5d42b532017-10-11 15:58:00 +0100169 /*
170 * If we get here, then either we prematurely aborted the loop because
171 * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must
172 * be 1 if D,E,N were consistent.
173 * Check if that's the case and abort if not, to avoid very long,
174 * yet eventually failing, computations if N,D,E were not sane.
175 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100176 if (mbedtls_mpi_cmp_int(&K, 1) != 0) {
Hanno Becker14a00c02017-10-11 12:58:23 +0100177 break;
178 }
Hanno Beckera565f542017-10-11 11:00:19 +0100179 }
180
181 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
182
183cleanup:
184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100185 mbedtls_mpi_free(&K);
186 mbedtls_mpi_free(&T);
187 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100188}
189
190/*
191 * Given P, Q and the public exponent E, deduce D.
192 * This is essentially a modular inversion.
193 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P,
195 mbedtls_mpi const *Q,
196 mbedtls_mpi const *E,
197 mbedtls_mpi *D)
Hanno Beckera565f542017-10-11 11:00:19 +0100198{
199 int ret = 0;
200 mbedtls_mpi K, L;
201
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100202 if (D == NULL || mbedtls_mpi_cmp_int(D, 0) != 0) {
203 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
Hanno Beckera565f542017-10-11 11:00:19 +0100204 }
205
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100206 if (mbedtls_mpi_cmp_int(P, 1) <= 0 ||
207 mbedtls_mpi_cmp_int(Q, 1) <= 0 ||
208 mbedtls_mpi_cmp_int(E, 0) == 0) {
209 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
210 }
211
212 mbedtls_mpi_init(&K);
213 mbedtls_mpi_init(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100214
215 /* Temporarily put K := P-1 and L := Q-1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
217 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1));
Hanno Beckera565f542017-10-11 11:00:19 +0100218
219 /* Temporarily put D := gcd(P-1, Q-1) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100220 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(D, &K, &L));
Hanno Beckera565f542017-10-11 11:00:19 +0100221
222 /* K := LCM(P-1, Q-1) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100223 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &L));
224 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&K, NULL, &K, D));
Hanno Beckera565f542017-10-11 11:00:19 +0100225
226 /* Compute modular inverse of E in LCM(P-1, Q-1) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(D, E, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100228
229cleanup:
230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100231 mbedtls_mpi_free(&K);
232 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100235}
236
237/*
238 * Check that RSA CRT parameters are in accordance with core parameters.
239 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100240int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
241 const mbedtls_mpi *D, const mbedtls_mpi *DP,
242 const mbedtls_mpi *DQ, const mbedtls_mpi *QP)
Hanno Beckera565f542017-10-11 11:00:19 +0100243{
244 int ret = 0;
245
246 mbedtls_mpi K, L;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 mbedtls_mpi_init(&K);
248 mbedtls_mpi_init(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100249
250 /* Check that DP - D == 0 mod P - 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 if (DP != NULL) {
252 if (P == NULL) {
Hanno Beckera565f542017-10-11 11:00:19 +0100253 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
254 goto cleanup;
255 }
256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
258 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DP, D));
259 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100260
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100261 if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100262 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
263 goto cleanup;
264 }
265 }
266
267 /* Check that DQ - D == 0 mod Q - 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 if (DQ != NULL) {
269 if (Q == NULL) {
Hanno Beckera565f542017-10-11 11:00:19 +0100270 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
271 goto cleanup;
272 }
273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
275 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DQ, D));
276 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100277
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100279 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
280 goto cleanup;
281 }
282 }
283
284 /* Check that QP * Q - 1 == 0 mod P */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100285 if (QP != NULL) {
286 if (P == NULL || Q == NULL) {
Hanno Beckera565f542017-10-11 11:00:19 +0100287 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
288 goto cleanup;
289 }
290
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100291 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, QP, Q));
292 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
293 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, P));
294 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100295 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
296 goto cleanup;
297 }
298 }
299
300cleanup:
301
302 /* Wrap MPI error codes by RSA check failure error code */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303 if (ret != 0 &&
Hanno Beckera565f542017-10-11 11:00:19 +0100304 ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA) {
Hanno Beckera565f542017-10-11 11:00:19 +0100306 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
307 }
308
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309 mbedtls_mpi_free(&K);
310 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100311
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100313}
314
315/*
316 * Check that core RSA parameters are sane.
317 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P,
319 const mbedtls_mpi *Q, const mbedtls_mpi *D,
320 const mbedtls_mpi *E,
321 int (*f_rng)(void *, unsigned char *, size_t),
322 void *p_rng)
Hanno Beckera565f542017-10-11 11:00:19 +0100323{
324 int ret = 0;
325 mbedtls_mpi K, L;
326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327 mbedtls_mpi_init(&K);
328 mbedtls_mpi_init(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100329
330 /*
331 * Step 1: If PRNG provided, check that P and Q are prime
332 */
333
334#if defined(MBEDTLS_GENPRIME)
Janos Follatha0b67c22018-09-18 14:48:23 +0100335 /*
336 * When generating keys, the strongest security we support aims for an error
337 * rate of at most 2^-100 and we are aiming for the same certainty here as
338 * well.
339 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100340 if (f_rng != NULL && P != NULL &&
341 (ret = mbedtls_mpi_is_prime_ext(P, 50, f_rng, p_rng)) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100342 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
343 goto cleanup;
344 }
345
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100346 if (f_rng != NULL && Q != NULL &&
347 (ret = mbedtls_mpi_is_prime_ext(Q, 50, f_rng, p_rng)) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100348 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
349 goto cleanup;
350 }
351#else
352 ((void) f_rng);
353 ((void) p_rng);
354#endif /* MBEDTLS_GENPRIME */
355
356 /*
Hanno Beckerf8c028a2017-10-17 09:20:57 +0100357 * Step 2: Check that 1 < N = P * Q
Hanno Beckera565f542017-10-11 11:00:19 +0100358 */
359
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 if (P != NULL && Q != NULL && N != NULL) {
361 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, P, Q));
362 if (mbedtls_mpi_cmp_int(N, 1) <= 0 ||
363 mbedtls_mpi_cmp_mpi(&K, N) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100364 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
365 goto cleanup;
366 }
367 }
368
369 /*
370 * Step 3: Check and 1 < D, E < N if present.
371 */
372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 if (N != NULL && D != NULL && E != NULL) {
374 if (mbedtls_mpi_cmp_int(D, 1) <= 0 ||
375 mbedtls_mpi_cmp_int(E, 1) <= 0 ||
376 mbedtls_mpi_cmp_mpi(D, N) >= 0 ||
377 mbedtls_mpi_cmp_mpi(E, N) >= 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100378 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
379 goto cleanup;
380 }
381 }
382
383 /*
384 * Step 4: Check that D, E are inverse modulo P-1 and Q-1
385 */
386
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 if (P != NULL && Q != NULL && D != NULL && E != NULL) {
388 if (mbedtls_mpi_cmp_int(P, 1) <= 0 ||
389 mbedtls_mpi_cmp_int(Q, 1) <= 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100390 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
391 goto cleanup;
392 }
393
394 /* Compute DE-1 mod P-1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
396 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
397 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, P, 1));
398 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
399 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100400 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
401 goto cleanup;
402 }
403
404 /* Compute DE-1 mod Q-1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
406 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
407 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1));
408 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
409 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100410 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
411 goto cleanup;
412 }
413 }
414
415cleanup:
416
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 mbedtls_mpi_free(&K);
418 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100419
420 /* Wrap MPI error codes by RSA check failure error code */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 if (ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) {
Hanno Beckera565f542017-10-11 11:00:19 +0100422 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
423 }
424
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100426}
427
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100428int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
429 const mbedtls_mpi *D, mbedtls_mpi *DP,
430 mbedtls_mpi *DQ, mbedtls_mpi *QP)
Hanno Beckera565f542017-10-11 11:00:19 +0100431{
432 int ret = 0;
433 mbedtls_mpi K;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 mbedtls_mpi_init(&K);
Hanno Beckera565f542017-10-11 11:00:19 +0100435
436 /* DP = D mod P-1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100437 if (DP != NULL) {
438 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
439 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DP, D, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100440 }
441
442 /* DQ = D mod Q-1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100443 if (DQ != NULL) {
444 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
445 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DQ, D, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100446 }
447
448 /* QP = Q^{-1} mod P */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100449 if (QP != NULL) {
450 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(QP, Q, P));
Hanno Beckera565f542017-10-11 11:00:19 +0100451 }
452
453cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 mbedtls_mpi_free(&K);
Hanno Beckera565f542017-10-11 11:00:19 +0100455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100457}
458
459#endif /* MBEDTLS_RSA_C */