blob: 3451469b982c513f943c5b06a8da33c5b95656c1 [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"
Chris Jones66a4cd42021-03-09 16:04:12 +000027#include "rsa_alt_helpers.h"
Hanno Beckera565f542017-10-11 11:00:19 +010028
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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +010085 const size_t num_primes = sizeof(primes) / sizeof(*primes);
Hanno Beckera565f542017-10-11 11:00:19 +010086
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100103 mbedtls_mpi_init(&K);
104 mbedtls_mpi_init(&T);
Hanno Beckera565f542017-10-11 11:00:19 +0100105
106 /* T := DE - 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100124 if (N->p[0] % 8 == 1) {
Hanno Beckera565f542017-10-11 11:00:19 +0100125 attempt = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 }
Hanno Beckera565f542017-10-11 11:00:19 +0100127
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100146 if (mbedtls_mpi_cmp_int(&K, 1) == 0) {
Hanno Becker5d42b532017-10-11 15:58:00 +0100147 break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 }
Hanno Becker5d42b532017-10-11 15:58:00 +0100149
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100227 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(D, E, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100228
229cleanup:
230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 mbedtls_mpi_free(&K);
232 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100233
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100235}
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
238 const mbedtls_mpi *D, mbedtls_mpi *DP,
239 mbedtls_mpi *DQ, mbedtls_mpi *QP)
Hanno Beckera565f542017-10-11 11:00:19 +0100240{
241 int ret = 0;
Chris Jones66a4cd42021-03-09 16:04:12 +0000242 mbedtls_mpi K;
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 mbedtls_mpi_init(&K);
Hanno Beckera565f542017-10-11 11:00:19 +0100244
Chris Jones66a4cd42021-03-09 16:04:12 +0000245 /* DP = D mod P-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 if (DP != NULL) {
247 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
248 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DP, D, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100249 }
250
Chris Jones66a4cd42021-03-09 16:04:12 +0000251 /* DQ = D mod Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if (DQ != NULL) {
253 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
254 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DQ, D, &K));
Hanno Beckera565f542017-10-11 11:00:19 +0100255 }
256
Chris Jones66a4cd42021-03-09 16:04:12 +0000257 /* QP = Q^{-1} mod P */
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 if (QP != NULL) {
259 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(QP, Q, P));
Hanno Beckera565f542017-10-11 11:00:19 +0100260 }
261
262cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 mbedtls_mpi_free(&K);
Hanno Beckera565f542017-10-11 11:00:19 +0100264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100266}
267
268/*
269 * Check that core RSA parameters are sane.
270 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100271int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P,
272 const mbedtls_mpi *Q, const mbedtls_mpi *D,
273 const mbedtls_mpi *E,
274 int (*f_rng)(void *, unsigned char *, size_t),
275 void *p_rng)
Hanno Beckera565f542017-10-11 11:00:19 +0100276{
277 int ret = 0;
278 mbedtls_mpi K, L;
279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 mbedtls_mpi_init(&K);
281 mbedtls_mpi_init(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100282
283 /*
284 * Step 1: If PRNG provided, check that P and Q are prime
285 */
286
287#if defined(MBEDTLS_GENPRIME)
Janos Follatha0b67c22018-09-18 14:48:23 +0100288 /*
289 * When generating keys, the strongest security we support aims for an error
290 * rate of at most 2^-100 and we are aiming for the same certainty here as
291 * well.
292 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 if (f_rng != NULL && P != NULL &&
294 (ret = mbedtls_mpi_is_prime_ext(P, 50, f_rng, p_rng)) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100295 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
296 goto cleanup;
297 }
298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 if (f_rng != NULL && Q != NULL &&
300 (ret = mbedtls_mpi_is_prime_ext(Q, 50, f_rng, p_rng)) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100301 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
302 goto cleanup;
303 }
304#else
305 ((void) f_rng);
306 ((void) p_rng);
307#endif /* MBEDTLS_GENPRIME */
308
309 /*
Hanno Beckerf8c028a2017-10-17 09:20:57 +0100310 * Step 2: Check that 1 < N = P * Q
Hanno Beckera565f542017-10-11 11:00:19 +0100311 */
312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 if (P != NULL && Q != NULL && N != NULL) {
314 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, P, Q));
315 if (mbedtls_mpi_cmp_int(N, 1) <= 0 ||
316 mbedtls_mpi_cmp_mpi(&K, N) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100317 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
318 goto cleanup;
319 }
320 }
321
322 /*
323 * Step 3: Check and 1 < D, E < N if present.
324 */
325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 if (N != NULL && D != NULL && E != NULL) {
327 if (mbedtls_mpi_cmp_int(D, 1) <= 0 ||
328 mbedtls_mpi_cmp_int(E, 1) <= 0 ||
329 mbedtls_mpi_cmp_mpi(D, N) >= 0 ||
330 mbedtls_mpi_cmp_mpi(E, N) >= 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100331 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
332 goto cleanup;
333 }
334 }
335
336 /*
337 * Step 4: Check that D, E are inverse modulo P-1 and Q-1
338 */
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 if (P != NULL && Q != NULL && D != NULL && E != NULL) {
341 if (mbedtls_mpi_cmp_int(P, 1) <= 0 ||
342 mbedtls_mpi_cmp_int(Q, 1) <= 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100343 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
344 goto cleanup;
345 }
346
347 /* Compute DE-1 mod P-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
349 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
350 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, P, 1));
351 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
352 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100353 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
354 goto cleanup;
355 }
356
357 /* Compute DE-1 mod Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E));
359 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
360 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1));
361 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L));
362 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Hanno Beckera565f542017-10-11 11:00:19 +0100363 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
364 goto cleanup;
365 }
366 }
367
368cleanup:
369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 mbedtls_mpi_free(&K);
371 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100372
373 /* Wrap MPI error codes by RSA check failure error code */
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if (ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) {
Hanno Beckera565f542017-10-11 11:00:19 +0100375 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
376 }
377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100379}
380
Chris Jones66a4cd42021-03-09 16:04:12 +0000381/*
382 * Check that RSA CRT parameters are in accordance with core parameters.
383 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q,
385 const mbedtls_mpi *D, const mbedtls_mpi *DP,
386 const mbedtls_mpi *DQ, const mbedtls_mpi *QP)
Hanno Beckera565f542017-10-11 11:00:19 +0100387{
388 int ret = 0;
Hanno Beckera565f542017-10-11 11:00:19 +0100389
Chris Jones66a4cd42021-03-09 16:04:12 +0000390 mbedtls_mpi K, L;
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_mpi_init(&K);
392 mbedtls_mpi_init(&L);
Chris Jones66a4cd42021-03-09 16:04:12 +0000393
394 /* Check that DP - D == 0 mod P - 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 if (DP != NULL) {
396 if (P == NULL) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000397 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
398 goto cleanup;
399 }
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1));
402 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DP, D));
403 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
Chris Jones66a4cd42021-03-09 16:04:12 +0000404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000406 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
407 goto cleanup;
408 }
Hanno Beckera565f542017-10-11 11:00:19 +0100409 }
410
Chris Jones66a4cd42021-03-09 16:04:12 +0000411 /* Check that DQ - D == 0 mod Q - 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 if (DQ != NULL) {
413 if (Q == NULL) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000414 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
415 goto cleanup;
416 }
417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1));
419 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DQ, D));
420 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K));
Chris Jones66a4cd42021-03-09 16:04:12 +0000421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 if (mbedtls_mpi_cmp_int(&L, 0) != 0) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000423 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
424 goto cleanup;
425 }
Hanno Beckera565f542017-10-11 11:00:19 +0100426 }
427
Chris Jones66a4cd42021-03-09 16:04:12 +0000428 /* Check that QP * Q - 1 == 0 mod P */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 if (QP != NULL) {
430 if (P == NULL || Q == NULL) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000431 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
432 goto cleanup;
433 }
434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, QP, Q));
436 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1));
437 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, P));
438 if (mbedtls_mpi_cmp_int(&K, 0) != 0) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000439 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
440 goto cleanup;
441 }
Hanno Beckera565f542017-10-11 11:00:19 +0100442 }
443
444cleanup:
Chris Jones66a4cd42021-03-09 16:04:12 +0000445
446 /* Wrap MPI error codes by RSA check failure error code */
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 if (ret != 0 &&
Chris Jones66a4cd42021-03-09 16:04:12 +0000448 ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA) {
Chris Jones66a4cd42021-03-09 16:04:12 +0000450 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
451 }
452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 mbedtls_mpi_free(&K);
454 mbedtls_mpi_free(&L);
Hanno Beckera565f542017-10-11 11:00:19 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 return ret;
Hanno Beckera565f542017-10-11 11:00:19 +0100457}
458
459#endif /* MBEDTLS_RSA_C */