blob: 729e1f735d488f79546b305fb2135c7847bd80f8 [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
Manuel Pégourié-Gonnard1ba8a3f2018-03-13 13:27:14 +010078#if defined(MBEDTLS_PKCS1_V15)
Hanno Becker171a8f12017-09-06 12:32:16 +010079/* constant-time buffer comparison */
80static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
81{
82 size_t i;
83 const unsigned char *A = (const unsigned char *) a;
84 const unsigned char *B = (const unsigned char *) b;
85 unsigned char diff = 0;
86
87 for( i = 0; i < n; i++ )
88 diff |= A[i] ^ B[i];
89
90 return( diff );
91}
Manuel Pégourié-Gonnard1ba8a3f2018-03-13 13:27:14 +010092#endif /* MBEDTLS_PKCS1_V15 */
Hanno Becker171a8f12017-09-06 12:32:16 +010093
Hanno Becker617c1ae2017-08-23 14:11:24 +010094int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
95 const mbedtls_mpi *N,
96 const mbedtls_mpi *P, const mbedtls_mpi *Q,
97 const mbedtls_mpi *D, const mbedtls_mpi *E )
98{
99 int ret;
100
101 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
102 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
103 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
104 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
105 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
106 {
107 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
108 }
109
110 if( N != NULL )
111 ctx->len = mbedtls_mpi_size( &ctx->N );
112
113 return( 0 );
114}
115
116int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
Hanno Becker74716312017-10-02 10:00:37 +0100117 unsigned char const *N, size_t N_len,
118 unsigned char const *P, size_t P_len,
119 unsigned char const *Q, size_t Q_len,
120 unsigned char const *D, size_t D_len,
121 unsigned char const *E, size_t E_len )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100122{
Hanno Beckerd4d60572018-01-10 07:12:01 +0000123 int ret = 0;
Hanno Becker617c1ae2017-08-23 14:11:24 +0100124
125 if( N != NULL )
126 {
127 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
128 ctx->len = mbedtls_mpi_size( &ctx->N );
129 }
130
131 if( P != NULL )
132 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
133
134 if( Q != NULL )
135 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
136
137 if( D != NULL )
138 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
139
140 if( E != NULL )
141 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
142
143cleanup:
144
145 if( ret != 0 )
146 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
147
148 return( 0 );
149}
150
Hanno Becker705fc682017-10-10 17:57:02 +0100151/*
152 * Checks whether the context fields are set in such a way
153 * that the RSA primitives will be able to execute without error.
154 * It does *not* make guarantees for consistency of the parameters.
155 */
Hanno Beckerebd2c022017-10-12 10:54:53 +0100156static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
157 int blinding_needed )
Hanno Becker705fc682017-10-10 17:57:02 +0100158{
Hanno Beckerebd2c022017-10-12 10:54:53 +0100159#if !defined(MBEDTLS_RSA_NO_CRT)
160 /* blinding_needed is only used for NO_CRT to decide whether
161 * P,Q need to be present or not. */
162 ((void) blinding_needed);
163#endif
164
Hanno Becker3a760a12018-01-05 08:14:49 +0000165 if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
166 ctx->len > MBEDTLS_MPI_MAX_SIZE )
167 {
Hanno Becker705fc682017-10-10 17:57:02 +0100168 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Becker3a760a12018-01-05 08:14:49 +0000169 }
Hanno Becker705fc682017-10-10 17:57:02 +0100170
171 /*
172 * 1. Modular exponentiation needs positive, odd moduli.
173 */
174
175 /* Modular exponentiation wrt. N is always used for
176 * RSA public key operations. */
177 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
178 mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
179 {
180 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
181 }
182
183#if !defined(MBEDTLS_RSA_NO_CRT)
184 /* Modular exponentiation for P and Q is only
185 * used for private key operations and if CRT
186 * is used. */
187 if( is_priv &&
188 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
189 mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
190 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
191 mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
192 {
193 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
194 }
195#endif /* !MBEDTLS_RSA_NO_CRT */
196
197 /*
198 * 2. Exponents must be positive
199 */
200
201 /* Always need E for public key operations */
202 if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
203 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
204
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100205#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100206 /* For private key operations, use D or DP & DQ
207 * as (unblinded) exponents. */
208 if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
209 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
210#else
211 if( is_priv &&
212 ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
213 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
214 {
215 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
216 }
217#endif /* MBEDTLS_RSA_NO_CRT */
218
219 /* Blinding shouldn't make exponents negative either,
220 * so check that P, Q >= 1 if that hasn't yet been
221 * done as part of 1. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100222#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Beckerebd2c022017-10-12 10:54:53 +0100223 if( is_priv && blinding_needed &&
Hanno Becker705fc682017-10-10 17:57:02 +0100224 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
225 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
226 {
227 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
228 }
229#endif
230
231 /* It wouldn't lead to an error if it wasn't satisfied,
Hanno Beckerf8c028a2017-10-17 09:20:57 +0100232 * but check for QP >= 1 nonetheless. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100233#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100234 if( is_priv &&
235 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
236 {
237 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
238 }
239#endif
240
241 return( 0 );
242}
243
Hanno Beckerf9e184b2017-10-10 16:49:26 +0100244int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100245{
246 int ret = 0;
247
Hanno Becker617c1ae2017-08-23 14:11:24 +0100248 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
249 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
250 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
251 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
252 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100253
Hanno Becker617c1ae2017-08-23 14:11:24 +0100254 /*
255 * Check whether provided parameters are enough
256 * to deduce all others. The following incomplete
257 * parameter sets for private keys are supported:
258 *
259 * (1) P, Q missing.
260 * (2) D and potentially N missing.
261 *
262 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100263
Hanno Becker2cca6f32017-09-29 11:46:40 +0100264 const int n_missing = have_P && have_Q && have_D && have_E;
265 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
266 const int d_missing = have_P && have_Q && !have_D && have_E;
267 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
268
269 /* These three alternatives are mutually exclusive */
270 const int is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100271
Hanno Becker617c1ae2017-08-23 14:11:24 +0100272 if( !is_priv && !is_pub )
273 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
274
275 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100276 * Step 1: Deduce N if P, Q are provided.
277 */
278
279 if( !have_N && have_P && have_Q )
280 {
281 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
282 &ctx->Q ) ) != 0 )
283 {
284 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
285 }
286
287 ctx->len = mbedtls_mpi_size( &ctx->N );
288 }
289
290 /*
291 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100292 */
293
294 if( pq_missing )
295 {
Hanno Beckerc36aab62017-10-17 09:15:06 +0100296 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100297 &ctx->P, &ctx->Q );
298 if( ret != 0 )
299 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
300
301 }
302 else if( d_missing )
303 {
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100304 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
305 &ctx->Q,
306 &ctx->E,
307 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100308 {
309 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
310 }
311 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100312
Hanno Becker617c1ae2017-08-23 14:11:24 +0100313 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100314 * Step 3: Deduce all additional parameters specific
Hanno Beckere8674892017-10-10 17:56:14 +0100315 * to our current RSA implementation.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100316 */
317
Hanno Becker23344b52017-08-23 07:43:27 +0100318#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100319 if( is_priv )
320 {
321 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
322 &ctx->DP, &ctx->DQ, &ctx->QP );
323 if( ret != 0 )
324 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
325 }
Hanno Becker23344b52017-08-23 07:43:27 +0100326#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100327
328 /*
Hanno Becker705fc682017-10-10 17:57:02 +0100329 * Step 3: Basic sanity checks
Hanno Becker617c1ae2017-08-23 14:11:24 +0100330 */
331
Hanno Beckerebd2c022017-10-12 10:54:53 +0100332 return( rsa_check_context( ctx, is_priv, 1 ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100333}
334
Hanno Becker617c1ae2017-08-23 14:11:24 +0100335int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
336 unsigned char *N, size_t N_len,
337 unsigned char *P, size_t P_len,
338 unsigned char *Q, size_t Q_len,
339 unsigned char *D, size_t D_len,
340 unsigned char *E, size_t E_len )
341{
342 int ret = 0;
343
344 /* Check if key is private or public */
345 const int is_priv =
346 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
347 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
348 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
349 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
350 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
351
352 if( !is_priv )
353 {
354 /* If we're trying to export private parameters for a public key,
355 * something must be wrong. */
356 if( P != NULL || Q != NULL || D != NULL )
357 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
358
359 }
360
361 if( N != NULL )
362 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
363
364 if( P != NULL )
365 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
366
367 if( Q != NULL )
368 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
369
370 if( D != NULL )
371 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
372
373 if( E != NULL )
374 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100375
376cleanup:
377
378 return( ret );
379}
380
Hanno Becker617c1ae2017-08-23 14:11:24 +0100381int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
382 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
383 mbedtls_mpi *D, mbedtls_mpi *E )
384{
385 int ret;
386
387 /* Check if key is private or public */
388 int is_priv =
389 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
390 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
391 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
392 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
393 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
394
395 if( !is_priv )
396 {
397 /* If we're trying to export private parameters for a public key,
398 * something must be wrong. */
399 if( P != NULL || Q != NULL || D != NULL )
400 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
401
402 }
403
404 /* Export all requested core parameters. */
405
406 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
407 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
408 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
409 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
410 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
411 {
412 return( ret );
413 }
414
415 return( 0 );
416}
417
418/*
419 * Export CRT parameters
420 * This must also be implemented if CRT is not used, for being able to
421 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
422 * can be used in this case.
423 */
424int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
425 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
426{
427 int ret;
428
429 /* Check if key is private or public */
430 int is_priv =
431 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
432 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
433 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
434 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
435 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
436
437 if( !is_priv )
438 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
439
Hanno Beckerdc95c892017-08-23 06:57:02 +0100440#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100441 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100442 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
443 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
444 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
445 {
Hanno Beckerdc95c892017-08-23 06:57:02 +0100446 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100447 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100448#else
449 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
450 DP, DQ, QP ) ) != 0 )
451 {
452 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
453 }
454#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100455
456 return( 0 );
457}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100458
Paul Bakker5121ce52009-01-03 21:22:43 +0000459/*
460 * Initialize an RSA context
461 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +0000464 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470#if defined(MBEDTLS_THREADING_C)
471 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200472#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000473}
474
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100475/*
476 * Set padding for an existing RSA context
477 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100479{
480 ctx->padding = padding;
481 ctx->hash_id = hash_id;
482}
483
Hanno Becker617c1ae2017-08-23 14:11:24 +0100484/*
485 * Get length in bytes of RSA modulus
486 */
487
488size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
489{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100490 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100491}
492
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496/*
497 * Generate an RSA keypair
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800498 *
499 * This generation method follows the RSA key pair generation procedure of
500 * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000503 int (*f_rng)(void *, unsigned char *, size_t),
504 void *p_rng,
505 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000506{
507 int ret;
Jethro Beekman97f95c92018-02-13 15:50:36 -0800508 mbedtls_mpi H, G, L;
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Paul Bakker21eb2802010-08-16 11:10:02 +0000510 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Janos Follathef441782016-09-21 13:18:12 +0100513 if( nbits % 2 )
514 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
515
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100516 mbedtls_mpi_init( &H );
517 mbedtls_mpi_init( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800518 mbedtls_mpi_init( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000519
520 /*
521 * find primes P and Q with Q < P so that:
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800522 * 1. |P-Q| > 2^( nbits / 2 - 100 )
523 * 2. GCD( E, (P-1)*(Q-1) ) == 1
524 * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
528 do
529 {
Janos Follath10c575b2016-02-23 14:42:48 +0000530 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100531 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
Janos Follathef441782016-09-21 13:18:12 +0100533 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100534 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800536 /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
537 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
538 if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 continue;
540
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800541 /* not required by any standards, but some users rely on the fact that P > Q */
542 if( H.s < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100543 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100544
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100545 /* Temporarily replace P,Q by P-1, Q-1 */
546 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
547 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
548 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800549
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800550 /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800552 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
553 continue;
554
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800555 /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
Jethro Beekman97f95c92018-02-13 15:50:36 -0800556 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
557 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
558 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
559
560 if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
561 continue;
562
563 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 }
Jethro Beekman97f95c92018-02-13 15:50:36 -0800565 while( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100567 /* Restore P,Q */
568 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
569 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
570
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800571 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
572
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100573 ctx->len = mbedtls_mpi_size( &ctx->N );
574
Jethro Beekman97f95c92018-02-13 15:50:36 -0800575#if !defined(MBEDTLS_RSA_NO_CRT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000577 * DP = D mod (P - 1)
578 * DQ = D mod (Q - 1)
579 * QP = Q^-1 mod P
580 */
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100581 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
582 &ctx->DP, &ctx->DQ, &ctx->QP ) );
583#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
Hanno Becker83aad1f2017-08-23 06:45:10 +0100585 /* Double-check */
586 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588cleanup:
589
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100590 mbedtls_mpi_free( &H );
591 mbedtls_mpi_free( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800592 mbedtls_mpi_free( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 if( ret != 0 )
595 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_rsa_free( ctx );
597 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 }
599
Paul Bakker48377d92013-08-30 12:06:24 +0200600 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601}
602
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605/*
606 * Check a public RSA key
607 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000609{
Hanno Beckerebd2c022017-10-12 10:54:53 +0100610 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d9f2009-07-10 22:38:58 +0000612
Hanno Becker3a760a12018-01-05 08:14:49 +0000613 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
Hanno Becker98838b02017-10-02 13:16:10 +0100614 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100616 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
Hanno Becker705fc682017-10-10 17:57:02 +0100618 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
619 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100621 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100623 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625 return( 0 );
626}
627
628/*
Hanno Becker705fc682017-10-10 17:57:02 +0100629 * Check for the consistency of all fields in an RSA private key context
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000632{
Hanno Becker705fc682017-10-10 17:57:02 +0100633 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
Hanno Beckerebd2c022017-10-12 10:54:53 +0100634 rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 {
Hanno Becker98838b02017-10-02 13:16:10 +0100636 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 }
Paul Bakker48377d92013-08-30 12:06:24 +0200638
Hanno Becker98838b02017-10-02 13:16:10 +0100639 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +0100640 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000641 {
Hanno Beckerb269a852017-08-25 08:03:21 +0100642 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000643 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000644
Hanno Beckerb269a852017-08-25 08:03:21 +0100645#if !defined(MBEDTLS_RSA_NO_CRT)
646 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
647 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
648 {
649 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
650 }
651#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +0000652
653 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654}
655
656/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100657 * Check if contexts holding a public and private key match
658 */
Hanno Becker98838b02017-10-02 13:16:10 +0100659int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
660 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100661{
Hanno Becker98838b02017-10-02 13:16:10 +0100662 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100664 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100666 }
667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
669 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100670 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100672 }
673
674 return( 0 );
675}
676
677/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000678 * Do an RSA public key operation
679 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000681 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 unsigned char *output )
683{
Paul Bakker23986e52011-04-24 08:57:21 +0000684 int ret;
685 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Hanno Beckerebd2c022017-10-12 10:54:53 +0100688 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
Hanno Becker705fc682017-10-10 17:57:02 +0100689 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
690
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200693#if defined(MBEDTLS_THREADING_C)
694 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
695 return( ret );
696#endif
697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200702 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
703 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 }
705
706 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
708 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
710cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200712 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
713 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +0100714#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
718 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
721 return( 0 );
722}
723
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200724/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200725 * Generate or update blinding values, see section 10 of:
726 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200727 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200728 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200729 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200730static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200731 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
732{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200733 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200734
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200735 if( ctx->Vf.p != NULL )
736 {
737 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
739 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
740 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
741 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200742
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200743 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200744 }
745
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200746 /* Unblinding value: Vf = random number, invertible mod N */
747 do {
748 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200750
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
752 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
753 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200754
755 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
757 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 +0200758
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200759
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200760cleanup:
761 return( ret );
762}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200763
Paul Bakker5121ce52009-01-03 21:22:43 +0000764/*
Janos Follathe81102e2017-03-22 13:38:28 +0000765 * Exponent blinding supposed to prevent side-channel attacks using multiple
766 * traces of measurements to recover the RSA key. The more collisions are there,
767 * the more bits of the key can be recovered. See [3].
768 *
769 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
770 * observations on avarage.
771 *
772 * For example with 28 byte blinding to achieve 2 collisions the adversary has
773 * to make 2^112 observations on avarage.
774 *
775 * (With the currently (as of 2017 April) known best algorithms breaking 2048
776 * bit RSA requires approximately as much time as trying out 2^112 random keys.
777 * Thus in this sense with 28 byte blinding the security is not reduced by
778 * side-channel attacks like the one in [3])
779 *
780 * This countermeasure does not help if the key recovery is possible with a
781 * single trace.
782 */
783#define RSA_EXPONENT_BLINDING 28
784
785/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 * Do an RSA private key operation
787 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200789 int (*f_rng)(void *, unsigned char *, size_t),
790 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000791 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 unsigned char *output )
793{
Paul Bakker23986e52011-04-24 08:57:21 +0000794 int ret;
795 size_t olen;
Hanno Becker06811ce2017-05-03 15:10:34 +0100796
797 /* Temporary holding the result */
798 mbedtls_mpi T;
799
800 /* Temporaries holding P-1, Q-1 and the
801 * exponent blinding factor, respectively. */
Janos Follathf9203b42017-03-22 15:13:15 +0000802 mbedtls_mpi P1, Q1, R;
Hanno Becker06811ce2017-05-03 15:10:34 +0100803
804#if !defined(MBEDTLS_RSA_NO_CRT)
805 /* Temporaries holding the results mod p resp. mod q. */
806 mbedtls_mpi TP, TQ;
807
808 /* Temporaries holding the blinded exponents for
809 * the mod p resp. mod q computation (if used). */
Janos Follathf9203b42017-03-22 15:13:15 +0000810 mbedtls_mpi DP_blind, DQ_blind;
Hanno Becker06811ce2017-05-03 15:10:34 +0100811
812 /* Pointers to actual exponents to be used - either the unblinded
813 * or the blinded ones, depending on the presence of a PRNG. */
Janos Follathf9203b42017-03-22 15:13:15 +0000814 mbedtls_mpi *DP = &ctx->DP;
815 mbedtls_mpi *DQ = &ctx->DQ;
Hanno Becker06811ce2017-05-03 15:10:34 +0100816#else
817 /* Temporary holding the blinded exponent (if used). */
818 mbedtls_mpi D_blind;
819
820 /* Pointer to actual exponent to be used - either the unblinded
821 * or the blinded one, depending on the presence of a PRNG. */
822 mbedtls_mpi *D = &ctx->D;
Hanno Becker43f94722017-08-25 11:50:00 +0100823#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker06811ce2017-05-03 15:10:34 +0100824
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100825 /* Temporaries holding the initial input and the double
826 * checked result; should be the same in the end. */
827 mbedtls_mpi I, C;
Paul Bakker5121ce52009-01-03 21:22:43 +0000828
Hanno Beckerebd2c022017-10-12 10:54:53 +0100829 if( rsa_check_context( ctx, 1 /* private key checks */,
830 f_rng != NULL /* blinding y/n */ ) != 0 )
831 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100832 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Beckerebd2c022017-10-12 10:54:53 +0100833 }
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100834
Hanno Becker06811ce2017-05-03 15:10:34 +0100835#if defined(MBEDTLS_THREADING_C)
836 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
837 return( ret );
838#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000839
Hanno Becker06811ce2017-05-03 15:10:34 +0100840 /* MPI Initialization */
Hanno Becker06811ce2017-05-03 15:10:34 +0100841 mbedtls_mpi_init( &T );
842
843 mbedtls_mpi_init( &P1 );
844 mbedtls_mpi_init( &Q1 );
845 mbedtls_mpi_init( &R );
Janos Follathf9203b42017-03-22 15:13:15 +0000846
Janos Follathf9203b42017-03-22 15:13:15 +0000847 if( f_rng != NULL )
848 {
Janos Follathe81102e2017-03-22 13:38:28 +0000849#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000850 mbedtls_mpi_init( &D_blind );
851#else
852 mbedtls_mpi_init( &DP_blind );
853 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000854#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000855 }
Janos Follathe81102e2017-03-22 13:38:28 +0000856
Hanno Becker06811ce2017-05-03 15:10:34 +0100857#if !defined(MBEDTLS_RSA_NO_CRT)
858 mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200859#endif
860
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100861 mbedtls_mpi_init( &I );
862 mbedtls_mpi_init( &C );
Hanno Becker06811ce2017-05-03 15:10:34 +0100863
864 /* End of MPI initialization */
865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
867 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000868 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200869 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
870 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 }
872
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100873 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
Hanno Becker06811ce2017-05-03 15:10:34 +0100874
Paul Bakkerf451bac2013-08-30 15:37:02 +0200875 if( f_rng != NULL )
876 {
877 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200878 * Blinding
879 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200880 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200881 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
882 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000884
Janos Follathe81102e2017-03-22 13:38:28 +0000885 /*
886 * Exponent blinding
887 */
888 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
889 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
890
Janos Follathf9203b42017-03-22 15:13:15 +0000891#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000892 /*
893 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
894 */
895 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
896 f_rng, p_rng ) );
897 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
898 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
899 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
900
901 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +0000902#else
903 /*
904 * DP_blind = ( P - 1 ) * R + DP
905 */
906 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
907 f_rng, p_rng ) );
908 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
909 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
910 &ctx->DP ) );
911
912 DP = &DP_blind;
913
914 /*
915 * DQ_blind = ( Q - 1 ) * R + DQ
916 */
917 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
918 f_rng, p_rng ) );
919 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
920 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
921 &ctx->DQ ) );
922
923 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +0000924#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +0200925 }
Paul Bakkeraab30c12013-08-30 11:00:25 +0200926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000928 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +0100929#else
Paul Bakkeraab30c12013-08-30 11:00:25 +0200930 /*
Janos Follathe81102e2017-03-22 13:38:28 +0000931 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 *
Hanno Becker06811ce2017-05-03 15:10:34 +0100933 * TP = input ^ dP mod P
934 * TQ = input ^ dQ mod Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100936
937 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
938 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
940 /*
Hanno Becker06811ce2017-05-03 15:10:34 +0100941 * T = (TP - TQ) * (Q^-1 mod P) mod P
Paul Bakker5121ce52009-01-03 21:22:43 +0000942 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100943 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
944 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
945 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
947 /*
Hanno Becker06811ce2017-05-03 15:10:34 +0100948 * T = TQ + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100950 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
951 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +0200953
Paul Bakkerf451bac2013-08-30 15:37:02 +0200954 if( f_rng != NULL )
955 {
956 /*
957 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200958 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200959 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200960 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +0200962 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000963
Hanno Becker2dec5e82017-10-03 07:49:52 +0100964 /* Verify the result to prevent glitching attacks. */
965 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
966 &ctx->N, &ctx->RN ) );
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100967 if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
Hanno Becker06811ce2017-05-03 15:10:34 +0100968 {
Hanno Becker06811ce2017-05-03 15:10:34 +0100969 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
970 goto cleanup;
971 }
Hanno Becker06811ce2017-05-03 15:10:34 +0100972
Paul Bakker5121ce52009-01-03 21:22:43 +0000973 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000975
976cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200978 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
979 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200980#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200981
Hanno Becker06811ce2017-05-03 15:10:34 +0100982 mbedtls_mpi_free( &P1 );
983 mbedtls_mpi_free( &Q1 );
984 mbedtls_mpi_free( &R );
Janos Follathf9203b42017-03-22 15:13:15 +0000985
986 if( f_rng != NULL )
987 {
Janos Follathe81102e2017-03-22 13:38:28 +0000988#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000989 mbedtls_mpi_free( &D_blind );
990#else
991 mbedtls_mpi_free( &DP_blind );
992 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000993#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000994 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000995
Hanno Becker06811ce2017-05-03 15:10:34 +0100996 mbedtls_mpi_free( &T );
997
998#if !defined(MBEDTLS_RSA_NO_CRT)
999 mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
1000#endif
1001
Hanno Beckerc6075cc2017-08-25 11:45:35 +01001002 mbedtls_mpi_free( &C );
1003 mbedtls_mpi_free( &I );
Hanno Becker06811ce2017-05-03 15:10:34 +01001004
Paul Bakker5121ce52009-01-03 21:22:43 +00001005 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007
1008 return( 0 );
1009}
1010
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001012/**
1013 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1014 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001015 * \param dst buffer to mask
1016 * \param dlen length of destination buffer
1017 * \param src source of the mask generation
1018 * \param slen length of the source buffer
1019 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001020 */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001021static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001023{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001025 unsigned char counter[4];
1026 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001027 unsigned int hlen;
1028 size_t i, use_len;
Andres Amaya Garcia94682d12017-07-20 14:26:37 +01001029 int ret = 0;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001032 memset( counter, 0, 4 );
1033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001035
Simon Butcher02037452016-03-01 21:19:12 +00001036 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001037 p = dst;
1038
1039 while( dlen > 0 )
1040 {
1041 use_len = hlen;
1042 if( dlen < hlen )
1043 use_len = dlen;
1044
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001045 if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
1046 goto exit;
1047 if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
1048 goto exit;
1049 if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
1050 goto exit;
1051 if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
1052 goto exit;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001053
1054 for( i = 0; i < use_len; ++i )
1055 *p++ ^= mask[i];
1056
1057 counter[3]++;
1058
1059 dlen -= use_len;
1060 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001061
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001062exit:
Gilles Peskine18ac7162017-05-05 19:24:06 +02001063 mbedtls_zeroize( mask, sizeof( mask ) );
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001064
1065 return( ret );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001066}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001070/*
1071 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1072 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001074 int (*f_rng)(void *, unsigned char *, size_t),
1075 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001076 int mode,
1077 const unsigned char *label, size_t label_len,
1078 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001079 const unsigned char *input,
1080 unsigned char *output )
1081{
1082 size_t olen;
1083 int ret;
1084 unsigned char *p = output;
1085 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 const mbedtls_md_info_t *md_info;
1087 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1090 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001091
1092 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001096 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001098
1099 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001101
Simon Butcher02037452016-03-01 21:19:12 +00001102 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001103 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001105
1106 memset( output, 0, olen );
1107
1108 *p++ = 0;
1109
Simon Butcher02037452016-03-01 21:19:12 +00001110 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001111 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001113
1114 p += hlen;
1115
Simon Butcher02037452016-03-01 21:19:12 +00001116 /* Construct DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001117 if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
1118 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001119 p += hlen;
1120 p += olen - 2 * hlen - 2 - ilen;
1121 *p++ = 1;
1122 memcpy( p, input, ilen );
1123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001125 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001126 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001127
Simon Butcher02037452016-03-01 21:19:12 +00001128 /* maskedDB: Apply dbMask to DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001129 if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1130 &md_ctx ) ) != 0 )
1131 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001132
Simon Butcher02037452016-03-01 21:19:12 +00001133 /* maskedSeed: Apply seedMask to seed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001134 if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1135 &md_ctx ) ) != 0 )
1136 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001137
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001138exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001140
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001141 if( ret != 0 )
1142 return( ret );
1143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 return( ( mode == MBEDTLS_RSA_PUBLIC )
1145 ? mbedtls_rsa_public( ctx, output, output )
1146 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001147}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001150#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001151/*
1152 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1153 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001154int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001155 int (*f_rng)(void *, unsigned char *, size_t),
1156 void *p_rng,
1157 int mode, size_t ilen,
1158 const unsigned char *input,
1159 unsigned char *output )
1160{
1161 size_t nb_pad, olen;
1162 int ret;
1163 unsigned char *p = output;
1164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1166 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001167
Janos Follath1ed9f992016-03-18 11:45:44 +00001168 // We don't check p_rng because it won't be dereferenced here
1169 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001171
1172 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001173
Simon Butcher02037452016-03-01 21:19:12 +00001174 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001175 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001177
1178 nb_pad = olen - 3 - ilen;
1179
1180 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001181 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001182 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001184
1185 while( nb_pad-- > 0 )
1186 {
1187 int rng_dl = 100;
1188
1189 do {
1190 ret = f_rng( p_rng, p, 1 );
1191 } while( *p == 0 && --rng_dl && ret == 0 );
1192
Simon Butcher02037452016-03-01 21:19:12 +00001193 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001194 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001195 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001196
1197 p++;
1198 }
1199 }
1200 else
1201 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001202 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001203
1204 while( nb_pad-- > 0 )
1205 *p++ = 0xFF;
1206 }
1207
1208 *p++ = 0;
1209 memcpy( p, input, ilen );
1210
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211 return( ( mode == MBEDTLS_RSA_PUBLIC )
1212 ? mbedtls_rsa_public( ctx, output, output )
1213 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001214}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001216
Paul Bakker5121ce52009-01-03 21:22:43 +00001217/*
1218 * Add the message padding, then do an RSA operation
1219 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001220int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001221 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001222 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001223 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001224 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 unsigned char *output )
1226{
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 switch( ctx->padding )
1228 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001229#if defined(MBEDTLS_PKCS1_V15)
1230 case MBEDTLS_RSA_PKCS_V15:
1231 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001232 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001233#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001235#if defined(MBEDTLS_PKCS1_V21)
1236 case MBEDTLS_RSA_PKCS_V21:
1237 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001238 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001239#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001240
1241 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001243 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001244}
1245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001246#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001247/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001248 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001250int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001251 int (*f_rng)(void *, unsigned char *, size_t),
1252 void *p_rng,
1253 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001254 const unsigned char *label, size_t label_len,
1255 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001256 const unsigned char *input,
1257 unsigned char *output,
1258 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001259{
Paul Bakker23986e52011-04-24 08:57:21 +00001260 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001261 size_t ilen, i, pad_len;
1262 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1264 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001265 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266 const mbedtls_md_info_t *md_info;
1267 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001268
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001269 /*
1270 * Parameters sanity checks
1271 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1273 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001274
1275 ilen = ctx->len;
1276
Paul Bakker27fdf462011-06-09 13:55:13 +00001277 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001278 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001280 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001281 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001283
Janos Follathc17cda12016-02-11 11:08:18 +00001284 hlen = mbedtls_md_get_size( md_info );
1285
1286 // checking for integer underflow
1287 if( 2 * hlen + 2 > ilen )
1288 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1289
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001290 /*
1291 * RSA operation
1292 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1294 ? mbedtls_rsa_public( ctx, input, buf )
1295 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001296
1297 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001298 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001299
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001300 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001301 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001302 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001303 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001304 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1305 {
1306 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001307 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001308 }
1309
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001310 /* seed: Apply seedMask to maskedSeed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001311 if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1312 &md_ctx ) ) != 0 ||
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001313 /* DB: Apply dbMask to maskedDB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001314 ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1315 &md_ctx ) ) != 0 )
1316 {
1317 mbedtls_md_free( &md_ctx );
1318 goto cleanup;
1319 }
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001322
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001323 /* Generate lHash */
1324 if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
1325 goto cleanup;
1326
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001327 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001328 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001329 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001331 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001332
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001333 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001334
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001335 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001336
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001337 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001338 for( i = 0; i < hlen; i++ )
1339 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001340
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001341 /* Get zero-padding len, but always read till end of buffer
1342 * (minus one, for the 01 byte) */
1343 pad_len = 0;
1344 pad_done = 0;
1345 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1346 {
1347 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001348 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001349 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001350
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001351 p += pad_len;
1352 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001353
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001354 /*
1355 * The only information "leaked" is whether the padding was correct or not
1356 * (eg, no data is copied if it was not correct). This meets the
1357 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1358 * the different error conditions.
1359 */
1360 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001361 {
1362 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1363 goto cleanup;
1364 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001365
Paul Bakker66d5d072014-06-17 16:39:18 +02001366 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001367 {
1368 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1369 goto cleanup;
1370 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001371
1372 *olen = ilen - (p - buf);
1373 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001374 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001375
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001376cleanup:
1377 mbedtls_zeroize( buf, sizeof( buf ) );
1378 mbedtls_zeroize( lhash, sizeof( lhash ) );
1379
1380 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001381}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001383
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001385/*
1386 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1387 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001389 int (*f_rng)(void *, unsigned char *, size_t),
1390 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001391 int mode, size_t *olen,
1392 const unsigned char *input,
1393 unsigned char *output,
1394 size_t output_max_len)
1395{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001396 int ret;
1397 size_t ilen, pad_count = 0, i;
1398 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001401 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1402 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001403
1404 ilen = ctx->len;
1405
1406 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1410 ? mbedtls_rsa_public( ctx, input, buf )
1411 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001412
1413 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001414 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001415
1416 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001417 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001418
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001419 /*
1420 * Check and get padding len in "constant-time"
1421 */
1422 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001423
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001424 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001426 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001428
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001429 /* Get padding len, but always read till end of buffer
1430 * (minus one, for the 00 byte) */
1431 for( i = 0; i < ilen - 3; i++ )
1432 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001433 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1434 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001435 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001436
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001437 p += pad_count;
1438 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001439 }
1440 else
1441 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001443
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001444 /* Get padding len, but always read till end of buffer
1445 * (minus one, for the 00 byte) */
1446 for( i = 0; i < ilen - 3; i++ )
1447 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001448 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001449 pad_count += ( pad_done == 0 );
1450 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001451
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001452 p += pad_count;
1453 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001454 }
1455
Janos Follathc69fa502016-02-12 13:30:09 +00001456 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001457
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001458 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001459 {
1460 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1461 goto cleanup;
1462 }
Paul Bakker8804f692013-02-28 18:06:26 +01001463
Paul Bakker66d5d072014-06-17 16:39:18 +02001464 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001465 {
1466 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1467 goto cleanup;
1468 }
Paul Bakker060c5682009-01-12 21:48:39 +00001469
Paul Bakker27fdf462011-06-09 13:55:13 +00001470 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001471 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001472 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001473
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001474cleanup:
1475 mbedtls_zeroize( buf, sizeof( buf ) );
1476
1477 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001478}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001480
1481/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001482 * Do an RSA operation, then remove the message padding
1483 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001485 int (*f_rng)(void *, unsigned char *, size_t),
1486 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001487 int mode, size_t *olen,
1488 const unsigned char *input,
1489 unsigned char *output,
1490 size_t output_max_len)
1491{
1492 switch( ctx->padding )
1493 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#if defined(MBEDTLS_PKCS1_V15)
1495 case MBEDTLS_RSA_PKCS_V15:
1496 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001497 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001498#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#if defined(MBEDTLS_PKCS1_V21)
1501 case MBEDTLS_RSA_PKCS_V21:
1502 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001503 olen, input, output,
1504 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001505#endif
1506
1507 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001509 }
1510}
1511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001512#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001513/*
1514 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1515 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001517 int (*f_rng)(void *, unsigned char *, size_t),
1518 void *p_rng,
1519 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001521 unsigned int hashlen,
1522 const unsigned char *hash,
1523 unsigned char *sig )
1524{
1525 size_t olen;
1526 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001527 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001528 unsigned int slen, hlen, offset = 0;
1529 int ret;
1530 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531 const mbedtls_md_info_t *md_info;
1532 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1535 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001536
1537 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001539
1540 olen = ctx->len;
1541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001543 {
Simon Butcher02037452016-03-01 21:19:12 +00001544 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001546 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001548
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001550 }
1551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001553 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001557 slen = hlen;
1558
1559 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001560 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001561
1562 memset( sig, 0, olen );
1563
Simon Butcher02037452016-03-01 21:19:12 +00001564 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001565 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001567
Simon Butcher02037452016-03-01 21:19:12 +00001568 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001569 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001570 p += olen - hlen * 2 - 2;
1571 *p++ = 0x01;
1572 memcpy( p, salt, slen );
1573 p += slen;
1574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001576 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001577 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001578
Simon Butcher02037452016-03-01 21:19:12 +00001579 /* Generate H = Hash( M' ) */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001580 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
1581 goto exit;
1582 if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
1583 goto exit;
1584 if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
1585 goto exit;
1586 if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
1587 goto exit;
1588 if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
1589 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001590
Simon Butcher02037452016-03-01 21:19:12 +00001591 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001592 if( msb % 8 == 0 )
1593 offset = 1;
1594
Simon Butcher02037452016-03-01 21:19:12 +00001595 /* maskedDB: Apply dbMask to DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001596 if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
1597 &md_ctx ) ) != 0 )
1598 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001599
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001600 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001601 sig[0] &= 0xFF >> ( olen * 8 - msb );
1602
1603 p += hlen;
1604 *p++ = 0xBC;
1605
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001606 mbedtls_zeroize( salt, sizeof( salt ) );
1607
1608exit:
1609 mbedtls_md_free( &md_ctx );
1610
1611 if( ret != 0 )
1612 return( ret );
1613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614 return( ( mode == MBEDTLS_RSA_PUBLIC )
1615 ? mbedtls_rsa_public( ctx, sig, sig )
1616 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001617}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001618#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001620#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001621/*
1622 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1623 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001624
1625/* Construct a PKCS v1.5 encoding of a hashed message
1626 *
1627 * This is used both for signature generation and verification.
1628 *
1629 * Parameters:
1630 * - md_alg: Identifies the hash algorithm used to generate the given hash;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001631 * MBEDTLS_MD_NONE if raw data is signed.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001632 * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001633 * - hash: Buffer containing the hashed message or the raw data.
1634 * - dst_len: Length of the encoded message.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001635 * - dst: Buffer to hold the encoded message.
1636 *
1637 * Assumptions:
1638 * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
1639 * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001640 * - dst points to a buffer of size at least dst_len.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001641 *
1642 */
1643static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
1644 unsigned int hashlen,
1645 const unsigned char *hash,
Hanno Beckere58d38c2017-09-27 17:09:00 +01001646 size_t dst_len,
Hanno Beckerfdf38032017-09-06 12:35:55 +01001647 unsigned char *dst )
1648{
1649 size_t oid_size = 0;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001650 size_t nb_pad = dst_len;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001651 unsigned char *p = dst;
1652 const char *oid = NULL;
1653
1654 /* Are we signing hashed or raw data? */
1655 if( md_alg != MBEDTLS_MD_NONE )
1656 {
1657 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
1658 if( md_info == NULL )
1659 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1660
1661 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1662 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1663
1664 hashlen = mbedtls_md_get_size( md_info );
1665
1666 /* Double-check that 8 + hashlen + oid_size can be used as a
1667 * 1-byte ASN.1 length encoding and that there's no overflow. */
1668 if( 8 + hashlen + oid_size >= 0x80 ||
1669 10 + hashlen < hashlen ||
1670 10 + hashlen + oid_size < 10 + hashlen )
1671 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1672
1673 /*
1674 * Static bounds check:
1675 * - Need 10 bytes for five tag-length pairs.
1676 * (Insist on 1-byte length encodings to protect against variants of
1677 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
1678 * - Need hashlen bytes for hash
1679 * - Need oid_size bytes for hash alg OID.
1680 */
1681 if( nb_pad < 10 + hashlen + oid_size )
1682 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1683 nb_pad -= 10 + hashlen + oid_size;
1684 }
1685 else
1686 {
1687 if( nb_pad < hashlen )
1688 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1689
1690 nb_pad -= hashlen;
1691 }
1692
Hanno Becker2b2f8982017-09-27 17:10:03 +01001693 /* Need space for signature header and padding delimiter (3 bytes),
1694 * and 8 bytes for the minimal padding */
1695 if( nb_pad < 3 + 8 )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001696 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1697 nb_pad -= 3;
1698
1699 /* Now nb_pad is the amount of memory to be filled
Hanno Becker2b2f8982017-09-27 17:10:03 +01001700 * with padding, and at least 8 bytes long. */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001701
1702 /* Write signature header and padding */
1703 *p++ = 0;
1704 *p++ = MBEDTLS_RSA_SIGN;
1705 memset( p, 0xFF, nb_pad );
1706 p += nb_pad;
1707 *p++ = 0;
1708
1709 /* Are we signing raw data? */
1710 if( md_alg == MBEDTLS_MD_NONE )
1711 {
1712 memcpy( p, hash, hashlen );
1713 return( 0 );
1714 }
1715
1716 /* Signing hashed data, add corresponding ASN.1 structure
1717 *
1718 * DigestInfo ::= SEQUENCE {
1719 * digestAlgorithm DigestAlgorithmIdentifier,
1720 * digest Digest }
1721 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1722 * Digest ::= OCTET STRING
1723 *
1724 * Schematic:
1725 * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
1726 * TAG-NULL + LEN [ NULL ] ]
1727 * TAG-OCTET + LEN [ HASH ] ]
1728 */
1729 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001730 *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001731 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001732 *p++ = (unsigned char)( 0x04 + oid_size );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001733 *p++ = MBEDTLS_ASN1_OID;
Hanno Becker87ae1972018-01-15 15:27:56 +00001734 *p++ = (unsigned char) oid_size;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001735 memcpy( p, oid, oid_size );
1736 p += oid_size;
1737 *p++ = MBEDTLS_ASN1_NULL;
1738 *p++ = 0x00;
1739 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Hanno Becker87ae1972018-01-15 15:27:56 +00001740 *p++ = (unsigned char) hashlen;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001741 memcpy( p, hash, hashlen );
1742 p += hashlen;
1743
1744 /* Just a sanity-check, should be automatic
1745 * after the initial bounds check. */
Hanno Beckere58d38c2017-09-27 17:09:00 +01001746 if( p != dst + dst_len )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001747 {
Hanno Beckere58d38c2017-09-27 17:09:00 +01001748 mbedtls_zeroize( dst, dst_len );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001749 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1750 }
1751
1752 return( 0 );
1753}
1754
Paul Bakkerb3869132013-02-28 17:21:01 +01001755/*
1756 * Do an RSA operation to sign the message digest
1757 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001758int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001759 int (*f_rng)(void *, unsigned char *, size_t),
1760 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001761 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001762 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001763 unsigned int hashlen,
1764 const unsigned char *hash,
1765 unsigned char *sig )
1766{
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001767 int ret;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001768 unsigned char *sig_try = NULL, *verif = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01001769
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001770 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1771 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001772
Hanno Beckerfdf38032017-09-06 12:35:55 +01001773 /*
1774 * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
1775 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001776
Hanno Beckerfdf38032017-09-06 12:35:55 +01001777 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
1778 ctx->len, sig ) ) != 0 )
1779 return( ret );
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001780
1781 /*
Hanno Beckerfdf38032017-09-06 12:35:55 +01001782 * Call respective RSA primitive
1783 */
1784
1785 if( mode == MBEDTLS_RSA_PUBLIC )
1786 {
1787 /* Skip verification on a public key operation */
1788 return( mbedtls_rsa_public( ctx, sig, sig ) );
1789 }
1790
1791 /* Private key operation
1792 *
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001793 * In order to prevent Lenstra's attack, make the signature in a
1794 * temporary buffer and check it before returning it.
1795 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001796
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001797 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001798 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001799 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1800
Hanno Beckerfdf38032017-09-06 12:35:55 +01001801 verif = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001802 if( verif == NULL )
1803 {
1804 mbedtls_free( sig_try );
1805 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1806 }
1807
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001808 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
1809 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
1810
Hanno Becker171a8f12017-09-06 12:32:16 +01001811 if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001812 {
1813 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
1814 goto cleanup;
1815 }
1816
1817 memcpy( sig, sig_try, ctx->len );
1818
1819cleanup:
1820 mbedtls_free( sig_try );
1821 mbedtls_free( verif );
1822
1823 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001824}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001826
1827/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 * Do an RSA operation to sign the message digest
1829 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001830int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001831 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00001832 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001834 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00001835 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001836 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00001837 unsigned char *sig )
1838{
Paul Bakker5121ce52009-01-03 21:22:43 +00001839 switch( ctx->padding )
1840 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001841#if defined(MBEDTLS_PKCS1_V15)
1842 case MBEDTLS_RSA_PKCS_V15:
1843 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001844 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001845#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847#if defined(MBEDTLS_PKCS1_V21)
1848 case MBEDTLS_RSA_PKCS_V21:
1849 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001850 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001851#endif
1852
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001856}
1857
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001858#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001859/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001860 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001862int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001863 int (*f_rng)(void *, unsigned char *, size_t),
1864 void *p_rng,
1865 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001867 unsigned int hashlen,
1868 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001869 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001870 int expected_salt_len,
1871 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00001872{
Paul Bakker23986e52011-04-24 08:57:21 +00001873 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001874 size_t siglen;
1875 unsigned char *p;
Gilles Peskine6a54b022017-10-17 19:02:13 +02001876 unsigned char *hash_start;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001878 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00001879 unsigned int hlen;
Gilles Peskine6a54b022017-10-17 19:02:13 +02001880 size_t observed_salt_len, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001881 const mbedtls_md_info_t *md_info;
1882 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01001883 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1886 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001887
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 siglen = ctx->len;
1889
Paul Bakker27fdf462011-06-09 13:55:13 +00001890 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001891 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001893 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1894 ? mbedtls_rsa_public( ctx, sig, buf )
1895 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
1897 if( ret != 0 )
1898 return( ret );
1899
1900 p = buf;
1901
Paul Bakkerb3869132013-02-28 17:21:01 +01001902 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001906 {
Simon Butcher02037452016-03-01 21:19:12 +00001907 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001909 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001911
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001912 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001913 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001915 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001916 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001917 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001918
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919 hlen = mbedtls_md_get_size( md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001920
Paul Bakkerb3869132013-02-28 17:21:01 +01001921 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00001922
Simon Butcher02037452016-03-01 21:19:12 +00001923 /*
1924 * Note: EMSA-PSS verification is over the length of N - 1 bits
1925 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001926 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001927
Gilles Peskineb00b0da2017-10-19 15:23:49 +02001928 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
1929 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1930
Simon Butcher02037452016-03-01 21:19:12 +00001931 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001932 if( msb % 8 == 0 )
1933 {
1934 p++;
1935 siglen -= 1;
1936 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001937
Gilles Peskine139108a2017-10-18 19:03:42 +02001938 if( siglen < hlen + 2 )
1939 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1940 hash_start = p + siglen - hlen - 1;
1941
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001942 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001943 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001944 goto exit;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001945
Jaeden Amero66954e12018-01-25 16:05:54 +00001946 ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
1947 if( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001948 goto exit;
Paul Bakker02303e82013-01-03 11:08:31 +01001949
Paul Bakkerb3869132013-02-28 17:21:01 +01001950 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001951
Gilles Peskine6a54b022017-10-17 19:02:13 +02001952 while( p < hash_start - 1 && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001953 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001954
Gilles Peskine91048a32017-10-19 17:46:14 +02001955 if( *p++ != 0x01 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001956 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001957 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1958 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001959 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001960
Gilles Peskine6a54b022017-10-17 19:02:13 +02001961 observed_salt_len = hash_start - p;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001963 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Gilles Peskine6a54b022017-10-17 19:02:13 +02001964 observed_salt_len != (size_t) expected_salt_len )
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001965 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001966 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1967 goto exit;
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001968 }
1969
Simon Butcher02037452016-03-01 21:19:12 +00001970 /*
1971 * Generate H = Hash( M' )
1972 */
Jaeden Amero66954e12018-01-25 16:05:54 +00001973 ret = mbedtls_md_starts( &md_ctx );
1974 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001975 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001976 ret = mbedtls_md_update( &md_ctx, zeros, 8 );
1977 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001978 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001979 ret = mbedtls_md_update( &md_ctx, hash, hashlen );
1980 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001981 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001982 ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );
1983 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001984 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001985 ret = mbedtls_md_finish( &md_ctx, result );
1986 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001987 goto exit;
Paul Bakker53019ae2011-03-25 13:58:48 +00001988
Jaeden Amero66954e12018-01-25 16:05:54 +00001989 if( memcmp( hash_start, result, hlen ) != 0 )
Andres Amaya Garciac5c7d762017-07-20 14:42:16 +01001990 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001991 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
Andres Amaya Garciac5c7d762017-07-20 14:42:16 +01001992 goto exit;
1993 }
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001994
1995exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001996 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001997
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001998 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001999}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002000
2001/*
2002 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2003 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002004int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002005 int (*f_rng)(void *, unsigned char *, size_t),
2006 void *p_rng,
2007 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002008 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002009 unsigned int hashlen,
2010 const unsigned char *hash,
2011 const unsigned char *sig )
2012{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002013 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2014 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002015 : md_alg;
2016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002018 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002020 sig ) );
2021
2022}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002025#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002026/*
2027 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2028 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002029int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002030 int (*f_rng)(void *, unsigned char *, size_t),
2031 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002032 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002033 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002034 unsigned int hashlen,
2035 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002036 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002037{
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002038 int ret = 0;
2039 const size_t sig_len = ctx->len;
2040 unsigned char *encoded = NULL, *encoded_expected = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01002041
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2043 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002044
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002045 /*
2046 * Prepare expected PKCS1 v1.5 encoding of hash.
2047 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002048
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002049 if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL ||
2050 ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
2051 {
2052 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2053 goto cleanup;
2054 }
2055
2056 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
2057 encoded_expected ) ) != 0 )
2058 goto cleanup;
2059
2060 /*
2061 * Apply RSA primitive to get what should be PKCS1 encoded hash.
2062 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002064 ret = ( mode == MBEDTLS_RSA_PUBLIC )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002065 ? mbedtls_rsa_public( ctx, sig, encoded )
2066 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded );
Paul Bakkerb3869132013-02-28 17:21:01 +01002067 if( ret != 0 )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002068 goto cleanup;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002069
Simon Butcher02037452016-03-01 21:19:12 +00002070 /*
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002071 * Compare
Simon Butcher02037452016-03-01 21:19:12 +00002072 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002073
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002074 if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
2075 sig_len ) ) != 0 )
2076 {
2077 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2078 goto cleanup;
2079 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002080
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002081cleanup:
Paul Bakkerc70b9822013-04-07 22:00:46 +02002082
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002083 if( encoded != NULL )
2084 {
2085 mbedtls_zeroize( encoded, sig_len );
2086 mbedtls_free( encoded );
2087 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002088
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002089 if( encoded_expected != NULL )
2090 {
2091 mbedtls_zeroize( encoded_expected, sig_len );
2092 mbedtls_free( encoded_expected );
2093 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002094
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002095 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002096}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
2099/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002100 * Do an RSA operation and check the message digest
2101 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002102int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002103 int (*f_rng)(void *, unsigned char *, size_t),
2104 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002105 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002106 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002107 unsigned int hashlen,
2108 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002109 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002110{
2111 switch( ctx->padding )
2112 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113#if defined(MBEDTLS_PKCS1_V15)
2114 case MBEDTLS_RSA_PKCS_V15:
2115 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002116 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002117#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002119#if defined(MBEDTLS_PKCS1_V21)
2120 case MBEDTLS_RSA_PKCS_V21:
2121 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002122 hashlen, hash, sig );
2123#endif
2124
2125 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002126 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002127 }
2128}
2129
2130/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002131 * Copy the components of an RSA key
2132 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002133int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002134{
2135 int ret;
2136
2137 dst->ver = src->ver;
2138 dst->len = src->len;
2139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002140 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2141 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2144 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2145 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002146
2147#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002148 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2149 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2150 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2152 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002153#endif
2154
2155 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2158 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002159
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002160 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002161 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002162
2163cleanup:
2164 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002165 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002166
2167 return( ret );
2168}
2169
2170/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002171 * Free the components of an RSA key
2172 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002173void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002174{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002176 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2177 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002179
Hanno Becker33c30a02017-08-23 07:00:22 +01002180#if !defined(MBEDTLS_RSA_NO_CRT)
2181 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2182 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2183 mbedtls_mpi_free( &ctx->DP );
2184#endif /* MBEDTLS_RSA_NO_CRT */
2185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002186#if defined(MBEDTLS_THREADING_C)
2187 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002188#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002189}
2190
Hanno Beckerab377312017-08-23 16:24:51 +01002191#endif /* !MBEDTLS_RSA_ALT */
2192
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002193#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002194
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002195#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002196
2197/*
2198 * Example RSA-1024 keypair, for test purposes
2199 */
2200#define KEY_LEN 128
2201
2202#define RSA_N "9292758453063D803DD603D5E777D788" \
2203 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2204 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2205 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2206 "93A89813FBF3C4F8066D2D800F7C38A8" \
2207 "1AE31942917403FF4946B0A83D3D3E05" \
2208 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2209 "5E94BB77B07507233A0BC7BAC8F90F79"
2210
2211#define RSA_E "10001"
2212
2213#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2214 "66CA472BC44D253102F8B4A9D3BFA750" \
2215 "91386C0077937FE33FA3252D28855837" \
2216 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2217 "DF79C5CE07EE72C7F123142198164234" \
2218 "CABB724CF78B8173B9F880FC86322407" \
2219 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2220 "071513A1E85B5DFA031F21ECAE91A34D"
2221
2222#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2223 "2C01CAD19EA484A87EA4377637E75500" \
2224 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2225 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2226
2227#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2228 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2229 "910E4168387E3C30AA1E00C339A79508" \
2230 "8452DD96A9A5EA5D9DCA68DA636032AF"
2231
Paul Bakker5121ce52009-01-03 21:22:43 +00002232#define PT_LEN 24
2233#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2234 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002236#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002237static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002238{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002239#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002240 size_t i;
2241
Paul Bakker545570e2010-07-18 09:00:25 +00002242 if( rng_state != NULL )
2243 rng_state = NULL;
2244
Paul Bakkera3d195c2011-11-27 21:07:34 +00002245 for( i = 0; i < len; ++i )
2246 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002247#else
2248 if( rng_state != NULL )
2249 rng_state = NULL;
2250
2251 arc4random_buf( output, len );
2252#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002253
Paul Bakkera3d195c2011-11-27 21:07:34 +00002254 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002255}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002256#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002257
Paul Bakker5121ce52009-01-03 21:22:43 +00002258/*
2259 * Checkup routine
2260 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002261int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002262{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002263 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002264#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002265 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002266 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002267 unsigned char rsa_plaintext[PT_LEN];
2268 unsigned char rsa_decrypted[PT_LEN];
2269 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002270#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002271 unsigned char sha1sum[20];
2272#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002273
Hanno Becker3a701162017-08-22 13:52:43 +01002274 mbedtls_mpi K;
2275
2276 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
Hanno Becker3a701162017-08-22 13:52:43 +01002279 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2280 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2281 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2282 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2283 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2284 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2285 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2286 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2287 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2288 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2289
Hanno Becker7f25f852017-10-10 16:56:22 +01002290 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002291
2292 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002293 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2296 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002297 {
2298 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002299 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002300
Hanno Becker5bc87292017-05-03 15:09:31 +01002301 ret = 1;
2302 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002303 }
2304
2305 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002306 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002307
2308 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2309
Hanno Becker98838b02017-10-02 13:16:10 +01002310 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2311 PT_LEN, rsa_plaintext,
2312 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002313 {
2314 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002315 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002316
Hanno Becker5bc87292017-05-03 15:09:31 +01002317 ret = 1;
2318 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002319 }
2320
2321 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002323
Hanno Becker98838b02017-10-02 13:16:10 +01002324 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2325 &len, rsa_ciphertext, rsa_decrypted,
2326 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002327 {
2328 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002329 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002330
Hanno Becker5bc87292017-05-03 15:09:31 +01002331 ret = 1;
2332 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002333 }
2334
2335 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2336 {
2337 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002339
Hanno Becker5bc87292017-05-03 15:09:31 +01002340 ret = 1;
2341 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002342 }
2343
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002344 if( verbose != 0 )
2345 mbedtls_printf( "passed\n" );
2346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002347#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002348 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002349 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002350
Gilles Peskine9e4f77c2018-01-22 11:48:08 +01002351 if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01002352 {
2353 if( verbose != 0 )
2354 mbedtls_printf( "failed\n" );
2355
2356 return( 1 );
2357 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002358
Hanno Becker98838b02017-10-02 13:16:10 +01002359 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2360 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2361 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002362 {
2363 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002365
Hanno Becker5bc87292017-05-03 15:09:31 +01002366 ret = 1;
2367 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002368 }
2369
2370 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002371 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002372
Hanno Becker98838b02017-10-02 13:16:10 +01002373 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2374 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2375 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002376 {
2377 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002378 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002379
Hanno Becker5bc87292017-05-03 15:09:31 +01002380 ret = 1;
2381 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002382 }
2383
2384 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002385 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002386#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002387
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002388 if( verbose != 0 )
2389 mbedtls_printf( "\n" );
2390
Paul Bakker3d8fb632014-04-17 12:42:41 +02002391cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002392 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002393 mbedtls_rsa_free( &rsa );
2394#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002395 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002396#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002397 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002398}
2399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002400#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002402#endif /* MBEDTLS_RSA_C */