/work/mbedtls-3.6.6/library/rsa_alt_helpers.c
Line | Count | Source |
1 | | /* |
2 | | * Helper functions for the RSA module |
3 | | * |
4 | | * Copyright The Mbed TLS Contributors |
5 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
6 | | * |
7 | | */ |
8 | | |
9 | | #include "common.h" |
10 | | |
11 | | #if defined(MBEDTLS_RSA_C) |
12 | | |
13 | | #include "mbedtls/rsa.h" |
14 | | #include "mbedtls/bignum.h" |
15 | | #include "bignum_internal.h" |
16 | | #include "rsa_alt_helpers.h" |
17 | | |
18 | | /* |
19 | | * Compute RSA prime factors from public and private exponents |
20 | | * |
21 | | * Summary of algorithm: |
22 | | * Setting F := lcm(P-1,Q-1), the idea is as follows: |
23 | | * |
24 | | * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2) |
25 | | * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the |
26 | | * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four |
27 | | * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1) |
28 | | * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime |
29 | | * factors of N. |
30 | | * |
31 | | * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same |
32 | | * construction still applies since (-)^K is the identity on the set of |
33 | | * roots of 1 in Z/NZ. |
34 | | * |
35 | | * The public and private key primitives (-)^E and (-)^D are mutually inverse |
36 | | * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e. |
37 | | * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L. |
38 | | * Splitting L = 2^t * K with K odd, we have |
39 | | * |
40 | | * DE - 1 = FL = (F/2) * (2^(t+1)) * K, |
41 | | * |
42 | | * so (F / 2) * K is among the numbers |
43 | | * |
44 | | * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord |
45 | | * |
46 | | * where ord is the order of 2 in (DE - 1). |
47 | | * We can therefore iterate through these numbers apply the construction |
48 | | * of (a) and (b) above to attempt to factor N. |
49 | | * |
50 | | */ |
51 | | int mbedtls_rsa_deduce_primes(mbedtls_mpi const *N, |
52 | | mbedtls_mpi const *E, mbedtls_mpi const *D, |
53 | | mbedtls_mpi *P, mbedtls_mpi *Q) |
54 | 0 | { |
55 | 0 | int ret = 0; |
56 | |
|
57 | 0 | uint16_t attempt; /* Number of current attempt */ |
58 | 0 | uint16_t iter; /* Number of squares computed in the current attempt */ |
59 | |
|
60 | 0 | uint16_t order; /* Order of 2 in DE - 1 */ |
61 | |
|
62 | 0 | mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */ |
63 | 0 | mbedtls_mpi K; /* Temporary holding the current candidate */ |
64 | |
|
65 | 0 | const unsigned char primes[] = { 2, |
66 | 0 | 3, 5, 7, 11, 13, 17, 19, 23, |
67 | 0 | 29, 31, 37, 41, 43, 47, 53, 59, |
68 | 0 | 61, 67, 71, 73, 79, 83, 89, 97, |
69 | 0 | 101, 103, 107, 109, 113, 127, 131, 137, |
70 | 0 | 139, 149, 151, 157, 163, 167, 173, 179, |
71 | 0 | 181, 191, 193, 197, 199, 211, 223, 227, |
72 | 0 | 229, 233, 239, 241, 251 }; |
73 | |
|
74 | 0 | const size_t num_primes = sizeof(primes) / sizeof(*primes); |
75 | |
|
76 | 0 | if (P == NULL || Q == NULL || P->p != NULL || Q->p != NULL) { |
77 | 0 | return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
78 | 0 | } |
79 | | |
80 | 0 | if (mbedtls_mpi_cmp_int(N, 0) <= 0 || |
81 | 0 | mbedtls_mpi_cmp_int(D, 1) <= 0 || |
82 | 0 | mbedtls_mpi_cmp_mpi(D, N) >= 0 || |
83 | 0 | mbedtls_mpi_cmp_int(E, 1) <= 0 || |
84 | 0 | mbedtls_mpi_cmp_mpi(E, N) >= 0) { |
85 | 0 | return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
86 | 0 | } |
87 | | |
88 | | /* |
89 | | * Initializations and temporary changes |
90 | | */ |
91 | | |
92 | 0 | mbedtls_mpi_init(&K); |
93 | 0 | mbedtls_mpi_init(&T); |
94 | | |
95 | | /* T := DE - 1 */ |
96 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, D, E)); |
97 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&T, &T, 1)); |
98 | | |
99 | 0 | if ((order = (uint16_t) mbedtls_mpi_lsb(&T)) == 0) { |
100 | 0 | ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
101 | 0 | goto cleanup; |
102 | 0 | } |
103 | | |
104 | | /* After this operation, T holds the largest odd divisor of DE - 1. */ |
105 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&T, order)); |
106 | | |
107 | | /* |
108 | | * Actual work |
109 | | */ |
110 | | |
111 | | /* Skip trying 2 if N == 1 mod 8 */ |
112 | 0 | attempt = 0; |
113 | 0 | if (N->p[0] % 8 == 1) { |
114 | 0 | attempt = 1; |
115 | 0 | } |
116 | |
|
117 | 0 | for (; attempt < num_primes; ++attempt) { |
118 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&K, primes[attempt])); |
119 | | |
120 | | /* Check if gcd(K,N) = 1 */ |
121 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N)); |
122 | 0 | if (mbedtls_mpi_cmp_int(P, 1) != 0) { |
123 | 0 | continue; |
124 | 0 | } |
125 | | |
126 | | /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ... |
127 | | * and check whether they have nontrivial GCD with N. */ |
128 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &K, &T, N, |
129 | 0 | Q /* temporarily use Q for storing Montgomery |
130 | 0 | * multiplication helper values */)); |
131 | | |
132 | 0 | for (iter = 1; iter <= order; ++iter) { |
133 | | /* If we reach 1 prematurely, there's no point |
134 | | * in continuing to square K */ |
135 | 0 | if (mbedtls_mpi_cmp_int(&K, 1) == 0) { |
136 | 0 | break; |
137 | 0 | } |
138 | | |
139 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&K, &K, 1)); |
140 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(P, NULL, &K, N)); |
141 | | |
142 | 0 | if (mbedtls_mpi_cmp_int(P, 1) == 1 && |
143 | 0 | mbedtls_mpi_cmp_mpi(P, N) == -1) { |
144 | | /* |
145 | | * Have found a nontrivial divisor P of N. |
146 | | * Set Q := N / P. |
147 | | */ |
148 | |
|
149 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(Q, NULL, N, P)); |
150 | 0 | goto cleanup; |
151 | 0 | } |
152 | | |
153 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); |
154 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &K)); |
155 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, N)); |
156 | 0 | } |
157 | | |
158 | | /* |
159 | | * If we get here, then either we prematurely aborted the loop because |
160 | | * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must |
161 | | * be 1 if D,E,N were consistent. |
162 | | * Check if that's the case and abort if not, to avoid very long, |
163 | | * yet eventually failing, computations if N,D,E were not sane. |
164 | | */ |
165 | 0 | if (mbedtls_mpi_cmp_int(&K, 1) != 0) { |
166 | 0 | break; |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | 0 | ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
171 | |
|
172 | 0 | cleanup: |
173 | |
|
174 | 0 | mbedtls_mpi_free(&K); |
175 | 0 | mbedtls_mpi_free(&T); |
176 | 0 | return ret; |
177 | 0 | } |
178 | | |
179 | | /* |
180 | | * Given P, Q and the public exponent E, deduce D. |
181 | | * This is essentially a modular inversion. |
182 | | */ |
183 | | int mbedtls_rsa_deduce_private_exponent(mbedtls_mpi const *P, |
184 | | mbedtls_mpi const *Q, |
185 | | mbedtls_mpi const *E, |
186 | | mbedtls_mpi *D) |
187 | 0 | { |
188 | 0 | int ret = 0; |
189 | 0 | mbedtls_mpi K, L; |
190 | |
|
191 | 0 | if (D == NULL) { |
192 | 0 | return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
193 | 0 | } |
194 | | |
195 | 0 | if (mbedtls_mpi_cmp_int(P, 1) <= 0 || |
196 | 0 | mbedtls_mpi_cmp_int(Q, 1) <= 0 || |
197 | 0 | mbedtls_mpi_cmp_int(E, 0) == 0) { |
198 | 0 | return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; |
199 | 0 | } |
200 | | |
201 | 0 | if (mbedtls_mpi_get_bit(E, 0) != 1) { |
202 | 0 | return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; |
203 | 0 | } |
204 | | |
205 | 0 | mbedtls_mpi_init(&K); |
206 | 0 | mbedtls_mpi_init(&L); |
207 | | |
208 | | /* Temporarily put K := P-1 and L := Q-1 */ |
209 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); |
210 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1)); |
211 | | |
212 | | /* Temporarily put D := gcd(P-1, Q-1) */ |
213 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(D, &K, &L)); |
214 | | |
215 | | /* K := LCM(P-1, Q-1) */ |
216 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, &K, &L)); |
217 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&K, NULL, &K, D)); |
218 | | |
219 | | /* Compute modular inverse of E mod LCM(P-1, Q-1) |
220 | | * This is FIPS 186-4 §B.3.1 criterion 3(b). |
221 | | * This will return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if E is not coprime to |
222 | | * (P-1)(Q-1), also validating FIPS 186-4 §B.3.1 criterion 2(a). */ |
223 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(D, E, &K)); |
224 | | |
225 | 0 | cleanup: |
226 | |
|
227 | 0 | mbedtls_mpi_free(&K); |
228 | 0 | mbedtls_mpi_free(&L); |
229 | |
|
230 | 0 | return ret; |
231 | 0 | } |
232 | | |
233 | | int mbedtls_rsa_deduce_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, |
234 | | const mbedtls_mpi *D, mbedtls_mpi *DP, |
235 | | mbedtls_mpi *DQ, mbedtls_mpi *QP) |
236 | 0 | { |
237 | 0 | int ret = 0; |
238 | 0 | mbedtls_mpi K; |
239 | 0 | mbedtls_mpi_init(&K); |
240 | | |
241 | | /* DP = D mod P-1 */ |
242 | 0 | if (DP != NULL) { |
243 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); |
244 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DP, D, &K)); |
245 | 0 | } |
246 | | |
247 | | /* DQ = D mod Q-1 */ |
248 | 0 | if (DQ != NULL) { |
249 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1)); |
250 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(DQ, D, &K)); |
251 | 0 | } |
252 | | |
253 | | /* QP = Q^{-1} mod P */ |
254 | 0 | if (QP != NULL) { |
255 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_odd(QP, Q, P)); |
256 | 0 | } |
257 | | |
258 | 0 | cleanup: |
259 | 0 | mbedtls_mpi_free(&K); |
260 | |
|
261 | 0 | return ret; |
262 | 0 | } |
263 | | |
264 | | /* |
265 | | * Check that core RSA parameters are sane. |
266 | | */ |
267 | | int mbedtls_rsa_validate_params(const mbedtls_mpi *N, const mbedtls_mpi *P, |
268 | | const mbedtls_mpi *Q, const mbedtls_mpi *D, |
269 | | const mbedtls_mpi *E, |
270 | | int (*f_rng)(void *, unsigned char *, size_t), |
271 | | void *p_rng) |
272 | 0 | { |
273 | 0 | int ret = 0; |
274 | 0 | mbedtls_mpi K, L; |
275 | |
|
276 | 0 | mbedtls_mpi_init(&K); |
277 | 0 | mbedtls_mpi_init(&L); |
278 | | |
279 | | /* |
280 | | * Step 1: If PRNG provided, check that P and Q are prime |
281 | | */ |
282 | |
|
283 | 0 | #if defined(MBEDTLS_GENPRIME) |
284 | | /* |
285 | | * When generating keys, the strongest security we support aims for an error |
286 | | * rate of at most 2^-100 and we are aiming for the same certainty here as |
287 | | * well. |
288 | | */ |
289 | 0 | if (f_rng != NULL && P != NULL && |
290 | 0 | (ret = mbedtls_mpi_is_prime_ext(P, 50, f_rng, p_rng)) != 0) { |
291 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
292 | 0 | goto cleanup; |
293 | 0 | } |
294 | | |
295 | 0 | if (f_rng != NULL && Q != NULL && |
296 | 0 | (ret = mbedtls_mpi_is_prime_ext(Q, 50, f_rng, p_rng)) != 0) { |
297 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
298 | 0 | goto cleanup; |
299 | 0 | } |
300 | | #else |
301 | | ((void) f_rng); |
302 | | ((void) p_rng); |
303 | | #endif /* MBEDTLS_GENPRIME */ |
304 | | |
305 | | /* |
306 | | * Step 2: Check that 1 < N = P * Q |
307 | | */ |
308 | | |
309 | 0 | if (P != NULL && Q != NULL && N != NULL) { |
310 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, P, Q)); |
311 | 0 | if (mbedtls_mpi_cmp_int(N, 1) <= 0 || |
312 | 0 | mbedtls_mpi_cmp_mpi(&K, N) != 0) { |
313 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
314 | 0 | goto cleanup; |
315 | 0 | } |
316 | 0 | } |
317 | | |
318 | | /* |
319 | | * Step 3: Check and 1 < D, E < N if present. |
320 | | */ |
321 | | |
322 | 0 | if (N != NULL && D != NULL && E != NULL) { |
323 | 0 | if (mbedtls_mpi_cmp_int(D, 1) <= 0 || |
324 | 0 | mbedtls_mpi_cmp_int(E, 1) <= 0 || |
325 | 0 | mbedtls_mpi_cmp_mpi(D, N) >= 0 || |
326 | 0 | mbedtls_mpi_cmp_mpi(E, N) >= 0) { |
327 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
328 | 0 | goto cleanup; |
329 | 0 | } |
330 | 0 | } |
331 | | |
332 | | /* |
333 | | * Step 4: Check that D, E are inverse modulo P-1 and Q-1 |
334 | | */ |
335 | | |
336 | 0 | if (P != NULL && Q != NULL && D != NULL && E != NULL) { |
337 | 0 | if (mbedtls_mpi_cmp_int(P, 1) <= 0 || |
338 | 0 | mbedtls_mpi_cmp_int(Q, 1) <= 0) { |
339 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
340 | 0 | goto cleanup; |
341 | 0 | } |
342 | | |
343 | | /* Compute DE-1 mod P-1 */ |
344 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E)); |
345 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); |
346 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, P, 1)); |
347 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L)); |
348 | 0 | if (mbedtls_mpi_cmp_int(&K, 0) != 0) { |
349 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
350 | 0 | goto cleanup; |
351 | 0 | } |
352 | | |
353 | | /* Compute DE-1 mod Q-1 */ |
354 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, D, E)); |
355 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); |
356 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&L, Q, 1)); |
357 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, &L)); |
358 | 0 | if (mbedtls_mpi_cmp_int(&K, 0) != 0) { |
359 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
360 | 0 | goto cleanup; |
361 | 0 | } |
362 | 0 | } |
363 | | |
364 | 0 | cleanup: |
365 | |
|
366 | 0 | mbedtls_mpi_free(&K); |
367 | 0 | mbedtls_mpi_free(&L); |
368 | | |
369 | | /* Wrap MPI error codes by RSA check failure error code */ |
370 | 0 | if (ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) { |
371 | 0 | ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
372 | 0 | } |
373 | |
|
374 | 0 | return ret; |
375 | 0 | } |
376 | | |
377 | | /* |
378 | | * Check that RSA CRT parameters are in accordance with core parameters. |
379 | | */ |
380 | | int mbedtls_rsa_validate_crt(const mbedtls_mpi *P, const mbedtls_mpi *Q, |
381 | | const mbedtls_mpi *D, const mbedtls_mpi *DP, |
382 | | const mbedtls_mpi *DQ, const mbedtls_mpi *QP) |
383 | 0 | { |
384 | 0 | int ret = 0; |
385 | |
|
386 | 0 | mbedtls_mpi K, L; |
387 | 0 | mbedtls_mpi_init(&K); |
388 | 0 | mbedtls_mpi_init(&L); |
389 | | |
390 | | /* Check that DP - D == 0 mod P - 1 */ |
391 | 0 | if (DP != NULL) { |
392 | 0 | if (P == NULL) { |
393 | 0 | ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
394 | 0 | goto cleanup; |
395 | 0 | } |
396 | | |
397 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, P, 1)); |
398 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DP, D)); |
399 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K)); |
400 | | |
401 | 0 | if (mbedtls_mpi_cmp_int(&L, 0) != 0) { |
402 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
403 | 0 | goto cleanup; |
404 | 0 | } |
405 | 0 | } |
406 | | |
407 | | /* Check that DQ - D == 0 mod Q - 1 */ |
408 | 0 | if (DQ != NULL) { |
409 | 0 | if (Q == NULL) { |
410 | 0 | ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
411 | 0 | goto cleanup; |
412 | 0 | } |
413 | | |
414 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, Q, 1)); |
415 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&L, DQ, D)); |
416 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&L, &L, &K)); |
417 | | |
418 | 0 | if (mbedtls_mpi_cmp_int(&L, 0) != 0) { |
419 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
420 | 0 | goto cleanup; |
421 | 0 | } |
422 | 0 | } |
423 | | |
424 | | /* Check that QP * Q - 1 == 0 mod P */ |
425 | 0 | if (QP != NULL) { |
426 | 0 | if (P == NULL || Q == NULL) { |
427 | 0 | ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA; |
428 | 0 | goto cleanup; |
429 | 0 | } |
430 | | |
431 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&K, QP, Q)); |
432 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&K, &K, 1)); |
433 | 0 | MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&K, &K, P)); |
434 | 0 | if (mbedtls_mpi_cmp_int(&K, 0) != 0) { |
435 | 0 | ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
436 | 0 | goto cleanup; |
437 | 0 | } |
438 | 0 | } |
439 | | |
440 | 0 | cleanup: |
441 | | |
442 | | /* Wrap MPI error codes by RSA check failure error code */ |
443 | 0 | if (ret != 0 && |
444 | 0 | ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED && |
445 | 0 | ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA) { |
446 | 0 | ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; |
447 | 0 | } |
448 | |
|
449 | 0 | mbedtls_mpi_free(&K); |
450 | 0 | mbedtls_mpi_free(&L); |
451 | |
|
452 | 0 | return ret; |
453 | 0 | } |
454 | | |
455 | | #endif /* MBEDTLS_RSA_C */ |