blob: efc148956c64a8fab61989cd43951ca5ff828ab7 [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
Hanno Beckerf9e184b2017-10-10 16:49:26 +0100604int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100605{
606 int ret = 0;
607
Hanno Becker617c1ae2017-08-23 14:11:24 +0100608 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
609 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
610 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
611 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
612 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100613
Hanno Becker617c1ae2017-08-23 14:11:24 +0100614 /*
615 * Check whether provided parameters are enough
616 * to deduce all others. The following incomplete
617 * parameter sets for private keys are supported:
618 *
619 * (1) P, Q missing.
620 * (2) D and potentially N missing.
621 *
622 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100623
Hanno Becker2cca6f32017-09-29 11:46:40 +0100624 const int n_missing = have_P && have_Q && have_D && have_E;
625 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
626 const int d_missing = have_P && have_Q && !have_D && have_E;
627 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
628
629 /* These three alternatives are mutually exclusive */
630 const int is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100631
Hanno Becker617c1ae2017-08-23 14:11:24 +0100632 if( !is_priv && !is_pub )
633 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
634
635 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100636 * Step 1: Deduce N if P, Q are provided.
637 */
638
639 if( !have_N && have_P && have_Q )
640 {
641 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
642 &ctx->Q ) ) != 0 )
643 {
644 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
645 }
646
647 ctx->len = mbedtls_mpi_size( &ctx->N );
648 }
649
650 /*
651 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100652 */
653
654 if( pq_missing )
655 {
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100656 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->D, &ctx->E,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100657 &ctx->P, &ctx->Q );
658 if( ret != 0 )
659 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
660
661 }
662 else if( d_missing )
663 {
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100664 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
665 &ctx->Q,
666 &ctx->E,
667 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100668 {
669 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
670 }
671 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100672
Hanno Becker617c1ae2017-08-23 14:11:24 +0100673 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100674 * Step 3: Deduce all additional parameters specific
Hanno Beckere8674892017-10-10 17:56:14 +0100675 * to our current RSA implementation.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100676 */
677
Hanno Becker23344b52017-08-23 07:43:27 +0100678#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100679 if( is_priv )
680 {
681 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
682 &ctx->DP, &ctx->DQ, &ctx->QP );
683 if( ret != 0 )
684 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
685 }
Hanno Becker23344b52017-08-23 07:43:27 +0100686#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100687
688 /*
Hanno Becker98838b02017-10-02 13:16:10 +0100689 * Step 3: Basic sanity check
Hanno Becker617c1ae2017-08-23 14:11:24 +0100690 */
691
692 if( is_priv )
693 {
694 if( ( ret = mbedtls_rsa_check_privkey( ctx ) ) != 0 )
695 return( ret );
696 }
697 else
698 {
699 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
700 return( ret );
701 }
702
703 return( 0 );
704}
705
Hanno Becker617c1ae2017-08-23 14:11:24 +0100706int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
707 unsigned char *N, size_t N_len,
708 unsigned char *P, size_t P_len,
709 unsigned char *Q, size_t Q_len,
710 unsigned char *D, size_t D_len,
711 unsigned char *E, size_t E_len )
712{
713 int ret = 0;
714
715 /* Check if key is private or public */
716 const int is_priv =
717 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
718 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
719 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
720 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
721 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
722
723 if( !is_priv )
724 {
725 /* If we're trying to export private parameters for a public key,
726 * something must be wrong. */
727 if( P != NULL || Q != NULL || D != NULL )
728 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
729
730 }
731
732 if( N != NULL )
733 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
734
735 if( P != NULL )
736 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
737
738 if( Q != NULL )
739 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
740
741 if( D != NULL )
742 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
743
744 if( E != NULL )
745 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100746
747cleanup:
748
749 return( ret );
750}
751
Hanno Becker617c1ae2017-08-23 14:11:24 +0100752int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
753 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
754 mbedtls_mpi *D, mbedtls_mpi *E )
755{
756 int ret;
757
758 /* Check if key is private or public */
759 int is_priv =
760 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
761 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
762 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
763 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
764 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
765
766 if( !is_priv )
767 {
768 /* If we're trying to export private parameters for a public key,
769 * something must be wrong. */
770 if( P != NULL || Q != NULL || D != NULL )
771 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
772
773 }
774
775 /* Export all requested core parameters. */
776
777 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
778 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
779 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
780 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
781 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
782 {
783 return( ret );
784 }
785
786 return( 0 );
787}
788
789/*
790 * Export CRT parameters
791 * This must also be implemented if CRT is not used, for being able to
792 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
793 * can be used in this case.
794 */
795int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
796 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
797{
798 int ret;
799
800 /* Check if key is private or public */
801 int is_priv =
802 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
803 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
804 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
805 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
806 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
807
808 if( !is_priv )
809 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
810
Hanno Beckerdc95c892017-08-23 06:57:02 +0100811#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100812 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100813 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
814 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
815 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
816 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100817 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100818 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100819#else
820 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
821 DP, DQ, QP ) ) != 0 )
822 {
823 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
824 }
825#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100826
827 return( 0 );
828}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100829
830/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 * Initialize an RSA context
832 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000834 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000835 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000836{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#if defined(MBEDTLS_THREADING_C)
842 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200843#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000844}
845
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100846/*
847 * Set padding for an existing RSA context
848 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100850{
851 ctx->padding = padding;
852 ctx->hash_id = hash_id;
853}
854
Hanno Becker617c1ae2017-08-23 14:11:24 +0100855/*
856 * Get length in bytes of RSA modulus
857 */
858
859size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
860{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100861 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100862}
863
864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000866
867/*
868 * Generate an RSA keypair
869 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000871 int (*f_rng)(void *, unsigned char *, size_t),
872 void *p_rng,
873 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000874{
875 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100876 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
Paul Bakker21eb2802010-08-16 11:10:02 +0000878 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
Janos Follathef441782016-09-21 13:18:12 +0100881 if( nbits % 2 )
882 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
883
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100884 mbedtls_mpi_init( &H );
885 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
887 /*
888 * find primes P and Q with Q < P so that:
889 * GCD( E, (P-1)*(Q-1) ) == 1
890 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
893 do
894 {
Janos Follath10c575b2016-02-23 14:42:48 +0000895 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100896 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000897
Janos Follathef441782016-09-21 13:18:12 +0100898 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100899 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000902 continue;
903
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200905 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 continue;
907
Janos Follathef441782016-09-21 13:18:12 +0100908 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100909 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100910
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100911 /* Temporarily replace P,Q by P-1, Q-1 */
912 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
913 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
914 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000916 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000918
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100919 /* Restore P,Q */
920 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
921 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
922
923 ctx->len = mbedtls_mpi_size( &ctx->N );
924
Paul Bakker5121ce52009-01-03 21:22:43 +0000925 /*
926 * D = E^-1 mod ((P-1)*(Q-1))
927 * DP = D mod (P - 1)
928 * DQ = D mod (Q - 1)
929 * QP = Q^-1 mod P
930 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100932 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
933
934#if !defined(MBEDTLS_RSA_NO_CRT)
935 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
936 &ctx->DP, &ctx->DQ, &ctx->QP ) );
937#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Hanno Becker83aad1f2017-08-23 06:45:10 +0100939 /* Double-check */
940 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
941
Paul Bakker5121ce52009-01-03 21:22:43 +0000942cleanup:
943
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100944 mbedtls_mpi_free( &H );
945 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
947 if( ret != 0 )
948 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_rsa_free( ctx );
950 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 }
952
Paul Bakker48377d92013-08-30 12:06:24 +0200953 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000954}
955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
958/*
959 * Check a public RSA key
960 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000962{
Hanno Becker98838b02017-10-02 13:16:10 +0100963 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
964 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
965 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100967 }
Paul Bakker37940d92009-07-10 22:38:58 +0000968
Hanno Beckerba1ba112017-09-29 11:48:23 +0100969 if( ctx->len != mbedtls_mpi_size( &ctx->N ) )
970 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
971
Hanno Becker98838b02017-10-02 13:16:10 +0100972 if( mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ||
973 mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 )
974 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100976 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000977
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200978 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
979 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Hanno Becker98838b02017-10-02 13:16:10 +0100980 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100982 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000983
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200984 if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100986 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100988 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000989
990 return( 0 );
991}
992
993/*
994 * Check a private RSA key
995 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000997{
Hanno Becker98838b02017-10-02 13:16:10 +0100998 if( mbedtls_rsa_check_pubkey( ctx ) != 0 )
999 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1000
1001 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +01001002 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 {
Hanno Beckerb269a852017-08-25 08:03:21 +01001004 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 }
Hanno Beckerb269a852017-08-25 08:03:21 +01001006#if !defined(MBEDTLS_RSA_NO_CRT)
1007 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
1008 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
1009 {
1010 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1011 }
1012#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +00001013
1014 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001015}
1016
1017/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001018 * Check if contexts holding a public and private key match
1019 */
Hanno Becker98838b02017-10-02 13:16:10 +01001020int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
1021 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001022{
Hanno Becker98838b02017-10-02 13:16:10 +01001023 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001025 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001027 }
1028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
1030 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001031 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001033 }
1034
1035 return( 0 );
1036}
1037
1038/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 * Do an RSA public key operation
1040 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001042 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 unsigned char *output )
1044{
Paul Bakker23986e52011-04-24 08:57:21 +00001045 int ret;
1046 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001051#if defined(MBEDTLS_THREADING_C)
1052 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1053 return( ret );
1054#endif
1055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001059 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001060 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1061 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 }
1063
1064 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
1066 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001067
1068cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001070 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1071 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +01001072#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
1076 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001078
1079 return( 0 );
1080}
1081
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001082/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001083 * Generate or update blinding values, see section 10 of:
1084 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +02001085 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001086 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001087 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001088static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001089 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1090{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001091 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001092
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001093 if( ctx->Vf.p != NULL )
1094 {
1095 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
1097 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
1098 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
1099 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001100
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001101 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001102 }
1103
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001104 /* Unblinding value: Vf = random number, invertible mod N */
1105 do {
1106 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
1110 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1111 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001112
1113 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1115 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 +02001116
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001117
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001118cleanup:
1119 return( ret );
1120}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001121
Paul Bakker5121ce52009-01-03 21:22:43 +00001122/*
Janos Follathe81102e2017-03-22 13:38:28 +00001123 * Exponent blinding supposed to prevent side-channel attacks using multiple
1124 * traces of measurements to recover the RSA key. The more collisions are there,
1125 * the more bits of the key can be recovered. See [3].
1126 *
1127 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1128 * observations on avarage.
1129 *
1130 * For example with 28 byte blinding to achieve 2 collisions the adversary has
1131 * to make 2^112 observations on avarage.
1132 *
1133 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1134 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1135 * Thus in this sense with 28 byte blinding the security is not reduced by
1136 * side-channel attacks like the one in [3])
1137 *
1138 * This countermeasure does not help if the key recovery is possible with a
1139 * single trace.
1140 */
1141#define RSA_EXPONENT_BLINDING 28
1142
1143/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 * Do an RSA private key operation
1145 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001147 int (*f_rng)(void *, unsigned char *, size_t),
1148 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001149 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001150 unsigned char *output )
1151{
Paul Bakker23986e52011-04-24 08:57:21 +00001152 int ret;
1153 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001154 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +00001155 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +00001156#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001157 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001158 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +00001159#else
1160 mbedtls_mpi DP_blind, DQ_blind;
1161 mbedtls_mpi *DP = &ctx->DP;
1162 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +00001163#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
Hanno Becker45037ce2017-08-25 11:03:34 +01001165 /* Sanity-check that all relevant fields are at least set,
1166 * but don't perform a full keycheck. */
1167 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
1168 mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ||
1169 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) == 0 ||
1170 mbedtls_mpi_cmp_int( &ctx->D, 0 ) == 0 ||
1171 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
1172 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001173 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Becker45037ce2017-08-25 11:03:34 +01001174 }
1175#if !defined(MBEDTLS_RSA_NO_CRT)
1176 if( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) == 0 ||
1177 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) == 0 ||
1178 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) == 0 )
1179 {
1180 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1181 }
1182#endif /* MBEDTLS_RSA_NO_CRT */
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001185 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
1186
Janos Follathf9203b42017-03-22 15:13:15 +00001187 if( f_rng != NULL )
1188 {
Janos Follathe81102e2017-03-22 13:38:28 +00001189#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001190 mbedtls_mpi_init( &D_blind );
1191#else
1192 mbedtls_mpi_init( &DP_blind );
1193 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001194#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001195 }
Janos Follathe81102e2017-03-22 13:38:28 +00001196
Paul Bakker5121ce52009-01-03 21:22:43 +00001197
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001198#if defined(MBEDTLS_THREADING_C)
1199 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1200 return( ret );
1201#endif
1202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
1204 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001206 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1207 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001208 }
1209
Paul Bakkerf451bac2013-08-30 15:37:02 +02001210 if( f_rng != NULL )
1211 {
1212 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001213 * Blinding
1214 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001215 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001216 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
1217 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +00001219
Janos Follathe81102e2017-03-22 13:38:28 +00001220 /*
1221 * Exponent blinding
1222 */
1223 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1224 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1225
Janos Follathf9203b42017-03-22 15:13:15 +00001226#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001227 /*
1228 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1229 */
1230 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1231 f_rng, p_rng ) );
1232 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1233 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1234 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1235
1236 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001237#else
1238 /*
1239 * DP_blind = ( P - 1 ) * R + DP
1240 */
1241 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1242 f_rng, p_rng ) );
1243 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1244 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1245 &ctx->DP ) );
1246
1247 DP = &DP_blind;
1248
1249 /*
1250 * DQ_blind = ( Q - 1 ) * R + DQ
1251 */
1252 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1253 f_rng, p_rng ) );
1254 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1255 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1256 &ctx->DQ ) );
1257
1258 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001259#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +02001260 }
Paul Bakkeraab30c12013-08-30 11:00:25 +02001261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001262#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001263 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001264#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001265 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001266 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001267 *
1268 * T1 = input ^ dP mod P
1269 * T2 = input ^ dQ mod Q
1270 */
Janos Follathf9203b42017-03-22 15:13:15 +00001271 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
1272 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001273
1274 /*
1275 * T = (T1 - T2) * (Q^-1 mod P) mod P
1276 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001277 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
1278 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
1279 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001280
1281 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +02001282 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001283 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
1285 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
1286#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001287
Paul Bakkerf451bac2013-08-30 15:37:02 +02001288 if( f_rng != NULL )
1289 {
1290 /*
1291 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001292 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001293 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001294 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001295 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +02001296 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001297
1298 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
1301cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001302#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001303 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1304 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001305#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001308 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
1309
1310 if( f_rng != NULL )
1311 {
Janos Follathe81102e2017-03-22 13:38:28 +00001312#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001313 mbedtls_mpi_free( &D_blind );
1314#else
1315 mbedtls_mpi_free( &DP_blind );
1316 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001317#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001318 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001319
1320 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001322
1323 return( 0 );
1324}
1325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001326#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001327/**
1328 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1329 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001330 * \param dst buffer to mask
1331 * \param dlen length of destination buffer
1332 * \param src source of the mask generation
1333 * \param slen length of the source buffer
1334 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001335 */
Paul Bakker48377d92013-08-30 12:06:24 +02001336static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001338{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001339 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001340 unsigned char counter[4];
1341 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001342 unsigned int hlen;
1343 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001346 memset( counter, 0, 4 );
1347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001348 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001349
Simon Butcher02037452016-03-01 21:19:12 +00001350 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001351 p = dst;
1352
1353 while( dlen > 0 )
1354 {
1355 use_len = hlen;
1356 if( dlen < hlen )
1357 use_len = dlen;
1358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 mbedtls_md_starts( md_ctx );
1360 mbedtls_md_update( md_ctx, src, slen );
1361 mbedtls_md_update( md_ctx, counter, 4 );
1362 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001363
1364 for( i = 0; i < use_len; ++i )
1365 *p++ ^= mask[i];
1366
1367 counter[3]++;
1368
1369 dlen -= use_len;
1370 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001371
1372 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001373}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001374#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001376#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001377/*
1378 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1379 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001380int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001381 int (*f_rng)(void *, unsigned char *, size_t),
1382 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001383 int mode,
1384 const unsigned char *label, size_t label_len,
1385 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001386 const unsigned char *input,
1387 unsigned char *output )
1388{
1389 size_t olen;
1390 int ret;
1391 unsigned char *p = output;
1392 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001393 const mbedtls_md_info_t *md_info;
1394 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001396 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1397 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001398
1399 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001403 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001405
1406 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001408
Simon Butcher02037452016-03-01 21:19:12 +00001409 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001410 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001412
1413 memset( output, 0, olen );
1414
1415 *p++ = 0;
1416
Simon Butcher02037452016-03-01 21:19:12 +00001417 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001418 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001420
1421 p += hlen;
1422
Simon Butcher02037452016-03-01 21:19:12 +00001423 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001425 p += hlen;
1426 p += olen - 2 * hlen - 2 - ilen;
1427 *p++ = 1;
1428 memcpy( p, input, ilen );
1429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001431 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1432 {
1433 mbedtls_md_free( &md_ctx );
1434 return( ret );
1435 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001436
Simon Butcher02037452016-03-01 21:19:12 +00001437 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001438 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1439 &md_ctx );
1440
Simon Butcher02037452016-03-01 21:19:12 +00001441 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001442 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1443 &md_ctx );
1444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001445 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447 return( ( mode == MBEDTLS_RSA_PUBLIC )
1448 ? mbedtls_rsa_public( ctx, output, output )
1449 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001450}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001454/*
1455 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1456 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001457int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001458 int (*f_rng)(void *, unsigned char *, size_t),
1459 void *p_rng,
1460 int mode, size_t ilen,
1461 const unsigned char *input,
1462 unsigned char *output )
1463{
1464 size_t nb_pad, olen;
1465 int ret;
1466 unsigned char *p = output;
1467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1469 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001470
Janos Follath1ed9f992016-03-18 11:45:44 +00001471 // We don't check p_rng because it won't be dereferenced here
1472 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001473 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001474
1475 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001476
Simon Butcher02037452016-03-01 21:19:12 +00001477 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001478 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001480
1481 nb_pad = olen - 3 - ilen;
1482
1483 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001485 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001487
1488 while( nb_pad-- > 0 )
1489 {
1490 int rng_dl = 100;
1491
1492 do {
1493 ret = f_rng( p_rng, p, 1 );
1494 } while( *p == 0 && --rng_dl && ret == 0 );
1495
Simon Butcher02037452016-03-01 21:19:12 +00001496 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001497 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001499
1500 p++;
1501 }
1502 }
1503 else
1504 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001506
1507 while( nb_pad-- > 0 )
1508 *p++ = 0xFF;
1509 }
1510
1511 *p++ = 0;
1512 memcpy( p, input, ilen );
1513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001514 return( ( mode == MBEDTLS_RSA_PUBLIC )
1515 ? mbedtls_rsa_public( ctx, output, output )
1516 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001517}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001519
Paul Bakker5121ce52009-01-03 21:22:43 +00001520/*
1521 * Add the message padding, then do an RSA operation
1522 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001524 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001525 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001526 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001527 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001528 unsigned char *output )
1529{
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 switch( ctx->padding )
1531 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532#if defined(MBEDTLS_PKCS1_V15)
1533 case MBEDTLS_RSA_PKCS_V15:
1534 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001535 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001536#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#if defined(MBEDTLS_PKCS1_V21)
1539 case MBEDTLS_RSA_PKCS_V21:
1540 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001541 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001542#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001543
1544 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001547}
1548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001550/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001551 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001552 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001554 int (*f_rng)(void *, unsigned char *, size_t),
1555 void *p_rng,
1556 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001557 const unsigned char *label, size_t label_len,
1558 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001559 const unsigned char *input,
1560 unsigned char *output,
1561 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001562{
Paul Bakker23986e52011-04-24 08:57:21 +00001563 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001564 size_t ilen, i, pad_len;
1565 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1567 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001568 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569 const mbedtls_md_info_t *md_info;
1570 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001571
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001572 /*
1573 * Parameters sanity checks
1574 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1576 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001577
1578 ilen = ctx->len;
1579
Paul Bakker27fdf462011-06-09 13:55:13 +00001580 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001581 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001584 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001585 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001586
Janos Follathc17cda12016-02-11 11:08:18 +00001587 hlen = mbedtls_md_get_size( md_info );
1588
1589 // checking for integer underflow
1590 if( 2 * hlen + 2 > ilen )
1591 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1592
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001593 /*
1594 * RSA operation
1595 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1597 ? mbedtls_rsa_public( ctx, input, buf )
1598 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001599
1600 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001601 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001602
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001603 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001604 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001605 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001606 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001607 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1608 {
1609 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001610 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001611 }
1612
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001613
1614 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001615 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001616
1617 /* seed: Apply seedMask to maskedSeed */
1618 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1619 &md_ctx );
1620
1621 /* DB: Apply dbMask to maskedDB */
1622 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1623 &md_ctx );
1624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001625 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001626
1627 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001628 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001629 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001630 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001631 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001632
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001633 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001634
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001635 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001636
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001637 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001638 for( i = 0; i < hlen; i++ )
1639 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001640
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001641 /* Get zero-padding len, but always read till end of buffer
1642 * (minus one, for the 01 byte) */
1643 pad_len = 0;
1644 pad_done = 0;
1645 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1646 {
1647 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001648 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001649 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001650
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001651 p += pad_len;
1652 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001653
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001654 /*
1655 * The only information "leaked" is whether the padding was correct or not
1656 * (eg, no data is copied if it was not correct). This meets the
1657 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1658 * the different error conditions.
1659 */
1660 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001661 {
1662 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1663 goto cleanup;
1664 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001665
Paul Bakker66d5d072014-06-17 16:39:18 +02001666 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001667 {
1668 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1669 goto cleanup;
1670 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001671
1672 *olen = ilen - (p - buf);
1673 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001674 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001675
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001676cleanup:
1677 mbedtls_zeroize( buf, sizeof( buf ) );
1678 mbedtls_zeroize( lhash, sizeof( lhash ) );
1679
1680 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001681}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001682#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001685/*
1686 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1687 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001689 int (*f_rng)(void *, unsigned char *, size_t),
1690 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001691 int mode, size_t *olen,
1692 const unsigned char *input,
1693 unsigned char *output,
1694 size_t output_max_len)
1695{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001696 int ret;
1697 size_t ilen, pad_count = 0, i;
1698 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001700
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001701 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1702 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001703
1704 ilen = ctx->len;
1705
1706 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001707 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001709 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1710 ? mbedtls_rsa_public( ctx, input, buf )
1711 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001712
1713 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001714 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001715
1716 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001717 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001718
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001719 /*
1720 * Check and get padding len in "constant-time"
1721 */
1722 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001723
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001724 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001725 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001726 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001727 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001728
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001729 /* Get padding len, but always read till end of buffer
1730 * (minus one, for the 00 byte) */
1731 for( i = 0; i < ilen - 3; i++ )
1732 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001733 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1734 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001735 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001736
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001737 p += pad_count;
1738 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001739 }
1740 else
1741 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001742 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001743
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001744 /* Get padding len, but always read till end of buffer
1745 * (minus one, for the 00 byte) */
1746 for( i = 0; i < ilen - 3; i++ )
1747 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001748 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001749 pad_count += ( pad_done == 0 );
1750 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001751
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001752 p += pad_count;
1753 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001754 }
1755
Janos Follathc69fa502016-02-12 13:30:09 +00001756 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001757
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001758 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001759 {
1760 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1761 goto cleanup;
1762 }
Paul Bakker8804f692013-02-28 18:06:26 +01001763
Paul Bakker66d5d072014-06-17 16:39:18 +02001764 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001765 {
1766 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1767 goto cleanup;
1768 }
Paul Bakker060c5682009-01-12 21:48:39 +00001769
Paul Bakker27fdf462011-06-09 13:55:13 +00001770 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001771 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001772 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001773
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001774cleanup:
1775 mbedtls_zeroize( buf, sizeof( buf ) );
1776
1777 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001778}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
1781/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001782 * Do an RSA operation, then remove the message padding
1783 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001784int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001785 int (*f_rng)(void *, unsigned char *, size_t),
1786 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001787 int mode, size_t *olen,
1788 const unsigned char *input,
1789 unsigned char *output,
1790 size_t output_max_len)
1791{
1792 switch( ctx->padding )
1793 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001794#if defined(MBEDTLS_PKCS1_V15)
1795 case MBEDTLS_RSA_PKCS_V15:
1796 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001797 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001798#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001800#if defined(MBEDTLS_PKCS1_V21)
1801 case MBEDTLS_RSA_PKCS_V21:
1802 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001803 olen, input, output,
1804 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001805#endif
1806
1807 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001808 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001809 }
1810}
1811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001812#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001813/*
1814 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1815 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001816int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001817 int (*f_rng)(void *, unsigned char *, size_t),
1818 void *p_rng,
1819 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001820 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001821 unsigned int hashlen,
1822 const unsigned char *hash,
1823 unsigned char *sig )
1824{
1825 size_t olen;
1826 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001827 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001828 unsigned int slen, hlen, offset = 0;
1829 int ret;
1830 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831 const mbedtls_md_info_t *md_info;
1832 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001833
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001834 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1835 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001836
1837 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001838 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001839
1840 olen = ctx->len;
1841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001843 {
Simon Butcher02037452016-03-01 21:19:12 +00001844 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001846 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001850 }
1851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001852 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001853 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001856 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001857 slen = hlen;
1858
1859 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001861
1862 memset( sig, 0, olen );
1863
Simon Butcher02037452016-03-01 21:19:12 +00001864 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001865 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001867
Simon Butcher02037452016-03-01 21:19:12 +00001868 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001869 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001870 p += olen - hlen * 2 - 2;
1871 *p++ = 0x01;
1872 memcpy( p, salt, slen );
1873 p += slen;
1874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001875 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001876 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1877 {
1878 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001879 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001880 return( ret );
1881 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001882
Simon Butcher02037452016-03-01 21:19:12 +00001883 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001884 mbedtls_md_starts( &md_ctx );
1885 mbedtls_md_update( &md_ctx, p, 8 );
1886 mbedtls_md_update( &md_ctx, hash, hashlen );
1887 mbedtls_md_update( &md_ctx, salt, slen );
1888 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001889 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001890
Simon Butcher02037452016-03-01 21:19:12 +00001891 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001892 if( msb % 8 == 0 )
1893 offset = 1;
1894
Simon Butcher02037452016-03-01 21:19:12 +00001895 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001896 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1897
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001899
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001900 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001901 sig[0] &= 0xFF >> ( olen * 8 - msb );
1902
1903 p += hlen;
1904 *p++ = 0xBC;
1905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 return( ( mode == MBEDTLS_RSA_PUBLIC )
1907 ? mbedtls_rsa_public( ctx, sig, sig )
1908 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001909}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001911
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001912#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001913/*
1914 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1915 */
1916/*
1917 * Do an RSA operation to sign the message digest
1918 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001920 int (*f_rng)(void *, unsigned char *, size_t),
1921 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001922 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001923 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001924 unsigned int hashlen,
1925 const unsigned char *hash,
1926 unsigned char *sig )
1927{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001928 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001929 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001930 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001931 unsigned char *sig_try = NULL, *verif = NULL;
1932 size_t i;
1933 unsigned char diff;
1934 volatile unsigned char diff_no_optimize;
1935 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001937 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1938 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001939
1940 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001941 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001943 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001944 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001946 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001947 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001948
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001949 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1950 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001951
Paul Bakkerc70b9822013-04-07 22:00:46 +02001952 nb_pad -= 10 + oid_size;
1953
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001954 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001955 }
1956
Paul Bakkerc70b9822013-04-07 22:00:46 +02001957 nb_pad -= hashlen;
1958
Paul Bakkerb3869132013-02-28 17:21:01 +01001959 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001960 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001961
1962 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001963 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001964 memset( p, 0xFF, nb_pad );
1965 p += nb_pad;
1966 *p++ = 0;
1967
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001968 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001969 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001970 memcpy( p, hash, hashlen );
1971 }
1972 else
1973 {
1974 /*
1975 * DigestInfo ::= SEQUENCE {
1976 * digestAlgorithm DigestAlgorithmIdentifier,
1977 * digest Digest }
1978 *
1979 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1980 *
1981 * Digest ::= OCTET STRING
1982 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001983 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001984 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001985 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001986 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001987 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001988 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001989 memcpy( p, oid, oid_size );
1990 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001992 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001994 *p++ = hashlen;
1995 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01001996 }
1997
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001998 if( mode == MBEDTLS_RSA_PUBLIC )
1999 return( mbedtls_rsa_public( ctx, sig, sig ) );
2000
2001 /*
2002 * In order to prevent Lenstra's attack, make the signature in a
2003 * temporary buffer and check it before returning it.
2004 */
2005 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00002006 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002007 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2008
Simon Butcher1285ab52016-01-01 21:42:47 +00002009 verif = mbedtls_calloc( 1, ctx->len );
2010 if( verif == NULL )
2011 {
2012 mbedtls_free( sig_try );
2013 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2014 }
2015
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002016 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2017 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2018
2019 /* Compare in constant time just in case */
2020 for( diff = 0, i = 0; i < ctx->len; i++ )
2021 diff |= verif[i] ^ sig[i];
2022 diff_no_optimize = diff;
2023
2024 if( diff_no_optimize != 0 )
2025 {
2026 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2027 goto cleanup;
2028 }
2029
2030 memcpy( sig, sig_try, ctx->len );
2031
2032cleanup:
2033 mbedtls_free( sig_try );
2034 mbedtls_free( verif );
2035
2036 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002037}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002038#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002039
2040/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002041 * Do an RSA operation to sign the message digest
2042 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002043int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002044 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002045 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00002046 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002047 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002048 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002049 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002050 unsigned char *sig )
2051{
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 switch( ctx->padding )
2053 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002054#if defined(MBEDTLS_PKCS1_V15)
2055 case MBEDTLS_RSA_PKCS_V15:
2056 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002057 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002058#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060#if defined(MBEDTLS_PKCS1_V21)
2061 case MBEDTLS_RSA_PKCS_V21:
2062 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002063 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002064#endif
2065
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002069}
2070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002071#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002072/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002073 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002074 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002075int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002076 int (*f_rng)(void *, unsigned char *, size_t),
2077 void *p_rng,
2078 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002079 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002080 unsigned int hashlen,
2081 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002082 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002083 int expected_salt_len,
2084 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002085{
Paul Bakker23986e52011-04-24 08:57:21 +00002086 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002087 size_t siglen;
2088 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00002090 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00002091 unsigned int hlen;
2092 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002093 const mbedtls_md_info_t *md_info;
2094 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002095 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2098 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002099
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 siglen = ctx->len;
2101
Paul Bakker27fdf462011-06-09 13:55:13 +00002102 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2106 ? mbedtls_rsa_public( ctx, sig, buf )
2107 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
2109 if( ret != 0 )
2110 return( ret );
2111
2112 p = buf;
2113
Paul Bakkerb3869132013-02-28 17:21:01 +01002114 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002115 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002117 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 {
Simon Butcher02037452016-03-01 21:19:12 +00002119 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002120 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002121 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002122 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002124 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002125 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002127 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01002128 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002129 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002132 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00002133
Paul Bakkerb3869132013-02-28 17:21:01 +01002134 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00002135
Simon Butcher02037452016-03-01 21:19:12 +00002136 /*
2137 * Note: EMSA-PSS verification is over the length of N - 1 bits
2138 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002139 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002140
Simon Butcher02037452016-03-01 21:19:12 +00002141 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002142 if( msb % 8 == 0 )
2143 {
2144 p++;
2145 siglen -= 1;
2146 }
2147 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002148 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002150 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07002151 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2152 {
2153 mbedtls_md_free( &md_ctx );
2154 return( ret );
2155 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002156
Paul Bakkerb3869132013-02-28 17:21:01 +01002157 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01002158
Paul Bakkerb3869132013-02-28 17:21:01 +01002159 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002160
Paul Bakker4de44aa2013-12-31 11:43:01 +01002161 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002162 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002163
Paul Bakkerb3869132013-02-28 17:21:01 +01002164 if( p == buf + siglen ||
2165 *p++ != 0x01 )
2166 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002167 mbedtls_md_free( &md_ctx );
2168 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002169 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002170
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002171 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01002172 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002174 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002175 slen != (size_t) expected_salt_len )
2176 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002177 mbedtls_md_free( &md_ctx );
2178 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002179 }
2180
Simon Butcher02037452016-03-01 21:19:12 +00002181 /*
2182 * Generate H = Hash( M' )
2183 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002184 mbedtls_md_starts( &md_ctx );
2185 mbedtls_md_update( &md_ctx, zeros, 8 );
2186 mbedtls_md_update( &md_ctx, hash, hashlen );
2187 mbedtls_md_update( &md_ctx, p, slen );
2188 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00002189
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002190 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002191
Paul Bakkerb3869132013-02-28 17:21:01 +01002192 if( memcmp( p + slen, result, hlen ) == 0 )
2193 return( 0 );
2194 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002195 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01002196}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002197
2198/*
2199 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2200 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002201int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002202 int (*f_rng)(void *, unsigned char *, size_t),
2203 void *p_rng,
2204 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002205 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002206 unsigned int hashlen,
2207 const unsigned char *hash,
2208 const unsigned char *sig )
2209{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002210 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2211 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002212 : md_alg;
2213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002214 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002215 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002216 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002217 sig ) );
2218
2219}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002222#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002223/*
2224 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2225 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002226int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002227 int (*f_rng)(void *, unsigned char *, size_t),
2228 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002229 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002230 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002231 unsigned int hashlen,
2232 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002233 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002234{
2235 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002236 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002237 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002238 mbedtls_md_type_t msg_md_alg;
2239 const mbedtls_md_info_t *md_info;
2240 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002241 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002243 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2244 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002245
2246 siglen = ctx->len;
2247
2248 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002249 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2252 ? mbedtls_rsa_public( ctx, sig, buf )
2253 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01002254
2255 if( ret != 0 )
2256 return( ret );
2257
2258 p = buf;
2259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002260 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
2261 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002262
2263 while( *p != 0 )
2264 {
2265 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002266 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002267 p++;
2268 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02002269 p++; /* skip 00 byte */
2270
2271 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
2272 if( p - buf < 11 )
2273 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002274
2275 len = siglen - ( p - buf );
2276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002278 {
2279 if( memcmp( p, hash, hashlen ) == 0 )
2280 return( 0 );
2281 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002283 }
2284
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002285 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002286 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002287 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2288 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002289
2290 end = p + len;
2291
Simon Butcher02037452016-03-01 21:19:12 +00002292 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02002293 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
2294 * Insist on 2-byte length tags, to protect against variants of
2295 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00002296 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002297 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002298 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2299 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2300 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002301 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002302 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002303
Gilles Peskinee7e76502017-05-04 12:48:39 +02002304 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002305 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2306 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2307 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002308 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002309 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002310
Gilles Peskinee7e76502017-05-04 12:48:39 +02002311 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002312 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
2313 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002314 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002315 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002316
2317 oid.p = p;
2318 p += oid.len;
2319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
2321 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002322
2323 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002324 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002325
2326 /*
2327 * assume the algorithm parameters must be NULL
2328 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02002329 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002330 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
2331 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002332 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002334
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002335 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002336 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
2337 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002338 if( p != p0 + 2 || asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002339 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002340
2341 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002342 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002343
2344 p += hashlen;
2345
2346 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002347 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002348
2349 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002350}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002351#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002352
2353/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002354 * Do an RSA operation and check the message digest
2355 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002356int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002357 int (*f_rng)(void *, unsigned char *, size_t),
2358 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002359 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002360 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002361 unsigned int hashlen,
2362 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002363 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002364{
2365 switch( ctx->padding )
2366 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002367#if defined(MBEDTLS_PKCS1_V15)
2368 case MBEDTLS_RSA_PKCS_V15:
2369 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002370 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002371#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002373#if defined(MBEDTLS_PKCS1_V21)
2374 case MBEDTLS_RSA_PKCS_V21:
2375 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002376 hashlen, hash, sig );
2377#endif
2378
2379 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002380 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002381 }
2382}
2383
2384/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002385 * Copy the components of an RSA key
2386 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002387int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002388{
2389 int ret;
2390
2391 dst->ver = src->ver;
2392 dst->len = src->len;
2393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002394 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2395 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002397 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2398 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2399 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002400
2401#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002402 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2403 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2404 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002405 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2406 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002407#endif
2408
2409 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002411 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2412 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002413
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002414 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002415 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002416
2417cleanup:
2418 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002420
2421 return( ret );
2422}
2423
2424/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002425 * Free the components of an RSA key
2426 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002427void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002428{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002429 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002430 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2431 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002432 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002433
Hanno Becker33c30a02017-08-23 07:00:22 +01002434#if !defined(MBEDTLS_RSA_NO_CRT)
2435 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2436 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2437 mbedtls_mpi_free( &ctx->DP );
2438#endif /* MBEDTLS_RSA_NO_CRT */
2439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002440#if defined(MBEDTLS_THREADING_C)
2441 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002442#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002443}
2444
Hanno Beckerab377312017-08-23 16:24:51 +01002445#endif /* !MBEDTLS_RSA_ALT */
2446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002447#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002448
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002449#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002450
2451/*
2452 * Example RSA-1024 keypair, for test purposes
2453 */
2454#define KEY_LEN 128
2455
2456#define RSA_N "9292758453063D803DD603D5E777D788" \
2457 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2458 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2459 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2460 "93A89813FBF3C4F8066D2D800F7C38A8" \
2461 "1AE31942917403FF4946B0A83D3D3E05" \
2462 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2463 "5E94BB77B07507233A0BC7BAC8F90F79"
2464
2465#define RSA_E "10001"
2466
2467#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2468 "66CA472BC44D253102F8B4A9D3BFA750" \
2469 "91386C0077937FE33FA3252D28855837" \
2470 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2471 "DF79C5CE07EE72C7F123142198164234" \
2472 "CABB724CF78B8173B9F880FC86322407" \
2473 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2474 "071513A1E85B5DFA031F21ECAE91A34D"
2475
2476#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2477 "2C01CAD19EA484A87EA4377637E75500" \
2478 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2479 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2480
2481#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2482 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2483 "910E4168387E3C30AA1E00C339A79508" \
2484 "8452DD96A9A5EA5D9DCA68DA636032AF"
2485
Paul Bakker5121ce52009-01-03 21:22:43 +00002486#define PT_LEN 24
2487#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2488 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002490#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002491static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002492{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002493#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002494 size_t i;
2495
Paul Bakker545570e2010-07-18 09:00:25 +00002496 if( rng_state != NULL )
2497 rng_state = NULL;
2498
Paul Bakkera3d195c2011-11-27 21:07:34 +00002499 for( i = 0; i < len; ++i )
2500 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002501#else
2502 if( rng_state != NULL )
2503 rng_state = NULL;
2504
2505 arc4random_buf( output, len );
2506#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002507
Paul Bakkera3d195c2011-11-27 21:07:34 +00002508 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002509}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002510#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002511
Paul Bakker5121ce52009-01-03 21:22:43 +00002512/*
2513 * Checkup routine
2514 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002515int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002516{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002517 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002518#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002519 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002520 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002521 unsigned char rsa_plaintext[PT_LEN];
2522 unsigned char rsa_decrypted[PT_LEN];
2523 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002524#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002525 unsigned char sha1sum[20];
2526#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002527
Hanno Becker3a701162017-08-22 13:52:43 +01002528 mbedtls_mpi K;
2529
2530 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002531 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002532
Hanno Becker3a701162017-08-22 13:52:43 +01002533 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2534 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2535 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2536 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2537 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2538 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2539 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2540 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2541 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2542 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2543
Hanno Becker7f25f852017-10-10 16:56:22 +01002544 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002545
2546 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002547 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002549 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2550 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002551 {
2552 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002553 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002554
2555 return( 1 );
2556 }
2557
2558 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002559 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002560
2561 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2562
Hanno Becker98838b02017-10-02 13:16:10 +01002563 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2564 PT_LEN, rsa_plaintext,
2565 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002566 {
2567 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002568 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002569
2570 return( 1 );
2571 }
2572
2573 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002574 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002575
Hanno Becker98838b02017-10-02 13:16:10 +01002576 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2577 &len, rsa_ciphertext, rsa_decrypted,
2578 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002579 {
2580 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002581 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002582
2583 return( 1 );
2584 }
2585
2586 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2587 {
2588 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002589 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002590
2591 return( 1 );
2592 }
2593
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002594 if( verbose != 0 )
2595 mbedtls_printf( "passed\n" );
2596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002597#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002598 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002599 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002601 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002602
Hanno Becker98838b02017-10-02 13:16:10 +01002603 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2604 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2605 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002606 {
2607 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002608 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002609
2610 return( 1 );
2611 }
2612
2613 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002614 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002615
Hanno Becker98838b02017-10-02 13:16:10 +01002616 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2617 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2618 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002619 {
2620 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002621 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002622
2623 return( 1 );
2624 }
2625
2626 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002627 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002628#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002629
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002630 if( verbose != 0 )
2631 mbedtls_printf( "\n" );
2632
Paul Bakker3d8fb632014-04-17 12:42:41 +02002633cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002634 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002635 mbedtls_rsa_free( &rsa );
2636#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002637 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002638#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002639 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002640}
2641
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002642#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002644#endif /* MBEDTLS_RSA_C */