blob: 07cd66becffb9805969592fe244669201a19cae8 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * The RSA public-key cryptosystem
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000022 * The following sources were referenced in the design of this implementation
23 * of the RSA algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000024 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000025 * [1] A method for obtaining digital signatures and public-key cryptosystems
26 * R Rivest, A Shamir, and L Adleman
27 * http://people.csail.mit.edu/rivest/pubs.html#RSA78
28 *
29 * [2] Handbook of Applied Cryptography - 1997, Chapter 8
30 * Menezes, van Oorschot and Vanstone
31 *
Janos Follathe81102e2017-03-22 13:38:28 +000032 * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
33 * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
34 * Stefan Mangard
35 * https://arxiv.org/abs/1702.08719v2
36 *
Paul Bakker5121ce52009-01-03 21:22:43 +000037 */
38
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020041#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020043#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_RSA_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000046
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/rsa.h"
48#include "mbedtls/oid.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000049
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <string.h>
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if defined(MBEDTLS_PKCS1_V21)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000053#include "mbedtls/md.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000054#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
Paul Bakker5121ce52009-01-03 21:22:43 +000057#include <stdlib.h>
Rich Evans00ab4702015-02-06 13:43:58 +000058#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010062#else
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064#define mbedtls_printf printf
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +020065#define mbedtls_calloc calloc
66#define mbedtls_free free
Paul Bakker7dc4c442014-02-01 22:50:26 +010067#endif
68
Gilles Peskine4a7f6a02017-03-23 14:37:37 +010069/* Implementation that should never be optimized out by the compiler */
70static void mbedtls_zeroize( void *v, size_t n ) {
71 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
72}
73
Paul Bakker5121ce52009-01-03 21:22:43 +000074/*
Hanno Beckere2e8b8d2017-08-23 14:06:45 +010075 * Context-independent RSA helper functions.
76 *
77 * The following three functions
78 * - mbedtls_rsa_deduce_moduli
79 * - mbedtls_rsa_deduce_private
80 * - mbedtls_rsa_check_params
81 * are helper functions operating on the core RSA parameters
82 * (represented as MPI's). They do not use the RSA context structure
83 * and therefore need not be replaced when providing an alternative
84 * RSA implementation.
85 *
86 * Their purpose is to provide common MPI operations in the context
87 * of RSA that can be easily shared across multiple implementations.
88 */
89
90/*
91 * mbedtls_rsa_deduce_moduli
92 *
93 * Given the modulus N=PQ and a pair of public and private
94 * exponents E and D, respectively, factor N.
95 *
96 * Setting F := lcm(P-1,Q-1), the idea is as follows:
97 *
98 * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
99 * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
100 * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
101 * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
102 * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
103 * factors of N.
104 *
105 * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
106 * construction still applies since (-)^K is the identity on the set of
107 * roots of 1 in Z/NZ.
108 *
109 * The public and private key primitives (-)^E and (-)^D are mutually inverse
110 * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
111 * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
112 * Splitting L = 2^t * K with K odd, we have
113 *
114 * DE - 1 = FL = (F/2) * (2^(t+1)) * K,
115 *
116 * so (F / 2) * K is among the numbers
117 *
118 * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
119 *
120 * where ord is the order of 2 in (DE - 1).
121 * We can therefore iterate through these numbers apply the construction
122 * of (a) and (b) above to attempt to factor N.
123 *
124 */
125int mbedtls_rsa_deduce_moduli( mbedtls_mpi *N, mbedtls_mpi *D, mbedtls_mpi *E,
126 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
127 mbedtls_mpi *P, mbedtls_mpi *Q )
128{
129 /* Implementation note:
130 *
131 * Space-efficiency is given preference over time-efficiency here:
132 * several calculations are done in place and temporarily change
133 * the values of D and E.
134 *
135 * Specifically, D is replaced the largest odd divisor of DE - 1
136 * throughout the calculations.
137 */
138
139 int ret = 0;
140
141 uint16_t attempt; /* Number of current attempt */
142 uint16_t iter; /* Number of squares computed in the current attempt */
143
144 uint16_t bitlen_half; /* Half the bitsize of the modulus N */
145 uint16_t order; /* Order of 2 in DE - 1 */
146
147 mbedtls_mpi K; /* Temporary used for two purposes:
148 * - During factorization attempts, stores a andom integer
149 * in the range of [0,..,N]
150 * - During verification, holding intermediate results.
151 */
152
153 if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL )
154 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
155
156 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ||
157 mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
158 mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
159 mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
160 mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
161 {
162 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
163 }
164
165 /*
166 * Initializations and temporary changes
167 */
168
169 mbedtls_mpi_init( &K );
170 mbedtls_mpi_init( P );
171 mbedtls_mpi_init( Q );
172
173 /* Replace D by DE - 1 */
174 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( D, D, E ) );
175 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( D, D, 1 ) );
176
177 if( ( order = mbedtls_mpi_lsb( D ) ) == 0 )
178 {
179 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
180 goto cleanup;
181 }
182
183 /* After this operation, D holds the largest odd divisor
184 * of DE - 1 for the original values of D and E. */
185 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( D, order ) );
186
187 /* This is used to generate a few numbers around N / 2
188 * if no PRNG is provided. */
189 if( f_rng == NULL )
190 bitlen_half = mbedtls_mpi_bitlen( N ) / 2;
191
192 /*
193 * Actual work
194 */
195
196 for( attempt = 0; attempt < 30; ++attempt )
197 {
198 /* Generate some number in [0,N], either randomly
199 * if a PRNG is given, or try numbers around N/2 */
200 if( f_rng != NULL )
201 {
202 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &K,
203 mbedtls_mpi_size( N ),
204 f_rng, p_rng ) );
205 }
206 else
207 {
208 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &K, 1 ) ) ;
209 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &K, bitlen_half ) ) ;
210 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, attempt + 1 ) );
211 }
212
213 /* Check if gcd(K,N) = 1 */
214 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
215 if( mbedtls_mpi_cmp_int( P, 1 ) != 0 )
216 continue;
217
218 /* Go through K^X + 1, K^(2X) + 1, K^(4X) + 1, ...
219 * and check whether they have nontrivial GCD with N. */
220 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, D, N,
221 Q /* temporarily use Q for storing Montgomery
222 * multiplication helper values */ ) );
223
224 for( iter = 1; iter < order; ++iter )
225 {
226 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) );
227 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
228
229 if( mbedtls_mpi_cmp_int( P, 1 ) == 1 &&
230 mbedtls_mpi_cmp_mpi( P, N ) == -1 )
231 {
232 /*
233 * Have found a nontrivial divisor P of N.
234 * Set Q := N / P and verify D, E.
235 */
236
237 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, &K, N, P ) );
238
239 /*
240 * Verify that DE - 1 is indeed a multiple of
241 * lcm(P-1, Q-1), i.e. that it's a multiple of both
242 * P-1 and Q-1.
243 */
244
245 /* Restore DE - 1 and temporarily replace P, Q by P-1, Q-1. */
246 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( D, order ) );
247 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( P, P, 1 ) );
248 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( Q, Q, 1 ) );
249
250 /* Compute DE-1 mod P-1 */
251 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, D, P ) );
252 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
253 {
254 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
255 goto cleanup;
256 }
257
258 /* Compute DE-1 mod Q-1 */
259 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, D, Q ) );
260 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
261 {
262 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
263 goto cleanup;
264 }
265
266 /*
267 * All good, restore P, Q and D and return.
268 */
269
270 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( P, P, 1 ) );
271 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( Q, Q, 1 ) );
272 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( D, D, 1 ) );
273 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( D, NULL, D, E ) );
274
275 goto cleanup;
276 }
277
278 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
279 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) );
280 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) );
281 }
282 }
283
284 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
285
286cleanup:
287
288 mbedtls_mpi_free( &K );
289 return( ret );
290}
291
292/*
293 * Given P, Q and the public exponent E, deduce D.
294 * This is essentially a modular inversion.
295 */
296
297int mbedtls_rsa_deduce_private( mbedtls_mpi *P, mbedtls_mpi *Q,
298 mbedtls_mpi *D, mbedtls_mpi *E )
299{
300 int ret = 0;
301 mbedtls_mpi K;
302
303 if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 )
304 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
305
306 if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
307 mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ||
308 mbedtls_mpi_cmp_int( E, 0 ) == 0 )
309 {
310 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
311 }
312
313 mbedtls_mpi_init( &K );
314
315 /* Temporarily replace P and Q by P-1 and Q-1, respectively. */
316 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( P, P, 1 ) );
317 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( Q, Q, 1 ) );
318
319 /* Temporarily compute the gcd(P-1, Q-1) in D. */
320 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, P, Q ) );
321
322 /* Compute LCM(P-1, Q-1) in K */
323 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
324 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) );
325
326 /* Compute modular inverse of E in LCM(P-1, Q-1) */
327 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) );
328
329 /* Restore P and Q. */
330 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( P, P, 1 ) );
331 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( Q, Q, 1 ) );
332
333 /* Double-check result */
Hanno Becker750e8b42017-08-25 07:54:27 +0100334 MBEDTLS_MPI_CHK( mbedtls_rsa_validate_params( NULL, P, Q, D, E, NULL, NULL ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100335
336cleanup:
337
338 mbedtls_mpi_free( &K );
339
340 return( ret );
341}
342
343/*
344 * Check that core RSA parameters are sane.
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100345 */
346
Hanno Becker750e8b42017-08-25 07:54:27 +0100347int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
348 const mbedtls_mpi *Q, const mbedtls_mpi *D,
349 const mbedtls_mpi *E,
350 int (*f_rng)(void *, unsigned char *, size_t),
351 void *p_rng )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100352{
353 int ret = 0;
Hanno Becker750e8b42017-08-25 07:54:27 +0100354 mbedtls_mpi K, L;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100355
356 mbedtls_mpi_init( &K );
Hanno Becker750e8b42017-08-25 07:54:27 +0100357 mbedtls_mpi_init( &L );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100358
359 /*
360 * Step 1: If PRNG provided, check that P and Q are prime
361 */
362
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100363#if defined(MBEDTLS_GENPRIME)
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100364 if( f_rng != NULL && P != NULL &&
365 ( ret = mbedtls_mpi_is_prime( P, f_rng, p_rng ) ) != 0 )
366 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100367 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100368 goto cleanup;
369 }
370
371 if( f_rng != NULL && Q != NULL &&
372 ( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 )
373 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100374 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100375 goto cleanup;
376 }
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100377#else
378 ((void) f_rng);
379 ((void) p_rng);
380#endif /* MBEDTLS_GENPRIME */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100381
382 /*
383 * Step 2: Check that N = PQ
384 */
385
386 if( P != NULL && Q != NULL && N != NULL )
387 {
388 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
Hanno Becker750e8b42017-08-25 07:54:27 +0100389 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ||
390 mbedtls_mpi_cmp_mpi( &K, N ) != 0 )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100391 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100392 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100393 goto cleanup;
394 }
395 }
396
397 /*
398 * Step 3: Check that D, E are inverse modulo P-1 and Q-1
399 */
400
401 if( P != NULL && Q != NULL && D != NULL && E != NULL )
402 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100403 if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
404 mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ||
405 mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
406 mbedtls_mpi_cmp_int( E, 1 ) <= 0 )
407 {
408 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
409 goto cleanup;
410 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100411
412 /* Compute DE-1 mod P-1 */
Hanno Becker750e8b42017-08-25 07:54:27 +0100413 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
414 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
415 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) );
416 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100417 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
418 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100419 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100420 goto cleanup;
421 }
422
423 /* Compute DE-1 mod Q-1 */
Hanno Becker750e8b42017-08-25 07:54:27 +0100424 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
425 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
426 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
427 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100428 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
429 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100430 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100431 goto cleanup;
432 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100433 }
434
435cleanup:
436
437 mbedtls_mpi_free( &K );
Hanno Becker750e8b42017-08-25 07:54:27 +0100438 mbedtls_mpi_free( &L );
439
440 /* Wrap MPI error codes by RSA check failure error code */
441 if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
442 {
443 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
444 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100445
446 return( ret );
447}
448
449int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
450 const mbedtls_mpi *D, mbedtls_mpi *DP,
451 mbedtls_mpi *DQ, mbedtls_mpi *QP )
452{
453 int ret = 0;
454 mbedtls_mpi K;
455 mbedtls_mpi_init( &K );
456
457 if( DP != NULL )
458 {
459 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
460 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) );
461 }
462
463 if( DQ != NULL )
464 {
465 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
466 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) );
467 }
468
469 if( QP != NULL )
470 {
471 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) );
472 }
473
474cleanup:
475 mbedtls_mpi_free( &K );
476
477 return( ret );
478}
479
Hanno Becker617c1ae2017-08-23 14:11:24 +0100480
481/*
482 * Default RSA interface implementation
483 */
484
Hanno Beckerab377312017-08-23 16:24:51 +0100485#if !defined(MBEDTLS_RSA_ALT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100486
487int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
488 const mbedtls_mpi *N,
489 const mbedtls_mpi *P, const mbedtls_mpi *Q,
490 const mbedtls_mpi *D, const mbedtls_mpi *E )
491{
492 int ret;
493
494 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
495 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
496 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
497 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
498 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
499 {
500 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
501 }
502
503 if( N != NULL )
504 ctx->len = mbedtls_mpi_size( &ctx->N );
505
506 return( 0 );
507}
508
509int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
510 unsigned char *N, size_t N_len,
511 unsigned char *P, size_t P_len,
512 unsigned char *Q, size_t Q_len,
513 unsigned char *D, size_t D_len,
514 unsigned char *E, size_t E_len )
515{
516 int ret;
517
518 if( N != NULL )
519 {
520 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
521 ctx->len = mbedtls_mpi_size( &ctx->N );
522 }
523
524 if( P != NULL )
525 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
526
527 if( Q != NULL )
528 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
529
530 if( D != NULL )
531 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
532
533 if( E != NULL )
534 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
535
536cleanup:
537
538 if( ret != 0 )
539 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
540
541 return( 0 );
542}
543
544int mbedtls_rsa_complete( mbedtls_rsa_context *ctx,
545 int (*f_rng)(void *, unsigned char *, size_t),
546 void *p_rng )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100547{
548 int ret = 0;
549
Hanno Becker617c1ae2017-08-23 14:11:24 +0100550 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
551 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
552 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
553 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
554 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100555
Hanno Becker617c1ae2017-08-23 14:11:24 +0100556 /*
557 * Check whether provided parameters are enough
558 * to deduce all others. The following incomplete
559 * parameter sets for private keys are supported:
560 *
561 * (1) P, Q missing.
562 * (2) D and potentially N missing.
563 *
564 */
565 const int complete = have_N && have_P && have_Q && have_D && have_E;
566 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
567 const int d_missing = have_P && have_Q && !have_D && have_E;
568 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100569
Hanno Becker617c1ae2017-08-23 14:11:24 +0100570 const int is_priv = complete || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100571
Hanno Becker617c1ae2017-08-23 14:11:24 +0100572 if( !is_priv && !is_pub )
573 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
574
575 /*
576 * Step 1: Deduce and verify all core parameters.
577 */
578
579 if( pq_missing )
580 {
581 /* This includes sanity checking of core parameters,
582 * so no further checks necessary. */
583 ret = mbedtls_rsa_deduce_moduli( &ctx->N, &ctx->D, &ctx->E,
584 f_rng, p_rng,
585 &ctx->P, &ctx->Q );
586 if( ret != 0 )
587 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
588
589 }
590 else if( d_missing )
591 {
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100592#if defined(MBEDTLS_GENPRIME)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100593 /* If a PRNG is provided, check if P, Q are prime. */
594 if( f_rng != NULL &&
595 ( ( ret = mbedtls_mpi_is_prime( &ctx->P, f_rng, p_rng ) ) != 0 ||
596 ( ret = mbedtls_mpi_is_prime( &ctx->Q, f_rng, p_rng ) ) != 0 ) )
597 {
598 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
599 }
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100600#endif /* MBEDTLS_GENPRIME */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100601
602 /* Compute N if missing. */
603 if( !have_N &&
604 ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ) != 0 )
605 {
606 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
607 }
608
609 /* Deduce private exponent. This includes double-checking of the result,
610 * so together with the primality test above all core parameters are
611 * guaranteed to be sane if this call succeeds. */
612 if( ( ret = mbedtls_rsa_deduce_private( &ctx->P, &ctx->Q,
613 &ctx->D, &ctx->E ) ) != 0 )
614 {
615 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
616 }
617 }
618 else if( complete )
619 {
620 /* Check complete set of imported core parameters. */
Hanno Becker750e8b42017-08-25 07:54:27 +0100621 if( ( ret = mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
622 &ctx->D, &ctx->E,
623 f_rng, p_rng ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100624 {
625 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
626 }
627 }
628
629 /* In the remaining case of a public key, there's nothing to check for. */
630
631 /*
632 * Step 2: Deduce all additional parameters specific
633 * to our current RSA implementaiton.
634 */
635
Hanno Becker23344b52017-08-23 07:43:27 +0100636#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100637 if( is_priv )
638 {
639 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
640 &ctx->DP, &ctx->DQ, &ctx->QP );
641 if( ret != 0 )
642 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
643 }
Hanno Becker23344b52017-08-23 07:43:27 +0100644#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100645
646 /*
647 * Step 3: Double check
648 */
649
650 if( is_priv )
651 {
652 if( ( ret = mbedtls_rsa_check_privkey( ctx ) ) != 0 )
653 return( ret );
654 }
655 else
656 {
657 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
658 return( ret );
659 }
660
661 return( 0 );
662}
663
664/*
665 * Check if CRT parameters match RSA context.
666 * This has to be implemented even if CRT is not used,
667 * in order to be able to validate DER encoded RSA keys,
668 * which always contain CRT parameters.
669 */
670int mbedtls_rsa_check_crt( mbedtls_rsa_context *ctx, mbedtls_mpi *DP,
671 mbedtls_mpi *DQ, mbedtls_mpi *QP )
672{
Hanno Becker23344b52017-08-23 07:43:27 +0100673 int ret = 0;
Hanno Becker617c1ae2017-08-23 14:11:24 +0100674
Hanno Becker23344b52017-08-23 07:43:27 +0100675 /* Check if key is private or public */
676 const int is_priv =
677 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
678 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
679 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
680 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
681 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
682
683 if( !is_priv )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100684 {
685 /* Checking optional parameters only makes sense for private keys. */
686 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
687 }
688
Hanno Becker23344b52017-08-23 07:43:27 +0100689#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100690 if( ( DP != NULL && mbedtls_mpi_cmp_mpi( DP, &ctx->DP ) != 0 ) ||
691 ( DQ != NULL && mbedtls_mpi_cmp_mpi( DQ, &ctx->DQ ) != 0 ) ||
692 ( QP != NULL && mbedtls_mpi_cmp_mpi( QP, &ctx->QP ) != 0 ) )
693 {
694 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
695 }
Hanno Becker23344b52017-08-23 07:43:27 +0100696#else /* MBEDTLS_RSA_NO_CRT */
697
698 /*
699 * Check that DP, DQ and QP are in accordance with core parameters.
700 * (1) Check that DP - P == 0 mod P - 1
701 * (2) Check that DQ - Q == 0 mod Q - 1
702 * (3) Check that QP * P - 1 == 0 mod P
703
704 * Alternative implementation also not using DP, DQ and QP
705 * should be able to reuse this codepath.
706 */
707
708 /* Check (1) */
709 if( DP != NULL )
710 {
711 /* Temporarily replace P by P-1 and compute DP - D mod P-1 */
712 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
713 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( DP, DP, &ctx->D ) );
714 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, DP, &ctx->P ) );
715 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
716
717 if( mbedtls_mpi_cmp_int( DP, 0 ) != 0 )
718 {
719 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
720 }
721 }
722
723 /* Check (1) */
724 if( DQ != NULL )
725 {
726 /* Temporarily replace Q by Q-1 and compute DQ - D mod Q-1 */
727 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
728 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( DQ, DQ, &ctx->D ) );
729 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, DQ, &ctx->Q ) );
730 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
731
732 if( mbedtls_mpi_cmp_int( DQ, 0 ) != 0 )
733 {
734 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
735 }
736 }
737
738 /* Check (3) */
739 if( QP != NULL )
740 {
741 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( QP, QP, &ctx->Q ) );
742 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( QP, QP, 1 ) );
743 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( QP, QP, &ctx->P ) );
744 if( mbedtls_mpi_cmp_int( QP, 0 ) != 0 )
745 {
746 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
747 }
748 }
749
750cleanup:
751
752#endif
753
754 if( ret != 0 )
755 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100756
757 return( 0 );
758}
759
760int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
761 unsigned char *N, size_t N_len,
762 unsigned char *P, size_t P_len,
763 unsigned char *Q, size_t Q_len,
764 unsigned char *D, size_t D_len,
765 unsigned char *E, size_t E_len )
766{
767 int ret = 0;
768
769 /* Check if key is private or public */
770 const int is_priv =
771 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
772 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
773 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
774 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
775 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
776
777 if( !is_priv )
778 {
779 /* If we're trying to export private parameters for a public key,
780 * something must be wrong. */
781 if( P != NULL || Q != NULL || D != NULL )
782 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
783
784 }
785
786 if( N != NULL )
787 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
788
789 if( P != NULL )
790 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
791
792 if( Q != NULL )
793 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
794
795 if( D != NULL )
796 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
797
798 if( E != NULL )
799 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100800
801cleanup:
802
803 return( ret );
804}
805
Hanno Becker617c1ae2017-08-23 14:11:24 +0100806int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
807 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
808 mbedtls_mpi *D, mbedtls_mpi *E )
809{
810 int ret;
811
812 /* Check if key is private or public */
813 int is_priv =
814 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
815 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
816 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
817 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
818 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
819
820 if( !is_priv )
821 {
822 /* If we're trying to export private parameters for a public key,
823 * something must be wrong. */
824 if( P != NULL || Q != NULL || D != NULL )
825 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
826
827 }
828
829 /* Export all requested core parameters. */
830
831 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
832 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
833 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
834 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
835 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
836 {
837 return( ret );
838 }
839
840 return( 0 );
841}
842
843/*
844 * Export CRT parameters
845 * This must also be implemented if CRT is not used, for being able to
846 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
847 * can be used in this case.
848 */
849int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
850 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
851{
852 int ret;
853
854 /* Check if key is private or public */
855 int is_priv =
856 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
857 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
858 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
859 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
860 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
861
862 if( !is_priv )
863 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
864
Hanno Beckerdc95c892017-08-23 06:57:02 +0100865#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100866 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100867 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
868 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
869 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
870 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100871 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100872 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100873#else
874 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
875 DP, DQ, QP ) ) != 0 )
876 {
877 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
878 }
879#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100880
881 return( 0 );
882}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100883
884/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 * Initialize an RSA context
886 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000889 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000890{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200894
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895#if defined(MBEDTLS_THREADING_C)
896 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200897#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000898}
899
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100900/*
901 * Set padding for an existing RSA context
902 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100904{
905 ctx->padding = padding;
906 ctx->hash_id = hash_id;
907}
908
Hanno Becker617c1ae2017-08-23 14:11:24 +0100909/*
910 * Get length in bytes of RSA modulus
911 */
912
913size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
914{
915 return( mbedtls_mpi_size( &ctx->N ) );
916}
917
918
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
921/*
922 * Generate an RSA keypair
923 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000925 int (*f_rng)(void *, unsigned char *, size_t),
926 void *p_rng,
927 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000928{
929 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100930 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakker21eb2802010-08-16 11:10:02 +0000932 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
Janos Follathef441782016-09-21 13:18:12 +0100935 if( nbits % 2 )
936 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
937
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100938 mbedtls_mpi_init( &H );
939 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
941 /*
942 * find primes P and Q with Q < P so that:
943 * GCD( E, (P-1)*(Q-1) ) == 1
944 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200945 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
947 do
948 {
Janos Follath10c575b2016-02-23 14:42:48 +0000949 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100950 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Janos Follathef441782016-09-21 13:18:12 +0100952 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100953 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000956 continue;
957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200959 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 continue;
961
Janos Follathef441782016-09-21 13:18:12 +0100962 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100963 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100964
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100965 /* Temporarily replace P,Q by P-1, Q-1 */
966 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
967 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
968 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000970 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100973 /* Restore P,Q */
974 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
975 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
976
977 ctx->len = mbedtls_mpi_size( &ctx->N );
978
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 /*
980 * D = E^-1 mod ((P-1)*(Q-1))
981 * DP = D mod (P - 1)
982 * DQ = D mod (Q - 1)
983 * QP = Q^-1 mod P
984 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000985
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100986 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
987
988#if !defined(MBEDTLS_RSA_NO_CRT)
989 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
990 &ctx->DP, &ctx->DQ, &ctx->QP ) );
991#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000992
Hanno Becker83aad1f2017-08-23 06:45:10 +0100993 /* Double-check */
994 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
995
Paul Bakker5121ce52009-01-03 21:22:43 +0000996cleanup:
997
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100998 mbedtls_mpi_free( &H );
999 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +00001000
1001 if( ret != 0 )
1002 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003 mbedtls_rsa_free( ctx );
1004 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 }
1006
Paul Bakker48377d92013-08-30 12:06:24 +02001007 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001008}
1009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
1012/*
1013 * Check a public RSA key
1014 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001016{
Paul Bakker37940d92009-07-10 22:38:58 +00001017 if( !ctx->N.p || !ctx->E.p )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d92009-07-10 22:38:58 +00001019
Paul Bakker48377d92013-08-30 12:06:24 +02001020 if( ( ctx->N.p[0] & 1 ) == 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +00001021 ( ctx->E.p[0] & 1 ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001024 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
1025 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001027
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001028 if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
1030 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001031
1032 return( 0 );
1033}
1034
1035/*
1036 * Check a private RSA key
1037 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001039{
1040 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 return( ret );
1045
Paul Bakker37940d92009-07-10 22:38:58 +00001046 if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d92009-07-10 22:38:58 +00001048
Hanno Becker6345dd32017-08-23 06:59:48 +01001049 mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 );
1050 mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I );
1051 mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 ); mbedtls_mpi_init( &L1 );
1052 mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 mbedtls_mpi_init( &QP );
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
1056 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
1057 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1058 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1059 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
1060 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) );
1063 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) );
1064 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) );
Paul Bakkerb572adf2010-07-18 08:29:32 +00001065
Hanno Becker6345dd32017-08-23 06:59:48 +01001066#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
1068 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
1069 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
Hanno Becker6345dd32017-08-23 06:59:48 +01001070#endif
1071
Paul Bakkerb572adf2010-07-18 08:29:32 +00001072 /*
1073 * Check for a valid PKCS1v2 private key
1074 */
Hanno Becker6345dd32017-08-23 06:59:48 +01001075 if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
1076#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
1078 mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
1079 mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 ||
Hanno Becker6345dd32017-08-23 06:59:48 +01001080#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 mbedtls_mpi_cmp_int( &L2, 0 ) != 0 ||
Hanno Becker6345dd32017-08-23 06:59:48 +01001082 mbedtls_mpi_cmp_int( &I, 1 ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001084 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 }
Paul Bakker48377d92013-08-30 12:06:24 +02001087
Paul Bakker5121ce52009-01-03 21:22:43 +00001088cleanup:
Hanno Becker6345dd32017-08-23 06:59:48 +01001089 mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 );
1090 mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I );
1091 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 ); mbedtls_mpi_free( &L1 );
1092 mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_mpi_free( &QP );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095 if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
Paul Bakker9d781402011-05-09 16:17:09 +00001096 return( ret );
1097
Paul Bakker6c591fa2011-05-05 11:49:20 +00001098 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001100
1101 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001102}
1103
1104/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001105 * Check if contexts holding a public and private key match
1106 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001108{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
1110 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001111 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001113 }
1114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
1116 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001117 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001119 }
1120
1121 return( 0 );
1122}
1123
1124/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001125 * Do an RSA public key operation
1126 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001127int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001128 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 unsigned char *output )
1130{
Paul Bakker23986e52011-04-24 08:57:21 +00001131 int ret;
1132 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001134
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001136
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001137#if defined(MBEDTLS_THREADING_C)
1138 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1139 return( ret );
1140#endif
1141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001146 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1147 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 }
1149
1150 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
1152 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001153
1154cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001156 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1157 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +01001158#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
1162 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
1165 return( 0 );
1166}
1167
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001168/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001169 * Generate or update blinding values, see section 10 of:
1170 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +02001171 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001172 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001173 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001174static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001175 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1176{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001177 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001178
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001179 if( ctx->Vf.p != NULL )
1180 {
1181 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
1183 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
1184 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
1185 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001186
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001187 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001188 }
1189
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001190 /* Unblinding value: Vf = random number, invertible mod N */
1191 do {
1192 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001195 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
1196 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1197 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001198
1199 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001200 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1201 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001202
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001203
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001204cleanup:
1205 return( ret );
1206}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001207
Paul Bakker5121ce52009-01-03 21:22:43 +00001208/*
Janos Follathe81102e2017-03-22 13:38:28 +00001209 * Exponent blinding supposed to prevent side-channel attacks using multiple
1210 * traces of measurements to recover the RSA key. The more collisions are there,
1211 * the more bits of the key can be recovered. See [3].
1212 *
1213 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1214 * observations on avarage.
1215 *
1216 * For example with 28 byte blinding to achieve 2 collisions the adversary has
1217 * to make 2^112 observations on avarage.
1218 *
1219 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1220 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1221 * Thus in this sense with 28 byte blinding the security is not reduced by
1222 * side-channel attacks like the one in [3])
1223 *
1224 * This countermeasure does not help if the key recovery is possible with a
1225 * single trace.
1226 */
1227#define RSA_EXPONENT_BLINDING 28
1228
1229/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001230 * Do an RSA private key operation
1231 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001233 int (*f_rng)(void *, unsigned char *, size_t),
1234 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001235 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001236 unsigned char *output )
1237{
Paul Bakker23986e52011-04-24 08:57:21 +00001238 int ret;
1239 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001240 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +00001241 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +00001242#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001243 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001244 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +00001245#else
1246 mbedtls_mpi DP_blind, DQ_blind;
1247 mbedtls_mpi *DP = &ctx->DP;
1248 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +00001249#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001250
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001251 /* Make sure we have private key info, prevent possible misuse */
1252 if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL )
1253 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001255 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001256 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
1257
1258
1259 if( f_rng != NULL )
1260 {
Janos Follathe81102e2017-03-22 13:38:28 +00001261#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001262 mbedtls_mpi_init( &D_blind );
1263#else
1264 mbedtls_mpi_init( &DP_blind );
1265 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001266#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001267 }
Janos Follathe81102e2017-03-22 13:38:28 +00001268
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001270#if defined(MBEDTLS_THREADING_C)
1271 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1272 return( ret );
1273#endif
1274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
1276 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001277 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001278 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1279 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 }
1281
Paul Bakkerf451bac2013-08-30 15:37:02 +02001282 if( f_rng != NULL )
1283 {
1284 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001285 * Blinding
1286 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001287 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001288 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
1289 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +00001291
Janos Follathe81102e2017-03-22 13:38:28 +00001292 /*
1293 * Exponent blinding
1294 */
1295 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1296 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1297
Janos Follathf9203b42017-03-22 15:13:15 +00001298#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001299 /*
1300 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1301 */
1302 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1303 f_rng, p_rng ) );
1304 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1305 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1306 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1307
1308 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001309#else
1310 /*
1311 * DP_blind = ( P - 1 ) * R + DP
1312 */
1313 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1314 f_rng, p_rng ) );
1315 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1316 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1317 &ctx->DP ) );
1318
1319 DP = &DP_blind;
1320
1321 /*
1322 * DQ_blind = ( Q - 1 ) * R + DQ
1323 */
1324 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1325 f_rng, p_rng ) );
1326 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1327 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1328 &ctx->DQ ) );
1329
1330 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001331#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +02001332 }
Paul Bakkeraab30c12013-08-30 11:00:25 +02001333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001334#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001335 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001336#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001337 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001338 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 *
1340 * T1 = input ^ dP mod P
1341 * T2 = input ^ dQ mod Q
1342 */
Janos Follathf9203b42017-03-22 15:13:15 +00001343 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
1344 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
1346 /*
1347 * T = (T1 - T2) * (Q^-1 mod P) mod P
1348 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001349 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
1350 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
1351 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352
1353 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +02001354 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001355 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
1357 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
1358#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001359
Paul Bakkerf451bac2013-08-30 15:37:02 +02001360 if( f_rng != NULL )
1361 {
1362 /*
1363 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001364 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001365 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001366 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +02001368 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001369
1370 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001371 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001372
1373cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001374#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001375 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1376 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001377#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001379 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001380 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
1381
1382 if( f_rng != NULL )
1383 {
Janos Follathe81102e2017-03-22 13:38:28 +00001384#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001385 mbedtls_mpi_free( &D_blind );
1386#else
1387 mbedtls_mpi_free( &DP_blind );
1388 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001389#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001390 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001391
1392 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001393 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001394
1395 return( 0 );
1396}
1397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001398#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001399/**
1400 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1401 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001402 * \param dst buffer to mask
1403 * \param dlen length of destination buffer
1404 * \param src source of the mask generation
1405 * \param slen length of the source buffer
1406 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001407 */
Paul Bakker48377d92013-08-30 12:06:24 +02001408static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001410{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001412 unsigned char counter[4];
1413 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001414 unsigned int hlen;
1415 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001417 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001418 memset( counter, 0, 4 );
1419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001421
Simon Butcher02037452016-03-01 21:19:12 +00001422 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001423 p = dst;
1424
1425 while( dlen > 0 )
1426 {
1427 use_len = hlen;
1428 if( dlen < hlen )
1429 use_len = dlen;
1430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431 mbedtls_md_starts( md_ctx );
1432 mbedtls_md_update( md_ctx, src, slen );
1433 mbedtls_md_update( md_ctx, counter, 4 );
1434 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001435
1436 for( i = 0; i < use_len; ++i )
1437 *p++ ^= mask[i];
1438
1439 counter[3]++;
1440
1441 dlen -= use_len;
1442 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001443
1444 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001445}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001446#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001449/*
1450 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1451 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001453 int (*f_rng)(void *, unsigned char *, size_t),
1454 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001455 int mode,
1456 const unsigned char *label, size_t label_len,
1457 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001458 const unsigned char *input,
1459 unsigned char *output )
1460{
1461 size_t olen;
1462 int ret;
1463 unsigned char *p = output;
1464 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465 const mbedtls_md_info_t *md_info;
1466 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1469 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001470
1471 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001475 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001477
1478 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001480
Simon Butcher02037452016-03-01 21:19:12 +00001481 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001482 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001483 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001484
1485 memset( output, 0, olen );
1486
1487 *p++ = 0;
1488
Simon Butcher02037452016-03-01 21:19:12 +00001489 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001490 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001492
1493 p += hlen;
1494
Simon Butcher02037452016-03-01 21:19:12 +00001495 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001496 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001497 p += hlen;
1498 p += olen - 2 * hlen - 2 - ilen;
1499 *p++ = 1;
1500 memcpy( p, input, ilen );
1501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001503 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1504 {
1505 mbedtls_md_free( &md_ctx );
1506 return( ret );
1507 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001508
Simon Butcher02037452016-03-01 21:19:12 +00001509 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001510 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1511 &md_ctx );
1512
Simon Butcher02037452016-03-01 21:19:12 +00001513 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001514 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1515 &md_ctx );
1516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519 return( ( mode == MBEDTLS_RSA_PUBLIC )
1520 ? mbedtls_rsa_public( ctx, output, output )
1521 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001522}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001526/*
1527 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1528 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001529int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001530 int (*f_rng)(void *, unsigned char *, size_t),
1531 void *p_rng,
1532 int mode, size_t ilen,
1533 const unsigned char *input,
1534 unsigned char *output )
1535{
1536 size_t nb_pad, olen;
1537 int ret;
1538 unsigned char *p = output;
1539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1541 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001542
Janos Follath1ed9f992016-03-18 11:45:44 +00001543 // We don't check p_rng because it won't be dereferenced here
1544 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001546
1547 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001548
Simon Butcher02037452016-03-01 21:19:12 +00001549 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001550 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001552
1553 nb_pad = olen - 3 - ilen;
1554
1555 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001557 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001558 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001559
1560 while( nb_pad-- > 0 )
1561 {
1562 int rng_dl = 100;
1563
1564 do {
1565 ret = f_rng( p_rng, p, 1 );
1566 } while( *p == 0 && --rng_dl && ret == 0 );
1567
Simon Butcher02037452016-03-01 21:19:12 +00001568 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001569 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001571
1572 p++;
1573 }
1574 }
1575 else
1576 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001578
1579 while( nb_pad-- > 0 )
1580 *p++ = 0xFF;
1581 }
1582
1583 *p++ = 0;
1584 memcpy( p, input, ilen );
1585
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586 return( ( mode == MBEDTLS_RSA_PUBLIC )
1587 ? mbedtls_rsa_public( ctx, output, output )
1588 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001589}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001590#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001591
Paul Bakker5121ce52009-01-03 21:22:43 +00001592/*
1593 * Add the message padding, then do an RSA operation
1594 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001596 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001597 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001598 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001599 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001600 unsigned char *output )
1601{
Paul Bakker5121ce52009-01-03 21:22:43 +00001602 switch( ctx->padding )
1603 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001604#if defined(MBEDTLS_PKCS1_V15)
1605 case MBEDTLS_RSA_PKCS_V15:
1606 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001607 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001608#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001609
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001610#if defined(MBEDTLS_PKCS1_V21)
1611 case MBEDTLS_RSA_PKCS_V21:
1612 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001613 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001614#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001615
1616 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001617 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001618 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001619}
1620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001621#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001622/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001623 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001624 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001625int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001626 int (*f_rng)(void *, unsigned char *, size_t),
1627 void *p_rng,
1628 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001629 const unsigned char *label, size_t label_len,
1630 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001631 const unsigned char *input,
1632 unsigned char *output,
1633 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001634{
Paul Bakker23986e52011-04-24 08:57:21 +00001635 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001636 size_t ilen, i, pad_len;
1637 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001638 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1639 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001640 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001641 const mbedtls_md_info_t *md_info;
1642 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001643
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001644 /*
1645 * Parameters sanity checks
1646 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001647 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1648 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001649
1650 ilen = ctx->len;
1651
Paul Bakker27fdf462011-06-09 13:55:13 +00001652 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001653 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001655 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001656 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001657 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001658
Janos Follathc17cda12016-02-11 11:08:18 +00001659 hlen = mbedtls_md_get_size( md_info );
1660
1661 // checking for integer underflow
1662 if( 2 * hlen + 2 > ilen )
1663 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1664
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001665 /*
1666 * RSA operation
1667 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001668 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1669 ? mbedtls_rsa_public( ctx, input, buf )
1670 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001671
1672 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001673 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001674
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001675 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001676 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001677 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001678 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001679 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1680 {
1681 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001682 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001683 }
1684
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001685
1686 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001687 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001688
1689 /* seed: Apply seedMask to maskedSeed */
1690 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1691 &md_ctx );
1692
1693 /* DB: Apply dbMask to maskedDB */
1694 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1695 &md_ctx );
1696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001697 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001698
1699 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001700 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001701 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001702 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001703 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001704
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001705 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001706
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001707 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001708
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001709 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001710 for( i = 0; i < hlen; i++ )
1711 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001712
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001713 /* Get zero-padding len, but always read till end of buffer
1714 * (minus one, for the 01 byte) */
1715 pad_len = 0;
1716 pad_done = 0;
1717 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1718 {
1719 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001720 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001721 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001722
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001723 p += pad_len;
1724 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001725
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001726 /*
1727 * The only information "leaked" is whether the padding was correct or not
1728 * (eg, no data is copied if it was not correct). This meets the
1729 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1730 * the different error conditions.
1731 */
1732 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001733 {
1734 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1735 goto cleanup;
1736 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001737
Paul Bakker66d5d072014-06-17 16:39:18 +02001738 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001739 {
1740 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1741 goto cleanup;
1742 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001743
1744 *olen = ilen - (p - buf);
1745 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001746 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001747
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001748cleanup:
1749 mbedtls_zeroize( buf, sizeof( buf ) );
1750 mbedtls_zeroize( lhash, sizeof( lhash ) );
1751
1752 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001753}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001754#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001755
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001756#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001757/*
1758 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1759 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001760int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001761 int (*f_rng)(void *, unsigned char *, size_t),
1762 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001763 int mode, size_t *olen,
1764 const unsigned char *input,
1765 unsigned char *output,
1766 size_t output_max_len)
1767{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001768 int ret;
1769 size_t ilen, pad_count = 0, i;
1770 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001771 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001772
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001773 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1774 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001775
1776 ilen = ctx->len;
1777
1778 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001780
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001781 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1782 ? mbedtls_rsa_public( ctx, input, buf )
1783 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001784
1785 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001786 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001787
1788 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001789 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001790
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001791 /*
1792 * Check and get padding len in "constant-time"
1793 */
1794 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001795
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001796 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001797 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001798 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001800
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001801 /* Get padding len, but always read till end of buffer
1802 * (minus one, for the 00 byte) */
1803 for( i = 0; i < ilen - 3; i++ )
1804 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001805 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1806 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001807 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001808
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001809 p += pad_count;
1810 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001811 }
1812 else
1813 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001814 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001815
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001816 /* Get padding len, but always read till end of buffer
1817 * (minus one, for the 00 byte) */
1818 for( i = 0; i < ilen - 3; i++ )
1819 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001820 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001821 pad_count += ( pad_done == 0 );
1822 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001823
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001824 p += pad_count;
1825 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 }
1827
Janos Follathc69fa502016-02-12 13:30:09 +00001828 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001829
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001830 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001831 {
1832 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1833 goto cleanup;
1834 }
Paul Bakker8804f692013-02-28 18:06:26 +01001835
Paul Bakker66d5d072014-06-17 16:39:18 +02001836 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001837 {
1838 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1839 goto cleanup;
1840 }
Paul Bakker060c5682009-01-12 21:48:39 +00001841
Paul Bakker27fdf462011-06-09 13:55:13 +00001842 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001843 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001844 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001845
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001846cleanup:
1847 mbedtls_zeroize( buf, sizeof( buf ) );
1848
1849 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001850}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
1853/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001854 * Do an RSA operation, then remove the message padding
1855 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001856int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001857 int (*f_rng)(void *, unsigned char *, size_t),
1858 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001859 int mode, size_t *olen,
1860 const unsigned char *input,
1861 unsigned char *output,
1862 size_t output_max_len)
1863{
1864 switch( ctx->padding )
1865 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866#if defined(MBEDTLS_PKCS1_V15)
1867 case MBEDTLS_RSA_PKCS_V15:
1868 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001869 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001870#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001872#if defined(MBEDTLS_PKCS1_V21)
1873 case MBEDTLS_RSA_PKCS_V21:
1874 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001875 olen, input, output,
1876 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001877#endif
1878
1879 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001881 }
1882}
1883
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001884#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001885/*
1886 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1887 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001888int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001889 int (*f_rng)(void *, unsigned char *, size_t),
1890 void *p_rng,
1891 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001892 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001893 unsigned int hashlen,
1894 const unsigned char *hash,
1895 unsigned char *sig )
1896{
1897 size_t olen;
1898 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001899 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001900 unsigned int slen, hlen, offset = 0;
1901 int ret;
1902 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 const mbedtls_md_info_t *md_info;
1904 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1907 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001908
1909 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001911
1912 olen = ctx->len;
1913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001914 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001915 {
Simon Butcher02037452016-03-01 21:19:12 +00001916 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001917 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001918 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001921 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001922 }
1923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001924 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001925 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001926 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001928 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001929 slen = hlen;
1930
1931 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001933
1934 memset( sig, 0, olen );
1935
Simon Butcher02037452016-03-01 21:19:12 +00001936 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001937 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001938 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001939
Simon Butcher02037452016-03-01 21:19:12 +00001940 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001941 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001942 p += olen - hlen * 2 - 2;
1943 *p++ = 0x01;
1944 memcpy( p, salt, slen );
1945 p += slen;
1946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001947 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001948 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1949 {
1950 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001951 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001952 return( ret );
1953 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001954
Simon Butcher02037452016-03-01 21:19:12 +00001955 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956 mbedtls_md_starts( &md_ctx );
1957 mbedtls_md_update( &md_ctx, p, 8 );
1958 mbedtls_md_update( &md_ctx, hash, hashlen );
1959 mbedtls_md_update( &md_ctx, salt, slen );
1960 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001961 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001962
Simon Butcher02037452016-03-01 21:19:12 +00001963 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001964 if( msb % 8 == 0 )
1965 offset = 1;
1966
Simon Butcher02037452016-03-01 21:19:12 +00001967 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001968 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001970 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001971
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001972 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001973 sig[0] &= 0xFF >> ( olen * 8 - msb );
1974
1975 p += hlen;
1976 *p++ = 0xBC;
1977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001978 return( ( mode == MBEDTLS_RSA_PUBLIC )
1979 ? mbedtls_rsa_public( ctx, sig, sig )
1980 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001981}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001982#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001984#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001985/*
1986 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1987 */
1988/*
1989 * Do an RSA operation to sign the message digest
1990 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001992 int (*f_rng)(void *, unsigned char *, size_t),
1993 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001994 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001996 unsigned int hashlen,
1997 const unsigned char *hash,
1998 unsigned char *sig )
1999{
Paul Bakkerc70b9822013-04-07 22:00:46 +02002000 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01002001 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02002002 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002003 unsigned char *sig_try = NULL, *verif = NULL;
2004 size_t i;
2005 unsigned char diff;
2006 volatile unsigned char diff_no_optimize;
2007 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002008
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2010 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002011
2012 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002013 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01002014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002016 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002018 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002021 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
2022 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002023
Paul Bakkerc70b9822013-04-07 22:00:46 +02002024 nb_pad -= 10 + oid_size;
2025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002026 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002027 }
2028
Paul Bakkerc70b9822013-04-07 22:00:46 +02002029 nb_pad -= hashlen;
2030
Paul Bakkerb3869132013-02-28 17:21:01 +01002031 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002032 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002033
2034 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002035 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01002036 memset( p, 0xFF, nb_pad );
2037 p += nb_pad;
2038 *p++ = 0;
2039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002040 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002041 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02002042 memcpy( p, hash, hashlen );
2043 }
2044 else
2045 {
2046 /*
2047 * DigestInfo ::= SEQUENCE {
2048 * digestAlgorithm DigestAlgorithmIdentifier,
2049 * digest Digest }
2050 *
2051 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
2052 *
2053 * Digest ::= OCTET STRING
2054 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002055 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002056 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002058 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002060 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002061 memcpy( p, oid, oid_size );
2062 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002063 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002064 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002065 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002066 *p++ = hashlen;
2067 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01002068 }
2069
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002070 if( mode == MBEDTLS_RSA_PUBLIC )
2071 return( mbedtls_rsa_public( ctx, sig, sig ) );
2072
2073 /*
2074 * In order to prevent Lenstra's attack, make the signature in a
2075 * temporary buffer and check it before returning it.
2076 */
2077 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00002078 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002079 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2080
Simon Butcher1285ab52016-01-01 21:42:47 +00002081 verif = mbedtls_calloc( 1, ctx->len );
2082 if( verif == NULL )
2083 {
2084 mbedtls_free( sig_try );
2085 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2086 }
2087
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002088 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2089 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2090
2091 /* Compare in constant time just in case */
2092 for( diff = 0, i = 0; i < ctx->len; i++ )
2093 diff |= verif[i] ^ sig[i];
2094 diff_no_optimize = diff;
2095
2096 if( diff_no_optimize != 0 )
2097 {
2098 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2099 goto cleanup;
2100 }
2101
2102 memcpy( sig, sig_try, ctx->len );
2103
2104cleanup:
2105 mbedtls_free( sig_try );
2106 mbedtls_free( verif );
2107
2108 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002109}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002110#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002111
2112/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 * Do an RSA operation to sign the message digest
2114 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002115int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002116 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002117 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002119 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002120 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002121 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 unsigned char *sig )
2123{
Paul Bakker5121ce52009-01-03 21:22:43 +00002124 switch( ctx->padding )
2125 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002126#if defined(MBEDTLS_PKCS1_V15)
2127 case MBEDTLS_RSA_PKCS_V15:
2128 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002129 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002130#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002132#if defined(MBEDTLS_PKCS1_V21)
2133 case MBEDTLS_RSA_PKCS_V21:
2134 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002135 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002136#endif
2137
Paul Bakker5121ce52009-01-03 21:22:43 +00002138 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002139 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002141}
2142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002144/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002145 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002146 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002147int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002148 int (*f_rng)(void *, unsigned char *, size_t),
2149 void *p_rng,
2150 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002152 unsigned int hashlen,
2153 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002154 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002155 int expected_salt_len,
2156 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002157{
Paul Bakker23986e52011-04-24 08:57:21 +00002158 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002159 size_t siglen;
2160 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002161 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00002162 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00002163 unsigned int hlen;
2164 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002165 const mbedtls_md_info_t *md_info;
2166 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002167 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2170 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002171
Paul Bakker5121ce52009-01-03 21:22:43 +00002172 siglen = ctx->len;
2173
Paul Bakker27fdf462011-06-09 13:55:13 +00002174 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002177 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2178 ? mbedtls_rsa_public( ctx, sig, buf )
2179 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002180
2181 if( ret != 0 )
2182 return( ret );
2183
2184 p = buf;
2185
Paul Bakkerb3869132013-02-28 17:21:01 +01002186 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002189 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002190 {
Simon Butcher02037452016-03-01 21:19:12 +00002191 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002192 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002193 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002196 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002197 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002199 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01002200 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002201 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002203 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002204 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00002205
Paul Bakkerb3869132013-02-28 17:21:01 +01002206 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00002207
Simon Butcher02037452016-03-01 21:19:12 +00002208 /*
2209 * Note: EMSA-PSS verification is over the length of N - 1 bits
2210 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002211 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002212
Simon Butcher02037452016-03-01 21:19:12 +00002213 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002214 if( msb % 8 == 0 )
2215 {
2216 p++;
2217 siglen -= 1;
2218 }
2219 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002222 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07002223 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2224 {
2225 mbedtls_md_free( &md_ctx );
2226 return( ret );
2227 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002228
Paul Bakkerb3869132013-02-28 17:21:01 +01002229 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01002230
Paul Bakkerb3869132013-02-28 17:21:01 +01002231 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002232
Paul Bakker4de44aa2013-12-31 11:43:01 +01002233 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002234 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002235
Paul Bakkerb3869132013-02-28 17:21:01 +01002236 if( p == buf + siglen ||
2237 *p++ != 0x01 )
2238 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002239 mbedtls_md_free( &md_ctx );
2240 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002241 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002242
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002243 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01002244 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002247 slen != (size_t) expected_salt_len )
2248 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002249 mbedtls_md_free( &md_ctx );
2250 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002251 }
2252
Simon Butcher02037452016-03-01 21:19:12 +00002253 /*
2254 * Generate H = Hash( M' )
2255 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002256 mbedtls_md_starts( &md_ctx );
2257 mbedtls_md_update( &md_ctx, zeros, 8 );
2258 mbedtls_md_update( &md_ctx, hash, hashlen );
2259 mbedtls_md_update( &md_ctx, p, slen );
2260 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00002261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002262 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002263
Paul Bakkerb3869132013-02-28 17:21:01 +01002264 if( memcmp( p + slen, result, hlen ) == 0 )
2265 return( 0 );
2266 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002267 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01002268}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002269
2270/*
2271 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2272 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002273int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002274 int (*f_rng)(void *, unsigned char *, size_t),
2275 void *p_rng,
2276 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002278 unsigned int hashlen,
2279 const unsigned char *hash,
2280 const unsigned char *sig )
2281{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2283 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002284 : md_alg;
2285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002286 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002287 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002288 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002289 sig ) );
2290
2291}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002292#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002294#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002295/*
2296 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2297 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002298int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002299 int (*f_rng)(void *, unsigned char *, size_t),
2300 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002301 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002302 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002303 unsigned int hashlen,
2304 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002305 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002306{
2307 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002308 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002309 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002310 mbedtls_md_type_t msg_md_alg;
2311 const mbedtls_md_info_t *md_info;
2312 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002313 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002315 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2316 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002317
2318 siglen = ctx->len;
2319
2320 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002321 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002323 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2324 ? mbedtls_rsa_public( ctx, sig, buf )
2325 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01002326
2327 if( ret != 0 )
2328 return( ret );
2329
2330 p = buf;
2331
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002332 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
2333 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002334
2335 while( *p != 0 )
2336 {
2337 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002339 p++;
2340 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02002341 p++; /* skip 00 byte */
2342
2343 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
2344 if( p - buf < 11 )
2345 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002346
2347 len = siglen - ( p - buf );
2348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002349 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002350 {
2351 if( memcmp( p, hash, hashlen ) == 0 )
2352 return( 0 );
2353 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002354 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002355 }
2356
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002357 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002358 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2360 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002361
2362 end = p + len;
2363
Simon Butcher02037452016-03-01 21:19:12 +00002364 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02002365 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
2366 * Insist on 2-byte length tags, to protect against variants of
2367 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00002368 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002369 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002370 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2371 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2372 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002373 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002374 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002375
Gilles Peskinee7e76502017-05-04 12:48:39 +02002376 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002377 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2378 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2379 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002380 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002381 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002382
Gilles Peskinee7e76502017-05-04 12:48:39 +02002383 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002384 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
2385 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002386 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002387 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002388
2389 oid.p = p;
2390 p += oid.len;
2391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002392 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
2393 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002394
2395 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002396 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002397
2398 /*
2399 * assume the algorithm parameters must be NULL
2400 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02002401 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002402 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
2403 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002404 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002405 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002406
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002407 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002408 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
2409 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002410 if( p != p0 + 2 || asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002411 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002412
2413 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002414 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002415
2416 p += hashlen;
2417
2418 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002420
2421 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002422}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002423#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002424
2425/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002426 * Do an RSA operation and check the message digest
2427 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002428int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002429 int (*f_rng)(void *, unsigned char *, size_t),
2430 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002431 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002432 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002433 unsigned int hashlen,
2434 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002435 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002436{
2437 switch( ctx->padding )
2438 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002439#if defined(MBEDTLS_PKCS1_V15)
2440 case MBEDTLS_RSA_PKCS_V15:
2441 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002442 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002443#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002445#if defined(MBEDTLS_PKCS1_V21)
2446 case MBEDTLS_RSA_PKCS_V21:
2447 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002448 hashlen, hash, sig );
2449#endif
2450
2451 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002452 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002453 }
2454}
2455
2456/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002457 * Copy the components of an RSA key
2458 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002459int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002460{
2461 int ret;
2462
2463 dst->ver = src->ver;
2464 dst->len = src->len;
2465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002466 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2467 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002469 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2470 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2471 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002472
2473#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002474 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2475 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2476 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002477 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2478 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002479#endif
2480
2481 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002483 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2484 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002485
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002486 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002487 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002488
2489cleanup:
2490 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002491 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002492
2493 return( ret );
2494}
2495
2496/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002497 * Free the components of an RSA key
2498 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002499void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002500{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002501 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002502 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2503 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002504 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002505
Hanno Becker33c30a02017-08-23 07:00:22 +01002506#if !defined(MBEDTLS_RSA_NO_CRT)
2507 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2508 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2509 mbedtls_mpi_free( &ctx->DP );
2510#endif /* MBEDTLS_RSA_NO_CRT */
2511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002512#if defined(MBEDTLS_THREADING_C)
2513 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002514#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002515}
2516
Hanno Beckerab377312017-08-23 16:24:51 +01002517#endif /* !MBEDTLS_RSA_ALT */
2518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002519#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002520
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002521#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002522
2523/*
2524 * Example RSA-1024 keypair, for test purposes
2525 */
2526#define KEY_LEN 128
2527
2528#define RSA_N "9292758453063D803DD603D5E777D788" \
2529 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2530 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2531 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2532 "93A89813FBF3C4F8066D2D800F7C38A8" \
2533 "1AE31942917403FF4946B0A83D3D3E05" \
2534 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2535 "5E94BB77B07507233A0BC7BAC8F90F79"
2536
2537#define RSA_E "10001"
2538
2539#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2540 "66CA472BC44D253102F8B4A9D3BFA750" \
2541 "91386C0077937FE33FA3252D28855837" \
2542 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2543 "DF79C5CE07EE72C7F123142198164234" \
2544 "CABB724CF78B8173B9F880FC86322407" \
2545 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2546 "071513A1E85B5DFA031F21ECAE91A34D"
2547
2548#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2549 "2C01CAD19EA484A87EA4377637E75500" \
2550 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2551 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2552
2553#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2554 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2555 "910E4168387E3C30AA1E00C339A79508" \
2556 "8452DD96A9A5EA5D9DCA68DA636032AF"
2557
2558#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
2559 "3C94D22288ACD763FD8E5600ED4A702D" \
2560 "F84198A5F06C2E72236AE490C93F07F8" \
2561 "3CC559CD27BC2D1CA488811730BB5725"
2562
2563#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
2564 "D8AAEA56749EA28623272E4F7D0592AF" \
2565 "7C1F1313CAC9471B5C523BFE592F517B" \
2566 "407A1BD76C164B93DA2D32A383E58357"
2567
2568#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
2569 "F38D18D2B2F0E2DD275AA977E2BF4411" \
2570 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
2571 "A74206CEC169D74BF5A8C50D6F48EA08"
2572
2573#define PT_LEN 24
2574#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2575 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002577#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002578static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002579{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002580#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002581 size_t i;
2582
Paul Bakker545570e2010-07-18 09:00:25 +00002583 if( rng_state != NULL )
2584 rng_state = NULL;
2585
Paul Bakkera3d195c2011-11-27 21:07:34 +00002586 for( i = 0; i < len; ++i )
2587 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002588#else
2589 if( rng_state != NULL )
2590 rng_state = NULL;
2591
2592 arc4random_buf( output, len );
2593#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002594
Paul Bakkera3d195c2011-11-27 21:07:34 +00002595 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002596}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002597#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002598
Paul Bakker5121ce52009-01-03 21:22:43 +00002599/*
2600 * Checkup routine
2601 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002602int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002603{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002604 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002605#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002606 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002607 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002608 unsigned char rsa_plaintext[PT_LEN];
2609 unsigned char rsa_decrypted[PT_LEN];
2610 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002611#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002612 unsigned char sha1sum[20];
2613#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002614
Hanno Becker3a701162017-08-22 13:52:43 +01002615 mbedtls_mpi K;
2616
2617 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002618 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002619
Hanno Becker3a701162017-08-22 13:52:43 +01002620 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2621 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2622 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2623 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2624 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2625 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2626 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2627 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2628 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2629 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2630
2631 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa, NULL, NULL ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002632
2633 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002634 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002636 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2637 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002638 {
2639 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002640 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002641
2642 return( 1 );
2643 }
2644
Hanno Becker3a701162017-08-22 13:52:43 +01002645 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_DP ) );
2646 MBEDTLS_MPI_CHK( mbedtls_rsa_check_crt( &rsa, &K, NULL, NULL ) );
2647
2648 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_DQ ) );
2649 MBEDTLS_MPI_CHK( mbedtls_rsa_check_crt( &rsa, NULL, &K, NULL ) );
2650
2651 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_QP ) );
2652 MBEDTLS_MPI_CHK( mbedtls_rsa_check_crt( &rsa, NULL, NULL, &K ) );
2653
Paul Bakker5121ce52009-01-03 21:22:43 +00002654 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002656
2657 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002659 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, PT_LEN,
Paul Bakker5121ce52009-01-03 21:22:43 +00002660 rsa_plaintext, rsa_ciphertext ) != 0 )
2661 {
2662 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002663 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002664
2665 return( 1 );
2666 }
2667
2668 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002669 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002670
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002671 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, &len,
Paul Bakker060c5682009-01-12 21:48:39 +00002672 rsa_ciphertext, rsa_decrypted,
Paul Bakker23986e52011-04-24 08:57:21 +00002673 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002674 {
2675 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002676 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002677
2678 return( 1 );
2679 }
2680
2681 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2682 {
2683 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002684 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002685
2686 return( 1 );
2687 }
2688
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002689 if( verbose != 0 )
2690 mbedtls_printf( "passed\n" );
2691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002692#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002693 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002694 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002695
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002696 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002698 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 sha1sum, rsa_ciphertext ) != 0 )
2700 {
2701 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002702 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002703
2704 return( 1 );
2705 }
2706
2707 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002708 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002710 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
Paul Bakker5121ce52009-01-03 21:22:43 +00002711 sha1sum, rsa_ciphertext ) != 0 )
2712 {
2713 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002714 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002715
2716 return( 1 );
2717 }
2718
2719 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002720 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002721#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002722
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002723 if( verbose != 0 )
2724 mbedtls_printf( "\n" );
2725
Paul Bakker3d8fb632014-04-17 12:42:41 +02002726cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002727 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002728 mbedtls_rsa_free( &rsa );
2729#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002730 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002731#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002732 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002733}
2734
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002735#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002736
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002737#endif /* MBEDTLS_RSA_C */