blob: 493cd1c123b39a2fdff7298613b45ed0ab5712b9 [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 */
Hanno Becker74716312017-10-02 10:00:37 +010021
Paul Bakker5121ce52009-01-03 21:22:43 +000022/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000023 * The following sources were referenced in the design of this implementation
24 * of the RSA algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000025 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000026 * [1] A method for obtaining digital signatures and public-key cryptosystems
27 * R Rivest, A Shamir, and L Adleman
28 * http://people.csail.mit.edu/rivest/pubs.html#RSA78
29 *
30 * [2] Handbook of Applied Cryptography - 1997, Chapter 8
31 * Menezes, van Oorschot and Vanstone
32 *
Janos Follathe81102e2017-03-22 13:38:28 +000033 * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
34 * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
35 * Stefan Mangard
36 * https://arxiv.org/abs/1702.08719v2
37 *
Paul Bakker5121ce52009-01-03 21:22:43 +000038 */
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020042#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020044#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_RSA_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000047
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/rsa.h"
49#include "mbedtls/oid.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000050
Rich Evans00ab4702015-02-06 13:43:58 +000051#include <string.h>
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PKCS1_V21)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/md.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000055#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
Paul Bakker5121ce52009-01-03 21:22:43 +000058#include <stdlib.h>
Rich Evans00ab4702015-02-06 13:43:58 +000059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010063#else
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#define mbedtls_printf printf
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +020066#define mbedtls_calloc calloc
67#define mbedtls_free free
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#endif
69
Gilles Peskine4a7f6a02017-03-23 14:37:37 +010070/* Implementation that should never be optimized out by the compiler */
71static void mbedtls_zeroize( void *v, size_t n ) {
72 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
73}
74
Paul Bakker5121ce52009-01-03 21:22:43 +000075/*
Hanno Beckere2e8b8d2017-08-23 14:06:45 +010076 * Context-independent RSA helper functions.
77 *
Hanno Beckerd9431a72017-08-25 08:03:13 +010078 * There are two classes of helper functions:
79 * (1) Parameter-generating helpers. These are:
Hanno Becker0f65e0c2017-10-03 14:39:16 +010080 * - mbedtls_rsa_deduce_primes
Hanno Becker8ba6ce42017-10-03 14:36:26 +010081 * - mbedtls_rsa_deduce_private_exponent
Hanno Beckerd9431a72017-08-25 08:03:13 +010082 * - mbedtls_rsa_deduce_crt
83 * Each of these functions takes a set of core RSA parameters
84 * and generates some other, or CRT related parameters.
85 * (2) Parameter-checking helpers. These are:
86 * - mbedtls_rsa_validate_params
87 * - mbedtls_rsa_validate_crt
88 * They take a set of core or CRT related RSA parameters
89 * and check their validity.
Hanno Beckere2e8b8d2017-08-23 14:06:45 +010090 *
Hanno Beckerd9431a72017-08-25 08:03:13 +010091 * The helper functions do not use the RSA context structure
92 * and therefore do not need to be replaced when providing
93 * an alternative RSA implementation.
94 *
95 * Their main purpose is to provide common MPI operations in the context
Hanno Beckere2e8b8d2017-08-23 14:06:45 +010096 * of RSA that can be easily shared across multiple implementations.
97 */
98
99/*
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100100 *
101 * Given the modulus N=PQ and a pair of public and private
102 * exponents E and D, respectively, factor N.
103 *
104 * Setting F := lcm(P-1,Q-1), the idea is as follows:
105 *
106 * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
107 * is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
108 * square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
109 * possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
110 * or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
111 * factors of N.
112 *
113 * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
114 * construction still applies since (-)^K is the identity on the set of
115 * roots of 1 in Z/NZ.
116 *
117 * The public and private key primitives (-)^E and (-)^D are mutually inverse
118 * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
119 * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
120 * Splitting L = 2^t * K with K odd, we have
121 *
122 * DE - 1 = FL = (F/2) * (2^(t+1)) * K,
123 *
124 * so (F / 2) * K is among the numbers
125 *
126 * (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
127 *
128 * where ord is the order of 2 in (DE - 1).
129 * We can therefore iterate through these numbers apply the construction
130 * of (a) and (b) above to attempt to factor N.
131 *
132 */
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100133int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N,
Hanno Beckerba5b7552017-10-02 09:55:49 +0100134 mbedtls_mpi const *D, mbedtls_mpi const *E,
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100135 mbedtls_mpi *P, mbedtls_mpi *Q )
136{
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100137 int ret = 0;
138
139 uint16_t attempt; /* Number of current attempt */
140 uint16_t iter; /* Number of squares computed in the current attempt */
141
Hanno Becker705fc682017-10-10 17:57:02 +0100142 uint16_t order; /* Order of 2 in DE - 1 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100143
Hanno Beckerba5b7552017-10-02 09:55:49 +0100144 mbedtls_mpi T; /* Holds largest odd divisor of DE - 1 */
145 mbedtls_mpi K; /* During factorization attempts, stores a random integer
146 * in the range of [0,..,N] */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100147
Hanno Becker68b4d582017-10-10 16:39:10 +0100148 const unsigned int primes[] = { 2,
149 3, 5, 7, 11, 13, 17, 19, 23,
150 29, 31, 37, 41, 43, 47, 53, 59,
151 61, 67, 71, 73, 79, 83, 89, 97,
152 101, 103, 107, 109, 113, 127, 131, 137,
153 139, 149, 151, 157, 163, 167, 173, 179,
154 181, 191, 193, 197, 199, 211, 223, 227,
155 229, 233, 239, 241, 251, 257, 263, 269,
156 271, 277, 281, 283, 293, 307, 311, 313
157 };
158
159 const size_t num_primes = sizeof( primes ) / sizeof( *primes );
160
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100161 if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL )
162 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
163
164 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ||
165 mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
166 mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
167 mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
168 mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
169 {
170 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
171 }
172
173 /*
174 * Initializations and temporary changes
175 */
176
177 mbedtls_mpi_init( &K );
Hanno Beckerba5b7552017-10-02 09:55:49 +0100178 mbedtls_mpi_init( &T );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100179
Hanno Beckerba5b7552017-10-02 09:55:49 +0100180 /* T := DE - 1 */
181 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D, E ) );
182 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100183
Hanno Beckerba5b7552017-10-02 09:55:49 +0100184 if( ( order = mbedtls_mpi_lsb( &T ) ) == 0 )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100185 {
186 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
187 goto cleanup;
188 }
189
Hanno Beckerba5b7552017-10-02 09:55:49 +0100190 /* After this operation, T holds the largest odd divisor of DE - 1. */
191 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100192
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100193 /*
194 * Actual work
195 */
196
Hanno Becker68b4d582017-10-10 16:39:10 +0100197 /* Skip trying 2 if N == 1 mod 8 */
198 attempt = 0;
199 if( N->p[0] % 8 == 1 )
200 attempt = 1;
201
202 for( ; attempt < num_primes; ++attempt )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100203 {
Hanno Becker68b4d582017-10-10 16:39:10 +0100204 mbedtls_mpi_lset( &K, primes[attempt] );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100205
206 /* Check if gcd(K,N) = 1 */
207 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
208 if( mbedtls_mpi_cmp_int( P, 1 ) != 0 )
209 continue;
210
Hanno Beckerba5b7552017-10-02 09:55:49 +0100211 /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ...
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100212 * and check whether they have nontrivial GCD with N. */
Hanno Beckerba5b7552017-10-02 09:55:49 +0100213 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N,
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100214 Q /* temporarily use Q for storing Montgomery
215 * multiplication helper values */ ) );
216
217 for( iter = 1; iter < order; ++iter )
218 {
219 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) );
220 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
221
222 if( mbedtls_mpi_cmp_int( P, 1 ) == 1 &&
223 mbedtls_mpi_cmp_mpi( P, N ) == -1 )
224 {
225 /*
226 * Have found a nontrivial divisor P of N.
Hanno Beckerd56d83a2017-08-25 07:29:35 +0100227 * Set Q := N / P.
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100228 */
229
Hanno Beckerba5b7552017-10-02 09:55:49 +0100230 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100231 goto cleanup;
232 }
233
234 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
235 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) );
236 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) );
237 }
238 }
239
240 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
241
242cleanup:
243
244 mbedtls_mpi_free( &K );
Hanno Beckerba5b7552017-10-02 09:55:49 +0100245 mbedtls_mpi_free( &T );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100246 return( ret );
247}
248
249/*
250 * Given P, Q and the public exponent E, deduce D.
251 * This is essentially a modular inversion.
252 */
253
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100254int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
255 mbedtls_mpi const *Q,
256 mbedtls_mpi const *E,
257 mbedtls_mpi *D )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100258{
259 int ret = 0;
Hanno Beckerbdefff12017-10-02 09:57:50 +0100260 mbedtls_mpi K, L;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100261
262 if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 )
263 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
264
265 if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
266 mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ||
267 mbedtls_mpi_cmp_int( E, 0 ) == 0 )
268 {
269 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
270 }
271
272 mbedtls_mpi_init( &K );
Hanno Beckerbdefff12017-10-02 09:57:50 +0100273 mbedtls_mpi_init( &L );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100274
Hanno Beckerbdefff12017-10-02 09:57:50 +0100275 /* Temporarily put K := P-1 and L := Q-1 */
276 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
277 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100278
Hanno Beckerbdefff12017-10-02 09:57:50 +0100279 /* Temporarily put D := gcd(P-1, Q-1) */
280 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100281
Hanno Beckerbdefff12017-10-02 09:57:50 +0100282 /* K := LCM(P-1, Q-1) */
283 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100284 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) );
285
286 /* Compute modular inverse of E in LCM(P-1, Q-1) */
287 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) );
288
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100289cleanup:
290
291 mbedtls_mpi_free( &K );
Hanno Beckerbdefff12017-10-02 09:57:50 +0100292 mbedtls_mpi_free( &L );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100293
294 return( ret );
295}
296
297/*
Hanno Beckerd3637992017-08-25 07:55:03 +0100298 * Check that RSA CRT parameters are in accordance with core parameters.
299 */
300
301int mbedtls_rsa_validate_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
302 const mbedtls_mpi *D, const mbedtls_mpi *DP,
303 const mbedtls_mpi *DQ, const mbedtls_mpi *QP )
304{
305 int ret = 0;
306
307 mbedtls_mpi K, L;
308 mbedtls_mpi_init( &K );
309 mbedtls_mpi_init( &L );
310
Hanno Becker98838b02017-10-02 13:16:10 +0100311 /* Check that DP - D == 0 mod P - 1 */
Hanno Beckerd3637992017-08-25 07:55:03 +0100312 if( DP != NULL )
313 {
314 if( P == NULL )
315 {
316 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
317 goto cleanup;
318 }
319
320 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
321 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) );
322 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
323
324 if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
325 {
Hanno Becker45a0ef32017-10-03 14:32:56 +0100326 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
327 goto cleanup;
Hanno Beckerd3637992017-08-25 07:55:03 +0100328 }
329 }
330
Hanno Becker98838b02017-10-02 13:16:10 +0100331 /* Check that DQ - D == 0 mod Q - 1 */
Hanno Beckerd3637992017-08-25 07:55:03 +0100332 if( DQ != NULL )
333 {
334 if( Q == NULL )
335 {
336 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
337 goto cleanup;
338 }
339
340 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
341 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) );
342 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
343
344 if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
345 {
Hanno Becker45a0ef32017-10-03 14:32:56 +0100346 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
347 goto cleanup;
Hanno Beckerd3637992017-08-25 07:55:03 +0100348 }
349 }
350
Hanno Becker98838b02017-10-02 13:16:10 +0100351 /* Check that QP * Q - 1 == 0 mod P */
Hanno Beckerd3637992017-08-25 07:55:03 +0100352 if( QP != NULL )
353 {
354 if( P == NULL || Q == NULL )
355 {
356 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
357 goto cleanup;
358 }
359
360 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) );
361 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
362 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) );
363 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
364 {
Hanno Becker45a0ef32017-10-03 14:32:56 +0100365 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
366 goto cleanup;
Hanno Beckerd3637992017-08-25 07:55:03 +0100367 }
368 }
369
370cleanup:
371
372 /* Wrap MPI error codes by RSA check failure error code */
373 if( ret != 0 &&
374 ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
375 ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
376 {
377 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
378 }
379
380 mbedtls_mpi_free( &K );
381 mbedtls_mpi_free( &L );
382
383 return( ret );
384}
385
386/*
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100387 * Check that core RSA parameters are sane.
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100388 */
389
Hanno Becker750e8b42017-08-25 07:54:27 +0100390int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
391 const mbedtls_mpi *Q, const mbedtls_mpi *D,
392 const mbedtls_mpi *E,
393 int (*f_rng)(void *, unsigned char *, size_t),
394 void *p_rng )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100395{
396 int ret = 0;
Hanno Becker750e8b42017-08-25 07:54:27 +0100397 mbedtls_mpi K, L;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100398
399 mbedtls_mpi_init( &K );
Hanno Becker750e8b42017-08-25 07:54:27 +0100400 mbedtls_mpi_init( &L );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100401
402 /*
403 * Step 1: If PRNG provided, check that P and Q are prime
404 */
405
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100406#if defined(MBEDTLS_GENPRIME)
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100407 if( f_rng != NULL && P != NULL &&
408 ( ret = mbedtls_mpi_is_prime( P, f_rng, p_rng ) ) != 0 )
409 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100410 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100411 goto cleanup;
412 }
413
414 if( f_rng != NULL && Q != NULL &&
415 ( ret = mbedtls_mpi_is_prime( Q, f_rng, p_rng ) ) != 0 )
416 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100417 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100418 goto cleanup;
419 }
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100420#else
421 ((void) f_rng);
422 ((void) p_rng);
423#endif /* MBEDTLS_GENPRIME */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100424
425 /*
Hanno Beckerb5beaa82017-10-02 13:01:43 +0100426 * Step 2: Check that 1 < N = PQ
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100427 */
428
429 if( P != NULL && Q != NULL && N != NULL )
430 {
431 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
Hanno Beckerb5beaa82017-10-02 13:01:43 +0100432 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ||
Hanno Becker750e8b42017-08-25 07:54:27 +0100433 mbedtls_mpi_cmp_mpi( &K, N ) != 0 )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100434 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100435 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100436 goto cleanup;
437 }
438 }
439
440 /*
Hanno Beckerb5beaa82017-10-02 13:01:43 +0100441 * Step 3: Check and 1 < D, E < N if present.
442 */
443
444 if( N != NULL && D != NULL && E != NULL )
445 {
446 if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
447 mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
448 mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
449 mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
450 {
451 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
452 goto cleanup;
453 }
454 }
455
456 /*
457 * Step 4: Check that D, E are inverse modulo P-1 and Q-1
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100458 */
459
460 if( P != NULL && Q != NULL && D != NULL && E != NULL )
461 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100462 if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
Hanno Beckerb5beaa82017-10-02 13:01:43 +0100463 mbedtls_mpi_cmp_int( Q, 1 ) <= 0 )
Hanno Becker750e8b42017-08-25 07:54:27 +0100464 {
465 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
466 goto cleanup;
467 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100468
469 /* Compute DE-1 mod P-1 */
Hanno Becker750e8b42017-08-25 07:54:27 +0100470 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
471 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
472 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) );
473 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100474 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
475 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100476 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100477 goto cleanup;
478 }
479
480 /* Compute DE-1 mod Q-1 */
Hanno Becker750e8b42017-08-25 07:54:27 +0100481 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
482 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
483 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
484 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100485 if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
486 {
Hanno Becker750e8b42017-08-25 07:54:27 +0100487 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100488 goto cleanup;
489 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100490 }
491
492cleanup:
493
494 mbedtls_mpi_free( &K );
Hanno Becker750e8b42017-08-25 07:54:27 +0100495 mbedtls_mpi_free( &L );
496
497 /* Wrap MPI error codes by RSA check failure error code */
498 if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
499 {
500 ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
501 }
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100502
503 return( ret );
504}
505
506int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
507 const mbedtls_mpi *D, mbedtls_mpi *DP,
508 mbedtls_mpi *DQ, mbedtls_mpi *QP )
509{
510 int ret = 0;
511 mbedtls_mpi K;
512 mbedtls_mpi_init( &K );
513
Hanno Beckerd9431a72017-08-25 08:03:13 +0100514 /* DP = D mod P-1 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100515 if( DP != NULL )
516 {
517 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
518 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) );
519 }
520
Hanno Beckerd9431a72017-08-25 08:03:13 +0100521 /* DQ = D mod Q-1 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100522 if( DQ != NULL )
523 {
524 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
525 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) );
526 }
527
Hanno Beckerd9431a72017-08-25 08:03:13 +0100528 /* QP = Q^{-1} mod P */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100529 if( QP != NULL )
530 {
531 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) );
532 }
533
534cleanup:
535 mbedtls_mpi_free( &K );
536
537 return( ret );
538}
539
Hanno Becker617c1ae2017-08-23 14:11:24 +0100540
541/*
542 * Default RSA interface implementation
543 */
544
Hanno Beckerab377312017-08-23 16:24:51 +0100545#if !defined(MBEDTLS_RSA_ALT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100546
547int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
548 const mbedtls_mpi *N,
549 const mbedtls_mpi *P, const mbedtls_mpi *Q,
550 const mbedtls_mpi *D, const mbedtls_mpi *E )
551{
552 int ret;
553
554 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
555 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
556 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
557 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
558 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
559 {
560 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
561 }
562
563 if( N != NULL )
564 ctx->len = mbedtls_mpi_size( &ctx->N );
565
566 return( 0 );
567}
568
569int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
Hanno Becker74716312017-10-02 10:00:37 +0100570 unsigned char const *N, size_t N_len,
571 unsigned char const *P, size_t P_len,
572 unsigned char const *Q, size_t Q_len,
573 unsigned char const *D, size_t D_len,
574 unsigned char const *E, size_t E_len )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100575{
576 int ret;
577
578 if( N != NULL )
579 {
580 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
581 ctx->len = mbedtls_mpi_size( &ctx->N );
582 }
583
584 if( P != NULL )
585 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
586
587 if( Q != NULL )
588 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
589
590 if( D != NULL )
591 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
592
593 if( E != NULL )
594 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
595
596cleanup:
597
598 if( ret != 0 )
599 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
600
601 return( 0 );
602}
603
Hanno Becker705fc682017-10-10 17:57:02 +0100604/*
605 * Checks whether the context fields are set in such a way
606 * that the RSA primitives will be able to execute without error.
607 * It does *not* make guarantees for consistency of the parameters.
608 */
609static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv )
610{
611 if( ctx->len != mbedtls_mpi_size( &ctx->N ) )
612 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
613
614 /*
615 * 1. Modular exponentiation needs positive, odd moduli.
616 */
617
618 /* Modular exponentiation wrt. N is always used for
619 * RSA public key operations. */
620 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
621 mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
622 {
623 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
624 }
625
626#if !defined(MBEDTLS_RSA_NO_CRT)
627 /* Modular exponentiation for P and Q is only
628 * used for private key operations and if CRT
629 * is used. */
630 if( is_priv &&
631 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
632 mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
633 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
634 mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
635 {
636 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
637 }
638#endif /* !MBEDTLS_RSA_NO_CRT */
639
640 /*
641 * 2. Exponents must be positive
642 */
643
644 /* Always need E for public key operations */
645 if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
646 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
647
648#if !defined(MBEDTLS_NO_CRT)
649 /* For private key operations, use D or DP & DQ
650 * as (unblinded) exponents. */
651 if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
652 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
653#else
654 if( is_priv &&
655 ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
656 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
657 {
658 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
659 }
660#endif /* MBEDTLS_RSA_NO_CRT */
661
662 /* Blinding shouldn't make exponents negative either,
663 * so check that P, Q >= 1 if that hasn't yet been
664 * done as part of 1. */
665#if defined(MBEDTLS_NO_CRT)
666 if( is_priv &&
667 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
668 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
669 {
670 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
671 }
672#endif
673
674 /* It wouldn't lead to an error if it wasn't satisfied,
675 * but check for PQ >= 1 nonetheless. */
676#if !defined(MBEDTLS_NO_CRT)
677 if( is_priv &&
678 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
679 {
680 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
681 }
682#endif
683
684 return( 0 );
685}
686
Hanno Beckerf9e184b2017-10-10 16:49:26 +0100687int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100688{
689 int ret = 0;
690
Hanno Becker617c1ae2017-08-23 14:11:24 +0100691 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
692 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
693 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
694 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
695 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100696
Hanno Becker617c1ae2017-08-23 14:11:24 +0100697 /*
698 * Check whether provided parameters are enough
699 * to deduce all others. The following incomplete
700 * parameter sets for private keys are supported:
701 *
702 * (1) P, Q missing.
703 * (2) D and potentially N missing.
704 *
705 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100706
Hanno Becker2cca6f32017-09-29 11:46:40 +0100707 const int n_missing = have_P && have_Q && have_D && have_E;
708 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
709 const int d_missing = have_P && have_Q && !have_D && have_E;
710 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
711
712 /* These three alternatives are mutually exclusive */
713 const int is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100714
Hanno Becker617c1ae2017-08-23 14:11:24 +0100715 if( !is_priv && !is_pub )
716 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
717
718 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100719 * Step 1: Deduce N if P, Q are provided.
720 */
721
722 if( !have_N && have_P && have_Q )
723 {
724 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
725 &ctx->Q ) ) != 0 )
726 {
727 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
728 }
729
730 ctx->len = mbedtls_mpi_size( &ctx->N );
731 }
732
733 /*
734 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100735 */
736
737 if( pq_missing )
738 {
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100739 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->D, &ctx->E,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100740 &ctx->P, &ctx->Q );
741 if( ret != 0 )
742 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
743
744 }
745 else if( d_missing )
746 {
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100747 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
748 &ctx->Q,
749 &ctx->E,
750 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100751 {
752 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
753 }
754 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100755
Hanno Becker617c1ae2017-08-23 14:11:24 +0100756 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100757 * Step 3: Deduce all additional parameters specific
Hanno Beckere8674892017-10-10 17:56:14 +0100758 * to our current RSA implementation.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100759 */
760
Hanno Becker23344b52017-08-23 07:43:27 +0100761#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100762 if( is_priv )
763 {
764 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
765 &ctx->DP, &ctx->DQ, &ctx->QP );
766 if( ret != 0 )
767 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
768 }
Hanno Becker23344b52017-08-23 07:43:27 +0100769#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100770
771 /*
Hanno Becker705fc682017-10-10 17:57:02 +0100772 * Step 3: Basic sanity checks
Hanno Becker617c1ae2017-08-23 14:11:24 +0100773 */
774
Hanno Becker705fc682017-10-10 17:57:02 +0100775 return( rsa_check_context( ctx, is_priv ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100776}
777
Hanno Becker617c1ae2017-08-23 14:11:24 +0100778int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
779 unsigned char *N, size_t N_len,
780 unsigned char *P, size_t P_len,
781 unsigned char *Q, size_t Q_len,
782 unsigned char *D, size_t D_len,
783 unsigned char *E, size_t E_len )
784{
785 int ret = 0;
786
787 /* Check if key is private or public */
788 const int is_priv =
789 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
790 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
791 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
792 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
793 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
794
795 if( !is_priv )
796 {
797 /* If we're trying to export private parameters for a public key,
798 * something must be wrong. */
799 if( P != NULL || Q != NULL || D != NULL )
800 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
801
802 }
803
804 if( N != NULL )
805 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
806
807 if( P != NULL )
808 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
809
810 if( Q != NULL )
811 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
812
813 if( D != NULL )
814 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
815
816 if( E != NULL )
817 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100818
819cleanup:
820
821 return( ret );
822}
823
Hanno Becker617c1ae2017-08-23 14:11:24 +0100824int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
825 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
826 mbedtls_mpi *D, mbedtls_mpi *E )
827{
828 int ret;
829
830 /* Check if key is private or public */
831 int is_priv =
832 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
833 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
834 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
835 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
836 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
837
838 if( !is_priv )
839 {
840 /* If we're trying to export private parameters for a public key,
841 * something must be wrong. */
842 if( P != NULL || Q != NULL || D != NULL )
843 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
844
845 }
846
847 /* Export all requested core parameters. */
848
849 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
850 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
851 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
852 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
853 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
854 {
855 return( ret );
856 }
857
858 return( 0 );
859}
860
861/*
862 * Export CRT parameters
863 * This must also be implemented if CRT is not used, for being able to
864 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
865 * can be used in this case.
866 */
867int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
868 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
869{
870 int ret;
871
872 /* Check if key is private or public */
873 int is_priv =
874 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
875 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
876 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
877 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
878 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
879
880 if( !is_priv )
881 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
882
Hanno Beckerdc95c892017-08-23 06:57:02 +0100883#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100884 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100885 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
886 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
887 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
888 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100889 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100890 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100891#else
892 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
893 DP, DQ, QP ) ) != 0 )
894 {
895 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
896 }
897#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100898
899 return( 0 );
900}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100901
902/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 * Initialize an RSA context
904 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000907 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000908{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000910
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913#if defined(MBEDTLS_THREADING_C)
914 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200915#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000916}
917
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100918/*
919 * Set padding for an existing RSA context
920 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100922{
923 ctx->padding = padding;
924 ctx->hash_id = hash_id;
925}
926
Hanno Becker617c1ae2017-08-23 14:11:24 +0100927/*
928 * Get length in bytes of RSA modulus
929 */
930
931size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
932{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100933 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100934}
935
936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
939/*
940 * Generate an RSA keypair
941 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000943 int (*f_rng)(void *, unsigned char *, size_t),
944 void *p_rng,
945 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000946{
947 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100948 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000949
Paul Bakker21eb2802010-08-16 11:10:02 +0000950 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000952
Janos Follathef441782016-09-21 13:18:12 +0100953 if( nbits % 2 )
954 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
955
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100956 mbedtls_mpi_init( &H );
957 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
959 /*
960 * find primes P and Q with Q < P so that:
961 * GCD( E, (P-1)*(Q-1) ) == 1
962 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000964
965 do
966 {
Janos Follath10c575b2016-02-23 14:42:48 +0000967 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100968 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969
Janos Follathef441782016-09-21 13:18:12 +0100970 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100971 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 continue;
975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200977 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 continue;
979
Janos Follathef441782016-09-21 13:18:12 +0100980 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100981 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100982
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100983 /* Temporarily replace P,Q by P-1, Q-1 */
984 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
985 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
986 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100991 /* Restore P,Q */
992 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
993 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
994
995 ctx->len = mbedtls_mpi_size( &ctx->N );
996
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 /*
998 * D = E^-1 mod ((P-1)*(Q-1))
999 * DP = D mod (P - 1)
1000 * DQ = D mod (Q - 1)
1001 * QP = Q^-1 mod P
1002 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001003
Hanno Beckerbee3aae2017-08-23 06:59:15 +01001004 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
1005
1006#if !defined(MBEDTLS_RSA_NO_CRT)
1007 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
1008 &ctx->DP, &ctx->DQ, &ctx->QP ) );
1009#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001010
Hanno Becker83aad1f2017-08-23 06:45:10 +01001011 /* Double-check */
1012 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
1013
Paul Bakker5121ce52009-01-03 21:22:43 +00001014cleanup:
1015
Hanno Beckerbee3aae2017-08-23 06:59:15 +01001016 mbedtls_mpi_free( &H );
1017 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018
1019 if( ret != 0 )
1020 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_rsa_free( ctx );
1022 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 }
1024
Paul Bakker48377d92013-08-30 12:06:24 +02001025 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001026}
1027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00001029
1030/*
1031 * Check a public RSA key
1032 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001034{
Hanno Becker705fc682017-10-10 17:57:02 +01001035 if( rsa_check_context( ctx, 0 /* public */ ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001038 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
1039 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Hanno Becker98838b02017-10-02 13:16:10 +01001040 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +01001042 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001043
Hanno Becker705fc682017-10-10 17:57:02 +01001044 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
1045 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +01001047 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +01001049 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
1051 return( 0 );
1052}
1053
1054/*
Hanno Becker705fc682017-10-10 17:57:02 +01001055 * Check for the consistency of all fields in an RSA private key context
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001058{
Hanno Becker705fc682017-10-10 17:57:02 +01001059 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
1060 rsa_check_context( ctx, 1 /* private */ ) != 0 )
1061 {
Hanno Becker98838b02017-10-02 13:16:10 +01001062 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker705fc682017-10-10 17:57:02 +01001063 }
Hanno Becker98838b02017-10-02 13:16:10 +01001064
1065 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +01001066 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 {
Hanno Beckerb269a852017-08-25 08:03:21 +01001068 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001069 }
Hanno Becker705fc682017-10-10 17:57:02 +01001070
Hanno Beckerb269a852017-08-25 08:03:21 +01001071#if !defined(MBEDTLS_RSA_NO_CRT)
1072 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
1073 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
1074 {
1075 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1076 }
1077#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +00001078
1079 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001080}
1081
1082/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001083 * Check if contexts holding a public and private key match
1084 */
Hanno Becker98838b02017-10-02 13:16:10 +01001085int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
1086 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001087{
Hanno Becker98838b02017-10-02 13:16:10 +01001088 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001090 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001092 }
1093
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
1095 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001096 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001098 }
1099
1100 return( 0 );
1101}
1102
1103/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001104 * Do an RSA public key operation
1105 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001107 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001108 unsigned char *output )
1109{
Paul Bakker23986e52011-04-24 08:57:21 +00001110 int ret;
1111 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001113
Hanno Becker705fc682017-10-10 17:57:02 +01001114 if( rsa_check_context( ctx, 0 /* public */ ) )
1115 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001118
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001119#if defined(MBEDTLS_THREADING_C)
1120 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1121 return( ret );
1122#endif
1123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001128 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1129 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 }
1131
1132 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
1134 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001138 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1139 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +01001140#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
1144 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
1147 return( 0 );
1148}
1149
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001150/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001151 * Generate or update blinding values, see section 10 of:
1152 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +02001153 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001154 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001155 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001156static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001157 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1158{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001159 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001160
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001161 if( ctx->Vf.p != NULL )
1162 {
1163 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
1165 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
1166 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
1167 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001168
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001169 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001170 }
1171
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001172 /* Unblinding value: Vf = random number, invertible mod N */
1173 do {
1174 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
1178 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1179 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001180
1181 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1183 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 +02001184
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001185
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001186cleanup:
1187 return( ret );
1188}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001189
Paul Bakker5121ce52009-01-03 21:22:43 +00001190/*
Janos Follathe81102e2017-03-22 13:38:28 +00001191 * Exponent blinding supposed to prevent side-channel attacks using multiple
1192 * traces of measurements to recover the RSA key. The more collisions are there,
1193 * the more bits of the key can be recovered. See [3].
1194 *
1195 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1196 * observations on avarage.
1197 *
1198 * For example with 28 byte blinding to achieve 2 collisions the adversary has
1199 * to make 2^112 observations on avarage.
1200 *
1201 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1202 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1203 * Thus in this sense with 28 byte blinding the security is not reduced by
1204 * side-channel attacks like the one in [3])
1205 *
1206 * This countermeasure does not help if the key recovery is possible with a
1207 * single trace.
1208 */
1209#define RSA_EXPONENT_BLINDING 28
1210
1211/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001212 * Do an RSA private key operation
1213 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001215 int (*f_rng)(void *, unsigned char *, size_t),
1216 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001217 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001218 unsigned char *output )
1219{
Paul Bakker23986e52011-04-24 08:57:21 +00001220 int ret;
1221 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +00001223 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +00001224#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001225 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001226 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +00001227#else
1228 mbedtls_mpi DP_blind, DQ_blind;
1229 mbedtls_mpi *DP = &ctx->DP;
1230 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +00001231#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001232
Hanno Becker705fc682017-10-10 17:57:02 +01001233 if( rsa_check_context( ctx, 1 /* private */ ) != 0 )
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001234 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001237 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
1238
Janos Follathf9203b42017-03-22 15:13:15 +00001239 if( f_rng != NULL )
1240 {
Janos Follathe81102e2017-03-22 13:38:28 +00001241#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001242 mbedtls_mpi_init( &D_blind );
1243#else
1244 mbedtls_mpi_init( &DP_blind );
1245 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001246#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001247 }
Janos Follathe81102e2017-03-22 13:38:28 +00001248
Paul Bakker5121ce52009-01-03 21:22:43 +00001249
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001250#if defined(MBEDTLS_THREADING_C)
1251 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1252 return( ret );
1253#endif
1254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001255 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
1256 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001257 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001258 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1259 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001260 }
1261
Paul Bakkerf451bac2013-08-30 15:37:02 +02001262 if( f_rng != NULL )
1263 {
1264 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001265 * Blinding
1266 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001267 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001268 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
1269 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +00001271
Janos Follathe81102e2017-03-22 13:38:28 +00001272 /*
1273 * Exponent blinding
1274 */
1275 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1276 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1277
Janos Follathf9203b42017-03-22 15:13:15 +00001278#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001279 /*
1280 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1281 */
1282 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1283 f_rng, p_rng ) );
1284 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1285 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1286 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1287
1288 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001289#else
1290 /*
1291 * DP_blind = ( P - 1 ) * R + DP
1292 */
1293 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1294 f_rng, p_rng ) );
1295 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1296 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1297 &ctx->DP ) );
1298
1299 DP = &DP_blind;
1300
1301 /*
1302 * DQ_blind = ( Q - 1 ) * R + DQ
1303 */
1304 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1305 f_rng, p_rng ) );
1306 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1307 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1308 &ctx->DQ ) );
1309
1310 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001311#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +02001312 }
Paul Bakkeraab30c12013-08-30 11:00:25 +02001313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001314#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001315 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001316#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001317 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001318 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001319 *
1320 * T1 = input ^ dP mod P
1321 * T2 = input ^ dQ mod Q
1322 */
Janos Follathf9203b42017-03-22 15:13:15 +00001323 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
1324 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001325
1326 /*
1327 * T = (T1 - T2) * (Q^-1 mod P) mod P
1328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
1330 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
1331 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001332
1333 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +02001334 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001335 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001336 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
1337 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
1338#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001339
Paul Bakkerf451bac2013-08-30 15:37:02 +02001340 if( f_rng != NULL )
1341 {
1342 /*
1343 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001344 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001345 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001346 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +02001348 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
1350 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352
1353cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001354#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001355 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1356 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001357#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001360 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
1361
1362 if( f_rng != NULL )
1363 {
Janos Follathe81102e2017-03-22 13:38:28 +00001364#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001365 mbedtls_mpi_free( &D_blind );
1366#else
1367 mbedtls_mpi_free( &DP_blind );
1368 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001369#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001370 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001371
1372 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001373 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001374
1375 return( 0 );
1376}
1377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001379/**
1380 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1381 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001382 * \param dst buffer to mask
1383 * \param dlen length of destination buffer
1384 * \param src source of the mask generation
1385 * \param slen length of the source buffer
1386 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001387 */
Paul Bakker48377d92013-08-30 12:06:24 +02001388static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001389 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001390{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001391 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001392 unsigned char counter[4];
1393 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001394 unsigned int hlen;
1395 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001398 memset( counter, 0, 4 );
1399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001401
Simon Butcher02037452016-03-01 21:19:12 +00001402 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001403 p = dst;
1404
1405 while( dlen > 0 )
1406 {
1407 use_len = hlen;
1408 if( dlen < hlen )
1409 use_len = dlen;
1410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411 mbedtls_md_starts( md_ctx );
1412 mbedtls_md_update( md_ctx, src, slen );
1413 mbedtls_md_update( md_ctx, counter, 4 );
1414 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001415
1416 for( i = 0; i < use_len; ++i )
1417 *p++ ^= mask[i];
1418
1419 counter[3]++;
1420
1421 dlen -= use_len;
1422 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001423
1424 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001425}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001429/*
1430 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1431 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001433 int (*f_rng)(void *, unsigned char *, size_t),
1434 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001435 int mode,
1436 const unsigned char *label, size_t label_len,
1437 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001438 const unsigned char *input,
1439 unsigned char *output )
1440{
1441 size_t olen;
1442 int ret;
1443 unsigned char *p = output;
1444 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001445 const mbedtls_md_info_t *md_info;
1446 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1449 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001450
1451 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001454 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001455 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001456 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001457
1458 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001460
Simon Butcher02037452016-03-01 21:19:12 +00001461 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001462 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001463 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001464
1465 memset( output, 0, olen );
1466
1467 *p++ = 0;
1468
Simon Butcher02037452016-03-01 21:19:12 +00001469 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001470 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001472
1473 p += hlen;
1474
Simon Butcher02037452016-03-01 21:19:12 +00001475 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001477 p += hlen;
1478 p += olen - 2 * hlen - 2 - ilen;
1479 *p++ = 1;
1480 memcpy( p, input, ilen );
1481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001483 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1484 {
1485 mbedtls_md_free( &md_ctx );
1486 return( ret );
1487 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001488
Simon Butcher02037452016-03-01 21:19:12 +00001489 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001490 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1491 &md_ctx );
1492
Simon Butcher02037452016-03-01 21:19:12 +00001493 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001494 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1495 &md_ctx );
1496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001499 return( ( mode == MBEDTLS_RSA_PUBLIC )
1500 ? mbedtls_rsa_public( ctx, output, output )
1501 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001502}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001503#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001506/*
1507 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1508 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001509int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001510 int (*f_rng)(void *, unsigned char *, size_t),
1511 void *p_rng,
1512 int mode, size_t ilen,
1513 const unsigned char *input,
1514 unsigned char *output )
1515{
1516 size_t nb_pad, olen;
1517 int ret;
1518 unsigned char *p = output;
1519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1521 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001522
Janos Follath1ed9f992016-03-18 11:45:44 +00001523 // We don't check p_rng because it won't be dereferenced here
1524 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001526
1527 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001528
Simon Butcher02037452016-03-01 21:19:12 +00001529 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001530 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001532
1533 nb_pad = olen - 3 - ilen;
1534
1535 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001537 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001539
1540 while( nb_pad-- > 0 )
1541 {
1542 int rng_dl = 100;
1543
1544 do {
1545 ret = f_rng( p_rng, p, 1 );
1546 } while( *p == 0 && --rng_dl && ret == 0 );
1547
Simon Butcher02037452016-03-01 21:19:12 +00001548 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001549 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001551
1552 p++;
1553 }
1554 }
1555 else
1556 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001558
1559 while( nb_pad-- > 0 )
1560 *p++ = 0xFF;
1561 }
1562
1563 *p++ = 0;
1564 memcpy( p, input, ilen );
1565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 return( ( mode == MBEDTLS_RSA_PUBLIC )
1567 ? mbedtls_rsa_public( ctx, output, output )
1568 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001569}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001571
Paul Bakker5121ce52009-01-03 21:22:43 +00001572/*
1573 * Add the message padding, then do an RSA operation
1574 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001576 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001577 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001578 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001579 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001580 unsigned char *output )
1581{
Paul Bakker5121ce52009-01-03 21:22:43 +00001582 switch( ctx->padding )
1583 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001584#if defined(MBEDTLS_PKCS1_V15)
1585 case MBEDTLS_RSA_PKCS_V15:
1586 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001587 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001588#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001589
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001590#if defined(MBEDTLS_PKCS1_V21)
1591 case MBEDTLS_RSA_PKCS_V21:
1592 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001593 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001594#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001595
1596 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001597 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001598 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001599}
1600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001601#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001602/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001603 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001604 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001605int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001606 int (*f_rng)(void *, unsigned char *, size_t),
1607 void *p_rng,
1608 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001609 const unsigned char *label, size_t label_len,
1610 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001611 const unsigned char *input,
1612 unsigned char *output,
1613 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001614{
Paul Bakker23986e52011-04-24 08:57:21 +00001615 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001616 size_t ilen, i, pad_len;
1617 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001618 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1619 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001620 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001621 const mbedtls_md_info_t *md_info;
1622 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001623
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001624 /*
1625 * Parameters sanity checks
1626 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001627 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1628 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001629
1630 ilen = ctx->len;
1631
Paul Bakker27fdf462011-06-09 13:55:13 +00001632 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001633 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001634
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001635 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001636 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001637 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001638
Janos Follathc17cda12016-02-11 11:08:18 +00001639 hlen = mbedtls_md_get_size( md_info );
1640
1641 // checking for integer underflow
1642 if( 2 * hlen + 2 > ilen )
1643 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1644
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001645 /*
1646 * RSA operation
1647 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001648 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1649 ? mbedtls_rsa_public( ctx, input, buf )
1650 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001651
1652 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001653 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001654
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001655 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001656 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001657 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001658 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001659 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1660 {
1661 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001662 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001663 }
1664
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001665
1666 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001667 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001668
1669 /* seed: Apply seedMask to maskedSeed */
1670 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1671 &md_ctx );
1672
1673 /* DB: Apply dbMask to maskedDB */
1674 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1675 &md_ctx );
1676
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001677 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001678
1679 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001680 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001681 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001682 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001683 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001684
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001685 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001686
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001687 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001688
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001689 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001690 for( i = 0; i < hlen; i++ )
1691 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001692
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001693 /* Get zero-padding len, but always read till end of buffer
1694 * (minus one, for the 01 byte) */
1695 pad_len = 0;
1696 pad_done = 0;
1697 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1698 {
1699 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001700 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001701 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001702
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001703 p += pad_len;
1704 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001705
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001706 /*
1707 * The only information "leaked" is whether the padding was correct or not
1708 * (eg, no data is copied if it was not correct). This meets the
1709 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1710 * the different error conditions.
1711 */
1712 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001713 {
1714 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1715 goto cleanup;
1716 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001717
Paul Bakker66d5d072014-06-17 16:39:18 +02001718 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001719 {
1720 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1721 goto cleanup;
1722 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001723
1724 *olen = ilen - (p - buf);
1725 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001726 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001727
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001728cleanup:
1729 mbedtls_zeroize( buf, sizeof( buf ) );
1730 mbedtls_zeroize( lhash, sizeof( lhash ) );
1731
1732 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001733}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001734#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001737/*
1738 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1739 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001740int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001741 int (*f_rng)(void *, unsigned char *, size_t),
1742 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001743 int mode, size_t *olen,
1744 const unsigned char *input,
1745 unsigned char *output,
1746 size_t output_max_len)
1747{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001748 int ret;
1749 size_t ilen, pad_count = 0, i;
1750 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001751 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001752
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1754 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001755
1756 ilen = ctx->len;
1757
1758 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001759 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001761 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1762 ? mbedtls_rsa_public( ctx, input, buf )
1763 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001764
1765 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001766 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001767
1768 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001769 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001770
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001771 /*
1772 * Check and get padding len in "constant-time"
1773 */
1774 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001775
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001776 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001777 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001778 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001781 /* Get padding len, but always read till end of buffer
1782 * (minus one, for the 00 byte) */
1783 for( i = 0; i < ilen - 3; i++ )
1784 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001785 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1786 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001787 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001788
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001789 p += pad_count;
1790 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001791 }
1792 else
1793 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001794 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001795
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001796 /* Get padding len, but always read till end of buffer
1797 * (minus one, for the 00 byte) */
1798 for( i = 0; i < ilen - 3; i++ )
1799 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001800 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001801 pad_count += ( pad_done == 0 );
1802 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001803
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001804 p += pad_count;
1805 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001806 }
1807
Janos Follathc69fa502016-02-12 13:30:09 +00001808 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001809
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001810 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001811 {
1812 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1813 goto cleanup;
1814 }
Paul Bakker8804f692013-02-28 18:06:26 +01001815
Paul Bakker66d5d072014-06-17 16:39:18 +02001816 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001817 {
1818 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1819 goto cleanup;
1820 }
Paul Bakker060c5682009-01-12 21:48:39 +00001821
Paul Bakker27fdf462011-06-09 13:55:13 +00001822 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001824 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001825
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001826cleanup:
1827 mbedtls_zeroize( buf, sizeof( buf ) );
1828
1829 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001830}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001832
1833/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001834 * Do an RSA operation, then remove the message padding
1835 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001837 int (*f_rng)(void *, unsigned char *, size_t),
1838 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001839 int mode, size_t *olen,
1840 const unsigned char *input,
1841 unsigned char *output,
1842 size_t output_max_len)
1843{
1844 switch( ctx->padding )
1845 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001846#if defined(MBEDTLS_PKCS1_V15)
1847 case MBEDTLS_RSA_PKCS_V15:
1848 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001849 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001850#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001852#if defined(MBEDTLS_PKCS1_V21)
1853 case MBEDTLS_RSA_PKCS_V21:
1854 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001855 olen, input, output,
1856 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001857#endif
1858
1859 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001861 }
1862}
1863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001865/*
1866 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1867 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001869 int (*f_rng)(void *, unsigned char *, size_t),
1870 void *p_rng,
1871 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001872 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001873 unsigned int hashlen,
1874 const unsigned char *hash,
1875 unsigned char *sig )
1876{
1877 size_t olen;
1878 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001879 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001880 unsigned int slen, hlen, offset = 0;
1881 int ret;
1882 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001883 const mbedtls_md_info_t *md_info;
1884 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1887 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001888
1889 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001890 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001891
1892 olen = ctx->len;
1893
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001894 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001895 {
Simon Butcher02037452016-03-01 21:19:12 +00001896 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001897 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001898 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001899 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001902 }
1903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001904 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001905 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001909 slen = hlen;
1910
1911 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001912 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001913
1914 memset( sig, 0, olen );
1915
Simon Butcher02037452016-03-01 21:19:12 +00001916 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001917 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001918 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001919
Simon Butcher02037452016-03-01 21:19:12 +00001920 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001921 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001922 p += olen - hlen * 2 - 2;
1923 *p++ = 0x01;
1924 memcpy( p, salt, slen );
1925 p += slen;
1926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001927 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001928 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1929 {
1930 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001931 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001932 return( ret );
1933 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001934
Simon Butcher02037452016-03-01 21:19:12 +00001935 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001936 mbedtls_md_starts( &md_ctx );
1937 mbedtls_md_update( &md_ctx, p, 8 );
1938 mbedtls_md_update( &md_ctx, hash, hashlen );
1939 mbedtls_md_update( &md_ctx, salt, slen );
1940 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001941 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001942
Simon Butcher02037452016-03-01 21:19:12 +00001943 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001944 if( msb % 8 == 0 )
1945 offset = 1;
1946
Simon Butcher02037452016-03-01 21:19:12 +00001947 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001948 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001950 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001951
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001952 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001953 sig[0] &= 0xFF >> ( olen * 8 - msb );
1954
1955 p += hlen;
1956 *p++ = 0xBC;
1957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001958 return( ( mode == MBEDTLS_RSA_PUBLIC )
1959 ? mbedtls_rsa_public( ctx, sig, sig )
1960 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001961}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001962#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001964#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001965/*
1966 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1967 */
1968/*
1969 * Do an RSA operation to sign the message digest
1970 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001971int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001972 int (*f_rng)(void *, unsigned char *, size_t),
1973 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001974 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001975 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001976 unsigned int hashlen,
1977 const unsigned char *hash,
1978 unsigned char *sig )
1979{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001980 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001981 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001982 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001983 unsigned char *sig_try = NULL, *verif = NULL;
1984 size_t i;
1985 unsigned char diff;
1986 volatile unsigned char diff_no_optimize;
1987 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001989 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1990 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001991
1992 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001993 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001996 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001997 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001998 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
2002 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002003
Paul Bakkerc70b9822013-04-07 22:00:46 +02002004 nb_pad -= 10 + oid_size;
2005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002006 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002007 }
2008
Paul Bakkerc70b9822013-04-07 22:00:46 +02002009 nb_pad -= hashlen;
2010
Paul Bakkerb3869132013-02-28 17:21:01 +01002011 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002013
2014 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01002016 memset( p, 0xFF, nb_pad );
2017 p += nb_pad;
2018 *p++ = 0;
2019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002020 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002021 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02002022 memcpy( p, hash, hashlen );
2023 }
2024 else
2025 {
2026 /*
2027 * DigestInfo ::= SEQUENCE {
2028 * digestAlgorithm DigestAlgorithmIdentifier,
2029 * digest Digest }
2030 *
2031 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
2032 *
2033 * Digest ::= OCTET STRING
2034 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002035 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002036 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002037 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002038 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002040 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002041 memcpy( p, oid, oid_size );
2042 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002043 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002044 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002045 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002046 *p++ = hashlen;
2047 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01002048 }
2049
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002050 if( mode == MBEDTLS_RSA_PUBLIC )
2051 return( mbedtls_rsa_public( ctx, sig, sig ) );
2052
2053 /*
2054 * In order to prevent Lenstra's attack, make the signature in a
2055 * temporary buffer and check it before returning it.
2056 */
2057 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00002058 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002059 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2060
Simon Butcher1285ab52016-01-01 21:42:47 +00002061 verif = mbedtls_calloc( 1, ctx->len );
2062 if( verif == NULL )
2063 {
2064 mbedtls_free( sig_try );
2065 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2066 }
2067
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002068 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2069 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2070
2071 /* Compare in constant time just in case */
2072 for( diff = 0, i = 0; i < ctx->len; i++ )
2073 diff |= verif[i] ^ sig[i];
2074 diff_no_optimize = diff;
2075
2076 if( diff_no_optimize != 0 )
2077 {
2078 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2079 goto cleanup;
2080 }
2081
2082 memcpy( sig, sig_try, ctx->len );
2083
2084cleanup:
2085 mbedtls_free( sig_try );
2086 mbedtls_free( verif );
2087
2088 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002089}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002090#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002091
2092/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002093 * Do an RSA operation to sign the message digest
2094 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002096 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002097 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00002098 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002100 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002101 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 unsigned char *sig )
2103{
Paul Bakker5121ce52009-01-03 21:22:43 +00002104 switch( ctx->padding )
2105 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002106#if defined(MBEDTLS_PKCS1_V15)
2107 case MBEDTLS_RSA_PKCS_V15:
2108 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002109 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002110#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002112#if defined(MBEDTLS_PKCS1_V21)
2113 case MBEDTLS_RSA_PKCS_V21:
2114 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002115 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002116#endif
2117
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002119 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002121}
2122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002124/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002125 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002127int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002128 int (*f_rng)(void *, unsigned char *, size_t),
2129 void *p_rng,
2130 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002132 unsigned int hashlen,
2133 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002134 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002135 int expected_salt_len,
2136 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002137{
Paul Bakker23986e52011-04-24 08:57:21 +00002138 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002139 size_t siglen;
2140 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002141 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00002142 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00002143 unsigned int hlen;
2144 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002145 const mbedtls_md_info_t *md_info;
2146 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002147 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002149 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2150 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002151
Paul Bakker5121ce52009-01-03 21:22:43 +00002152 siglen = ctx->len;
2153
Paul Bakker27fdf462011-06-09 13:55:13 +00002154 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2158 ? mbedtls_rsa_public( ctx, sig, buf )
2159 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002160
2161 if( ret != 0 )
2162 return( ret );
2163
2164 p = buf;
2165
Paul Bakkerb3869132013-02-28 17:21:01 +01002166 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002167 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002170 {
Simon Butcher02037452016-03-01 21:19:12 +00002171 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002172 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002173 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002174 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002176 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002177 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01002180 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002183 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002184 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00002185
Paul Bakkerb3869132013-02-28 17:21:01 +01002186 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00002187
Simon Butcher02037452016-03-01 21:19:12 +00002188 /*
2189 * Note: EMSA-PSS verification is over the length of N - 1 bits
2190 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002191 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002192
Simon Butcher02037452016-03-01 21:19:12 +00002193 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002194 if( msb % 8 == 0 )
2195 {
2196 p++;
2197 siglen -= 1;
2198 }
2199 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002200 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002201
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002202 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07002203 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2204 {
2205 mbedtls_md_free( &md_ctx );
2206 return( ret );
2207 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002208
Paul Bakkerb3869132013-02-28 17:21:01 +01002209 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01002210
Paul Bakkerb3869132013-02-28 17:21:01 +01002211 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002212
Paul Bakker4de44aa2013-12-31 11:43:01 +01002213 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002214 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002215
Paul Bakkerb3869132013-02-28 17:21:01 +01002216 if( p == buf + siglen ||
2217 *p++ != 0x01 )
2218 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002219 mbedtls_md_free( &md_ctx );
2220 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002221 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002222
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002223 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01002224 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002225
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002226 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002227 slen != (size_t) expected_salt_len )
2228 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002229 mbedtls_md_free( &md_ctx );
2230 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002231 }
2232
Simon Butcher02037452016-03-01 21:19:12 +00002233 /*
2234 * Generate H = Hash( M' )
2235 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002236 mbedtls_md_starts( &md_ctx );
2237 mbedtls_md_update( &md_ctx, zeros, 8 );
2238 mbedtls_md_update( &md_ctx, hash, hashlen );
2239 mbedtls_md_update( &md_ctx, p, slen );
2240 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00002241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002243
Paul Bakkerb3869132013-02-28 17:21:01 +01002244 if( memcmp( p + slen, result, hlen ) == 0 )
2245 return( 0 );
2246 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002247 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01002248}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002249
2250/*
2251 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2252 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002253int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002254 int (*f_rng)(void *, unsigned char *, size_t),
2255 void *p_rng,
2256 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002257 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002258 unsigned int hashlen,
2259 const unsigned char *hash,
2260 const unsigned char *sig )
2261{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002262 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2263 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002264 : md_alg;
2265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002266 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002267 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002268 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002269 sig ) );
2270
2271}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002273
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002274#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002275/*
2276 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2277 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002278int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002279 int (*f_rng)(void *, unsigned char *, size_t),
2280 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002281 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002283 unsigned int hashlen,
2284 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002285 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002286{
2287 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002288 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002289 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002290 mbedtls_md_type_t msg_md_alg;
2291 const mbedtls_md_info_t *md_info;
2292 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002293 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2296 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002297
2298 siglen = ctx->len;
2299
2300 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002301 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2304 ? mbedtls_rsa_public( ctx, sig, buf )
2305 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01002306
2307 if( ret != 0 )
2308 return( ret );
2309
2310 p = buf;
2311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002312 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
2313 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002314
2315 while( *p != 0 )
2316 {
2317 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002319 p++;
2320 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02002321 p++; /* skip 00 byte */
2322
2323 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
2324 if( p - buf < 11 )
2325 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002326
2327 len = siglen - ( p - buf );
2328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002329 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002330 {
2331 if( memcmp( p, hash, hashlen ) == 0 )
2332 return( 0 );
2333 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002334 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002335 }
2336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002337 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002338 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002339 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2340 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002341
2342 end = p + len;
2343
Simon Butcher02037452016-03-01 21:19:12 +00002344 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02002345 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
2346 * Insist on 2-byte length tags, to protect against variants of
2347 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00002348 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002349 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002350 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2351 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2352 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002353 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002354 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002355
Gilles Peskinee7e76502017-05-04 12:48:39 +02002356 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002357 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2358 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2359 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002360 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002361 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002362
Gilles Peskinee7e76502017-05-04 12:48:39 +02002363 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
2365 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002366 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002367 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002368
2369 oid.p = p;
2370 p += oid.len;
2371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002372 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
2373 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002374
2375 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002376 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002377
2378 /*
2379 * assume the algorithm parameters must be NULL
2380 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02002381 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002382 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
2383 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002384 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002385 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002386
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002387 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002388 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
2389 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002390 if( p != p0 + 2 || asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002391 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002392
2393 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002394 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002395
2396 p += hashlen;
2397
2398 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002399 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002400
2401 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002402}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002403#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002404
2405/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002406 * Do an RSA operation and check the message digest
2407 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002408int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002409 int (*f_rng)(void *, unsigned char *, size_t),
2410 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002411 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002412 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002413 unsigned int hashlen,
2414 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002415 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002416{
2417 switch( ctx->padding )
2418 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419#if defined(MBEDTLS_PKCS1_V15)
2420 case MBEDTLS_RSA_PKCS_V15:
2421 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002422 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002423#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002425#if defined(MBEDTLS_PKCS1_V21)
2426 case MBEDTLS_RSA_PKCS_V21:
2427 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002428 hashlen, hash, sig );
2429#endif
2430
2431 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002432 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002433 }
2434}
2435
2436/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002437 * Copy the components of an RSA key
2438 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002439int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002440{
2441 int ret;
2442
2443 dst->ver = src->ver;
2444 dst->len = src->len;
2445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002446 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2447 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2450 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2451 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002452
2453#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002454 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2455 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2456 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002457 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2458 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002459#endif
2460
2461 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002463 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2464 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002465
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002466 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002467 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002468
2469cleanup:
2470 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002471 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002472
2473 return( ret );
2474}
2475
2476/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002477 * Free the components of an RSA key
2478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002479void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002480{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002481 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002482 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2483 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002484 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002485
Hanno Becker33c30a02017-08-23 07:00:22 +01002486#if !defined(MBEDTLS_RSA_NO_CRT)
2487 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2488 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2489 mbedtls_mpi_free( &ctx->DP );
2490#endif /* MBEDTLS_RSA_NO_CRT */
2491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002492#if defined(MBEDTLS_THREADING_C)
2493 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002494#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002495}
2496
Hanno Beckerab377312017-08-23 16:24:51 +01002497#endif /* !MBEDTLS_RSA_ALT */
2498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002499#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002500
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002501#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002502
2503/*
2504 * Example RSA-1024 keypair, for test purposes
2505 */
2506#define KEY_LEN 128
2507
2508#define RSA_N "9292758453063D803DD603D5E777D788" \
2509 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2510 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2511 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2512 "93A89813FBF3C4F8066D2D800F7C38A8" \
2513 "1AE31942917403FF4946B0A83D3D3E05" \
2514 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2515 "5E94BB77B07507233A0BC7BAC8F90F79"
2516
2517#define RSA_E "10001"
2518
2519#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2520 "66CA472BC44D253102F8B4A9D3BFA750" \
2521 "91386C0077937FE33FA3252D28855837" \
2522 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2523 "DF79C5CE07EE72C7F123142198164234" \
2524 "CABB724CF78B8173B9F880FC86322407" \
2525 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2526 "071513A1E85B5DFA031F21ECAE91A34D"
2527
2528#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2529 "2C01CAD19EA484A87EA4377637E75500" \
2530 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2531 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2532
2533#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2534 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2535 "910E4168387E3C30AA1E00C339A79508" \
2536 "8452DD96A9A5EA5D9DCA68DA636032AF"
2537
Paul Bakker5121ce52009-01-03 21:22:43 +00002538#define PT_LEN 24
2539#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2540 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002542#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002543static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002544{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002545#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002546 size_t i;
2547
Paul Bakker545570e2010-07-18 09:00:25 +00002548 if( rng_state != NULL )
2549 rng_state = NULL;
2550
Paul Bakkera3d195c2011-11-27 21:07:34 +00002551 for( i = 0; i < len; ++i )
2552 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002553#else
2554 if( rng_state != NULL )
2555 rng_state = NULL;
2556
2557 arc4random_buf( output, len );
2558#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002559
Paul Bakkera3d195c2011-11-27 21:07:34 +00002560 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002561}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002562#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002563
Paul Bakker5121ce52009-01-03 21:22:43 +00002564/*
2565 * Checkup routine
2566 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002567int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002568{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002569 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002570#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002571 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002572 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002573 unsigned char rsa_plaintext[PT_LEN];
2574 unsigned char rsa_decrypted[PT_LEN];
2575 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002576#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002577 unsigned char sha1sum[20];
2578#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002579
Hanno Becker3a701162017-08-22 13:52:43 +01002580 mbedtls_mpi K;
2581
2582 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002583 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002584
Hanno Becker3a701162017-08-22 13:52:43 +01002585 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2586 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2587 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2588 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2589 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2590 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2591 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2592 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2593 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2594 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2595
Hanno Becker7f25f852017-10-10 16:56:22 +01002596 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002597
2598 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002599 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2602 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002603 {
2604 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002605 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002606
2607 return( 1 );
2608 }
2609
2610 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002611 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002612
2613 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2614
Hanno Becker98838b02017-10-02 13:16:10 +01002615 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2616 PT_LEN, rsa_plaintext,
2617 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002618 {
2619 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002620 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002621
2622 return( 1 );
2623 }
2624
2625 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002626 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002627
Hanno Becker98838b02017-10-02 13:16:10 +01002628 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2629 &len, rsa_ciphertext, rsa_decrypted,
2630 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002631 {
2632 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002633 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002634
2635 return( 1 );
2636 }
2637
2638 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2639 {
2640 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002641 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002642
2643 return( 1 );
2644 }
2645
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002646 if( verbose != 0 )
2647 mbedtls_printf( "passed\n" );
2648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002649#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002650 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002651 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002653 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002654
Hanno Becker98838b02017-10-02 13:16:10 +01002655 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2656 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2657 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002658 {
2659 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002660 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002661
2662 return( 1 );
2663 }
2664
2665 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002666 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002667
Hanno Becker98838b02017-10-02 13:16:10 +01002668 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2669 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2670 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002671 {
2672 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002673 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002674
2675 return( 1 );
2676 }
2677
2678 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002679 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002680#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002681
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002682 if( verbose != 0 )
2683 mbedtls_printf( "\n" );
2684
Paul Bakker3d8fb632014-04-17 12:42:41 +02002685cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002686 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002687 mbedtls_rsa_free( &rsa );
2688#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002689 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002690#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002691 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002692}
2693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002694#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002695
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002696#endif /* MBEDTLS_RSA_C */