blob: 2f72d4064cc7aa4b4829b6c141f9ddaae516275a [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
498 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000500 int (*f_rng)(void *, unsigned char *, size_t),
501 void *p_rng,
502 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000503{
504 int ret;
Jethro Beekman97f95c92018-02-13 15:50:36 -0800505 mbedtls_mpi H, G, L;
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Paul Bakker21eb2802010-08-16 11:10:02 +0000507 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Janos Follathef441782016-09-21 13:18:12 +0100510 if( nbits % 2 )
511 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
512
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100513 mbedtls_mpi_init( &H );
514 mbedtls_mpi_init( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800515 mbedtls_mpi_init( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
517 /*
518 * find primes P and Q with Q < P so that:
Jethro Beekman97f95c92018-02-13 15:50:36 -0800519 * 1. GCD( E, (P-1)*(Q-1) ) == 1
520 * 2. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524 do
525 {
Janos Follath10c575b2016-02-23 14:42:48 +0000526 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100527 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
Janos Follathef441782016-09-21 13:18:12 +0100529 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100530 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 continue;
534
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200536 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 continue;
538
Janos Follathef441782016-09-21 13:18:12 +0100539 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100540 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100541
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100542 /* Temporarily replace P,Q by P-1, Q-1 */
543 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
544 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
545 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800546
547 /* check GCD( E, (P-1)*(Q-1) ) == 1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800549 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
550 continue;
551
552 /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) */
553 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
554 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
555 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
556
557 if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
558 continue;
559
560 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 }
Jethro Beekman97f95c92018-02-13 15:50:36 -0800562 while( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100564 /* Restore P,Q */
565 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
566 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
567
568 ctx->len = mbedtls_mpi_size( &ctx->N );
569
Jethro Beekman97f95c92018-02-13 15:50:36 -0800570#if !defined(MBEDTLS_RSA_NO_CRT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 * DP = D mod (P - 1)
573 * DQ = D mod (Q - 1)
574 * QP = Q^-1 mod P
575 */
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100576 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
577 &ctx->DP, &ctx->DQ, &ctx->QP ) );
578#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Hanno Becker83aad1f2017-08-23 06:45:10 +0100580 /* Double-check */
581 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583cleanup:
584
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100585 mbedtls_mpi_free( &H );
586 mbedtls_mpi_free( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800587 mbedtls_mpi_free( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
589 if( ret != 0 )
590 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_rsa_free( ctx );
592 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 }
594
Paul Bakker48377d92013-08-30 12:06:24 +0200595 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596}
597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600/*
601 * Check a public RSA key
602 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000604{
Hanno Beckerebd2c022017-10-12 10:54:53 +0100605 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d9f2009-07-10 22:38:58 +0000607
Hanno Becker3a760a12018-01-05 08:14:49 +0000608 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
Hanno Becker98838b02017-10-02 13:16:10 +0100609 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100611 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Hanno Becker705fc682017-10-10 17:57:02 +0100613 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
614 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100616 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100618 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620 return( 0 );
621}
622
623/*
Hanno Becker705fc682017-10-10 17:57:02 +0100624 * Check for the consistency of all fields in an RSA private key context
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000627{
Hanno Becker705fc682017-10-10 17:57:02 +0100628 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
Hanno Beckerebd2c022017-10-12 10:54:53 +0100629 rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 {
Hanno Becker98838b02017-10-02 13:16:10 +0100631 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 }
Paul Bakker48377d92013-08-30 12:06:24 +0200633
Hanno Becker98838b02017-10-02 13:16:10 +0100634 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +0100635 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 {
Hanno Beckerb269a852017-08-25 08:03:21 +0100637 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000639
Hanno Beckerb269a852017-08-25 08:03:21 +0100640#if !defined(MBEDTLS_RSA_NO_CRT)
641 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
642 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
643 {
644 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
645 }
646#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +0000647
648 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649}
650
651/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100652 * Check if contexts holding a public and private key match
653 */
Hanno Becker98838b02017-10-02 13:16:10 +0100654int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
655 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100656{
Hanno Becker98838b02017-10-02 13:16:10 +0100657 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100659 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100661 }
662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
664 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100665 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100667 }
668
669 return( 0 );
670}
671
672/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 * Do an RSA public key operation
674 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000676 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 unsigned char *output )
678{
Paul Bakker23986e52011-04-24 08:57:21 +0000679 int ret;
680 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Hanno Beckerebd2c022017-10-12 10:54:53 +0100683 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
Hanno Becker705fc682017-10-10 17:57:02 +0100684 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200688#if defined(MBEDTLS_THREADING_C)
689 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
690 return( ret );
691#endif
692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200697 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
698 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 }
700
701 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
703 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
705cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200707 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
708 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +0100709#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
713 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716 return( 0 );
717}
718
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200719/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200720 * Generate or update blinding values, see section 10 of:
721 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200722 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200723 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200724 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200725static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200726 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
727{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200728 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200729
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200730 if( ctx->Vf.p != NULL )
731 {
732 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
734 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
735 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
736 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200737
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200738 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200739 }
740
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200741 /* Unblinding value: Vf = random number, invertible mod N */
742 do {
743 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
747 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
748 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200749
750 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
752 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 +0200753
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200754
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200755cleanup:
756 return( ret );
757}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200758
Paul Bakker5121ce52009-01-03 21:22:43 +0000759/*
Janos Follathe81102e2017-03-22 13:38:28 +0000760 * Exponent blinding supposed to prevent side-channel attacks using multiple
761 * traces of measurements to recover the RSA key. The more collisions are there,
762 * the more bits of the key can be recovered. See [3].
763 *
764 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
765 * observations on avarage.
766 *
767 * For example with 28 byte blinding to achieve 2 collisions the adversary has
768 * to make 2^112 observations on avarage.
769 *
770 * (With the currently (as of 2017 April) known best algorithms breaking 2048
771 * bit RSA requires approximately as much time as trying out 2^112 random keys.
772 * Thus in this sense with 28 byte blinding the security is not reduced by
773 * side-channel attacks like the one in [3])
774 *
775 * This countermeasure does not help if the key recovery is possible with a
776 * single trace.
777 */
778#define RSA_EXPONENT_BLINDING 28
779
780/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 * Do an RSA private key operation
782 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200784 int (*f_rng)(void *, unsigned char *, size_t),
785 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000786 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 unsigned char *output )
788{
Paul Bakker23986e52011-04-24 08:57:21 +0000789 int ret;
790 size_t olen;
Hanno Becker06811ce2017-05-03 15:10:34 +0100791
792 /* Temporary holding the result */
793 mbedtls_mpi T;
794
795 /* Temporaries holding P-1, Q-1 and the
796 * exponent blinding factor, respectively. */
Janos Follathf9203b42017-03-22 15:13:15 +0000797 mbedtls_mpi P1, Q1, R;
Hanno Becker06811ce2017-05-03 15:10:34 +0100798
799#if !defined(MBEDTLS_RSA_NO_CRT)
800 /* Temporaries holding the results mod p resp. mod q. */
801 mbedtls_mpi TP, TQ;
802
803 /* Temporaries holding the blinded exponents for
804 * the mod p resp. mod q computation (if used). */
Janos Follathf9203b42017-03-22 15:13:15 +0000805 mbedtls_mpi DP_blind, DQ_blind;
Hanno Becker06811ce2017-05-03 15:10:34 +0100806
807 /* Pointers to actual exponents to be used - either the unblinded
808 * or the blinded ones, depending on the presence of a PRNG. */
Janos Follathf9203b42017-03-22 15:13:15 +0000809 mbedtls_mpi *DP = &ctx->DP;
810 mbedtls_mpi *DQ = &ctx->DQ;
Hanno Becker06811ce2017-05-03 15:10:34 +0100811#else
812 /* Temporary holding the blinded exponent (if used). */
813 mbedtls_mpi D_blind;
814
815 /* Pointer to actual exponent to be used - either the unblinded
816 * or the blinded one, depending on the presence of a PRNG. */
817 mbedtls_mpi *D = &ctx->D;
Hanno Becker43f94722017-08-25 11:50:00 +0100818#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker06811ce2017-05-03 15:10:34 +0100819
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100820 /* Temporaries holding the initial input and the double
821 * checked result; should be the same in the end. */
822 mbedtls_mpi I, C;
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
Hanno Beckerebd2c022017-10-12 10:54:53 +0100824 if( rsa_check_context( ctx, 1 /* private key checks */,
825 f_rng != NULL /* blinding y/n */ ) != 0 )
826 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100827 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Beckerebd2c022017-10-12 10:54:53 +0100828 }
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100829
Hanno Becker06811ce2017-05-03 15:10:34 +0100830#if defined(MBEDTLS_THREADING_C)
831 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
832 return( ret );
833#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000834
Hanno Becker06811ce2017-05-03 15:10:34 +0100835 /* MPI Initialization */
Hanno Becker06811ce2017-05-03 15:10:34 +0100836 mbedtls_mpi_init( &T );
837
838 mbedtls_mpi_init( &P1 );
839 mbedtls_mpi_init( &Q1 );
840 mbedtls_mpi_init( &R );
Janos Follathf9203b42017-03-22 15:13:15 +0000841
Janos Follathf9203b42017-03-22 15:13:15 +0000842 if( f_rng != NULL )
843 {
Janos Follathe81102e2017-03-22 13:38:28 +0000844#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000845 mbedtls_mpi_init( &D_blind );
846#else
847 mbedtls_mpi_init( &DP_blind );
848 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000849#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000850 }
Janos Follathe81102e2017-03-22 13:38:28 +0000851
Hanno Becker06811ce2017-05-03 15:10:34 +0100852#if !defined(MBEDTLS_RSA_NO_CRT)
853 mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200854#endif
855
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100856 mbedtls_mpi_init( &I );
857 mbedtls_mpi_init( &C );
Hanno Becker06811ce2017-05-03 15:10:34 +0100858
859 /* End of MPI initialization */
860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
862 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000863 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200864 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
865 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 }
867
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100868 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
Hanno Becker06811ce2017-05-03 15:10:34 +0100869
Paul Bakkerf451bac2013-08-30 15:37:02 +0200870 if( f_rng != NULL )
871 {
872 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200873 * Blinding
874 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200875 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200876 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
877 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000879
Janos Follathe81102e2017-03-22 13:38:28 +0000880 /*
881 * Exponent blinding
882 */
883 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
884 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
885
Janos Follathf9203b42017-03-22 15:13:15 +0000886#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000887 /*
888 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
889 */
890 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
891 f_rng, p_rng ) );
892 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
893 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
894 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
895
896 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +0000897#else
898 /*
899 * DP_blind = ( P - 1 ) * R + DP
900 */
901 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
902 f_rng, p_rng ) );
903 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
904 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
905 &ctx->DP ) );
906
907 DP = &DP_blind;
908
909 /*
910 * DQ_blind = ( Q - 1 ) * R + DQ
911 */
912 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
913 f_rng, p_rng ) );
914 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
915 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
916 &ctx->DQ ) );
917
918 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +0000919#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkerf451bac2013-08-30 15:37:02 +0200920 }
Paul Bakkeraab30c12013-08-30 11:00:25 +0200921
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +0000923 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +0100924#else
Paul Bakkeraab30c12013-08-30 11:00:25 +0200925 /*
Janos Follathe81102e2017-03-22 13:38:28 +0000926 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 *
Hanno Becker06811ce2017-05-03 15:10:34 +0100928 * TP = input ^ dP mod P
929 * TQ = input ^ dQ mod Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100931
932 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
933 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
935 /*
Hanno Becker06811ce2017-05-03 15:10:34 +0100936 * T = (TP - TQ) * (Q^-1 mod P) mod P
Paul Bakker5121ce52009-01-03 21:22:43 +0000937 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100938 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
939 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
940 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
942 /*
Hanno Becker06811ce2017-05-03 15:10:34 +0100943 * T = TQ + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 */
Hanno Becker06811ce2017-05-03 15:10:34 +0100945 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
946 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +0200948
Paul Bakkerf451bac2013-08-30 15:37:02 +0200949 if( f_rng != NULL )
950 {
951 /*
952 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200953 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200954 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200955 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +0200957 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000958
Hanno Becker2dec5e82017-10-03 07:49:52 +0100959 /* Verify the result to prevent glitching attacks. */
960 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
961 &ctx->N, &ctx->RN ) );
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100962 if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
Hanno Becker06811ce2017-05-03 15:10:34 +0100963 {
Hanno Becker06811ce2017-05-03 15:10:34 +0100964 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
965 goto cleanup;
966 }
Hanno Becker06811ce2017-05-03 15:10:34 +0100967
Paul Bakker5121ce52009-01-03 21:22:43 +0000968 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000970
971cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200973 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
974 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200975#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200976
Hanno Becker06811ce2017-05-03 15:10:34 +0100977 mbedtls_mpi_free( &P1 );
978 mbedtls_mpi_free( &Q1 );
979 mbedtls_mpi_free( &R );
Janos Follathf9203b42017-03-22 15:13:15 +0000980
981 if( f_rng != NULL )
982 {
Janos Follathe81102e2017-03-22 13:38:28 +0000983#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathf9203b42017-03-22 15:13:15 +0000984 mbedtls_mpi_free( &D_blind );
985#else
986 mbedtls_mpi_free( &DP_blind );
987 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000988#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000989 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
Hanno Becker06811ce2017-05-03 15:10:34 +0100991 mbedtls_mpi_free( &T );
992
993#if !defined(MBEDTLS_RSA_NO_CRT)
994 mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
995#endif
996
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100997 mbedtls_mpi_free( &C );
998 mbedtls_mpi_free( &I );
Hanno Becker06811ce2017-05-03 15:10:34 +0100999
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001002
1003 return( 0 );
1004}
1005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001007/**
1008 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1009 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001010 * \param dst buffer to mask
1011 * \param dlen length of destination buffer
1012 * \param src source of the mask generation
1013 * \param slen length of the source buffer
1014 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001015 */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001016static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001018{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001020 unsigned char counter[4];
1021 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001022 unsigned int hlen;
1023 size_t i, use_len;
Andres Amaya Garcia94682d12017-07-20 14:26:37 +01001024 int ret = 0;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001027 memset( counter, 0, 4 );
1028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001030
Simon Butcher02037452016-03-01 21:19:12 +00001031 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001032 p = dst;
1033
1034 while( dlen > 0 )
1035 {
1036 use_len = hlen;
1037 if( dlen < hlen )
1038 use_len = dlen;
1039
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001040 if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
1041 goto exit;
1042 if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
1043 goto exit;
1044 if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
1045 goto exit;
1046 if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
1047 goto exit;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001048
1049 for( i = 0; i < use_len; ++i )
1050 *p++ ^= mask[i];
1051
1052 counter[3]++;
1053
1054 dlen -= use_len;
1055 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001056
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001057exit:
Gilles Peskine18ac7162017-05-05 19:24:06 +02001058 mbedtls_zeroize( mask, sizeof( mask ) );
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001059
1060 return( ret );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001061}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001065/*
1066 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1067 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001069 int (*f_rng)(void *, unsigned char *, size_t),
1070 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001071 int mode,
1072 const unsigned char *label, size_t label_len,
1073 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001074 const unsigned char *input,
1075 unsigned char *output )
1076{
1077 size_t olen;
1078 int ret;
1079 unsigned char *p = output;
1080 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 const mbedtls_md_info_t *md_info;
1082 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1085 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001086
1087 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001089
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001090 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001091 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001092 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001093
1094 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001096
Simon Butcher02037452016-03-01 21:19:12 +00001097 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001098 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001100
1101 memset( output, 0, olen );
1102
1103 *p++ = 0;
1104
Simon Butcher02037452016-03-01 21:19:12 +00001105 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001106 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001108
1109 p += hlen;
1110
Simon Butcher02037452016-03-01 21:19:12 +00001111 /* Construct DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001112 if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
1113 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001114 p += hlen;
1115 p += olen - 2 * hlen - 2 - ilen;
1116 *p++ = 1;
1117 memcpy( p, input, ilen );
1118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001120 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001121 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001122
Simon Butcher02037452016-03-01 21:19:12 +00001123 /* maskedDB: Apply dbMask to DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001124 if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1125 &md_ctx ) ) != 0 )
1126 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001127
Simon Butcher02037452016-03-01 21:19:12 +00001128 /* maskedSeed: Apply seedMask to seed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001129 if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1130 &md_ctx ) ) != 0 )
1131 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001132
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001133exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +01001135
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001136 if( ret != 0 )
1137 return( ret );
1138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 return( ( mode == MBEDTLS_RSA_PUBLIC )
1140 ? mbedtls_rsa_public( ctx, output, output )
1141 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001142}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001143#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001146/*
1147 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1148 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001149int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001150 int (*f_rng)(void *, unsigned char *, size_t),
1151 void *p_rng,
1152 int mode, size_t ilen,
1153 const unsigned char *input,
1154 unsigned char *output )
1155{
1156 size_t nb_pad, olen;
1157 int ret;
1158 unsigned char *p = output;
1159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1161 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001162
Janos Follath1ed9f992016-03-18 11:45:44 +00001163 // We don't check p_rng because it won't be dereferenced here
1164 if( f_rng == NULL || input == NULL || output == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001166
1167 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001168
Simon Butcher02037452016-03-01 21:19:12 +00001169 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001170 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001172
1173 nb_pad = olen - 3 - ilen;
1174
1175 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +01001177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +01001179
1180 while( nb_pad-- > 0 )
1181 {
1182 int rng_dl = 100;
1183
1184 do {
1185 ret = f_rng( p_rng, p, 1 );
1186 } while( *p == 0 && --rng_dl && ret == 0 );
1187
Simon Butcher02037452016-03-01 21:19:12 +00001188 /* Check if RNG failed to generate data */
Paul Bakker66d5d072014-06-17 16:39:18 +02001189 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001191
1192 p++;
1193 }
1194 }
1195 else
1196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001197 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001198
1199 while( nb_pad-- > 0 )
1200 *p++ = 0xFF;
1201 }
1202
1203 *p++ = 0;
1204 memcpy( p, input, ilen );
1205
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001206 return( ( mode == MBEDTLS_RSA_PUBLIC )
1207 ? mbedtls_rsa_public( ctx, output, output )
1208 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001209}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001210#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001211
Paul Bakker5121ce52009-01-03 21:22:43 +00001212/*
1213 * Add the message padding, then do an RSA operation
1214 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001216 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001217 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +00001218 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001219 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001220 unsigned char *output )
1221{
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 switch( ctx->padding )
1223 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224#if defined(MBEDTLS_PKCS1_V15)
1225 case MBEDTLS_RSA_PKCS_V15:
1226 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001227 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001228#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230#if defined(MBEDTLS_PKCS1_V21)
1231 case MBEDTLS_RSA_PKCS_V21:
1232 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +01001233 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001234#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001235
1236 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001238 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001239}
1240
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001242/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001243 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001244 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001245int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001246 int (*f_rng)(void *, unsigned char *, size_t),
1247 void *p_rng,
1248 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +01001249 const unsigned char *label, size_t label_len,
1250 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001251 const unsigned char *input,
1252 unsigned char *output,
1253 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001254{
Paul Bakker23986e52011-04-24 08:57:21 +00001255 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001256 size_t ilen, i, pad_len;
1257 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001258 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1259 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001260 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001261 const mbedtls_md_info_t *md_info;
1262 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001263
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001264 /*
1265 * Parameters sanity checks
1266 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1268 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
1270 ilen = ctx->len;
1271
Paul Bakker27fdf462011-06-09 13:55:13 +00001272 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001273 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001276 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001277 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001278
Janos Follathc17cda12016-02-11 11:08:18 +00001279 hlen = mbedtls_md_get_size( md_info );
1280
1281 // checking for integer underflow
1282 if( 2 * hlen + 2 > ilen )
1283 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1284
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001285 /*
1286 * RSA operation
1287 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1289 ? mbedtls_rsa_public( ctx, input, buf )
1290 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001291
1292 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001293 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001294
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001295 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001296 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001297 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001299 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1300 {
1301 mbedtls_md_free( &md_ctx );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001302 goto cleanup;
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001303 }
1304
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001305 /* seed: Apply seedMask to maskedSeed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001306 if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1307 &md_ctx ) ) != 0 ||
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001308 /* DB: Apply dbMask to maskedDB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001309 ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1310 &md_ctx ) ) != 0 )
1311 {
1312 mbedtls_md_free( &md_ctx );
1313 goto cleanup;
1314 }
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001316 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001317
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001318 /* Generate lHash */
1319 if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
1320 goto cleanup;
1321
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001322 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001323 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001324 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001325 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001326 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001328 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001329
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001330 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001331
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001332 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001333 for( i = 0; i < hlen; i++ )
1334 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001335
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001336 /* Get zero-padding len, but always read till end of buffer
1337 * (minus one, for the 01 byte) */
1338 pad_len = 0;
1339 pad_done = 0;
1340 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1341 {
1342 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001343 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001344 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001345
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001346 p += pad_len;
1347 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001348
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001349 /*
1350 * The only information "leaked" is whether the padding was correct or not
1351 * (eg, no data is copied if it was not correct). This meets the
1352 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1353 * the different error conditions.
1354 */
1355 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001356 {
1357 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1358 goto cleanup;
1359 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001360
Paul Bakker66d5d072014-06-17 16:39:18 +02001361 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001362 {
1363 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1364 goto cleanup;
1365 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001366
1367 *olen = ilen - (p - buf);
1368 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001369 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001370
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001371cleanup:
1372 mbedtls_zeroize( buf, sizeof( buf ) );
1373 mbedtls_zeroize( lhash, sizeof( lhash ) );
1374
1375 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001376}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001379#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001380/*
1381 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1382 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001384 int (*f_rng)(void *, unsigned char *, size_t),
1385 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001386 int mode, size_t *olen,
1387 const unsigned char *input,
1388 unsigned char *output,
1389 size_t output_max_len)
1390{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001391 int ret;
1392 size_t ilen, pad_count = 0, i;
1393 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001394 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001396 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1397 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001398
1399 ilen = ctx->len;
1400
1401 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1405 ? mbedtls_rsa_public( ctx, input, buf )
1406 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001407
1408 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001409 goto cleanup;
Paul Bakkerb3869132013-02-28 17:21:01 +01001410
1411 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001412 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001413
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001414 /*
1415 * Check and get padding len in "constant-time"
1416 */
1417 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001418
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001419 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001421 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +00001423
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001424 /* Get padding len, but always read till end of buffer
1425 * (minus one, for the 00 byte) */
1426 for( i = 0; i < ilen - 3; i++ )
1427 {
Pascal Junodb99183d2015-03-11 16:49:45 +01001428 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
1429 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001430 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +00001431
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001432 p += pad_count;
1433 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +01001434 }
1435 else
1436 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001438
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001439 /* Get padding len, but always read till end of buffer
1440 * (minus one, for the 00 byte) */
1441 for( i = 0; i < ilen - 3; i++ )
1442 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +01001443 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001444 pad_count += ( pad_done == 0 );
1445 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001446
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001447 p += pad_count;
1448 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +00001449 }
1450
Janos Follathc69fa502016-02-12 13:30:09 +00001451 bad |= ( pad_count < 8 );
Janos Follathb6eb1ca2016-02-08 13:59:25 +00001452
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +01001453 if( bad )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001454 {
1455 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1456 goto cleanup;
1457 }
Paul Bakker8804f692013-02-28 18:06:26 +01001458
Paul Bakker66d5d072014-06-17 16:39:18 +02001459 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001460 {
1461 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1462 goto cleanup;
1463 }
Paul Bakker060c5682009-01-12 21:48:39 +00001464
Paul Bakker27fdf462011-06-09 13:55:13 +00001465 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +00001466 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001467 ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001468
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001469cleanup:
1470 mbedtls_zeroize( buf, sizeof( buf ) );
1471
1472 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001473}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001475
1476/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001477 * Do an RSA operation, then remove the message padding
1478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001480 int (*f_rng)(void *, unsigned char *, size_t),
1481 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001482 int mode, size_t *olen,
1483 const unsigned char *input,
1484 unsigned char *output,
1485 size_t output_max_len)
1486{
1487 switch( ctx->padding )
1488 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_PKCS1_V15)
1490 case MBEDTLS_RSA_PKCS_V15:
1491 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001492 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001493#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#if defined(MBEDTLS_PKCS1_V21)
1496 case MBEDTLS_RSA_PKCS_V21:
1497 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001498 olen, input, output,
1499 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001500#endif
1501
1502 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001503 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001504 }
1505}
1506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001508/*
1509 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1510 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001511int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001512 int (*f_rng)(void *, unsigned char *, size_t),
1513 void *p_rng,
1514 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001515 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001516 unsigned int hashlen,
1517 const unsigned char *hash,
1518 unsigned char *sig )
1519{
1520 size_t olen;
1521 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001523 unsigned int slen, hlen, offset = 0;
1524 int ret;
1525 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 const mbedtls_md_info_t *md_info;
1527 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001528
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001529 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1530 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001531
1532 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001533 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001534
1535 olen = ctx->len;
1536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001538 {
Simon Butcher02037452016-03-01 21:19:12 +00001539 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001541 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001545 }
1546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001548 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001552 slen = hlen;
1553
1554 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001555 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001556
1557 memset( sig, 0, olen );
1558
Simon Butcher02037452016-03-01 21:19:12 +00001559 /* Generate salt of length slen */
Paul Bakkerb3869132013-02-28 17:21:01 +01001560 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001561 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001562
Simon Butcher02037452016-03-01 21:19:12 +00001563 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001564 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001565 p += olen - hlen * 2 - 2;
1566 *p++ = 0x01;
1567 memcpy( p, salt, slen );
1568 p += slen;
1569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001571 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001572 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001573
Simon Butcher02037452016-03-01 21:19:12 +00001574 /* Generate H = Hash( M' ) */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001575 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
1576 goto exit;
1577 if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
1578 goto exit;
1579 if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
1580 goto exit;
1581 if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
1582 goto exit;
1583 if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
1584 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001585
Simon Butcher02037452016-03-01 21:19:12 +00001586 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001587 if( msb % 8 == 0 )
1588 offset = 1;
1589
Simon Butcher02037452016-03-01 21:19:12 +00001590 /* maskedDB: Apply dbMask to DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001591 if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
1592 &md_ctx ) ) != 0 )
1593 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001594
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001595 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001596 sig[0] &= 0xFF >> ( olen * 8 - msb );
1597
1598 p += hlen;
1599 *p++ = 0xBC;
1600
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001601 mbedtls_zeroize( salt, sizeof( salt ) );
1602
1603exit:
1604 mbedtls_md_free( &md_ctx );
1605
1606 if( ret != 0 )
1607 return( ret );
1608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609 return( ( mode == MBEDTLS_RSA_PUBLIC )
1610 ? mbedtls_rsa_public( ctx, sig, sig )
1611 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001612}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001613#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001615#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001616/*
1617 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1618 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001619
1620/* Construct a PKCS v1.5 encoding of a hashed message
1621 *
1622 * This is used both for signature generation and verification.
1623 *
1624 * Parameters:
1625 * - md_alg: Identifies the hash algorithm used to generate the given hash;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001626 * MBEDTLS_MD_NONE if raw data is signed.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001627 * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001628 * - hash: Buffer containing the hashed message or the raw data.
1629 * - dst_len: Length of the encoded message.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001630 * - dst: Buffer to hold the encoded message.
1631 *
1632 * Assumptions:
1633 * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
1634 * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001635 * - dst points to a buffer of size at least dst_len.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001636 *
1637 */
1638static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
1639 unsigned int hashlen,
1640 const unsigned char *hash,
Hanno Beckere58d38c2017-09-27 17:09:00 +01001641 size_t dst_len,
Hanno Beckerfdf38032017-09-06 12:35:55 +01001642 unsigned char *dst )
1643{
1644 size_t oid_size = 0;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001645 size_t nb_pad = dst_len;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001646 unsigned char *p = dst;
1647 const char *oid = NULL;
1648
1649 /* Are we signing hashed or raw data? */
1650 if( md_alg != MBEDTLS_MD_NONE )
1651 {
1652 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
1653 if( md_info == NULL )
1654 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1655
1656 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1657 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1658
1659 hashlen = mbedtls_md_get_size( md_info );
1660
1661 /* Double-check that 8 + hashlen + oid_size can be used as a
1662 * 1-byte ASN.1 length encoding and that there's no overflow. */
1663 if( 8 + hashlen + oid_size >= 0x80 ||
1664 10 + hashlen < hashlen ||
1665 10 + hashlen + oid_size < 10 + hashlen )
1666 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1667
1668 /*
1669 * Static bounds check:
1670 * - Need 10 bytes for five tag-length pairs.
1671 * (Insist on 1-byte length encodings to protect against variants of
1672 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
1673 * - Need hashlen bytes for hash
1674 * - Need oid_size bytes for hash alg OID.
1675 */
1676 if( nb_pad < 10 + hashlen + oid_size )
1677 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1678 nb_pad -= 10 + hashlen + oid_size;
1679 }
1680 else
1681 {
1682 if( nb_pad < hashlen )
1683 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1684
1685 nb_pad -= hashlen;
1686 }
1687
Hanno Becker2b2f8982017-09-27 17:10:03 +01001688 /* Need space for signature header and padding delimiter (3 bytes),
1689 * and 8 bytes for the minimal padding */
1690 if( nb_pad < 3 + 8 )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001691 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1692 nb_pad -= 3;
1693
1694 /* Now nb_pad is the amount of memory to be filled
Hanno Becker2b2f8982017-09-27 17:10:03 +01001695 * with padding, and at least 8 bytes long. */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001696
1697 /* Write signature header and padding */
1698 *p++ = 0;
1699 *p++ = MBEDTLS_RSA_SIGN;
1700 memset( p, 0xFF, nb_pad );
1701 p += nb_pad;
1702 *p++ = 0;
1703
1704 /* Are we signing raw data? */
1705 if( md_alg == MBEDTLS_MD_NONE )
1706 {
1707 memcpy( p, hash, hashlen );
1708 return( 0 );
1709 }
1710
1711 /* Signing hashed data, add corresponding ASN.1 structure
1712 *
1713 * DigestInfo ::= SEQUENCE {
1714 * digestAlgorithm DigestAlgorithmIdentifier,
1715 * digest Digest }
1716 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1717 * Digest ::= OCTET STRING
1718 *
1719 * Schematic:
1720 * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
1721 * TAG-NULL + LEN [ NULL ] ]
1722 * TAG-OCTET + LEN [ HASH ] ]
1723 */
1724 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001725 *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001726 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001727 *p++ = (unsigned char)( 0x04 + oid_size );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001728 *p++ = MBEDTLS_ASN1_OID;
Hanno Becker87ae1972018-01-15 15:27:56 +00001729 *p++ = (unsigned char) oid_size;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001730 memcpy( p, oid, oid_size );
1731 p += oid_size;
1732 *p++ = MBEDTLS_ASN1_NULL;
1733 *p++ = 0x00;
1734 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Hanno Becker87ae1972018-01-15 15:27:56 +00001735 *p++ = (unsigned char) hashlen;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001736 memcpy( p, hash, hashlen );
1737 p += hashlen;
1738
1739 /* Just a sanity-check, should be automatic
1740 * after the initial bounds check. */
Hanno Beckere58d38c2017-09-27 17:09:00 +01001741 if( p != dst + dst_len )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001742 {
Hanno Beckere58d38c2017-09-27 17:09:00 +01001743 mbedtls_zeroize( dst, dst_len );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001744 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1745 }
1746
1747 return( 0 );
1748}
1749
Paul Bakkerb3869132013-02-28 17:21:01 +01001750/*
1751 * Do an RSA operation to sign the message digest
1752 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001754 int (*f_rng)(void *, unsigned char *, size_t),
1755 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001756 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001757 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001758 unsigned int hashlen,
1759 const unsigned char *hash,
1760 unsigned char *sig )
1761{
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001762 int ret;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001763 unsigned char *sig_try = NULL, *verif = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01001764
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001765 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1766 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001767
Hanno Beckerfdf38032017-09-06 12:35:55 +01001768 /*
1769 * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
1770 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001771
Hanno Beckerfdf38032017-09-06 12:35:55 +01001772 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
1773 ctx->len, sig ) ) != 0 )
1774 return( ret );
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001775
1776 /*
Hanno Beckerfdf38032017-09-06 12:35:55 +01001777 * Call respective RSA primitive
1778 */
1779
1780 if( mode == MBEDTLS_RSA_PUBLIC )
1781 {
1782 /* Skip verification on a public key operation */
1783 return( mbedtls_rsa_public( ctx, sig, sig ) );
1784 }
1785
1786 /* Private key operation
1787 *
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001788 * In order to prevent Lenstra's attack, make the signature in a
1789 * temporary buffer and check it before returning it.
1790 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001791
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001792 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001793 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001794 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1795
Hanno Beckerfdf38032017-09-06 12:35:55 +01001796 verif = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001797 if( verif == NULL )
1798 {
1799 mbedtls_free( sig_try );
1800 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1801 }
1802
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001803 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
1804 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
1805
Hanno Becker171a8f12017-09-06 12:32:16 +01001806 if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001807 {
1808 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
1809 goto cleanup;
1810 }
1811
1812 memcpy( sig, sig_try, ctx->len );
1813
1814cleanup:
1815 mbedtls_free( sig_try );
1816 mbedtls_free( verif );
1817
1818 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001819}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001820#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001821
1822/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 * Do an RSA operation to sign the message digest
1824 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001826 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00001827 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001829 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00001830 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001831 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00001832 unsigned char *sig )
1833{
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 switch( ctx->padding )
1835 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836#if defined(MBEDTLS_PKCS1_V15)
1837 case MBEDTLS_RSA_PKCS_V15:
1838 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001839 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001840#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842#if defined(MBEDTLS_PKCS1_V21)
1843 case MBEDTLS_RSA_PKCS_V21:
1844 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001845 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001846#endif
1847
Paul Bakker5121ce52009-01-03 21:22:43 +00001848 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001851}
1852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001853#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001854/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001855 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001857int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001858 int (*f_rng)(void *, unsigned char *, size_t),
1859 void *p_rng,
1860 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001861 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001862 unsigned int hashlen,
1863 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001865 int expected_salt_len,
1866 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00001867{
Paul Bakker23986e52011-04-24 08:57:21 +00001868 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001869 size_t siglen;
1870 unsigned char *p;
Gilles Peskine6a54b022017-10-17 19:02:13 +02001871 unsigned char *hash_start;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001872 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001873 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00001874 unsigned int hlen;
Gilles Peskine6a54b022017-10-17 19:02:13 +02001875 size_t observed_salt_len, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001876 const mbedtls_md_info_t *md_info;
1877 mbedtls_md_context_t md_ctx;
Nicholas Wilson409401c2016-04-13 11:48:25 +01001878 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +01001879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1881 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001882
Paul Bakker5121ce52009-01-03 21:22:43 +00001883 siglen = ctx->len;
1884
Paul Bakker27fdf462011-06-09 13:55:13 +00001885 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001887
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001888 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1889 ? mbedtls_rsa_public( ctx, sig, buf )
1890 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001891
1892 if( ret != 0 )
1893 return( ret );
1894
1895 p = buf;
1896
Paul Bakkerb3869132013-02-28 17:21:01 +01001897 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001899
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001900 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001901 {
Simon Butcher02037452016-03-01 21:19:12 +00001902 /* Gather length of hash to sign */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001904 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001906
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001907 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001908 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001911 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001912 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001914 hlen = mbedtls_md_get_size( md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001915
Paul Bakkerb3869132013-02-28 17:21:01 +01001916 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00001917
Simon Butcher02037452016-03-01 21:19:12 +00001918 /*
1919 * Note: EMSA-PSS verification is over the length of N - 1 bits
1920 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001921 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001922
Gilles Peskineb00b0da2017-10-19 15:23:49 +02001923 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
1924 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1925
Simon Butcher02037452016-03-01 21:19:12 +00001926 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001927 if( msb % 8 == 0 )
1928 {
1929 p++;
1930 siglen -= 1;
1931 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001932
Gilles Peskine139108a2017-10-18 19:03:42 +02001933 if( siglen < hlen + 2 )
1934 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1935 hash_start = p + siglen - hlen - 1;
1936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001937 mbedtls_md_init( &md_ctx );
Brian J Murraye7be5bd2016-06-23 12:57:03 -07001938 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001939 goto exit;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001940
Jaeden Amero66954e12018-01-25 16:05:54 +00001941 ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
1942 if( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001943 goto exit;
Paul Bakker02303e82013-01-03 11:08:31 +01001944
Paul Bakkerb3869132013-02-28 17:21:01 +01001945 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001946
Gilles Peskine6a54b022017-10-17 19:02:13 +02001947 while( p < hash_start - 1 && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001948 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001949
Gilles Peskine91048a32017-10-19 17:46:14 +02001950 if( *p++ != 0x01 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001951 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001952 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1953 goto exit;
Paul Bakkerb3869132013-02-28 17:21:01 +01001954 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001955
Gilles Peskine6a54b022017-10-17 19:02:13 +02001956 observed_salt_len = hash_start - p;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001957
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001958 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Gilles Peskine6a54b022017-10-17 19:02:13 +02001959 observed_salt_len != (size_t) expected_salt_len )
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001960 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001961 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1962 goto exit;
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001963 }
1964
Simon Butcher02037452016-03-01 21:19:12 +00001965 /*
1966 * Generate H = Hash( M' )
1967 */
Jaeden Amero66954e12018-01-25 16:05:54 +00001968 ret = mbedtls_md_starts( &md_ctx );
1969 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001970 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001971 ret = mbedtls_md_update( &md_ctx, zeros, 8 );
1972 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001973 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001974 ret = mbedtls_md_update( &md_ctx, hash, hashlen );
1975 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001976 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001977 ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );
1978 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001979 goto exit;
Jaeden Amero66954e12018-01-25 16:05:54 +00001980 ret = mbedtls_md_finish( &md_ctx, result );
1981 if ( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001982 goto exit;
Paul Bakker53019ae2011-03-25 13:58:48 +00001983
Jaeden Amero66954e12018-01-25 16:05:54 +00001984 if( memcmp( hash_start, result, hlen ) != 0 )
Andres Amaya Garciac5c7d762017-07-20 14:42:16 +01001985 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001986 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
Andres Amaya Garciac5c7d762017-07-20 14:42:16 +01001987 goto exit;
1988 }
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001989
1990exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001992
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001993 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001994}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001995
1996/*
1997 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
1998 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002000 int (*f_rng)(void *, unsigned char *, size_t),
2001 void *p_rng,
2002 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002004 unsigned int hashlen,
2005 const unsigned char *hash,
2006 const unsigned char *sig )
2007{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002008 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2009 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002010 : md_alg;
2011
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002013 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002014 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002015 sig ) );
2016
2017}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002018#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002020#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002021/*
2022 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2023 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002024int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002025 int (*f_rng)(void *, unsigned char *, size_t),
2026 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002027 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002028 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002029 unsigned int hashlen,
2030 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002031 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002032{
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002033 int ret = 0;
2034 const size_t sig_len = ctx->len;
2035 unsigned char *encoded = NULL, *encoded_expected = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01002036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002037 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2038 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002039
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002040 /*
2041 * Prepare expected PKCS1 v1.5 encoding of hash.
2042 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002043
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002044 if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL ||
2045 ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
2046 {
2047 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2048 goto cleanup;
2049 }
2050
2051 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
2052 encoded_expected ) ) != 0 )
2053 goto cleanup;
2054
2055 /*
2056 * Apply RSA primitive to get what should be PKCS1 encoded hash.
2057 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059 ret = ( mode == MBEDTLS_RSA_PUBLIC )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002060 ? mbedtls_rsa_public( ctx, sig, encoded )
2061 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded );
Paul Bakkerb3869132013-02-28 17:21:01 +01002062 if( ret != 0 )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002063 goto cleanup;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002064
Simon Butcher02037452016-03-01 21:19:12 +00002065 /*
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002066 * Compare
Simon Butcher02037452016-03-01 21:19:12 +00002067 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002068
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002069 if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
2070 sig_len ) ) != 0 )
2071 {
2072 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2073 goto cleanup;
2074 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002075
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002076cleanup:
Paul Bakkerc70b9822013-04-07 22:00:46 +02002077
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002078 if( encoded != NULL )
2079 {
2080 mbedtls_zeroize( encoded, sig_len );
2081 mbedtls_free( encoded );
2082 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002083
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002084 if( encoded_expected != NULL )
2085 {
2086 mbedtls_zeroize( encoded_expected, sig_len );
2087 mbedtls_free( encoded_expected );
2088 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002089
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002090 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002091}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002092#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
2094/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002095 * Do an RSA operation and check the message digest
2096 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02002098 int (*f_rng)(void *, unsigned char *, size_t),
2099 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01002100 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002102 unsigned int hashlen,
2103 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002104 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002105{
2106 switch( ctx->padding )
2107 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002108#if defined(MBEDTLS_PKCS1_V15)
2109 case MBEDTLS_RSA_PKCS_V15:
2110 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002111 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002112#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002114#if defined(MBEDTLS_PKCS1_V21)
2115 case MBEDTLS_RSA_PKCS_V21:
2116 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002117 hashlen, hash, sig );
2118#endif
2119
2120 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002121 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002122 }
2123}
2124
2125/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002126 * Copy the components of an RSA key
2127 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002128int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002129{
2130 int ret;
2131
2132 dst->ver = src->ver;
2133 dst->len = src->len;
2134
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002135 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2136 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002138 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2139 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2140 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002141
2142#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2144 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2145 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002146 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2147 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002148#endif
2149
2150 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002152 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2153 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002154
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002155 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002156 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002157
2158cleanup:
2159 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002160 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002161
2162 return( ret );
2163}
2164
2165/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002166 * Free the components of an RSA key
2167 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002169{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002170 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
Hanno Becker33c30a02017-08-23 07:00:22 +01002171 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
2172 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002173 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002174
Hanno Becker33c30a02017-08-23 07:00:22 +01002175#if !defined(MBEDTLS_RSA_NO_CRT)
2176 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
2177 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
2178 mbedtls_mpi_free( &ctx->DP );
2179#endif /* MBEDTLS_RSA_NO_CRT */
2180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181#if defined(MBEDTLS_THREADING_C)
2182 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002183#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002184}
2185
Hanno Beckerab377312017-08-23 16:24:51 +01002186#endif /* !MBEDTLS_RSA_ALT */
2187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002188#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002190#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002191
2192/*
2193 * Example RSA-1024 keypair, for test purposes
2194 */
2195#define KEY_LEN 128
2196
2197#define RSA_N "9292758453063D803DD603D5E777D788" \
2198 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2199 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2200 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2201 "93A89813FBF3C4F8066D2D800F7C38A8" \
2202 "1AE31942917403FF4946B0A83D3D3E05" \
2203 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2204 "5E94BB77B07507233A0BC7BAC8F90F79"
2205
2206#define RSA_E "10001"
2207
2208#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2209 "66CA472BC44D253102F8B4A9D3BFA750" \
2210 "91386C0077937FE33FA3252D28855837" \
2211 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2212 "DF79C5CE07EE72C7F123142198164234" \
2213 "CABB724CF78B8173B9F880FC86322407" \
2214 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2215 "071513A1E85B5DFA031F21ECAE91A34D"
2216
2217#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2218 "2C01CAD19EA484A87EA4377637E75500" \
2219 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2220 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2221
2222#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2223 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2224 "910E4168387E3C30AA1E00C339A79508" \
2225 "8452DD96A9A5EA5D9DCA68DA636032AF"
2226
Paul Bakker5121ce52009-01-03 21:22:43 +00002227#define PT_LEN 24
2228#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2229 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002231#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002232static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002233{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002234#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002235 size_t i;
2236
Paul Bakker545570e2010-07-18 09:00:25 +00002237 if( rng_state != NULL )
2238 rng_state = NULL;
2239
Paul Bakkera3d195c2011-11-27 21:07:34 +00002240 for( i = 0; i < len; ++i )
2241 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002242#else
2243 if( rng_state != NULL )
2244 rng_state = NULL;
2245
2246 arc4random_buf( output, len );
2247#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002248
Paul Bakkera3d195c2011-11-27 21:07:34 +00002249 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002250}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002252
Paul Bakker5121ce52009-01-03 21:22:43 +00002253/*
2254 * Checkup routine
2255 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002256int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002257{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002258 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002260 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002261 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002262 unsigned char rsa_plaintext[PT_LEN];
2263 unsigned char rsa_decrypted[PT_LEN];
2264 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002265#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002266 unsigned char sha1sum[20];
2267#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002268
Hanno Becker3a701162017-08-22 13:52:43 +01002269 mbedtls_mpi K;
2270
2271 mbedtls_mpi_init( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002273
Hanno Becker3a701162017-08-22 13:52:43 +01002274 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2275 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2276 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2277 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2278 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2279 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2280 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2281 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2282 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2283 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2284
Hanno Becker7f25f852017-10-10 16:56:22 +01002285 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002286
2287 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002288 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002290 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2291 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002292 {
2293 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002294 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002295
Hanno Becker5bc87292017-05-03 15:09:31 +01002296 ret = 1;
2297 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002298 }
2299
2300 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002301 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002302
2303 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2304
Hanno Becker98838b02017-10-02 13:16:10 +01002305 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2306 PT_LEN, rsa_plaintext,
2307 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002308 {
2309 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002310 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002311
Hanno Becker5bc87292017-05-03 15:09:31 +01002312 ret = 1;
2313 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002314 }
2315
2316 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002318
Hanno Becker98838b02017-10-02 13:16:10 +01002319 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2320 &len, rsa_ciphertext, rsa_decrypted,
2321 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002322 {
2323 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002324 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002325
Hanno Becker5bc87292017-05-03 15:09:31 +01002326 ret = 1;
2327 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002328 }
2329
2330 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2331 {
2332 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002334
Hanno Becker5bc87292017-05-03 15:09:31 +01002335 ret = 1;
2336 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002337 }
2338
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002339 if( verbose != 0 )
2340 mbedtls_printf( "passed\n" );
2341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002342#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002343 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002344 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002345
Gilles Peskine9e4f77c2018-01-22 11:48:08 +01002346 if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01002347 {
2348 if( verbose != 0 )
2349 mbedtls_printf( "failed\n" );
2350
2351 return( 1 );
2352 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002353
Hanno Becker98838b02017-10-02 13:16:10 +01002354 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2355 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2356 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002357 {
2358 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002360
Hanno Becker5bc87292017-05-03 15:09:31 +01002361 ret = 1;
2362 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002363 }
2364
2365 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002366 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002367
Hanno Becker98838b02017-10-02 13:16:10 +01002368 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2369 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2370 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002371 {
2372 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002373 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002374
Hanno Becker5bc87292017-05-03 15:09:31 +01002375 ret = 1;
2376 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002377 }
2378
2379 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002380 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002381#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002382
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002383 if( verbose != 0 )
2384 mbedtls_printf( "\n" );
2385
Paul Bakker3d8fb632014-04-17 12:42:41 +02002386cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002387 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002388 mbedtls_rsa_free( &rsa );
2389#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002390 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002391#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002392 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002393}
2394
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002395#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002397#endif /* MBEDTLS_RSA_C */