blob: b932d977a01dfaeeb9082ae5a2e66142d30100ce [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 Beckere2e8b8d2017-08-23 14:06:45 +0100142 uint16_t order; /* Order of 2 in DE - 1 */
143
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
604int mbedtls_rsa_complete( mbedtls_rsa_context *ctx,
605 int (*f_rng)(void *, unsigned char *, size_t),
606 void *p_rng )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100607{
608 int ret = 0;
609
Hanno Becker617c1ae2017-08-23 14:11:24 +0100610 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
611 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
612 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
613 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
614 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100615
Hanno Becker617c1ae2017-08-23 14:11:24 +0100616 /*
617 * Check whether provided parameters are enough
618 * to deduce all others. The following incomplete
619 * parameter sets for private keys are supported:
620 *
621 * (1) P, Q missing.
622 * (2) D and potentially N missing.
623 *
624 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100625
Hanno Becker2cca6f32017-09-29 11:46:40 +0100626 const int n_missing = have_P && have_Q && have_D && have_E;
627 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
628 const int d_missing = have_P && have_Q && !have_D && have_E;
629 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
630
631 /* These three alternatives are mutually exclusive */
632 const int is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100633
Hanno Becker617c1ae2017-08-23 14:11:24 +0100634 if( !is_priv && !is_pub )
635 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
636
637 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100638 * Step 1: Deduce N if P, Q are provided.
639 */
640
641 if( !have_N && have_P && have_Q )
642 {
643 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
644 &ctx->Q ) ) != 0 )
645 {
646 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
647 }
648
649 ctx->len = mbedtls_mpi_size( &ctx->N );
650 }
651
652 /*
653 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100654 */
655
656 if( pq_missing )
657 {
658 /* This includes sanity checking of core parameters,
659 * so no further checks necessary. */
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100660 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->D, &ctx->E,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100661 f_rng, p_rng,
662 &ctx->P, &ctx->Q );
663 if( ret != 0 )
664 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
665
666 }
667 else if( d_missing )
668 {
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100669#if defined(MBEDTLS_GENPRIME)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100670 /* If a PRNG is provided, check if P, Q are prime. */
671 if( f_rng != NULL &&
672 ( ( ret = mbedtls_mpi_is_prime( &ctx->P, f_rng, p_rng ) ) != 0 ||
673 ( ret = mbedtls_mpi_is_prime( &ctx->Q, f_rng, p_rng ) ) != 0 ) )
674 {
675 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
676 }
Hanno Beckerfb81c0e2017-08-24 06:55:11 +0100677#endif /* MBEDTLS_GENPRIME */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100678
Hanno Becker617c1ae2017-08-23 14:11:24 +0100679 /* Deduce private exponent. This includes double-checking of the result,
680 * so together with the primality test above all core parameters are
681 * guaranteed to be sane if this call succeeds. */
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100682 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
683 &ctx->Q,
684 &ctx->E,
685 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100686 {
687 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
688 }
689 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100690
691 /* In the remaining case of a public key, there's nothing to check for. */
692
693 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100694 * Step 3: Deduce all additional parameters specific
Hanno Becker617c1ae2017-08-23 14:11:24 +0100695 * to our current RSA implementaiton.
696 */
697
Hanno Becker23344b52017-08-23 07:43:27 +0100698#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100699 if( is_priv )
700 {
701 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
702 &ctx->DP, &ctx->DQ, &ctx->QP );
703 if( ret != 0 )
704 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
705 }
Hanno Becker23344b52017-08-23 07:43:27 +0100706#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100707
708 /*
Hanno Becker98838b02017-10-02 13:16:10 +0100709 * Step 3: Basic sanity check
Hanno Becker617c1ae2017-08-23 14:11:24 +0100710 */
711
712 if( is_priv )
713 {
714 if( ( ret = mbedtls_rsa_check_privkey( ctx ) ) != 0 )
715 return( ret );
716 }
717 else
718 {
719 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
720 return( ret );
721 }
722
723 return( 0 );
724}
725
Hanno Becker617c1ae2017-08-23 14:11:24 +0100726int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
727 unsigned char *N, size_t N_len,
728 unsigned char *P, size_t P_len,
729 unsigned char *Q, size_t Q_len,
730 unsigned char *D, size_t D_len,
731 unsigned char *E, size_t E_len )
732{
733 int ret = 0;
734
735 /* Check if key is private or public */
736 const int is_priv =
737 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
738 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
739 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
740 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
741 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
742
743 if( !is_priv )
744 {
745 /* If we're trying to export private parameters for a public key,
746 * something must be wrong. */
747 if( P != NULL || Q != NULL || D != NULL )
748 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
749
750 }
751
752 if( N != NULL )
753 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
754
755 if( P != NULL )
756 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
757
758 if( Q != NULL )
759 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
760
761 if( D != NULL )
762 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
763
764 if( E != NULL )
765 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100766
767cleanup:
768
769 return( ret );
770}
771
Hanno Becker617c1ae2017-08-23 14:11:24 +0100772int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
773 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
774 mbedtls_mpi *D, mbedtls_mpi *E )
775{
776 int ret;
777
778 /* Check if key is private or public */
779 int is_priv =
780 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
781 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
782 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
783 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
784 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
785
786 if( !is_priv )
787 {
788 /* If we're trying to export private parameters for a public key,
789 * something must be wrong. */
790 if( P != NULL || Q != NULL || D != NULL )
791 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
792
793 }
794
795 /* Export all requested core parameters. */
796
797 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
798 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
799 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
800 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
801 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
802 {
803 return( ret );
804 }
805
806 return( 0 );
807}
808
809/*
810 * Export CRT parameters
811 * This must also be implemented if CRT is not used, for being able to
812 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
813 * can be used in this case.
814 */
815int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
816 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
817{
818 int ret;
819
820 /* Check if key is private or public */
821 int is_priv =
822 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
823 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
824 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
825 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
826 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
827
828 if( !is_priv )
829 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
830
Hanno Beckerdc95c892017-08-23 06:57:02 +0100831#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100832 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100833 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
834 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
835 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
836 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100837 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100838 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100839#else
840 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
841 DP, DQ, QP ) ) != 0 )
842 {
843 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
844 }
845#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100846
847 return( 0 );
848}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100849
850/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000851 * Initialize an RSA context
852 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000855 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000856{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#if defined(MBEDTLS_THREADING_C)
862 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200863#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000864}
865
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100866/*
867 * Set padding for an existing RSA context
868 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100870{
871 ctx->padding = padding;
872 ctx->hash_id = hash_id;
873}
874
Hanno Becker617c1ae2017-08-23 14:11:24 +0100875/*
876 * Get length in bytes of RSA modulus
877 */
878
879size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
880{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100881 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100882}
883
884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
887/*
888 * Generate an RSA keypair
889 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000891 int (*f_rng)(void *, unsigned char *, size_t),
892 void *p_rng,
893 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000894{
895 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100896 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Paul Bakker21eb2802010-08-16 11:10:02 +0000898 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Janos Follathef441782016-09-21 13:18:12 +0100901 if( nbits % 2 )
902 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
903
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100904 mbedtls_mpi_init( &H );
905 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000906
907 /*
908 * find primes P and Q with Q < P so that:
909 * GCD( E, (P-1)*(Q-1) ) == 1
910 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000912
913 do
914 {
Janos Follath10c575b2016-02-23 14:42:48 +0000915 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100916 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Janos Follathef441782016-09-21 13:18:12 +0100918 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100919 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 continue;
923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200925 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000926 continue;
927
Janos Follathef441782016-09-21 13:18:12 +0100928 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100929 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100930
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100931 /* Temporarily replace P,Q by P-1, Q-1 */
932 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
933 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
934 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200935 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100939 /* Restore P,Q */
940 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
941 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
942
943 ctx->len = mbedtls_mpi_size( &ctx->N );
944
Paul Bakker5121ce52009-01-03 21:22:43 +0000945 /*
946 * D = E^-1 mod ((P-1)*(Q-1))
947 * DP = D mod (P - 1)
948 * DQ = D mod (Q - 1)
949 * QP = Q^-1 mod P
950 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100952 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
953
954#if !defined(MBEDTLS_RSA_NO_CRT)
955 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
956 &ctx->DP, &ctx->DQ, &ctx->QP ) );
957#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Hanno Becker83aad1f2017-08-23 06:45:10 +0100959 /* Double-check */
960 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
961
Paul Bakker5121ce52009-01-03 21:22:43 +0000962cleanup:
963
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100964 mbedtls_mpi_free( &H );
965 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000966
967 if( ret != 0 )
968 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_rsa_free( ctx );
970 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 }
972
Paul Bakker48377d92013-08-30 12:06:24 +0200973 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000974}
975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000977
978/*
979 * Check a public RSA key
980 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000982{
Hanno Becker98838b02017-10-02 13:16:10 +0100983 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
984 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
985 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100987 }
Paul Bakker37940d92009-07-10 22:38:58 +0000988
Hanno Beckerba1ba112017-09-29 11:48:23 +0100989 if( ctx->len != mbedtls_mpi_size( &ctx->N ) )
990 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
991
Hanno Becker98838b02017-10-02 13:16:10 +0100992 if( mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ||
993 mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 )
994 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100996 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200998 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
999 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Hanno Becker98838b02017-10-02 13:16:10 +01001000 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +01001002 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001003
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001004 if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +01001006 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +01001008 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
1010 return( 0 );
1011}
1012
1013/*
1014 * Check a private RSA key
1015 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001017{
Hanno Becker98838b02017-10-02 13:16:10 +01001018 if( mbedtls_rsa_check_pubkey( ctx ) != 0 )
1019 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1020
1021 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +01001022 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 {
Hanno Beckerb269a852017-08-25 08:03:21 +01001024 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025 }
Hanno Beckerb269a852017-08-25 08:03:21 +01001026#if !defined(MBEDTLS_RSA_NO_CRT)
1027 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
1028 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
1029 {
1030 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1031 }
1032#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +00001033
1034 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001035}
1036
1037/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001038 * Check if contexts holding a public and private key match
1039 */
Hanno Becker98838b02017-10-02 13:16:10 +01001040int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
1041 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001042{
Hanno Becker98838b02017-10-02 13:16:10 +01001043 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001045 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001047 }
1048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
1050 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001051 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001053 }
1054
1055 return( 0 );
1056}
1057
1058/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001059 * Do an RSA public key operation
1060 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001062 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 unsigned char *output )
1064{
Paul Bakker23986e52011-04-24 08:57:21 +00001065 int ret;
1066 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001070
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001071#if defined(MBEDTLS_THREADING_C)
1072 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1073 return( ret );
1074#endif
1075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001079 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001080 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1081 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 }
1083
1084 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
1086 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001087
1088cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001090 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1091 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +01001092#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001093
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001095
1096 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001098
1099 return( 0 );
1100}
1101
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001102/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001103 * Generate or update blinding values, see section 10 of:
1104 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +02001105 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001106 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001107 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001108static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001109 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1110{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001111 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001112
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001113 if( ctx->Vf.p != NULL )
1114 {
1115 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
1117 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
1118 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
1119 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001120
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001121 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001122 }
1123
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001124 /* Unblinding value: Vf = random number, invertible mod N */
1125 do {
1126 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001127 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
1130 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1131 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001132
1133 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1135 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 +02001136
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001137
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001138cleanup:
1139 return( ret );
1140}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001141
Paul Bakker5121ce52009-01-03 21:22:43 +00001142/*
Janos Follathe81102e2017-03-22 13:38:28 +00001143 * Exponent blinding supposed to prevent side-channel attacks using multiple
1144 * traces of measurements to recover the RSA key. The more collisions are there,
1145 * the more bits of the key can be recovered. See [3].
1146 *
1147 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1148 * observations on avarage.
1149 *
1150 * For example with 28 byte blinding to achieve 2 collisions the adversary has
1151 * to make 2^112 observations on avarage.
1152 *
1153 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1154 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1155 * Thus in this sense with 28 byte blinding the security is not reduced by
1156 * side-channel attacks like the one in [3])
1157 *
1158 * This countermeasure does not help if the key recovery is possible with a
1159 * single trace.
1160 */
1161#define RSA_EXPONENT_BLINDING 28
1162
1163/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001164 * Do an RSA private key operation
1165 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001167 int (*f_rng)(void *, unsigned char *, size_t),
1168 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001169 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001170 unsigned char *output )
1171{
Paul Bakker23986e52011-04-24 08:57:21 +00001172 int ret;
1173 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +00001175 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +00001176#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001177 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001178 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +00001179#else
1180 mbedtls_mpi DP_blind, DQ_blind;
1181 mbedtls_mpi *DP = &ctx->DP;
1182 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +00001183#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001184
Hanno Becker45037ce2017-08-25 11:03:34 +01001185 /* Sanity-check that all relevant fields are at least set,
1186 * but don't perform a full keycheck. */
1187 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
1188 mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ||
1189 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) == 0 ||
1190 mbedtls_mpi_cmp_int( &ctx->D, 0 ) == 0 ||
1191 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
1192 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001193 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Becker45037ce2017-08-25 11:03:34 +01001194 }
1195#if !defined(MBEDTLS_RSA_NO_CRT)
1196 if( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) == 0 ||
1197 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) == 0 ||
1198 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) == 0 )
1199 {
1200 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1201 }
1202#endif /* MBEDTLS_RSA_NO_CRT */
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001205 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
1206
Janos Follathf9203b42017-03-22 15:13:15 +00001207 if( f_rng != NULL )
1208 {
Janos Follathe81102e2017-03-22 13:38:28 +00001209#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001210 mbedtls_mpi_init( &D_blind );
1211#else
1212 mbedtls_mpi_init( &DP_blind );
1213 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001214#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001215 }
Janos Follathe81102e2017-03-22 13:38:28 +00001216
Paul Bakker5121ce52009-01-03 21:22:43 +00001217
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001218#if defined(MBEDTLS_THREADING_C)
1219 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1220 return( ret );
1221#endif
1222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001223 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
1224 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001226 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1227 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 }
1229
Paul Bakkerf451bac2013-08-30 15:37:02 +02001230 if( f_rng != NULL )
1231 {
1232 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001233 * Blinding
1234 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001235 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001236 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
1237 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +00001239
Janos Follathe81102e2017-03-22 13:38:28 +00001240 /*
1241 * Exponent blinding
1242 */
1243 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1244 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1245
Janos Follathf9203b42017-03-22 15:13:15 +00001246#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001247 /*
1248 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1249 */
1250 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1251 f_rng, p_rng ) );
1252 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1253 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1254 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1255
1256 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001257#else
1258 /*
1259 * DP_blind = ( P - 1 ) * R + DP
1260 */
1261 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1262 f_rng, p_rng ) );
1263 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1264 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1265 &ctx->DP ) );
1266
1267 DP = &DP_blind;
1268
1269 /*
1270 * DQ_blind = ( Q - 1 ) * R + DQ
1271 */
1272 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1273 f_rng, p_rng ) );
1274 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1275 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1276 &ctx->DQ ) );
1277
1278 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001279#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +02001280 }
Paul Bakkeraab30c12013-08-30 11:00:25 +02001281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001283 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001284#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001285 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001286 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001287 *
1288 * T1 = input ^ dP mod P
1289 * T2 = input ^ dQ mod Q
1290 */
Janos Follathf9203b42017-03-22 15:13:15 +00001291 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
1292 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001293
1294 /*
1295 * T = (T1 - T2) * (Q^-1 mod P) mod P
1296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001297 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
1298 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
1299 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
1301 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +02001302 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
1305 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
1306#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001307
Paul Bakkerf451bac2013-08-30 15:37:02 +02001308 if( f_rng != NULL )
1309 {
1310 /*
1311 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001312 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001313 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001314 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001315 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +02001316 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001317
1318 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001319 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320
1321cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001322#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001323 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1324 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001325#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001328 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
1329
1330 if( f_rng != NULL )
1331 {
Janos Follathe81102e2017-03-22 13:38:28 +00001332#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001333 mbedtls_mpi_free( &D_blind );
1334#else
1335 mbedtls_mpi_free( &DP_blind );
1336 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001337#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001338 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
1340 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001341 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001342
1343 return( 0 );
1344}
1345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001347/**
1348 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1349 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001350 * \param dst buffer to mask
1351 * \param dlen length of destination buffer
1352 * \param src source of the mask generation
1353 * \param slen length of the source buffer
1354 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001355 */
Paul Bakker48377d92013-08-30 12:06:24 +02001356static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001357 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001358{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001360 unsigned char counter[4];
1361 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001362 unsigned int hlen;
1363 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001365 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001366 memset( counter, 0, 4 );
1367
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001369
Simon Butcher02037452016-03-01 21:19:12 +00001370 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001371 p = dst;
1372
1373 while( dlen > 0 )
1374 {
1375 use_len = hlen;
1376 if( dlen < hlen )
1377 use_len = dlen;
1378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001379 mbedtls_md_starts( md_ctx );
1380 mbedtls_md_update( md_ctx, src, slen );
1381 mbedtls_md_update( md_ctx, counter, 4 );
1382 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001383
1384 for( i = 0; i < use_len; ++i )
1385 *p++ ^= mask[i];
1386
1387 counter[3]++;
1388
1389 dlen -= use_len;
1390 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001391
1392 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001393}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001394#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001396#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001397/*
1398 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1399 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001401 int (*f_rng)(void *, unsigned char *, size_t),
1402 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001403 int mode,
1404 const unsigned char *label, size_t label_len,
1405 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001406 const unsigned char *input,
1407 unsigned char *output )
1408{
1409 size_t olen;
1410 int ret;
1411 unsigned char *p = output;
1412 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001413 const mbedtls_md_info_t *md_info;
1414 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1417 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001418
1419 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001423 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001425
1426 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001428
Simon Butcher02037452016-03-01 21:19:12 +00001429 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001430 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001432
1433 memset( output, 0, olen );
1434
1435 *p++ = 0;
1436
Simon Butcher02037452016-03-01 21:19:12 +00001437 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001438 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001440
1441 p += hlen;
1442
Simon Butcher02037452016-03-01 21:19:12 +00001443 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001445 p += hlen;
1446 p += olen - 2 * hlen - 2 - ilen;
1447 *p++ = 1;
1448 memcpy( p, input, ilen );
1449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001451 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1452 {
1453 mbedtls_md_free( &md_ctx );
1454 return( ret );
1455 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001456
Simon Butcher02037452016-03-01 21:19:12 +00001457 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001458 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1459 &md_ctx );
1460
Simon Butcher02037452016-03-01 21:19:12 +00001461 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001462 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1463 &md_ctx );
1464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 return( ( mode == MBEDTLS_RSA_PUBLIC )
1468 ? mbedtls_rsa_public( ctx, output, output )
1469 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001470}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001473#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001474/*
1475 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1476 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001478 int (*f_rng)(void *, unsigned char *, size_t),
1479 void *p_rng,
1480 int mode, size_t ilen,
1481 const unsigned char *input,
1482 unsigned char *output )
1483{
1484 size_t nb_pad, olen;
1485 int ret;
1486 unsigned char *p = output;
1487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1489 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001490
Janos Follath1ed9f992016-03-18 11:45:44 +00001491 // We don't check p_rng because it won't be dereferenced here
1492 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001494
1495 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001496
Simon Butcher02037452016-03-01 21:19:12 +00001497 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001498 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001499 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001500
1501 nb_pad = olen - 3 - ilen;
1502
1503 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001505 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001507
1508 while( nb_pad-- > 0 )
1509 {
1510 int rng_dl = 100;
1511
1512 do {
1513 ret = f_rng( p_rng, p, 1 );
1514 } while( *p == 0 && --rng_dl && ret == 0 );
1515
Simon Butcher02037452016-03-01 21:19:12 +00001516 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001517 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001519
1520 p++;
1521 }
1522 }
1523 else
1524 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001526
1527 while( nb_pad-- > 0 )
1528 *p++ = 0xFF;
1529 }
1530
1531 *p++ = 0;
1532 memcpy( p, input, ilen );
1533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534 return( ( mode == MBEDTLS_RSA_PUBLIC )
1535 ? mbedtls_rsa_public( ctx, output, output )
1536 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001537}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001539
Paul Bakker5121ce52009-01-03 21:22:43 +00001540/*
1541 * Add the message padding, then do an RSA operation
1542 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001544 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001545 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001546 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001547 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001548 unsigned char *output )
1549{
Paul Bakker5121ce52009-01-03 21:22:43 +00001550 switch( ctx->padding )
1551 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#if defined(MBEDTLS_PKCS1_V15)
1553 case MBEDTLS_RSA_PKCS_V15:
1554 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001555 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001556#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001558#if defined(MBEDTLS_PKCS1_V21)
1559 case MBEDTLS_RSA_PKCS_V21:
1560 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001561 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001562#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001563
1564 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001565 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001566 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001567}
1568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001570/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001571 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001572 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001573int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001574 int (*f_rng)(void *, unsigned char *, size_t),
1575 void *p_rng,
1576 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001577 const unsigned char *label, size_t label_len,
1578 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001579 const unsigned char *input,
1580 unsigned char *output,
1581 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001582{
Paul Bakker23986e52011-04-24 08:57:21 +00001583 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001584 size_t ilen, i, pad_len;
1585 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1587 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001588 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589 const mbedtls_md_info_t *md_info;
1590 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001591
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001592 /*
1593 * Parameters sanity checks
1594 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1596 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
1598 ilen = ctx->len;
1599
Paul Bakker27fdf462011-06-09 13:55:13 +00001600 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001601 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001602
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001603 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001604 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001605 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001606
Janos Follathc17cda12016-02-11 11:08:18 +00001607 hlen = mbedtls_md_get_size( md_info );
1608
1609 // checking for integer underflow
1610 if( 2 * hlen + 2 > ilen )
1611 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1612
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001613 /*
1614 * RSA operation
1615 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001616 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1617 ? mbedtls_rsa_public( ctx, input, buf )
1618 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001619
1620 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001621 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001622
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001623 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001624 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001625 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001626 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001627 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1628 {
1629 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001630 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001631 }
1632
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001633
1634 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001635 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001636
1637 /* seed: Apply seedMask to maskedSeed */
1638 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1639 &md_ctx );
1640
1641 /* DB: Apply dbMask to maskedDB */
1642 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1643 &md_ctx );
1644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001645 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001646
1647 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001648 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001649 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001650 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001651 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001652
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001653 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001654
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001655 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001656
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001657 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001658 for( i = 0; i < hlen; i++ )
1659 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001660
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001661 /* Get zero-padding len, but always read till end of buffer
1662 * (minus one, for the 01 byte) */
1663 pad_len = 0;
1664 pad_done = 0;
1665 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1666 {
1667 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001668 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001669 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001670
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001671 p += pad_len;
1672 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001673
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001674 /*
1675 * The only information "leaked" is whether the padding was correct or not
1676 * (eg, no data is copied if it was not correct). This meets the
1677 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1678 * the different error conditions.
1679 */
1680 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001681 {
1682 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1683 goto cleanup;
1684 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001685
Paul Bakker66d5d072014-06-17 16:39:18 +02001686 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001687 {
1688 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1689 goto cleanup;
1690 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001691
1692 *olen = ilen - (p - buf);
1693 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001694 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001695
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001696cleanup:
1697 mbedtls_zeroize( buf, sizeof( buf ) );
1698 mbedtls_zeroize( lhash, sizeof( lhash ) );
1699
1700 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001701}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001702#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001704#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001705/*
1706 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1707 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001708int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001709 int (*f_rng)(void *, unsigned char *, size_t),
1710 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001711 int mode, size_t *olen,
1712 const unsigned char *input,
1713 unsigned char *output,
1714 size_t output_max_len)
1715{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001716 int ret;
1717 size_t ilen, pad_count = 0, i;
1718 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001719 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001720
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001721 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1722 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001723
1724 ilen = ctx->len;
1725
1726 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001727 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001728
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001729 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1730 ? mbedtls_rsa_public( ctx, input, buf )
1731 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001732
1733 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001734 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001735
1736 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001737 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001738
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001739 /*
1740 * Check and get padding len in "constant-time"
1741 */
1742 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001743
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001744 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001745 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001746 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001747 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001748
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001749 /* Get padding len, but always read till end of buffer
1750 * (minus one, for the 00 byte) */
1751 for( i = 0; i < ilen - 3; i++ )
1752 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001753 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1754 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001755 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001756
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001757 p += pad_count;
1758 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001759 }
1760 else
1761 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001762 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001763
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001764 /* Get padding len, but always read till end of buffer
1765 * (minus one, for the 00 byte) */
1766 for( i = 0; i < ilen - 3; i++ )
1767 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001768 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001769 pad_count += ( pad_done == 0 );
1770 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001771
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001772 p += pad_count;
1773 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001774 }
1775
Janos Follathc69fa502016-02-12 13:30:09 +00001776 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001777
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001778 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001779 {
1780 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1781 goto cleanup;
1782 }
Paul Bakker8804f692013-02-28 18:06:26 +01001783
Paul Bakker66d5d072014-06-17 16:39:18 +02001784 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001785 {
1786 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1787 goto cleanup;
1788 }
Paul Bakker060c5682009-01-12 21:48:39 +00001789
Paul Bakker27fdf462011-06-09 13:55:13 +00001790 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001791 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001792 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001793
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001794cleanup:
1795 mbedtls_zeroize( buf, sizeof( buf ) );
1796
1797 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001798}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001800
1801/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001802 * Do an RSA operation, then remove the message padding
1803 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001804int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001805 int (*f_rng)(void *, unsigned char *, size_t),
1806 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001807 int mode, size_t *olen,
1808 const unsigned char *input,
1809 unsigned char *output,
1810 size_t output_max_len)
1811{
1812 switch( ctx->padding )
1813 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001814#if defined(MBEDTLS_PKCS1_V15)
1815 case MBEDTLS_RSA_PKCS_V15:
1816 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001817 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001818#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001820#if defined(MBEDTLS_PKCS1_V21)
1821 case MBEDTLS_RSA_PKCS_V21:
1822 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001823 olen, input, output,
1824 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001825#endif
1826
1827 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001829 }
1830}
1831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001833/*
1834 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1835 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001837 int (*f_rng)(void *, unsigned char *, size_t),
1838 void *p_rng,
1839 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001840 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001841 unsigned int hashlen,
1842 const unsigned char *hash,
1843 unsigned char *sig )
1844{
1845 size_t olen;
1846 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001848 unsigned int slen, hlen, offset = 0;
1849 int ret;
1850 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851 const mbedtls_md_info_t *md_info;
1852 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1855 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001856
1857 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001858 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001859
1860 olen = ctx->len;
1861
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001862 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001863 {
Simon Butcher02037452016-03-01 21:19:12 +00001864 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001865 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001866 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001867 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001869 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001870 }
1871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001872 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001873 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001874 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001875
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001876 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001877 slen = hlen;
1878
1879 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001881
1882 memset( sig, 0, olen );
1883
Simon Butcher02037452016-03-01 21:19:12 +00001884 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001885 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001887
Simon Butcher02037452016-03-01 21:19:12 +00001888 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001889 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001890 p += olen - hlen * 2 - 2;
1891 *p++ = 0x01;
1892 memcpy( p, salt, slen );
1893 p += slen;
1894
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001895 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001896 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1897 {
1898 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001899 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001900 return( ret );
1901 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001902
Simon Butcher02037452016-03-01 21:19:12 +00001903 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001904 mbedtls_md_starts( &md_ctx );
1905 mbedtls_md_update( &md_ctx, p, 8 );
1906 mbedtls_md_update( &md_ctx, hash, hashlen );
1907 mbedtls_md_update( &md_ctx, salt, slen );
1908 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001909 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001910
Simon Butcher02037452016-03-01 21:19:12 +00001911 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001912 if( msb % 8 == 0 )
1913 offset = 1;
1914
Simon Butcher02037452016-03-01 21:19:12 +00001915 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001916 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1917
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001918 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001919
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001920 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001921 sig[0] &= 0xFF >> ( olen * 8 - msb );
1922
1923 p += hlen;
1924 *p++ = 0xBC;
1925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001926 return( ( mode == MBEDTLS_RSA_PUBLIC )
1927 ? mbedtls_rsa_public( ctx, sig, sig )
1928 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001929}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001930#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001933/*
1934 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1935 */
1936/*
1937 * Do an RSA operation to sign the message digest
1938 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001939int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001940 int (*f_rng)(void *, unsigned char *, size_t),
1941 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001942 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001943 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001944 unsigned int hashlen,
1945 const unsigned char *hash,
1946 unsigned char *sig )
1947{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001948 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001949 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001950 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001951 unsigned char *sig_try = NULL, *verif = NULL;
1952 size_t i;
1953 unsigned char diff;
1954 volatile unsigned char diff_no_optimize;
1955 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1958 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001959
1960 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001961 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001963 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001964 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001965 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001966 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001967 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001969 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1970 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001971
Paul Bakkerc70b9822013-04-07 22:00:46 +02001972 nb_pad -= 10 + oid_size;
1973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001974 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001975 }
1976
Paul Bakkerc70b9822013-04-07 22:00:46 +02001977 nb_pad -= hashlen;
1978
Paul Bakkerb3869132013-02-28 17:21:01 +01001979 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001981
1982 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001983 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001984 memset( p, 0xFF, nb_pad );
1985 p += nb_pad;
1986 *p++ = 0;
1987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001988 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001989 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001990 memcpy( p, hash, hashlen );
1991 }
1992 else
1993 {
1994 /*
1995 * DigestInfo ::= SEQUENCE {
1996 * digestAlgorithm DigestAlgorithmIdentifier,
1997 * digest Digest }
1998 *
1999 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
2000 *
2001 * Digest ::= OCTET STRING
2002 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002004 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002005 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002006 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002007 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02002008 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002009 memcpy( p, oid, oid_size );
2010 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002011 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002012 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002013 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002014 *p++ = hashlen;
2015 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01002016 }
2017
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002018 if( mode == MBEDTLS_RSA_PUBLIC )
2019 return( mbedtls_rsa_public( ctx, sig, sig ) );
2020
2021 /*
2022 * In order to prevent Lenstra's attack, make the signature in a
2023 * temporary buffer and check it before returning it.
2024 */
2025 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00002026 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002027 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2028
Simon Butcher1285ab52016-01-01 21:42:47 +00002029 verif = mbedtls_calloc( 1, ctx->len );
2030 if( verif == NULL )
2031 {
2032 mbedtls_free( sig_try );
2033 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2034 }
2035
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002036 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2037 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2038
2039 /* Compare in constant time just in case */
2040 for( diff = 0, i = 0; i < ctx->len; i++ )
2041 diff |= verif[i] ^ sig[i];
2042 diff_no_optimize = diff;
2043
2044 if( diff_no_optimize != 0 )
2045 {
2046 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2047 goto cleanup;
2048 }
2049
2050 memcpy( sig, sig_try, ctx->len );
2051
2052cleanup:
2053 mbedtls_free( sig_try );
2054 mbedtls_free( verif );
2055
2056 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002057}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002058#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002059
2060/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 * Do an RSA operation to sign the message digest
2062 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002063int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002064 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002065 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002068 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002069 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 unsigned char *sig )
2071{
Paul Bakker5121ce52009-01-03 21:22:43 +00002072 switch( ctx->padding )
2073 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002074#if defined(MBEDTLS_PKCS1_V15)
2075 case MBEDTLS_RSA_PKCS_V15:
2076 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002077 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002078#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002080#if defined(MBEDTLS_PKCS1_V21)
2081 case MBEDTLS_RSA_PKCS_V21:
2082 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002083 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002084#endif
2085
Paul Bakker5121ce52009-01-03 21:22:43 +00002086 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002087 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002089}
2090
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002091#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002092/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002093 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002096 int (*f_rng)(void *, unsigned char *, size_t),
2097 void *p_rng,
2098 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002100 unsigned int hashlen,
2101 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002102 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002103 int expected_salt_len,
2104 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002105{
Paul Bakker23986e52011-04-24 08:57:21 +00002106 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002107 size_t siglen;
2108 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002109 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00002110 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00002111 unsigned int hlen;
2112 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113 const mbedtls_md_info_t *md_info;
2114 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002115 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002117 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2118 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002119
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 siglen = ctx->len;
2121
Paul Bakker27fdf462011-06-09 13:55:13 +00002122 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002125 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2126 ? mbedtls_rsa_public( ctx, sig, buf )
2127 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128
2129 if( ret != 0 )
2130 return( ret );
2131
2132 p = buf;
2133
Paul Bakkerb3869132013-02-28 17:21:01 +01002134 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002135 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002137 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002138 {
Simon Butcher02037452016-03-01 21:19:12 +00002139 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002140 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002141 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002142 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002144 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002145 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002147 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01002148 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002149 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002152 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00002153
Paul Bakkerb3869132013-02-28 17:21:01 +01002154 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00002155
Simon Butcher02037452016-03-01 21:19:12 +00002156 /*
2157 * Note: EMSA-PSS verification is over the length of N - 1 bits
2158 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002159 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002160
Simon Butcher02037452016-03-01 21:19:12 +00002161 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002162 if( msb % 8 == 0 )
2163 {
2164 p++;
2165 siglen -= 1;
2166 }
2167 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002170 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07002171 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2172 {
2173 mbedtls_md_free( &md_ctx );
2174 return( ret );
2175 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002176
Paul Bakkerb3869132013-02-28 17:21:01 +01002177 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01002178
Paul Bakkerb3869132013-02-28 17:21:01 +01002179 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002180
Paul Bakker4de44aa2013-12-31 11:43:01 +01002181 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002182 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002183
Paul Bakkerb3869132013-02-28 17:21:01 +01002184 if( p == buf + siglen ||
2185 *p++ != 0x01 )
2186 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187 mbedtls_md_free( &md_ctx );
2188 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002189 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002190
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002191 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01002192 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002195 slen != (size_t) expected_salt_len )
2196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197 mbedtls_md_free( &md_ctx );
2198 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002199 }
2200
Simon Butcher02037452016-03-01 21:19:12 +00002201 /*
2202 * Generate H = Hash( M' )
2203 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002204 mbedtls_md_starts( &md_ctx );
2205 mbedtls_md_update( &md_ctx, zeros, 8 );
2206 mbedtls_md_update( &md_ctx, hash, hashlen );
2207 mbedtls_md_update( &md_ctx, p, slen );
2208 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00002209
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002210 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002211
Paul Bakkerb3869132013-02-28 17:21:01 +01002212 if( memcmp( p + slen, result, hlen ) == 0 )
2213 return( 0 );
2214 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002215 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01002216}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002217
2218/*
2219 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2220 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002221int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002222 int (*f_rng)(void *, unsigned char *, size_t),
2223 void *p_rng,
2224 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002225 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002226 unsigned int hashlen,
2227 const unsigned char *hash,
2228 const unsigned char *sig )
2229{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002230 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2231 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002232 : md_alg;
2233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002234 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002235 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002236 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002237 sig ) );
2238
2239}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002240#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002243/*
2244 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2245 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002247 int (*f_rng)(void *, unsigned char *, size_t),
2248 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002249 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002250 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002251 unsigned int hashlen,
2252 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002253 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002254{
2255 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002256 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002257 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002258 mbedtls_md_type_t msg_md_alg;
2259 const mbedtls_md_info_t *md_info;
2260 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002261 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002263 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2264 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002265
2266 siglen = ctx->len;
2267
2268 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002269 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002271 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2272 ? mbedtls_rsa_public( ctx, sig, buf )
2273 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01002274
2275 if( ret != 0 )
2276 return( ret );
2277
2278 p = buf;
2279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002280 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
2281 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002282
2283 while( *p != 0 )
2284 {
2285 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002286 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002287 p++;
2288 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02002289 p++; /* skip 00 byte */
2290
2291 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
2292 if( p - buf < 11 )
2293 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002294
2295 len = siglen - ( p - buf );
2296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002297 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002298 {
2299 if( memcmp( p, hash, hashlen ) == 0 )
2300 return( 0 );
2301 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002302 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002303 }
2304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002305 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002306 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002307 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2308 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002309
2310 end = p + len;
2311
Simon Butcher02037452016-03-01 21:19:12 +00002312 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02002313 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
2314 * Insist on 2-byte length tags, to protect against variants of
2315 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00002316 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002317 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2319 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2320 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002321 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002323
Gilles Peskinee7e76502017-05-04 12:48:39 +02002324 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002325 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2326 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2327 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002328 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002329 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002330
Gilles Peskinee7e76502017-05-04 12:48:39 +02002331 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002332 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
2333 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002334 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002335 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002336
2337 oid.p = p;
2338 p += oid.len;
2339
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002340 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
2341 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002342
2343 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002344 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002345
2346 /*
2347 * assume the algorithm parameters must be NULL
2348 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02002349 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002350 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
2351 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002352 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002353 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002354
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002355 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002356 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
2357 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002358 if( p != p0 + 2 || asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002360
2361 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002362 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002363
2364 p += hashlen;
2365
2366 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002367 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002368
2369 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002370}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002371#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002372
2373/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002374 * Do an RSA operation and check the message digest
2375 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002376int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002377 int (*f_rng)(void *, unsigned char *, size_t),
2378 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002379 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002380 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002381 unsigned int hashlen,
2382 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002383 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002384{
2385 switch( ctx->padding )
2386 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002387#if defined(MBEDTLS_PKCS1_V15)
2388 case MBEDTLS_RSA_PKCS_V15:
2389 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002390 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002391#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002392
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002393#if defined(MBEDTLS_PKCS1_V21)
2394 case MBEDTLS_RSA_PKCS_V21:
2395 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002396 hashlen, hash, sig );
2397#endif
2398
2399 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002400 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002401 }
2402}
2403
2404/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002405 * Copy the components of an RSA key
2406 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002407int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002408{
2409 int ret;
2410
2411 dst->ver = src->ver;
2412 dst->len = src->len;
2413
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002414 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2415 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002417 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2418 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2419 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002420
2421#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002422 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2423 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2424 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002425 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2426 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002427#endif
2428
2429 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002431 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2432 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002433
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002434 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002435 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002436
2437cleanup:
2438 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002439 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002440
2441 return( ret );
2442}
2443
2444/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002445 * Free the components of an RSA key
2446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002447void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002448{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002450 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2451 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002452 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002453
Hanno Becker33c30a02017-08-23 07:00:22 +01002454#if !defined(MBEDTLS_RSA_NO_CRT)
2455 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2456 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2457 mbedtls_mpi_free( &ctx->DP );
2458#endif /* MBEDTLS_RSA_NO_CRT */
2459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002460#if defined(MBEDTLS_THREADING_C)
2461 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002462#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002463}
2464
Hanno Beckerab377312017-08-23 16:24:51 +01002465#endif /* !MBEDTLS_RSA_ALT */
2466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002468
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002469#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002470
2471/*
2472 * Example RSA-1024 keypair, for test purposes
2473 */
2474#define KEY_LEN 128
2475
2476#define RSA_N "9292758453063D803DD603D5E777D788" \
2477 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2478 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2479 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2480 "93A89813FBF3C4F8066D2D800F7C38A8" \
2481 "1AE31942917403FF4946B0A83D3D3E05" \
2482 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2483 "5E94BB77B07507233A0BC7BAC8F90F79"
2484
2485#define RSA_E "10001"
2486
2487#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2488 "66CA472BC44D253102F8B4A9D3BFA750" \
2489 "91386C0077937FE33FA3252D28855837" \
2490 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2491 "DF79C5CE07EE72C7F123142198164234" \
2492 "CABB724CF78B8173B9F880FC86322407" \
2493 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2494 "071513A1E85B5DFA031F21ECAE91A34D"
2495
2496#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2497 "2C01CAD19EA484A87EA4377637E75500" \
2498 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2499 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2500
2501#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2502 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2503 "910E4168387E3C30AA1E00C339A79508" \
2504 "8452DD96A9A5EA5D9DCA68DA636032AF"
2505
Paul Bakker5121ce52009-01-03 21:22:43 +00002506#define PT_LEN 24
2507#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2508 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002510#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002511static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002512{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002513#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002514 size_t i;
2515
Paul Bakker545570e2010-07-18 09:00:25 +00002516 if( rng_state != NULL )
2517 rng_state = NULL;
2518
Paul Bakkera3d195c2011-11-27 21:07:34 +00002519 for( i = 0; i < len; ++i )
2520 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002521#else
2522 if( rng_state != NULL )
2523 rng_state = NULL;
2524
2525 arc4random_buf( output, len );
2526#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002527
Paul Bakkera3d195c2011-11-27 21:07:34 +00002528 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002529}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002530#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002531
Paul Bakker5121ce52009-01-03 21:22:43 +00002532/*
2533 * Checkup routine
2534 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002535int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002536{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002537 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002538#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002539 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002540 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002541 unsigned char rsa_plaintext[PT_LEN];
2542 unsigned char rsa_decrypted[PT_LEN];
2543 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002544#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002545 unsigned char sha1sum[20];
2546#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002547
Hanno Becker3a701162017-08-22 13:52:43 +01002548 mbedtls_mpi K;
2549
2550 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002551 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002552
Hanno Becker3a701162017-08-22 13:52:43 +01002553 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2554 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2555 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2556 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2557 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2558 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2559 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2560 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2561 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2562 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2563
2564 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa, NULL, NULL ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002565
2566 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002567 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002569 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2570 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002571 {
2572 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002573 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002574
2575 return( 1 );
2576 }
2577
2578 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002579 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002580
2581 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2582
Hanno Becker98838b02017-10-02 13:16:10 +01002583 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2584 PT_LEN, rsa_plaintext,
2585 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002586 {
2587 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002588 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002589
2590 return( 1 );
2591 }
2592
2593 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002594 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002595
Hanno Becker98838b02017-10-02 13:16:10 +01002596 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2597 &len, rsa_ciphertext, rsa_decrypted,
2598 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002599 {
2600 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002602
2603 return( 1 );
2604 }
2605
2606 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2607 {
2608 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002609 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002610
2611 return( 1 );
2612 }
2613
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002614 if( verbose != 0 )
2615 mbedtls_printf( "passed\n" );
2616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002617#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002618 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002619 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002621 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002622
Hanno Becker98838b02017-10-02 13:16:10 +01002623 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2624 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2625 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002626 {
2627 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002628 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002629
2630 return( 1 );
2631 }
2632
2633 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002634 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002635
Hanno Becker98838b02017-10-02 13:16:10 +01002636 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2637 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2638 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002639 {
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
2646 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002647 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002648#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002649
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002650 if( verbose != 0 )
2651 mbedtls_printf( "\n" );
2652
Paul Bakker3d8fb632014-04-17 12:42:41 +02002653cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002654 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 mbedtls_rsa_free( &rsa );
2656#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002657 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002658#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002659 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002660}
2661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002662#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002663
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002664#endif /* MBEDTLS_RSA_C */