blob: 388b634268e7b195099bf62b3c8b088d87f64305 [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 {
656 /* This includes sanity checking of core parameters,
657 * so no further checks necessary. */
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100658 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->D, &ctx->E,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100659 &ctx->P, &ctx->Q );
660 if( ret != 0 )
661 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
662
663 }
664 else if( d_missing )
665 {
Hanno Becker617c1ae2017-08-23 14:11:24 +0100666
Hanno Becker617c1ae2017-08-23 14:11:24 +0100667 /* Deduce private exponent. This includes double-checking of the result,
668 * so together with the primality test above all core parameters are
669 * guaranteed to be sane if this call succeeds. */
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100670 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
671 &ctx->Q,
672 &ctx->E,
673 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100674 {
675 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
676 }
677 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100678
679 /* In the remaining case of a public key, there's nothing to check for. */
680
681 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100682 * Step 3: Deduce all additional parameters specific
Hanno Becker617c1ae2017-08-23 14:11:24 +0100683 * to our current RSA implementaiton.
684 */
685
Hanno Becker23344b52017-08-23 07:43:27 +0100686#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100687 if( is_priv )
688 {
689 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
690 &ctx->DP, &ctx->DQ, &ctx->QP );
691 if( ret != 0 )
692 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
693 }
Hanno Becker23344b52017-08-23 07:43:27 +0100694#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100695
696 /*
Hanno Becker98838b02017-10-02 13:16:10 +0100697 * Step 3: Basic sanity check
Hanno Becker617c1ae2017-08-23 14:11:24 +0100698 */
699
700 if( is_priv )
701 {
702 if( ( ret = mbedtls_rsa_check_privkey( ctx ) ) != 0 )
703 return( ret );
704 }
705 else
706 {
707 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
708 return( ret );
709 }
710
711 return( 0 );
712}
713
Hanno Becker617c1ae2017-08-23 14:11:24 +0100714int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
715 unsigned char *N, size_t N_len,
716 unsigned char *P, size_t P_len,
717 unsigned char *Q, size_t Q_len,
718 unsigned char *D, size_t D_len,
719 unsigned char *E, size_t E_len )
720{
721 int ret = 0;
722
723 /* Check if key is private or public */
724 const int is_priv =
725 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
726 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
727 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
728 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
729 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
730
731 if( !is_priv )
732 {
733 /* If we're trying to export private parameters for a public key,
734 * something must be wrong. */
735 if( P != NULL || Q != NULL || D != NULL )
736 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
737
738 }
739
740 if( N != NULL )
741 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
742
743 if( P != NULL )
744 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
745
746 if( Q != NULL )
747 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
748
749 if( D != NULL )
750 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
751
752 if( E != NULL )
753 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100754
755cleanup:
756
757 return( ret );
758}
759
Hanno Becker617c1ae2017-08-23 14:11:24 +0100760int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
761 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
762 mbedtls_mpi *D, mbedtls_mpi *E )
763{
764 int ret;
765
766 /* Check if key is private or public */
767 int is_priv =
768 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
769 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
770 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
771 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
772 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
773
774 if( !is_priv )
775 {
776 /* If we're trying to export private parameters for a public key,
777 * something must be wrong. */
778 if( P != NULL || Q != NULL || D != NULL )
779 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
780
781 }
782
783 /* Export all requested core parameters. */
784
785 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
786 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
787 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
788 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
789 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
790 {
791 return( ret );
792 }
793
794 return( 0 );
795}
796
797/*
798 * Export CRT parameters
799 * This must also be implemented if CRT is not used, for being able to
800 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
801 * can be used in this case.
802 */
803int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
804 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
805{
806 int ret;
807
808 /* Check if key is private or public */
809 int is_priv =
810 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
811 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
812 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
813 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
814 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
815
816 if( !is_priv )
817 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
818
Hanno Beckerdc95c892017-08-23 06:57:02 +0100819#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100820 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100821 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
822 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
823 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
824 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100825 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100826 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100827#else
828 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
829 DP, DQ, QP ) ) != 0 )
830 {
831 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
832 }
833#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100834
835 return( 0 );
836}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100837
838/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000839 * Initialize an RSA context
840 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000842 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000843 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000844{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#if defined(MBEDTLS_THREADING_C)
850 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200851#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000852}
853
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100854/*
855 * Set padding for an existing RSA context
856 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100858{
859 ctx->padding = padding;
860 ctx->hash_id = hash_id;
861}
862
Hanno Becker617c1ae2017-08-23 14:11:24 +0100863/*
864 * Get length in bytes of RSA modulus
865 */
866
867size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
868{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100869 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100870}
871
872
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
875/*
876 * Generate an RSA keypair
877 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000879 int (*f_rng)(void *, unsigned char *, size_t),
880 void *p_rng,
881 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000882{
883 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100884 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
Paul Bakker21eb2802010-08-16 11:10:02 +0000886 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
Janos Follathef441782016-09-21 13:18:12 +0100889 if( nbits % 2 )
890 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
891
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100892 mbedtls_mpi_init( &H );
893 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
895 /*
896 * find primes P and Q with Q < P so that:
897 * GCD( E, (P-1)*(Q-1) ) == 1
898 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
901 do
902 {
Janos Follath10c575b2016-02-23 14:42:48 +0000903 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100904 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
Janos Follathef441782016-09-21 13:18:12 +0100906 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100907 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000910 continue;
911
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200913 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 continue;
915
Janos Follathef441782016-09-21 13:18:12 +0100916 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100917 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100918
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100919 /* Temporarily replace P,Q by P-1, Q-1 */
920 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
921 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
922 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100927 /* Restore P,Q */
928 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
929 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
930
931 ctx->len = mbedtls_mpi_size( &ctx->N );
932
Paul Bakker5121ce52009-01-03 21:22:43 +0000933 /*
934 * D = E^-1 mod ((P-1)*(Q-1))
935 * DP = D mod (P - 1)
936 * DQ = D mod (Q - 1)
937 * QP = Q^-1 mod P
938 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100940 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
941
942#if !defined(MBEDTLS_RSA_NO_CRT)
943 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
944 &ctx->DP, &ctx->DQ, &ctx->QP ) );
945#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
Hanno Becker83aad1f2017-08-23 06:45:10 +0100947 /* Double-check */
948 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
949
Paul Bakker5121ce52009-01-03 21:22:43 +0000950cleanup:
951
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100952 mbedtls_mpi_free( &H );
953 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000954
955 if( ret != 0 )
956 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 mbedtls_rsa_free( ctx );
958 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 }
960
Paul Bakker48377d92013-08-30 12:06:24 +0200961 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962}
963
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000965
966/*
967 * Check a public RSA key
968 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000970{
Hanno Becker98838b02017-10-02 13:16:10 +0100971 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
972 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
973 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100975 }
Paul Bakker37940d9f2009-07-10 22:38:58 +0000976
Hanno Beckerba1ba112017-09-29 11:48:23 +0100977 if( ctx->len != mbedtls_mpi_size( &ctx->N ) )
978 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
979
Hanno Becker98838b02017-10-02 13:16:10 +0100980 if( mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 ||
981 mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 )
982 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100984 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000985
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200986 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
987 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Hanno Becker98838b02017-10-02 13:16:10 +0100988 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100990 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000991
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200992 if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100994 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100996 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
998 return( 0 );
999}
1000
1001/*
1002 * Check a private RSA key
1003 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001005{
Hanno Becker98838b02017-10-02 13:16:10 +01001006 if( mbedtls_rsa_check_pubkey( ctx ) != 0 )
1007 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1008
1009 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +01001010 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 {
Hanno Beckerb269a852017-08-25 08:03:21 +01001012 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013 }
Hanno Beckerb269a852017-08-25 08:03:21 +01001014#if !defined(MBEDTLS_RSA_NO_CRT)
1015 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
1016 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
1017 {
1018 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
1019 }
1020#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +00001021
1022 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001023}
1024
1025/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001026 * Check if contexts holding a public and private key match
1027 */
Hanno Becker98838b02017-10-02 13:16:10 +01001028int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
1029 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001030{
Hanno Becker98838b02017-10-02 13:16:10 +01001031 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001033 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001035 }
1036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
1038 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001039 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +01001041 }
1042
1043 return( 0 );
1044}
1045
1046/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 * Do an RSA public key operation
1048 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001050 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 unsigned char *output )
1052{
Paul Bakker23986e52011-04-24 08:57:21 +00001053 int ret;
1054 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001058
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001059#if defined(MBEDTLS_THREADING_C)
1060 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1061 return( ret );
1062#endif
1063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001065
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001068 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1069 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 }
1071
1072 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
1074 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
1076cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001078 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1079 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +01001080#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
1084 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001086
1087 return( 0 );
1088}
1089
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001090/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001091 * Generate or update blinding values, see section 10 of:
1092 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +02001093 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001094 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001095 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001096static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001097 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1098{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001099 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001100
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001101 if( ctx->Vf.p != NULL )
1102 {
1103 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
1105 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
1106 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
1107 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001108
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001109 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +02001110 }
1111
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001112 /* Unblinding value: Vf = random number, invertible mod N */
1113 do {
1114 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +02001116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
1118 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1119 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001120
1121 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001122 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
1123 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 +02001124
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001125
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001126cleanup:
1127 return( ret );
1128}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001129
Paul Bakker5121ce52009-01-03 21:22:43 +00001130/*
Janos Follathe81102e2017-03-22 13:38:28 +00001131 * Exponent blinding supposed to prevent side-channel attacks using multiple
1132 * traces of measurements to recover the RSA key. The more collisions are there,
1133 * the more bits of the key can be recovered. See [3].
1134 *
1135 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
1136 * observations on avarage.
1137 *
1138 * For example with 28 byte blinding to achieve 2 collisions the adversary has
1139 * to make 2^112 observations on avarage.
1140 *
1141 * (With the currently (as of 2017 April) known best algorithms breaking 2048
1142 * bit RSA requires approximately as much time as trying out 2^112 random keys.
1143 * Thus in this sense with 28 byte blinding the security is not reduced by
1144 * side-channel attacks like the one in [3])
1145 *
1146 * This countermeasure does not help if the key recovery is possible with a
1147 * single trace.
1148 */
1149#define RSA_EXPONENT_BLINDING 28
1150
1151/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 * Do an RSA private key operation
1153 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001154int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001155 int (*f_rng)(void *, unsigned char *, size_t),
1156 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001157 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001158 unsigned char *output )
1159{
Paul Bakker23986e52011-04-24 08:57:21 +00001160 int ret;
1161 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +00001163 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +00001164#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001165 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001166 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +00001167#else
1168 mbedtls_mpi DP_blind, DQ_blind;
1169 mbedtls_mpi *DP = &ctx->DP;
1170 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +00001171#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001172
Hanno Becker45037ce2017-08-25 11:03:34 +01001173 /* Sanity-check that all relevant fields are at least set,
1174 * but don't perform a full keycheck. */
1175 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) == 0 ||
1176 mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ||
1177 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) == 0 ||
1178 mbedtls_mpi_cmp_int( &ctx->D, 0 ) == 0 ||
1179 mbedtls_mpi_cmp_int( &ctx->E, 0 ) == 0 )
1180 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001181 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Becker45037ce2017-08-25 11:03:34 +01001182 }
1183#if !defined(MBEDTLS_RSA_NO_CRT)
1184 if( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) == 0 ||
1185 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) == 0 ||
1186 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) == 0 )
1187 {
1188 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1189 }
1190#endif /* MBEDTLS_RSA_NO_CRT */
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +01001191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001193 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
1194
Janos Follathf9203b42017-03-22 15:13:15 +00001195 if( f_rng != NULL )
1196 {
Janos Follathe81102e2017-03-22 13:38:28 +00001197#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001198 mbedtls_mpi_init( &D_blind );
1199#else
1200 mbedtls_mpi_init( &DP_blind );
1201 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001202#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001203 }
Janos Follathe81102e2017-03-22 13:38:28 +00001204
Paul Bakker5121ce52009-01-03 21:22:43 +00001205
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001206#if defined(MBEDTLS_THREADING_C)
1207 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
1208 return( ret );
1209#endif
1210
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
1212 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001214 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1215 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001216 }
1217
Paul Bakkerf451bac2013-08-30 15:37:02 +02001218 if( f_rng != NULL )
1219 {
1220 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001221 * Blinding
1222 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001223 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001224 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
1225 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +00001227
Janos Follathe81102e2017-03-22 13:38:28 +00001228 /*
1229 * Exponent blinding
1230 */
1231 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1232 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1233
Janos Follathf9203b42017-03-22 15:13:15 +00001234#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001235 /*
1236 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1237 */
1238 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1239 f_rng, p_rng ) );
1240 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1241 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1242 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1243
1244 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001245#else
1246 /*
1247 * DP_blind = ( P - 1 ) * R + DP
1248 */
1249 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1250 f_rng, p_rng ) );
1251 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1252 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1253 &ctx->DP ) );
1254
1255 DP = &DP_blind;
1256
1257 /*
1258 * DQ_blind = ( Q - 1 ) * R + DQ
1259 */
1260 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1261 f_rng, p_rng ) );
1262 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1263 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1264 &ctx->DQ ) );
1265
1266 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001267#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +02001268 }
Paul Bakkeraab30c12013-08-30 11:00:25 +02001269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001271 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001272#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001273 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001274 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 *
1276 * T1 = input ^ dP mod P
1277 * T2 = input ^ dQ mod Q
1278 */
Janos Follathf9203b42017-03-22 15:13:15 +00001279 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
1280 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001281
1282 /*
1283 * T = (T1 - T2) * (Q^-1 mod P) mod P
1284 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001285 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
1286 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
1287 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288
1289 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +02001290 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
1293 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
1294#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001295
Paul Bakkerf451bac2013-08-30 15:37:02 +02001296 if( f_rng != NULL )
1297 {
1298 /*
1299 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001300 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +02001301 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001302 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001303 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +02001304 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001305
1306 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001308
1309cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001311 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1312 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001313#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001315 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +00001316 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
1317
1318 if( f_rng != NULL )
1319 {
Janos Follathe81102e2017-03-22 13:38:28 +00001320#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +00001321 mbedtls_mpi_free( &D_blind );
1322#else
1323 mbedtls_mpi_free( &DP_blind );
1324 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001325#endif
Janos Follathf9203b42017-03-22 15:13:15 +00001326 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
1328 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330
1331 return( 0 );
1332}
1333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001334#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001335/**
1336 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1337 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001338 * \param dst buffer to mask
1339 * \param dlen length of destination buffer
1340 * \param src source of the mask generation
1341 * \param slen length of the source buffer
1342 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001343 */
Paul Bakker48377d92013-08-30 12:06:24 +02001344static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001346{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001348 unsigned char counter[4];
1349 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001350 unsigned int hlen;
1351 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001354 memset( counter, 0, 4 );
1355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001357
Simon Butcher02037452016-03-01 21:19:12 +00001358 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001359 p = dst;
1360
1361 while( dlen > 0 )
1362 {
1363 use_len = hlen;
1364 if( dlen < hlen )
1365 use_len = dlen;
1366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367 mbedtls_md_starts( md_ctx );
1368 mbedtls_md_update( md_ctx, src, slen );
1369 mbedtls_md_update( md_ctx, counter, 4 );
1370 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001371
1372 for( i = 0; i < use_len; ++i )
1373 *p++ ^= mask[i];
1374
1375 counter[3]++;
1376
1377 dlen -= use_len;
1378 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001379
1380 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001381}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001383
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001385/*
1386 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1387 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001389 int (*f_rng)(void *, unsigned char *, size_t),
1390 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001391 int mode,
1392 const unsigned char *label, size_t label_len,
1393 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001394 const unsigned char *input,
1395 unsigned char *output )
1396{
1397 size_t olen;
1398 int ret;
1399 unsigned char *p = output;
1400 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001401 const mbedtls_md_info_t *md_info;
1402 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1405 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001406
1407 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001409
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001411 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001412 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001413
1414 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001416
Simon Butcher02037452016-03-01 21:19:12 +00001417 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001418 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001420
1421 memset( output, 0, olen );
1422
1423 *p++ = 0;
1424
Simon Butcher02037452016-03-01 21:19:12 +00001425 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001426 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001428
1429 p += hlen;
1430
Simon Butcher02037452016-03-01 21:19:12 +00001431 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001433 p += hlen;
1434 p += olen - 2 * hlen - 2 - ilen;
1435 *p++ = 1;
1436 memcpy( p, input, ilen );
1437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001438 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001439 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1440 {
1441 mbedtls_md_free( &md_ctx );
1442 return( ret );
1443 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001444
Simon Butcher02037452016-03-01 21:19:12 +00001445 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001446 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1447 &md_ctx );
1448
Simon Butcher02037452016-03-01 21:19:12 +00001449 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001450 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1451 &md_ctx );
1452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001455 return( ( mode == MBEDTLS_RSA_PUBLIC )
1456 ? mbedtls_rsa_public( ctx, output, output )
1457 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001458}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001462/*
1463 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1464 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001466 int (*f_rng)(void *, unsigned char *, size_t),
1467 void *p_rng,
1468 int mode, size_t ilen,
1469 const unsigned char *input,
1470 unsigned char *output )
1471{
1472 size_t nb_pad, olen;
1473 int ret;
1474 unsigned char *p = output;
1475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1477 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001478
Janos Follath1ed9f992016-03-18 11:45:44 +00001479 // We don't check p_rng because it won't be dereferenced here
1480 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001481 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001482
1483 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001484
Simon Butcher02037452016-03-01 21:19:12 +00001485 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001486 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001488
1489 nb_pad = olen - 3 - ilen;
1490
1491 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001493 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001495
1496 while( nb_pad-- > 0 )
1497 {
1498 int rng_dl = 100;
1499
1500 do {
1501 ret = f_rng( p_rng, p, 1 );
1502 } while( *p == 0 && --rng_dl && ret == 0 );
1503
Simon Butcher02037452016-03-01 21:19:12 +00001504 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001505 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001507
1508 p++;
1509 }
1510 }
1511 else
1512 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001514
1515 while( nb_pad-- > 0 )
1516 *p++ = 0xFF;
1517 }
1518
1519 *p++ = 0;
1520 memcpy( p, input, ilen );
1521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522 return( ( mode == MBEDTLS_RSA_PUBLIC )
1523 ? mbedtls_rsa_public( ctx, output, output )
1524 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001525}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001527
Paul Bakker5121ce52009-01-03 21:22:43 +00001528/*
1529 * Add the message padding, then do an RSA operation
1530 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001532 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001533 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001534 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001535 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001536 unsigned char *output )
1537{
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 switch( ctx->padding )
1539 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#if defined(MBEDTLS_PKCS1_V15)
1541 case MBEDTLS_RSA_PKCS_V15:
1542 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001543 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001544#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546#if defined(MBEDTLS_PKCS1_V21)
1547 case MBEDTLS_RSA_PKCS_V21:
1548 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001549 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001550#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001551
1552 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001554 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001555}
1556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001558/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001559 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001560 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001561int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001562 int (*f_rng)(void *, unsigned char *, size_t),
1563 void *p_rng,
1564 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001565 const unsigned char *label, size_t label_len,
1566 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001567 const unsigned char *input,
1568 unsigned char *output,
1569 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001570{
Paul Bakker23986e52011-04-24 08:57:21 +00001571 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001572 size_t ilen, i, pad_len;
1573 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001574 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1575 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001576 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577 const mbedtls_md_info_t *md_info;
1578 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001579
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001580 /*
1581 * Parameters sanity checks
1582 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1584 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001585
1586 ilen = ctx->len;
1587
Paul Bakker27fdf462011-06-09 13:55:13 +00001588 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001590
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001591 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001592 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001593 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001594
Janos Follathc17cda12016-02-11 11:08:18 +00001595 hlen = mbedtls_md_get_size( md_info );
1596
1597 // checking for integer underflow
1598 if( 2 * hlen + 2 > ilen )
1599 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1600
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001601 /*
1602 * RSA operation
1603 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001604 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1605 ? mbedtls_rsa_public( ctx, input, buf )
1606 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001607
1608 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001609 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001610
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001611 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001612 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001613 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001615 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1616 {
1617 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001618 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001619 }
1620
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001621
1622 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001623 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001624
1625 /* seed: Apply seedMask to maskedSeed */
1626 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1627 &md_ctx );
1628
1629 /* DB: Apply dbMask to maskedDB */
1630 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1631 &md_ctx );
1632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001633 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001634
1635 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001636 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001637 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001638 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001639 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001640
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001641 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001642
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001643 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001644
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001645 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001646 for( i = 0; i < hlen; i++ )
1647 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001648
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001649 /* Get zero-padding len, but always read till end of buffer
1650 * (minus one, for the 01 byte) */
1651 pad_len = 0;
1652 pad_done = 0;
1653 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1654 {
1655 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001656 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001657 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001658
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001659 p += pad_len;
1660 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001661
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001662 /*
1663 * The only information "leaked" is whether the padding was correct or not
1664 * (eg, no data is copied if it was not correct). This meets the
1665 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1666 * the different error conditions.
1667 */
1668 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001669 {
1670 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1671 goto cleanup;
1672 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001673
Paul Bakker66d5d072014-06-17 16:39:18 +02001674 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001675 {
1676 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1677 goto cleanup;
1678 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001679
1680 *olen = ilen - (p - buf);
1681 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001682 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001683
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001684cleanup:
1685 mbedtls_zeroize( buf, sizeof( buf ) );
1686 mbedtls_zeroize( lhash, sizeof( lhash ) );
1687
1688 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001689}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001690#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001692#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001693/*
1694 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1695 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001696int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001697 int (*f_rng)(void *, unsigned char *, size_t),
1698 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001699 int mode, size_t *olen,
1700 const unsigned char *input,
1701 unsigned char *output,
1702 size_t output_max_len)
1703{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001704 int ret;
1705 size_t ilen, pad_count = 0, i;
1706 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001707 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001709 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1710 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001711
1712 ilen = ctx->len;
1713
1714 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001715 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001717 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1718 ? mbedtls_rsa_public( ctx, input, buf )
1719 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001720
1721 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001722 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001723
1724 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001725 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001726
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001727 /*
1728 * Check and get padding len in "constant-time"
1729 */
1730 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001731
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001732 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001733 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001734 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001735 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001736
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001737 /* Get padding len, but always read till end of buffer
1738 * (minus one, for the 00 byte) */
1739 for( i = 0; i < ilen - 3; i++ )
1740 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001741 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1742 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001743 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001744
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001745 p += pad_count;
1746 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001747 }
1748 else
1749 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001750 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001751
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001752 /* Get padding len, but always read till end of buffer
1753 * (minus one, for the 00 byte) */
1754 for( i = 0; i < ilen - 3; i++ )
1755 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001756 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001757 pad_count += ( pad_done == 0 );
1758 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001759
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001760 p += pad_count;
1761 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001762 }
1763
Janos Follathc69fa502016-02-12 13:30:09 +00001764 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001765
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001766 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001767 {
1768 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1769 goto cleanup;
1770 }
Paul Bakker8804f692013-02-28 18:06:26 +01001771
Paul Bakker66d5d072014-06-17 16:39:18 +02001772 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001773 {
1774 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1775 goto cleanup;
1776 }
Paul Bakker060c5682009-01-12 21:48:39 +00001777
Paul Bakker27fdf462011-06-09 13:55:13 +00001778 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001779 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001780 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001781
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001782cleanup:
1783 mbedtls_zeroize( buf, sizeof( buf ) );
1784
1785 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001786}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001788
1789/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001790 * Do an RSA operation, then remove the message padding
1791 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001792int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001793 int (*f_rng)(void *, unsigned char *, size_t),
1794 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001795 int mode, size_t *olen,
1796 const unsigned char *input,
1797 unsigned char *output,
1798 size_t output_max_len)
1799{
1800 switch( ctx->padding )
1801 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001802#if defined(MBEDTLS_PKCS1_V15)
1803 case MBEDTLS_RSA_PKCS_V15:
1804 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001805 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001806#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001808#if defined(MBEDTLS_PKCS1_V21)
1809 case MBEDTLS_RSA_PKCS_V21:
1810 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001811 olen, input, output,
1812 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001813#endif
1814
1815 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001816 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001817 }
1818}
1819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001820#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001821/*
1822 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1823 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001824int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001825 int (*f_rng)(void *, unsigned char *, size_t),
1826 void *p_rng,
1827 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001829 unsigned int hashlen,
1830 const unsigned char *hash,
1831 unsigned char *sig )
1832{
1833 size_t olen;
1834 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001836 unsigned int slen, hlen, offset = 0;
1837 int ret;
1838 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 const mbedtls_md_info_t *md_info;
1840 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1843 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001844
1845 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001846 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001847
1848 olen = ctx->len;
1849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001851 {
Simon Butcher02037452016-03-01 21:19:12 +00001852 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001853 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001854 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001857 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001858 }
1859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001861 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001862 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001865 slen = hlen;
1866
1867 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001869
1870 memset( sig, 0, olen );
1871
Simon Butcher02037452016-03-01 21:19:12 +00001872 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001873 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001874 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001875
Simon Butcher02037452016-03-01 21:19:12 +00001876 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001877 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001878 p += olen - hlen * 2 - 2;
1879 *p++ = 0x01;
1880 memcpy( p, salt, slen );
1881 p += slen;
1882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001883 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001884 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1885 {
1886 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001887 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001888 return( ret );
1889 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001890
Simon Butcher02037452016-03-01 21:19:12 +00001891 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001892 mbedtls_md_starts( &md_ctx );
1893 mbedtls_md_update( &md_ctx, p, 8 );
1894 mbedtls_md_update( &md_ctx, hash, hashlen );
1895 mbedtls_md_update( &md_ctx, salt, slen );
1896 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001897 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001898
Simon Butcher02037452016-03-01 21:19:12 +00001899 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001900 if( msb % 8 == 0 )
1901 offset = 1;
1902
Simon Butcher02037452016-03-01 21:19:12 +00001903 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001904 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001907
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001908 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001909 sig[0] &= 0xFF >> ( olen * 8 - msb );
1910
1911 p += hlen;
1912 *p++ = 0xBC;
1913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001914 return( ( mode == MBEDTLS_RSA_PUBLIC )
1915 ? mbedtls_rsa_public( ctx, sig, sig )
1916 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001917}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001918#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001920#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001921/*
1922 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1923 */
1924/*
1925 * Do an RSA operation to sign the message digest
1926 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001927int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001928 int (*f_rng)(void *, unsigned char *, size_t),
1929 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001930 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001932 unsigned int hashlen,
1933 const unsigned char *hash,
1934 unsigned char *sig )
1935{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001936 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001937 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001938 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001939 unsigned char *sig_try = NULL, *verif = NULL;
1940 size_t i;
1941 unsigned char diff;
1942 volatile unsigned char diff_no_optimize;
1943 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1946 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001947
1948 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001949 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001950
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001951 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001952 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001953 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001954 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001955 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001956
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001957 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1958 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001959
Paul Bakkerc70b9822013-04-07 22:00:46 +02001960 nb_pad -= 10 + oid_size;
1961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001962 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001963 }
1964
Paul Bakkerc70b9822013-04-07 22:00:46 +02001965 nb_pad -= hashlen;
1966
Paul Bakkerb3869132013-02-28 17:21:01 +01001967 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001968 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001969
1970 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001971 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001972 memset( p, 0xFF, nb_pad );
1973 p += nb_pad;
1974 *p++ = 0;
1975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001976 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001977 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001978 memcpy( p, hash, hashlen );
1979 }
1980 else
1981 {
1982 /*
1983 * DigestInfo ::= SEQUENCE {
1984 * digestAlgorithm DigestAlgorithmIdentifier,
1985 * digest Digest }
1986 *
1987 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1988 *
1989 * Digest ::= OCTET STRING
1990 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001992 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001994 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001996 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001997 memcpy( p, oid, oid_size );
1998 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002000 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002002 *p++ = hashlen;
2003 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01002004 }
2005
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002006 if( mode == MBEDTLS_RSA_PUBLIC )
2007 return( mbedtls_rsa_public( ctx, sig, sig ) );
2008
2009 /*
2010 * In order to prevent Lenstra's attack, make the signature in a
2011 * temporary buffer and check it before returning it.
2012 */
2013 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00002014 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002015 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2016
Simon Butcher1285ab52016-01-01 21:42:47 +00002017 verif = mbedtls_calloc( 1, ctx->len );
2018 if( verif == NULL )
2019 {
2020 mbedtls_free( sig_try );
2021 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2022 }
2023
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002024 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2025 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2026
2027 /* Compare in constant time just in case */
2028 for( diff = 0, i = 0; i < ctx->len; i++ )
2029 diff |= verif[i] ^ sig[i];
2030 diff_no_optimize = diff;
2031
2032 if( diff_no_optimize != 0 )
2033 {
2034 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2035 goto cleanup;
2036 }
2037
2038 memcpy( sig, sig_try, ctx->len );
2039
2040cleanup:
2041 mbedtls_free( sig_try );
2042 mbedtls_free( verif );
2043
2044 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002045}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002046#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002047
2048/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 * Do an RSA operation to sign the message digest
2050 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002051int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002052 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002053 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00002054 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002055 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002056 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002057 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002058 unsigned char *sig )
2059{
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 switch( ctx->padding )
2061 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002062#if defined(MBEDTLS_PKCS1_V15)
2063 case MBEDTLS_RSA_PKCS_V15:
2064 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002065 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002066#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#if defined(MBEDTLS_PKCS1_V21)
2069 case MBEDTLS_RSA_PKCS_V21:
2070 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002071 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002072#endif
2073
Paul Bakker5121ce52009-01-03 21:22:43 +00002074 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002075 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002077}
2078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002079#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002080/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002081 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002082 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002083int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002084 int (*f_rng)(void *, unsigned char *, size_t),
2085 void *p_rng,
2086 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002087 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002088 unsigned int hashlen,
2089 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002090 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002091 int expected_salt_len,
2092 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002093{
Paul Bakker23986e52011-04-24 08:57:21 +00002094 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01002095 size_t siglen;
2096 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00002098 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00002099 unsigned int hlen;
2100 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101 const mbedtls_md_info_t *md_info;
2102 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002103 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2106 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002107
Paul Bakker5121ce52009-01-03 21:22:43 +00002108 siglen = ctx->len;
2109
Paul Bakker27fdf462011-06-09 13:55:13 +00002110 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002111 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2114 ? mbedtls_rsa_public( ctx, sig, buf )
2115 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002116
2117 if( ret != 0 )
2118 return( ret );
2119
2120 p = buf;
2121
Paul Bakkerb3869132013-02-28 17:21:01 +01002122 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002125 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 {
Simon Butcher02037452016-03-01 21:19:12 +00002127 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002128 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002129 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002132 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01002133 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002134
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002135 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01002136 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002137 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002139 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002140 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00002141
Paul Bakkerb3869132013-02-28 17:21:01 +01002142 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00002143
Simon Butcher02037452016-03-01 21:19:12 +00002144 /*
2145 * Note: EMSA-PSS verification is over the length of N - 1 bits
2146 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002147 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002148
Simon Butcher02037452016-03-01 21:19:12 +00002149 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002150 if( msb % 8 == 0 )
2151 {
2152 p++;
2153 siglen -= 1;
2154 }
2155 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002156 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002158 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07002159 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2160 {
2161 mbedtls_md_free( &md_ctx );
2162 return( ret );
2163 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002164
Paul Bakkerb3869132013-02-28 17:21:01 +01002165 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01002166
Paul Bakkerb3869132013-02-28 17:21:01 +01002167 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002168
Paul Bakker4de44aa2013-12-31 11:43:01 +01002169 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002170 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002171
Paul Bakkerb3869132013-02-28 17:21:01 +01002172 if( p == buf + siglen ||
2173 *p++ != 0x01 )
2174 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 mbedtls_md_free( &md_ctx );
2176 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002177 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002178
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002179 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01002180 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002183 slen != (size_t) expected_salt_len )
2184 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185 mbedtls_md_free( &md_ctx );
2186 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002187 }
2188
Simon Butcher02037452016-03-01 21:19:12 +00002189 /*
2190 * Generate H = Hash( M' )
2191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002192 mbedtls_md_starts( &md_ctx );
2193 mbedtls_md_update( &md_ctx, zeros, 8 );
2194 mbedtls_md_update( &md_ctx, hash, hashlen );
2195 mbedtls_md_update( &md_ctx, p, slen );
2196 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00002197
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002198 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002199
Paul Bakkerb3869132013-02-28 17:21:01 +01002200 if( memcmp( p + slen, result, hlen ) == 0 )
2201 return( 0 );
2202 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002203 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01002204}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002205
2206/*
2207 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2208 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002209int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002210 int (*f_rng)(void *, unsigned char *, size_t),
2211 void *p_rng,
2212 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002213 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002214 unsigned int hashlen,
2215 const unsigned char *hash,
2216 const unsigned char *sig )
2217{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002218 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2219 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002220 : md_alg;
2221
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002222 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002223 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002224 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002225 sig ) );
2226
2227}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002228#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002230#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002231/*
2232 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2233 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002234int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002235 int (*f_rng)(void *, unsigned char *, size_t),
2236 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002237 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002238 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002239 unsigned int hashlen,
2240 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002241 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002242{
2243 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002244 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002245 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246 mbedtls_md_type_t msg_md_alg;
2247 const mbedtls_md_info_t *md_info;
2248 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01002249 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01002250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2252 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002253
2254 siglen = ctx->len;
2255
2256 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002257 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259 ret = ( mode == MBEDTLS_RSA_PUBLIC )
2260 ? mbedtls_rsa_public( ctx, sig, buf )
2261 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01002262
2263 if( ret != 0 )
2264 return( ret );
2265
2266 p = buf;
2267
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002268 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
2269 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002270
2271 while( *p != 0 )
2272 {
2273 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002274 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002275 p++;
2276 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02002277 p++; /* skip 00 byte */
2278
2279 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
2280 if( p - buf < 11 )
2281 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002282
2283 len = siglen - ( p - buf );
2284
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002285 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01002286 {
2287 if( memcmp( p, hash, hashlen ) == 0 )
2288 return( 0 );
2289 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002290 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00002291 }
2292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002293 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002294 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2296 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002297
2298 end = p + len;
2299
Simon Butcher02037452016-03-01 21:19:12 +00002300 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02002301 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
2302 * Insist on 2-byte length tags, to protect against variants of
2303 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00002304 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002305 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002306 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2307 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2308 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002309 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002310 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002311
Gilles Peskinee7e76502017-05-04 12:48:39 +02002312 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002313 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
2314 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
2315 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002316 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002318
Gilles Peskinee7e76502017-05-04 12:48:39 +02002319 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
2321 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002322 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002323 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002324
2325 oid.p = p;
2326 p += oid.len;
2327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002328 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
2329 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002330
2331 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002332 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002333
2334 /*
2335 * assume the algorithm parameters must be NULL
2336 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02002337 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
2339 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02002340 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002341 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002342
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002343 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002344 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
2345 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02002346 if( p != p0 + 2 || asn1_len != hashlen )
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 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002350 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002351
2352 p += hashlen;
2353
2354 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002355 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002356
2357 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002358}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002360
2361/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002362 * Do an RSA operation and check the message digest
2363 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002365 int (*f_rng)(void *, unsigned char *, size_t),
2366 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002367 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002368 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002369 unsigned int hashlen,
2370 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002371 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002372{
2373 switch( ctx->padding )
2374 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002375#if defined(MBEDTLS_PKCS1_V15)
2376 case MBEDTLS_RSA_PKCS_V15:
2377 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002378 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002379#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002381#if defined(MBEDTLS_PKCS1_V21)
2382 case MBEDTLS_RSA_PKCS_V21:
2383 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002384 hashlen, hash, sig );
2385#endif
2386
2387 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002388 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002389 }
2390}
2391
2392/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002393 * Copy the components of an RSA key
2394 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002395int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002396{
2397 int ret;
2398
2399 dst->ver = src->ver;
2400 dst->len = src->len;
2401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002402 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2403 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002405 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2406 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2407 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002408
2409#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002410 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2411 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2412 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002413 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2414 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002415#endif
2416
2417 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2420 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002421
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002422 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002423 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002424
2425cleanup:
2426 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002427 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002428
2429 return( ret );
2430}
2431
2432/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002433 * Free the components of an RSA key
2434 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002435void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002436{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002437 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002438 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2439 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002440 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002441
Hanno Becker33c30a02017-08-23 07:00:22 +01002442#if !defined(MBEDTLS_RSA_NO_CRT)
2443 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2444 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2445 mbedtls_mpi_free( &ctx->DP );
2446#endif /* MBEDTLS_RSA_NO_CRT */
2447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002448#if defined(MBEDTLS_THREADING_C)
2449 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002450#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002451}
2452
Hanno Beckerab377312017-08-23 16:24:51 +01002453#endif /* !MBEDTLS_RSA_ALT */
2454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002455#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002456
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002457#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002458
2459/*
2460 * Example RSA-1024 keypair, for test purposes
2461 */
2462#define KEY_LEN 128
2463
2464#define RSA_N "9292758453063D803DD603D5E777D788" \
2465 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2466 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2467 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2468 "93A89813FBF3C4F8066D2D800F7C38A8" \
2469 "1AE31942917403FF4946B0A83D3D3E05" \
2470 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2471 "5E94BB77B07507233A0BC7BAC8F90F79"
2472
2473#define RSA_E "10001"
2474
2475#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2476 "66CA472BC44D253102F8B4A9D3BFA750" \
2477 "91386C0077937FE33FA3252D28855837" \
2478 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2479 "DF79C5CE07EE72C7F123142198164234" \
2480 "CABB724CF78B8173B9F880FC86322407" \
2481 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2482 "071513A1E85B5DFA031F21ECAE91A34D"
2483
2484#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2485 "2C01CAD19EA484A87EA4377637E75500" \
2486 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2487 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2488
2489#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2490 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2491 "910E4168387E3C30AA1E00C339A79508" \
2492 "8452DD96A9A5EA5D9DCA68DA636032AF"
2493
Paul Bakker5121ce52009-01-03 21:22:43 +00002494#define PT_LEN 24
2495#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2496 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002498#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002499static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002500{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002501#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002502 size_t i;
2503
Paul Bakker545570e2010-07-18 09:00:25 +00002504 if( rng_state != NULL )
2505 rng_state = NULL;
2506
Paul Bakkera3d195c2011-11-27 21:07:34 +00002507 for( i = 0; i < len; ++i )
2508 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002509#else
2510 if( rng_state != NULL )
2511 rng_state = NULL;
2512
2513 arc4random_buf( output, len );
2514#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002515
Paul Bakkera3d195c2011-11-27 21:07:34 +00002516 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002517}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002518#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002519
Paul Bakker5121ce52009-01-03 21:22:43 +00002520/*
2521 * Checkup routine
2522 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002523int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002524{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002525 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002526#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002527 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002528 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002529 unsigned char rsa_plaintext[PT_LEN];
2530 unsigned char rsa_decrypted[PT_LEN];
2531 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002532#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002533 unsigned char sha1sum[20];
2534#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002535
Hanno Becker3a701162017-08-22 13:52:43 +01002536 mbedtls_mpi K;
2537
2538 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002539 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002540
Hanno Becker3a701162017-08-22 13:52:43 +01002541 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2542 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2543 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2544 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2545 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2546 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2547 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2548 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2549 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2550 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2551
Hanno Becker7f25f852017-10-10 16:56:22 +01002552 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002553
2554 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002555 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002557 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2558 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002559 {
2560 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002561 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002562
2563 return( 1 );
2564 }
2565
2566 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002567 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002568
2569 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2570
Hanno Becker98838b02017-10-02 13:16:10 +01002571 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2572 PT_LEN, rsa_plaintext,
2573 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002574 {
2575 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002576 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002577
2578 return( 1 );
2579 }
2580
2581 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002582 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002583
Hanno Becker98838b02017-10-02 13:16:10 +01002584 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2585 &len, rsa_ciphertext, rsa_decrypted,
2586 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002587 {
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
2594 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2595 {
2596 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002597 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002598
2599 return( 1 );
2600 }
2601
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002602 if( verbose != 0 )
2603 mbedtls_printf( "passed\n" );
2604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002605#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002606 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002607 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002609 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002610
Hanno Becker98838b02017-10-02 13:16:10 +01002611 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2612 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2613 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002614 {
2615 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002616 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002617
2618 return( 1 );
2619 }
2620
2621 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002622 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002623
Hanno Becker98838b02017-10-02 13:16:10 +01002624 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2625 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2626 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002627 {
2628 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002629 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002630
2631 return( 1 );
2632 }
2633
2634 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002635 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002636#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002637
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002638 if( verbose != 0 )
2639 mbedtls_printf( "\n" );
2640
Paul Bakker3d8fb632014-04-17 12:42:41 +02002641cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002642 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002643 mbedtls_rsa_free( &rsa );
2644#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002645 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002646#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002647 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002648}
2649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002650#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002651
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002652#endif /* MBEDTLS_RSA_C */