blob: 3913e61d97cc8ca4399d20108c975931f185f2c1 [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"
Hanno Beckera565f542017-10-11 11:00:19 +010049#include "mbedtls/rsa_internal.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/oid.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000051
Rich Evans00ab4702015-02-06 13:43:58 +000052#include <string.h>
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if defined(MBEDTLS_PKCS1_V21)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/md.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000056#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
Paul Bakker5121ce52009-01-03 21:22:43 +000059#include <stdlib.h>
Rich Evans00ab4702015-02-06 13:43:58 +000060#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010064#else
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#define mbedtls_printf printf
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +020067#define mbedtls_calloc calloc
68#define mbedtls_free free
Paul Bakker7dc4c442014-02-01 22:50:26 +010069#endif
70
Hanno Beckera565f542017-10-11 11:00:19 +010071#if !defined(MBEDTLS_RSA_ALT)
72
Gilles Peskine4a7f6a02017-03-23 14:37:37 +010073/* Implementation that should never be optimized out by the compiler */
74static void mbedtls_zeroize( void *v, size_t n ) {
75 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
76}
77
Hanno Becker617c1ae2017-08-23 14:11:24 +010078int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
79 const mbedtls_mpi *N,
80 const mbedtls_mpi *P, const mbedtls_mpi *Q,
81 const mbedtls_mpi *D, const mbedtls_mpi *E )
82{
83 int ret;
84
85 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
86 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
87 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
88 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
89 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
90 {
91 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
92 }
93
94 if( N != NULL )
95 ctx->len = mbedtls_mpi_size( &ctx->N );
96
97 return( 0 );
98}
99
100int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
Hanno Becker74716312017-10-02 10:00:37 +0100101 unsigned char const *N, size_t N_len,
102 unsigned char const *P, size_t P_len,
103 unsigned char const *Q, size_t Q_len,
104 unsigned char const *D, size_t D_len,
105 unsigned char const *E, size_t E_len )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100106{
107 int ret;
108
109 if( N != NULL )
110 {
111 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
112 ctx->len = mbedtls_mpi_size( &ctx->N );
113 }
114
115 if( P != NULL )
116 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
117
118 if( Q != NULL )
119 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
120
121 if( D != NULL )
122 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
123
124 if( E != NULL )
125 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
126
127cleanup:
128
129 if( ret != 0 )
130 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
131
132 return( 0 );
133}
134
Hanno Becker705fc682017-10-10 17:57:02 +0100135/*
136 * Checks whether the context fields are set in such a way
137 * that the RSA primitives will be able to execute without error.
138 * It does *not* make guarantees for consistency of the parameters.
139 */
140static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv )
141{
142 if( ctx->len != mbedtls_mpi_size( &ctx->N ) )
143 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
144
145 /*
146 * 1. Modular exponentiation needs positive, odd moduli.
147 */
148
149 /* Modular exponentiation wrt. N is always used for
150 * RSA public key operations. */
151 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
152 mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
153 {
154 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
155 }
156
157#if !defined(MBEDTLS_RSA_NO_CRT)
158 /* Modular exponentiation for P and Q is only
159 * used for private key operations and if CRT
160 * is used. */
161 if( is_priv &&
162 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
163 mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
164 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
165 mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
166 {
167 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
168 }
169#endif /* !MBEDTLS_RSA_NO_CRT */
170
171 /*
172 * 2. Exponents must be positive
173 */
174
175 /* Always need E for public key operations */
176 if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
177 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
178
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100179#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100180 /* For private key operations, use D or DP & DQ
181 * as (unblinded) exponents. */
182 if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
183 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
184#else
185 if( is_priv &&
186 ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
187 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
188 {
189 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
190 }
191#endif /* MBEDTLS_RSA_NO_CRT */
192
193 /* Blinding shouldn't make exponents negative either,
194 * so check that P, Q >= 1 if that hasn't yet been
195 * done as part of 1. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100196#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100197 if( is_priv &&
198 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
199 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
200 {
201 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
202 }
203#endif
204
205 /* It wouldn't lead to an error if it wasn't satisfied,
206 * but check for PQ >= 1 nonetheless. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100207#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100208 if( is_priv &&
209 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
210 {
211 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
212 }
213#endif
214
215 return( 0 );
216}
217
Hanno Beckerf9e184b2017-10-10 16:49:26 +0100218int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100219{
220 int ret = 0;
221
Hanno Becker617c1ae2017-08-23 14:11:24 +0100222 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
223 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
224 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
225 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
226 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100227
Hanno Becker617c1ae2017-08-23 14:11:24 +0100228 /*
229 * Check whether provided parameters are enough
230 * to deduce all others. The following incomplete
231 * parameter sets for private keys are supported:
232 *
233 * (1) P, Q missing.
234 * (2) D and potentially N missing.
235 *
236 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100237
Hanno Becker2cca6f32017-09-29 11:46:40 +0100238 const int n_missing = have_P && have_Q && have_D && have_E;
239 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
240 const int d_missing = have_P && have_Q && !have_D && have_E;
241 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
242
243 /* These three alternatives are mutually exclusive */
244 const int is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100245
Hanno Becker617c1ae2017-08-23 14:11:24 +0100246 if( !is_priv && !is_pub )
247 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
248
249 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100250 * Step 1: Deduce N if P, Q are provided.
251 */
252
253 if( !have_N && have_P && have_Q )
254 {
255 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
256 &ctx->Q ) ) != 0 )
257 {
258 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
259 }
260
261 ctx->len = mbedtls_mpi_size( &ctx->N );
262 }
263
264 /*
265 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100266 */
267
268 if( pq_missing )
269 {
Hanno Becker0f65e0c2017-10-03 14:39:16 +0100270 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->D, &ctx->E,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100271 &ctx->P, &ctx->Q );
272 if( ret != 0 )
273 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
274
275 }
276 else if( d_missing )
277 {
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100278 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
279 &ctx->Q,
280 &ctx->E,
281 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100282 {
283 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
284 }
285 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100286
Hanno Becker617c1ae2017-08-23 14:11:24 +0100287 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100288 * Step 3: Deduce all additional parameters specific
Hanno Beckere8674892017-10-10 17:56:14 +0100289 * to our current RSA implementation.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100290 */
291
Hanno Becker23344b52017-08-23 07:43:27 +0100292#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100293 if( is_priv )
294 {
295 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
296 &ctx->DP, &ctx->DQ, &ctx->QP );
297 if( ret != 0 )
298 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
299 }
Hanno Becker23344b52017-08-23 07:43:27 +0100300#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100301
302 /*
Hanno Becker705fc682017-10-10 17:57:02 +0100303 * Step 3: Basic sanity checks
Hanno Becker617c1ae2017-08-23 14:11:24 +0100304 */
305
Hanno Becker705fc682017-10-10 17:57:02 +0100306 return( rsa_check_context( ctx, is_priv ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100307}
308
Hanno Becker617c1ae2017-08-23 14:11:24 +0100309int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
310 unsigned char *N, size_t N_len,
311 unsigned char *P, size_t P_len,
312 unsigned char *Q, size_t Q_len,
313 unsigned char *D, size_t D_len,
314 unsigned char *E, size_t E_len )
315{
316 int ret = 0;
317
318 /* Check if key is private or public */
319 const int is_priv =
320 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
321 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
322 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
323 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
324 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
325
326 if( !is_priv )
327 {
328 /* If we're trying to export private parameters for a public key,
329 * something must be wrong. */
330 if( P != NULL || Q != NULL || D != NULL )
331 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
332
333 }
334
335 if( N != NULL )
336 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
337
338 if( P != NULL )
339 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
340
341 if( Q != NULL )
342 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
343
344 if( D != NULL )
345 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
346
347 if( E != NULL )
348 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100349
350cleanup:
351
352 return( ret );
353}
354
Hanno Becker617c1ae2017-08-23 14:11:24 +0100355int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
356 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
357 mbedtls_mpi *D, mbedtls_mpi *E )
358{
359 int ret;
360
361 /* Check if key is private or public */
362 int is_priv =
363 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
364 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
365 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
366 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
367 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
368
369 if( !is_priv )
370 {
371 /* If we're trying to export private parameters for a public key,
372 * something must be wrong. */
373 if( P != NULL || Q != NULL || D != NULL )
374 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
375
376 }
377
378 /* Export all requested core parameters. */
379
380 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
381 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
382 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
383 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
384 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
385 {
386 return( ret );
387 }
388
389 return( 0 );
390}
391
392/*
393 * Export CRT parameters
394 * This must also be implemented if CRT is not used, for being able to
395 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
396 * can be used in this case.
397 */
398int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
399 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
400{
401 int ret;
402
403 /* Check if key is private or public */
404 int is_priv =
405 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
406 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
407 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
408 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
409 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
410
411 if( !is_priv )
412 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
413
Hanno Beckerdc95c892017-08-23 06:57:02 +0100414#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100415 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100416 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
417 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
418 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
419 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100420 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100421 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100422#else
423 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
424 DP, DQ, QP ) ) != 0 )
425 {
426 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
427 }
428#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100429
430 return( 0 );
431}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100432
433/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 * Initialize an RSA context
435 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000438 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000439{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#if defined(MBEDTLS_THREADING_C)
445 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200446#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000447}
448
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100449/*
450 * Set padding for an existing RSA context
451 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100453{
454 ctx->padding = padding;
455 ctx->hash_id = hash_id;
456}
457
Hanno Becker617c1ae2017-08-23 14:11:24 +0100458/*
459 * Get length in bytes of RSA modulus
460 */
461
462size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
463{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100464 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100465}
466
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470/*
471 * Generate an RSA keypair
472 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000474 int (*f_rng)(void *, unsigned char *, size_t),
475 void *p_rng,
476 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000477{
478 int ret;
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100479 mbedtls_mpi H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Paul Bakker21eb2802010-08-16 11:10:02 +0000481 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
Janos Follathef441782016-09-21 13:18:12 +0100484 if( nbits % 2 )
485 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
486
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100487 mbedtls_mpi_init( &H );
488 mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490 /*
491 * find primes P and Q with Q < P so that:
492 * GCD( E, (P-1)*(Q-1) ) == 1
493 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496 do
497 {
Janos Follath10c575b2016-02-23 14:42:48 +0000498 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100499 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Janos Follathef441782016-09-21 13:18:12 +0100501 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100502 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 continue;
506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200508 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000509 continue;
510
Janos Follathef441782016-09-21 13:18:12 +0100511 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100512 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100513
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100514 /* Temporarily replace P,Q by P-1, Q-1 */
515 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
516 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
517 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100522 /* Restore P,Q */
523 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
524 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
525
526 ctx->len = mbedtls_mpi_size( &ctx->N );
527
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 /*
529 * D = E^-1 mod ((P-1)*(Q-1))
530 * DP = D mod (P - 1)
531 * DQ = D mod (Q - 1)
532 * QP = Q^-1 mod P
533 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000534
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100535 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
536
537#if !defined(MBEDTLS_RSA_NO_CRT)
538 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
539 &ctx->DP, &ctx->DQ, &ctx->QP ) );
540#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
Hanno Becker83aad1f2017-08-23 06:45:10 +0100542 /* Double-check */
543 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
544
Paul Bakker5121ce52009-01-03 21:22:43 +0000545cleanup:
546
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100547 mbedtls_mpi_free( &H );
548 mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 if( ret != 0 )
551 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_rsa_free( ctx );
553 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000554 }
555
Paul Bakker48377d92013-08-30 12:06:24 +0200556 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000557}
558
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561/*
562 * Check a public RSA key
563 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000565{
Hanno Becker705fc682017-10-10 17:57:02 +0100566 if( rsa_check_context( ctx, 0 /* public */ ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000568
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200569 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
570 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Hanno Becker98838b02017-10-02 13:16:10 +0100571 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100573 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
Hanno Becker705fc682017-10-10 17:57:02 +0100575 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
576 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100578 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100580 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 return( 0 );
583}
584
585/*
Hanno Becker705fc682017-10-10 17:57:02 +0100586 * Check for the consistency of all fields in an RSA private key context
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000589{
Hanno Becker705fc682017-10-10 17:57:02 +0100590 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
591 rsa_check_context( ctx, 1 /* private */ ) != 0 )
592 {
Hanno Becker98838b02017-10-02 13:16:10 +0100593 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker705fc682017-10-10 17:57:02 +0100594 }
Hanno Becker98838b02017-10-02 13:16:10 +0100595
596 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +0100597 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 {
Hanno Beckerb269a852017-08-25 08:03:21 +0100599 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 }
Hanno Becker705fc682017-10-10 17:57:02 +0100601
Hanno Beckerb269a852017-08-25 08:03:21 +0100602#if !defined(MBEDTLS_RSA_NO_CRT)
603 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
604 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
605 {
606 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
607 }
608#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +0000609
610 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611}
612
613/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100614 * Check if contexts holding a public and private key match
615 */
Hanno Becker98838b02017-10-02 13:16:10 +0100616int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
617 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100618{
Hanno Becker98838b02017-10-02 13:16:10 +0100619 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100621 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100623 }
624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
626 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100627 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100629 }
630
631 return( 0 );
632}
633
634/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 * Do an RSA public key operation
636 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000638 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 unsigned char *output )
640{
Paul Bakker23986e52011-04-24 08:57:21 +0000641 int ret;
642 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
Hanno Becker705fc682017-10-10 17:57:02 +0100645 if( rsa_check_context( ctx, 0 /* public */ ) )
646 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200650#if defined(MBEDTLS_THREADING_C)
651 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
652 return( ret );
653#endif
654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000658 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200659 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
660 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 }
662
663 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
665 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200669 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
670 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +0100671#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 return( 0 );
679}
680
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200681/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200682 * Generate or update blinding values, see section 10 of:
683 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200684 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200685 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200686 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200687static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200688 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
689{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200690 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200691
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200692 if( ctx->Vf.p != NULL )
693 {
694 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
696 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
697 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
698 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200699
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200700 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200701 }
702
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200703 /* Unblinding value: Vf = random number, invertible mod N */
704 do {
705 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200707
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
709 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
710 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200711
712 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
714 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 +0200715
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200716
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200717cleanup:
718 return( ret );
719}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200720
Paul Bakker5121ce52009-01-03 21:22:43 +0000721/*
Janos Follathe81102e2017-03-22 13:38:28 +0000722 * Exponent blinding supposed to prevent side-channel attacks using multiple
723 * traces of measurements to recover the RSA key. The more collisions are there,
724 * the more bits of the key can be recovered. See [3].
725 *
726 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
727 * observations on avarage.
728 *
729 * For example with 28 byte blinding to achieve 2 collisions the adversary has
730 * to make 2^112 observations on avarage.
731 *
732 * (With the currently (as of 2017 April) known best algorithms breaking 2048
733 * bit RSA requires approximately as much time as trying out 2^112 random keys.
734 * Thus in this sense with 28 byte blinding the security is not reduced by
735 * side-channel attacks like the one in [3])
736 *
737 * This countermeasure does not help if the key recovery is possible with a
738 * single trace.
739 */
740#define RSA_EXPONENT_BLINDING 28
741
742/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000743 * Do an RSA private key operation
744 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200746 int (*f_rng)(void *, unsigned char *, size_t),
747 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000748 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 unsigned char *output )
750{
Paul Bakker23986e52011-04-24 08:57:21 +0000751 int ret;
752 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753 mbedtls_mpi T, T1, T2;
Janos Follathf9203b42017-03-22 15:13:15 +0000754 mbedtls_mpi P1, Q1, R;
Janos Follathe81102e2017-03-22 13:38:28 +0000755#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000756 mbedtls_mpi D_blind;
Janos Follathe81102e2017-03-22 13:38:28 +0000757 mbedtls_mpi *D = &ctx->D;
Janos Follathf9203b42017-03-22 15:13:15 +0000758#else
759 mbedtls_mpi DP_blind, DQ_blind;
760 mbedtls_mpi *DP = &ctx->DP;
761 mbedtls_mpi *DQ = &ctx->DQ;
Janos Follathe81102e2017-03-22 13:38:28 +0000762#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
Hanno Becker705fc682017-10-10 17:57:02 +0100764 if( rsa_check_context( ctx, 1 /* private */ ) != 0 )
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100765 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
766
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +0000768 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
769
Janos Follathf9203b42017-03-22 15:13:15 +0000770 if( f_rng != NULL )
771 {
Janos Follathe81102e2017-03-22 13:38:28 +0000772#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000773 mbedtls_mpi_init( &D_blind );
774#else
775 mbedtls_mpi_init( &DP_blind );
776 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000777#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000778 }
Janos Follathe81102e2017-03-22 13:38:28 +0000779
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200781#if defined(MBEDTLS_THREADING_C)
782 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
783 return( ret );
784#endif
785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
787 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200789 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
790 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 }
792
Paul Bakkerf451bac2013-08-30 15:37:02 +0200793 if( f_rng != NULL )
794 {
795 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200796 * Blinding
797 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200798 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200799 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
800 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000802
Janos Follathe81102e2017-03-22 13:38:28 +0000803 /*
804 * Exponent blinding
805 */
806 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
807 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
808
Janos Follathf9203b42017-03-22 15:13:15 +0000809#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000810 /*
811 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
812 */
813 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
814 f_rng, p_rng ) );
815 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
816 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
817 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
818
819 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +0000820#else
821 /*
822 * DP_blind = ( P - 1 ) * R + DP
823 */
824 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
825 f_rng, p_rng ) );
826 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
827 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
828 &ctx->DP ) );
829
830 DP = &DP_blind;
831
832 /*
833 * DQ_blind = ( Q - 1 ) * R + DQ
834 */
835 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
836 f_rng, p_rng ) );
837 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
838 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
839 &ctx->DQ ) );
840
841 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +0000842#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +0200843 }
Paul Bakkeraab30c12013-08-30 11:00:25 +0200844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000846 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +0100847#else
Paul Bakkeraab30c12013-08-30 11:00:25 +0200848 /*
Janos Follathe81102e2017-03-22 13:38:28 +0000849 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +0000850 *
851 * T1 = input ^ dP mod P
852 * T2 = input ^ dQ mod Q
853 */
Janos Follathf9203b42017-03-22 15:13:15 +0000854 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
855 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000856
857 /*
858 * T = (T1 - T2) * (Q^-1 mod P) mod P
859 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
861 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
862 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
864 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +0200865 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
868 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
869#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +0200870
Paul Bakkerf451bac2013-08-30 15:37:02 +0200871 if( f_rng != NULL )
872 {
873 /*
874 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200875 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200876 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200877 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +0200879 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
881 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
884cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200886 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
887 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200888#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200889
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Janos Follathf9203b42017-03-22 15:13:15 +0000891 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
892
893 if( f_rng != NULL )
894 {
Janos Follathe81102e2017-03-22 13:38:28 +0000895#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000896 mbedtls_mpi_free( &D_blind );
897#else
898 mbedtls_mpi_free( &DP_blind );
899 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000900#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000901 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
903 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000905
906 return( 0 );
907}
908
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +0000910/**
911 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
912 *
Paul Bakkerb125ed82011-11-10 13:33:51 +0000913 * \param dst buffer to mask
914 * \param dlen length of destination buffer
915 * \param src source of the mask generation
916 * \param slen length of the source buffer
917 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +0000918 */
Paul Bakker48377d92013-08-30 12:06:24 +0200919static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000921{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +0000923 unsigned char counter[4];
924 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +0000925 unsigned int hlen;
926 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000927
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000929 memset( counter, 0, 4 );
930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000932
Simon Butcher02037452016-03-01 21:19:12 +0000933 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +0000934 p = dst;
935
936 while( dlen > 0 )
937 {
938 use_len = hlen;
939 if( dlen < hlen )
940 use_len = dlen;
941
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 mbedtls_md_starts( md_ctx );
943 mbedtls_md_update( md_ctx, src, slen );
944 mbedtls_md_update( md_ctx, counter, 4 );
945 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000946
947 for( i = 0; i < use_len; ++i )
948 *p++ ^= mask[i];
949
950 counter[3]++;
951
952 dlen -= use_len;
953 }
Gilles Peskine18ac7162017-05-05 19:24:06 +0200954
955 mbedtls_zeroize( mask, sizeof( mask ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000956}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +0000958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +0100960/*
961 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
962 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +0100964 int (*f_rng)(void *, unsigned char *, size_t),
965 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +0100966 int mode,
967 const unsigned char *label, size_t label_len,
968 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +0100969 const unsigned char *input,
970 unsigned char *output )
971{
972 size_t olen;
973 int ret;
974 unsigned char *p = output;
975 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 const mbedtls_md_info_t *md_info;
977 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +0100978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
980 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +0200981
982 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +0100986 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100988
989 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +0100991
Simon Butcher02037452016-03-01 21:19:12 +0000992 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +0000993 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200994 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100995
996 memset( output, 0, olen );
997
998 *p++ = 0;
999
Simon Butcher02037452016-03-01 21:19:12 +00001000 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001001 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001003
1004 p += hlen;
1005
Simon Butcher02037452016-03-01 21:19:12 +00001006 /* Construct DB */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +01001008 p += hlen;
1009 p += olen - 2 * hlen - 2 - ilen;
1010 *p++ = 1;
1011 memcpy( p, input, ilen );
1012
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001014 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1015 {
1016 mbedtls_md_free( &md_ctx );
1017 return( ret );
1018 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001019
Simon Butcher02037452016-03-01 21:19:12 +00001020 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001021 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1022 &md_ctx );
1023
Simon Butcher02037452016-03-01 21:19:12 +00001024 /* maskedSeed: Apply seedMask to seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001025 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1026 &md_ctx );
1027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 return( ( mode == MBEDTLS_RSA_PUBLIC )
1031 ? mbedtls_rsa_public( ctx, output, output )
1032 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001033}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001037/*
1038 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1039 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001041 int (*f_rng)(void *, unsigned char *, size_t),
1042 void *p_rng,
1043 int mode, size_t ilen,
1044 const unsigned char *input,
1045 unsigned char *output )
1046{
1047 size_t nb_pad, olen;
1048 int ret;
1049 unsigned char *p = output;
1050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1052 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001053
Janos Follath1ed9f992016-03-18 11:45:44 +00001054 // We don't check p_rng because it won't be dereferenced here
1055 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001057
1058 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001059
Simon Butcher02037452016-03-01 21:19:12 +00001060 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001061 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001063
1064 nb_pad = olen - 3 - ilen;
1065
1066 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001068 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001070
1071 while( nb_pad-- > 0 )
1072 {
1073 int rng_dl = 100;
1074
1075 do {
1076 ret = f_rng( p_rng, p, 1 );
1077 } while( *p == 0 && --rng_dl && ret == 0 );
1078
Simon Butcher02037452016-03-01 21:19:12 +00001079 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001080 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001082
1083 p++;
1084 }
1085 }
1086 else
1087 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001089
1090 while( nb_pad-- > 0 )
1091 *p++ = 0xFF;
1092 }
1093
1094 *p++ = 0;
1095 memcpy( p, input, ilen );
1096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 return( ( mode == MBEDTLS_RSA_PUBLIC )
1098 ? mbedtls_rsa_public( ctx, output, output )
1099 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001100}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001102
Paul Bakker5121ce52009-01-03 21:22:43 +00001103/*
1104 * Add the message padding, then do an RSA operation
1105 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001107 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001108 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001109 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001110 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001111 unsigned char *output )
1112{
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 switch( ctx->padding )
1114 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#if defined(MBEDTLS_PKCS1_V15)
1116 case MBEDTLS_RSA_PKCS_V15:
1117 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001118 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001119#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121#if defined(MBEDTLS_PKCS1_V21)
1122 case MBEDTLS_RSA_PKCS_V21:
1123 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001124 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001125#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001126
1127 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001130}
1131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001133/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001134 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001137 int (*f_rng)(void *, unsigned char *, size_t),
1138 void *p_rng,
1139 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001140 const unsigned char *label, size_t label_len,
1141 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001142 const unsigned char *input,
1143 unsigned char *output,
1144 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145{
Paul Bakker23986e52011-04-24 08:57:21 +00001146 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001147 size_t ilen, i, pad_len;
1148 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001149 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1150 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001151 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152 const mbedtls_md_info_t *md_info;
1153 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001154
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001155 /*
1156 * Parameters sanity checks
1157 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1159 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001160
1161 ilen = ctx->len;
1162
Paul Bakker27fdf462011-06-09 13:55:13 +00001163 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001167 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001169
Janos Follathc17cda12016-02-11 11:08:18 +00001170 hlen = mbedtls_md_get_size( md_info );
1171
1172 // checking for integer underflow
1173 if( 2 * hlen + 2 > ilen )
1174 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1175
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001176 /*
1177 * RSA operation
1178 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001179 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1180 ? mbedtls_rsa_public( ctx, input, buf )
1181 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001182
1183 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001184 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001186 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001187 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001188 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001190 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1191 {
1192 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001193 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001194 }
1195
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001196
1197 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001199
1200 /* seed: Apply seedMask to maskedSeed */
1201 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1202 &md_ctx );
1203
1204 /* DB: Apply dbMask to maskedDB */
1205 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1206 &md_ctx );
1207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001208 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001209
1210 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001211 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001212 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001214 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001215
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001216 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001217
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001218 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001219
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001220 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001221 for( i = 0; i < hlen; i++ )
1222 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001223
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001224 /* Get zero-padding len, but always read till end of buffer
1225 * (minus one, for the 01 byte) */
1226 pad_len = 0;
1227 pad_done = 0;
1228 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1229 {
1230 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001231 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001232 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001233
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001234 p += pad_len;
1235 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001236
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001237 /*
1238 * The only information "leaked" is whether the padding was correct or not
1239 * (eg, no data is copied if it was not correct). This meets the
1240 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1241 * the different error conditions.
1242 */
1243 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001244 {
1245 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1246 goto cleanup;
1247 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001248
Paul Bakker66d5d072014-06-17 16:39:18 +02001249 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001250 {
1251 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1252 goto cleanup;
1253 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001254
1255 *olen = ilen - (p - buf);
1256 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001257 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001258
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001259cleanup:
1260 mbedtls_zeroize( buf, sizeof( buf ) );
1261 mbedtls_zeroize( lhash, sizeof( lhash ) );
1262
1263 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001264}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001265#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001268/*
1269 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1270 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001271int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001272 int (*f_rng)(void *, unsigned char *, size_t),
1273 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001274 int mode, size_t *olen,
1275 const unsigned char *input,
1276 unsigned char *output,
1277 size_t output_max_len)
1278{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001279 int ret;
1280 size_t ilen, pad_count = 0, i;
1281 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1285 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001286
1287 ilen = ctx->len;
1288
1289 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1293 ? mbedtls_rsa_public( ctx, input, buf )
1294 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001295
1296 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001297 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001298
1299 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001300 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001301
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001302 /*
1303 * Check and get padding len in "constant-time"
1304 */
1305 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001306
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001307 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001308 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001309 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001311
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001312 /* Get padding len, but always read till end of buffer
1313 * (minus one, for the 00 byte) */
1314 for( i = 0; i < ilen - 3; i++ )
1315 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001316 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1317 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001318 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001319
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001320 p += pad_count;
1321 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001322 }
1323 else
1324 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001325 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001326
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001327 /* Get padding len, but always read till end of buffer
1328 * (minus one, for the 00 byte) */
1329 for( i = 0; i < ilen - 3; i++ )
1330 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001331 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001332 pad_count += ( pad_done == 0 );
1333 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001334
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001335 p += pad_count;
1336 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 }
1338
Janos Follathc69fa502016-02-12 13:30:09 +00001339 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001340
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001341 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001342 {
1343 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1344 goto cleanup;
1345 }
Paul Bakker8804f692013-02-28 18:06:26 +01001346
Paul Bakker66d5d072014-06-17 16:39:18 +02001347 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001348 {
1349 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1350 goto cleanup;
1351 }
Paul Bakker060c5682009-01-12 21:48:39 +00001352
Paul Bakker27fdf462011-06-09 13:55:13 +00001353 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001355 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001356
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001357cleanup:
1358 mbedtls_zeroize( buf, sizeof( buf ) );
1359
1360 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001361}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001362#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001363
1364/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001365 * Do an RSA operation, then remove the message padding
1366 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001368 int (*f_rng)(void *, unsigned char *, size_t),
1369 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001370 int mode, size_t *olen,
1371 const unsigned char *input,
1372 unsigned char *output,
1373 size_t output_max_len)
1374{
1375 switch( ctx->padding )
1376 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377#if defined(MBEDTLS_PKCS1_V15)
1378 case MBEDTLS_RSA_PKCS_V15:
1379 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001380 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001381#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383#if defined(MBEDTLS_PKCS1_V21)
1384 case MBEDTLS_RSA_PKCS_V21:
1385 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001386 olen, input, output,
1387 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001388#endif
1389
1390 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001391 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001392 }
1393}
1394
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001395#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001396/*
1397 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1398 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001400 int (*f_rng)(void *, unsigned char *, size_t),
1401 void *p_rng,
1402 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001403 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001404 unsigned int hashlen,
1405 const unsigned char *hash,
1406 unsigned char *sig )
1407{
1408 size_t olen;
1409 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001411 unsigned int slen, hlen, offset = 0;
1412 int ret;
1413 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001414 const mbedtls_md_info_t *md_info;
1415 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001417 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1418 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001419
1420 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001421 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001422
1423 olen = ctx->len;
1424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001426 {
Simon Butcher02037452016-03-01 21:19:12 +00001427 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001429 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001433 }
1434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001436 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001440 slen = hlen;
1441
1442 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001444
1445 memset( sig, 0, olen );
1446
Simon Butcher02037452016-03-01 21:19:12 +00001447 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001448 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001450
Simon Butcher02037452016-03-01 21:19:12 +00001451 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001452 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001453 p += olen - hlen * 2 - 2;
1454 *p++ = 0x01;
1455 memcpy( p, salt, slen );
1456 p += slen;
1457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001458 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001459 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1460 {
1461 mbedtls_md_free( &md_ctx );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001462 /* No need to zeroize salt: we didn't use it. */
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001463 return( ret );
1464 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001465
Simon Butcher02037452016-03-01 21:19:12 +00001466 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 mbedtls_md_starts( &md_ctx );
1468 mbedtls_md_update( &md_ctx, p, 8 );
1469 mbedtls_md_update( &md_ctx, hash, hashlen );
1470 mbedtls_md_update( &md_ctx, salt, slen );
1471 mbedtls_md_finish( &md_ctx, p );
Gilles Peskine18ac7162017-05-05 19:24:06 +02001472 mbedtls_zeroize( salt, sizeof( salt ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001473
Simon Butcher02037452016-03-01 21:19:12 +00001474 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001475 if( msb % 8 == 0 )
1476 offset = 1;
1477
Simon Butcher02037452016-03-01 21:19:12 +00001478 /* maskedDB: Apply dbMask to DB */
Paul Bakkerb3869132013-02-28 17:21:01 +01001479 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
1480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001481 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001482
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001483 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001484 sig[0] &= 0xFF >> ( olen * 8 - msb );
1485
1486 p += hlen;
1487 *p++ = 0xBC;
1488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489 return( ( mode == MBEDTLS_RSA_PUBLIC )
1490 ? mbedtls_rsa_public( ctx, sig, sig )
1491 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001492}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001496/*
1497 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1498 */
1499/*
1500 * Do an RSA operation to sign the message digest
1501 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001503 int (*f_rng)(void *, unsigned char *, size_t),
1504 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001505 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001507 unsigned int hashlen,
1508 const unsigned char *hash,
1509 unsigned char *sig )
1510{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001511 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001512 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001513 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001514 unsigned char *sig_try = NULL, *verif = NULL;
1515 size_t i;
1516 unsigned char diff;
1517 volatile unsigned char diff_no_optimize;
1518 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1521 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001522
1523 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001524 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001527 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001529 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1533 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001534
Paul Bakkerc70b9822013-04-07 22:00:46 +02001535 nb_pad -= 10 + oid_size;
1536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001538 }
1539
Paul Bakkerc70b9822013-04-07 22:00:46 +02001540 nb_pad -= hashlen;
1541
Paul Bakkerb3869132013-02-28 17:21:01 +01001542 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001544
1545 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001547 memset( p, 0xFF, nb_pad );
1548 p += nb_pad;
1549 *p++ = 0;
1550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001552 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001553 memcpy( p, hash, hashlen );
1554 }
1555 else
1556 {
1557 /*
1558 * DigestInfo ::= SEQUENCE {
1559 * digestAlgorithm DigestAlgorithmIdentifier,
1560 * digest Digest }
1561 *
1562 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1563 *
1564 * Digest ::= OCTET STRING
1565 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001567 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001568 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001569 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001571 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001572 memcpy( p, oid, oid_size );
1573 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001574 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001575 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001576 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001577 *p++ = hashlen;
1578 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01001579 }
1580
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001581 if( mode == MBEDTLS_RSA_PUBLIC )
1582 return( mbedtls_rsa_public( ctx, sig, sig ) );
1583
1584 /*
1585 * In order to prevent Lenstra's attack, make the signature in a
1586 * temporary buffer and check it before returning it.
1587 */
1588 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001589 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001590 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1591
Simon Butcher1285ab52016-01-01 21:42:47 +00001592 verif = mbedtls_calloc( 1, ctx->len );
1593 if( verif == NULL )
1594 {
1595 mbedtls_free( sig_try );
1596 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1597 }
1598
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001599 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
1600 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
1601
1602 /* Compare in constant time just in case */
1603 for( diff = 0, i = 0; i < ctx->len; i++ )
1604 diff |= verif[i] ^ sig[i];
1605 diff_no_optimize = diff;
1606
1607 if( diff_no_optimize != 0 )
1608 {
1609 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
1610 goto cleanup;
1611 }
1612
1613 memcpy( sig, sig_try, ctx->len );
1614
1615cleanup:
1616 mbedtls_free( sig_try );
1617 mbedtls_free( verif );
1618
1619 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001620}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001621#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001622
1623/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001624 * Do an RSA operation to sign the message digest
1625 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001626int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001627 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00001628 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001630 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00001631 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001632 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00001633 unsigned char *sig )
1634{
Paul Bakker5121ce52009-01-03 21:22:43 +00001635 switch( ctx->padding )
1636 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001637#if defined(MBEDTLS_PKCS1_V15)
1638 case MBEDTLS_RSA_PKCS_V15:
1639 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001640 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001641#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001642
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001643#if defined(MBEDTLS_PKCS1_V21)
1644 case MBEDTLS_RSA_PKCS_V21:
1645 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001646 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001647#endif
1648
Paul Bakker5121ce52009-01-03 21:22:43 +00001649 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001650 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001651 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001652}
1653
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001654#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001655/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001656 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00001657 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001658int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001659 int (*f_rng)(void *, unsigned char *, size_t),
1660 void *p_rng,
1661 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001662 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001663 unsigned int hashlen,
1664 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001666 int expected_salt_len,
1667 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00001668{
Paul Bakker23986e52011-04-24 08:57:21 +00001669 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001670 size_t siglen;
1671 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001672 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001673 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00001674 unsigned int hlen;
1675 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001676 const mbedtls_md_info_t *md_info;
1677 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01001678 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001680 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1681 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001682
Paul Bakker5121ce52009-01-03 21:22:43 +00001683 siglen = ctx->len;
1684
Paul Bakker27fdf462011-06-09 13:55:13 +00001685 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001687
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1689 ? mbedtls_rsa_public( ctx, sig, buf )
1690 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001691
1692 if( ret != 0 )
1693 return( ret );
1694
1695 p = buf;
1696
Paul Bakkerb3869132013-02-28 17:21:01 +01001697 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001698 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001700 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001701 {
Simon Butcher02037452016-03-01 21:19:12 +00001702 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001703 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001704 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001705 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001706
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001707 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001708 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001710 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001711 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001712 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001714 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001715 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001716
Paul Bakkerb3869132013-02-28 17:21:01 +01001717 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00001718
Simon Butcher02037452016-03-01 21:19:12 +00001719 /*
1720 * Note: EMSA-PSS verification is over the length of N - 1 bits
1721 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001722 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001723
Simon Butcher02037452016-03-01 21:19:12 +00001724 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001725 if( msb % 8 == 0 )
1726 {
1727 p++;
1728 siglen -= 1;
1729 }
1730 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001731 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001732
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001733 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001734 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1735 {
1736 mbedtls_md_free( &md_ctx );
1737 return( ret );
1738 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001739
Paul Bakkerb3869132013-02-28 17:21:01 +01001740 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01001741
Paul Bakkerb3869132013-02-28 17:21:01 +01001742 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001743
Paul Bakker4de44aa2013-12-31 11:43:01 +01001744 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001745 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001746
Paul Bakkerb3869132013-02-28 17:21:01 +01001747 if( p == buf + siglen ||
1748 *p++ != 0x01 )
1749 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001750 mbedtls_md_free( &md_ctx );
1751 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001752 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001753
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001754 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01001755 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001756
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001757 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001758 slen != (size_t) expected_salt_len )
1759 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001760 mbedtls_md_free( &md_ctx );
1761 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001762 }
1763
Simon Butcher02037452016-03-01 21:19:12 +00001764 /*
1765 * Generate H = Hash( M' )
1766 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001767 mbedtls_md_starts( &md_ctx );
1768 mbedtls_md_update( &md_ctx, zeros, 8 );
1769 mbedtls_md_update( &md_ctx, hash, hashlen );
1770 mbedtls_md_update( &md_ctx, p, slen );
1771 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00001772
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001773 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001774
Paul Bakkerb3869132013-02-28 17:21:01 +01001775 if( memcmp( p + slen, result, hlen ) == 0 )
1776 return( 0 );
1777 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001778 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01001779}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001780
1781/*
1782 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
1783 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001784int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001785 int (*f_rng)(void *, unsigned char *, size_t),
1786 void *p_rng,
1787 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001788 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001789 unsigned int hashlen,
1790 const unsigned char *hash,
1791 const unsigned char *sig )
1792{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001793 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
1794 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001795 : md_alg;
1796
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001797 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001798 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001800 sig ) );
1801
1802}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001803#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01001804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001805#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001806/*
1807 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
1808 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001809int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001810 int (*f_rng)(void *, unsigned char *, size_t),
1811 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001812 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001813 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001814 unsigned int hashlen,
1815 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02001816 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01001817{
1818 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001819 size_t len, siglen, asn1_len;
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001820 unsigned char *p, *p0, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001821 mbedtls_md_type_t msg_md_alg;
1822 const mbedtls_md_info_t *md_info;
1823 mbedtls_asn1_buf oid;
Nicholas Wilson409401c2016-04-13 11:48:25 +01001824 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001826 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1827 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001828
1829 siglen = ctx->len;
1830
1831 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001833
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001834 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1835 ? mbedtls_rsa_public( ctx, sig, buf )
1836 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001837
1838 if( ret != 0 )
1839 return( ret );
1840
1841 p = buf;
1842
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
1844 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001845
1846 while( *p != 0 )
1847 {
1848 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001850 p++;
1851 }
Manuel Pégourié-Gonnardc1380de2017-05-11 12:49:51 +02001852 p++; /* skip 00 byte */
1853
1854 /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */
1855 if( p - buf < 11 )
1856 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001857
1858 len = siglen - ( p - buf );
1859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001861 {
1862 if( memcmp( p, hash, hashlen ) == 0 )
1863 return( 0 );
1864 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001865 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001866 }
1867
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001869 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001870 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1871 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001872
1873 end = p + len;
1874
Simon Butcher02037452016-03-01 21:19:12 +00001875 /*
Gilles Peskinee7e76502017-05-04 12:48:39 +02001876 * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure.
1877 * Insist on 2-byte length tags, to protect against variants of
1878 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification.
Simon Butcher02037452016-03-01 21:19:12 +00001879 */
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001880 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001881 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
1882 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1883 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001884 if( p != p0 + 2 || asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001886
Gilles Peskinee7e76502017-05-04 12:48:39 +02001887 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001888 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
1889 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1890 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02001891 if( p != p0 + 2 || asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001892 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001893
Gilles Peskinee7e76502017-05-04 12:48:39 +02001894 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001895 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
1896 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02001897 if( p != p0 + 2 )
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001898 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001899
1900 oid.p = p;
1901 p += oid.len;
1902
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
1904 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001905
1906 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001907 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001908
1909 /*
1910 * assume the algorithm parameters must be NULL
1911 */
Gilles Peskinee7e76502017-05-04 12:48:39 +02001912 p0 = p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001913 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
1914 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskinee7e76502017-05-04 12:48:39 +02001915 if( p != p0 + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001916 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001917
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001918 p0 = p;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001919 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
1920 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Gilles Peskine0e17eb02017-05-03 18:32:21 +02001921 if( p != p0 + 2 || asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001922 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001923
1924 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001925 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001926
1927 p += hashlen;
1928
1929 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001930 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001931
1932 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001933}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001934#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001935
1936/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001937 * Do an RSA operation and check the message digest
1938 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001939int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001940 int (*f_rng)(void *, unsigned char *, size_t),
1941 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001942 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001943 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001944 unsigned int hashlen,
1945 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02001946 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01001947{
1948 switch( ctx->padding )
1949 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001950#if defined(MBEDTLS_PKCS1_V15)
1951 case MBEDTLS_RSA_PKCS_V15:
1952 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001953 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001954#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956#if defined(MBEDTLS_PKCS1_V21)
1957 case MBEDTLS_RSA_PKCS_V21:
1958 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001959 hashlen, hash, sig );
1960#endif
1961
1962 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001963 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001964 }
1965}
1966
1967/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001968 * Copy the components of an RSA key
1969 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001970int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001971{
1972 int ret;
1973
1974 dst->ver = src->ver;
1975 dst->len = src->len;
1976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
1978 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
1981 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
1982 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01001983
1984#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001985 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
1986 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
1987 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001988 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
1989 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01001990#endif
1991
1992 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001994 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
1995 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001996
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001997 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01001998 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001999
2000cleanup:
2001 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002002 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002003
2004 return( ret );
2005}
2006
2007/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002008 * Free the components of an RSA key
2009 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002010void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002011{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002013 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2014 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002016
Hanno Becker33c30a02017-08-23 07:00:22 +01002017#if !defined(MBEDTLS_RSA_NO_CRT)
2018 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2019 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2020 mbedtls_mpi_free( &ctx->DP );
2021#endif /* MBEDTLS_RSA_NO_CRT */
2022
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#if defined(MBEDTLS_THREADING_C)
2024 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002025#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002026}
2027
Hanno Beckerab377312017-08-23 16:24:51 +01002028#endif /* !MBEDTLS_RSA_ALT */
2029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002030#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002032#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002033
2034/*
2035 * Example RSA-1024 keypair, for test purposes
2036 */
2037#define KEY_LEN 128
2038
2039#define RSA_N "9292758453063D803DD603D5E777D788" \
2040 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2041 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2042 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2043 "93A89813FBF3C4F8066D2D800F7C38A8" \
2044 "1AE31942917403FF4946B0A83D3D3E05" \
2045 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2046 "5E94BB77B07507233A0BC7BAC8F90F79"
2047
2048#define RSA_E "10001"
2049
2050#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2051 "66CA472BC44D253102F8B4A9D3BFA750" \
2052 "91386C0077937FE33FA3252D28855837" \
2053 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2054 "DF79C5CE07EE72C7F123142198164234" \
2055 "CABB724CF78B8173B9F880FC86322407" \
2056 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2057 "071513A1E85B5DFA031F21ECAE91A34D"
2058
2059#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2060 "2C01CAD19EA484A87EA4377637E75500" \
2061 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2062 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2063
2064#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2065 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2066 "910E4168387E3C30AA1E00C339A79508" \
2067 "8452DD96A9A5EA5D9DCA68DA636032AF"
2068
Paul Bakker5121ce52009-01-03 21:22:43 +00002069#define PT_LEN 24
2070#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2071 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002073#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002074static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002075{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002076#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002077 size_t i;
2078
Paul Bakker545570e2010-07-18 09:00:25 +00002079 if( rng_state != NULL )
2080 rng_state = NULL;
2081
Paul Bakkera3d195c2011-11-27 21:07:34 +00002082 for( i = 0; i < len; ++i )
2083 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002084#else
2085 if( rng_state != NULL )
2086 rng_state = NULL;
2087
2088 arc4random_buf( output, len );
2089#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002090
Paul Bakkera3d195c2011-11-27 21:07:34 +00002091 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002092}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002093#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002094
Paul Bakker5121ce52009-01-03 21:22:43 +00002095/*
2096 * Checkup routine
2097 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002098int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002099{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002100 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002102 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002104 unsigned char rsa_plaintext[PT_LEN];
2105 unsigned char rsa_decrypted[PT_LEN];
2106 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002108 unsigned char sha1sum[20];
2109#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Hanno Becker3a701162017-08-22 13:52:43 +01002111 mbedtls_mpi K;
2112
2113 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002114 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002115
Hanno Becker3a701162017-08-22 13:52:43 +01002116 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2117 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2118 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2119 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2120 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2121 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2122 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2123 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2124 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2125 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2126
Hanno Becker7f25f852017-10-10 16:56:22 +01002127 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128
2129 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002132 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2133 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002134 {
2135 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002136 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002137
2138 return( 1 );
2139 }
2140
2141 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002142 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002143
2144 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2145
Hanno Becker98838b02017-10-02 13:16:10 +01002146 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2147 PT_LEN, rsa_plaintext,
2148 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002149 {
2150 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002152
2153 return( 1 );
2154 }
2155
2156 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002158
Hanno Becker98838b02017-10-02 13:16:10 +01002159 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2160 &len, rsa_ciphertext, rsa_decrypted,
2161 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002162 {
2163 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002164 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002165
2166 return( 1 );
2167 }
2168
2169 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2170 {
2171 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002172 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002173
2174 return( 1 );
2175 }
2176
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002177 if( verbose != 0 )
2178 mbedtls_printf( "passed\n" );
2179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002180#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002181 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002182 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002184 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00002185
Hanno Becker98838b02017-10-02 13:16:10 +01002186 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2187 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2188 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002189 {
2190 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002191 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002192
2193 return( 1 );
2194 }
2195
2196 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002198
Hanno Becker98838b02017-10-02 13:16:10 +01002199 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2200 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2201 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002202 {
2203 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002204 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002205
2206 return( 1 );
2207 }
2208
2209 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002210 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002211#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002212
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002213 if( verbose != 0 )
2214 mbedtls_printf( "\n" );
2215
Paul Bakker3d8fb632014-04-17 12:42:41 +02002216cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002217 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002218 mbedtls_rsa_free( &rsa );
2219#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002220 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002221#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002222 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002223}
2224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002225#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002227#endif /* MBEDTLS_RSA_C */