blob: e59755534f671113398f7ea9c08d68ef160c8f04 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * The RSA public-key cryptosystem
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 Bakker5121ce52009-01-03 21:22:43 +000018 */
Hanno Becker74716312017-10-02 10:00:37 +010019
Paul Bakker5121ce52009-01-03 21:22:43 +000020/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000021 * The following sources were referenced in the design of this implementation
22 * of the RSA algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000023 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000024 * [1] A method for obtaining digital signatures and public-key cryptosystems
25 * R Rivest, A Shamir, and L Adleman
26 * http://people.csail.mit.edu/rivest/pubs.html#RSA78
27 *
28 * [2] Handbook of Applied Cryptography - 1997, Chapter 8
29 * Menezes, van Oorschot and Vanstone
30 *
Janos Follathe81102e2017-03-22 13:38:28 +000031 * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
32 * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
33 * Stefan Mangard
34 * https://arxiv.org/abs/1702.08719v2
35 *
Paul Bakker5121ce52009-01-03 21:22:43 +000036 */
37
Gilles Peskinedb09ef62020-06-03 01:43:33 +020038#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_RSA_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/rsa.h"
Chris Jones66a4cd42021-03-09 16:04:12 +000043#include "rsa_alt_helpers.h"
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000044#include "mbedtls/oid.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050045#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000046#include "mbedtls/error.h"
Gabor Mezei22c9a6f2021-10-20 12:09:35 +020047#include "constant_time_internal.h"
Gabor Mezei765862c2021-10-19 12:22:25 +020048#include "mbedtls/constant_time.h"
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +020049#include "hash_info.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000050
Rich Evans00ab4702015-02-06 13:43:58 +000051#include <string.h>
52
gufe44c2620da2020-08-03 17:56:50 +020053#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
Paul Bakker5121ce52009-01-03 21:22:43 +000054#include <stdlib.h>
Rich Evans00ab4702015-02-06 13:43:58 +000055#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000056
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +020057/* We use MD first if it's available (for compatibility reasons)
58 * and "fall back" to PSA otherwise (which needs psa_crypto_init()). */
59#if defined(MBEDTLS_PKCS1_V21)
Przemek Stekiel40afdd22022-09-06 13:08:28 +020060#if !defined(MBEDTLS_MD_C)
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +020061#include "psa/crypto.h"
62#include "mbedtls/psa_util.h"
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +020063#endif /* MBEDTLS_MD_C */
64#endif /* MBEDTLS_PKCS1_V21 */
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#else
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#define mbedtls_printf printf
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +020071#define mbedtls_calloc calloc
72#define mbedtls_free free
Paul Bakker7dc4c442014-02-01 22:50:26 +010073#endif
74
Hanno Beckera565f542017-10-11 11:00:19 +010075#if !defined(MBEDTLS_RSA_ALT)
76
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050077/* Parameter validation macros */
78#define RSA_VALIDATE_RET( cond ) \
79 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
80#define RSA_VALIDATE( cond ) \
81 MBEDTLS_INTERNAL_VALIDATE( cond )
82
Hanno Becker617c1ae2017-08-23 14:11:24 +010083int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
84 const mbedtls_mpi *N,
85 const mbedtls_mpi *P, const mbedtls_mpi *Q,
86 const mbedtls_mpi *D, const mbedtls_mpi *E )
87{
Janos Follath24eed8d2019-11-22 13:21:35 +000088 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050089 RSA_VALIDATE_RET( ctx != NULL );
Hanno Becker617c1ae2017-08-23 14:11:24 +010090
91 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
92 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
93 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
94 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
95 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
96 {
Chris Jonesb7d02e02021-04-01 17:40:03 +010097 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +010098 }
99
100 if( N != NULL )
101 ctx->len = mbedtls_mpi_size( &ctx->N );
102
103 return( 0 );
104}
105
106int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
Hanno Becker74716312017-10-02 10:00:37 +0100107 unsigned char const *N, size_t N_len,
108 unsigned char const *P, size_t P_len,
109 unsigned char const *Q, size_t Q_len,
110 unsigned char const *D, size_t D_len,
111 unsigned char const *E, size_t E_len )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100112{
Hanno Beckerd4d60572018-01-10 07:12:01 +0000113 int ret = 0;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500114 RSA_VALIDATE_RET( ctx != NULL );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100115
116 if( N != NULL )
117 {
118 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
119 ctx->len = mbedtls_mpi_size( &ctx->N );
120 }
121
122 if( P != NULL )
123 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
124
125 if( Q != NULL )
126 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
127
128 if( D != NULL )
129 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
130
131 if( E != NULL )
132 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
133
134cleanup:
135
136 if( ret != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +0100137 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100138
139 return( 0 );
140}
141
Hanno Becker705fc682017-10-10 17:57:02 +0100142/*
143 * Checks whether the context fields are set in such a way
144 * that the RSA primitives will be able to execute without error.
145 * It does *not* make guarantees for consistency of the parameters.
146 */
Hanno Beckerebd2c022017-10-12 10:54:53 +0100147static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
148 int blinding_needed )
Hanno Becker705fc682017-10-10 17:57:02 +0100149{
Hanno Beckerebd2c022017-10-12 10:54:53 +0100150#if !defined(MBEDTLS_RSA_NO_CRT)
151 /* blinding_needed is only used for NO_CRT to decide whether
152 * P,Q need to be present or not. */
153 ((void) blinding_needed);
154#endif
155
Hanno Becker3a760a12018-01-05 08:14:49 +0000156 if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
157 ctx->len > MBEDTLS_MPI_MAX_SIZE )
158 {
Hanno Becker705fc682017-10-10 17:57:02 +0100159 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Becker3a760a12018-01-05 08:14:49 +0000160 }
Hanno Becker705fc682017-10-10 17:57:02 +0100161
162 /*
163 * 1. Modular exponentiation needs positive, odd moduli.
164 */
165
166 /* Modular exponentiation wrt. N is always used for
167 * RSA public key operations. */
168 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
169 mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
170 {
171 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
172 }
173
174#if !defined(MBEDTLS_RSA_NO_CRT)
175 /* Modular exponentiation for P and Q is only
176 * used for private key operations and if CRT
177 * is used. */
178 if( is_priv &&
179 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
180 mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
181 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
182 mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
183 {
184 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
185 }
186#endif /* !MBEDTLS_RSA_NO_CRT */
187
188 /*
189 * 2. Exponents must be positive
190 */
191
192 /* Always need E for public key operations */
193 if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
194 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
195
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100196#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100197 /* For private key operations, use D or DP & DQ
198 * as (unblinded) exponents. */
199 if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
200 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
201#else
202 if( is_priv &&
203 ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
204 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
205 {
206 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
207 }
208#endif /* MBEDTLS_RSA_NO_CRT */
209
210 /* Blinding shouldn't make exponents negative either,
211 * so check that P, Q >= 1 if that hasn't yet been
212 * done as part of 1. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100213#if defined(MBEDTLS_RSA_NO_CRT)
Hanno Beckerebd2c022017-10-12 10:54:53 +0100214 if( is_priv && blinding_needed &&
Hanno Becker705fc682017-10-10 17:57:02 +0100215 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
216 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
217 {
218 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
219 }
220#endif
221
222 /* It wouldn't lead to an error if it wasn't satisfied,
Hanno Beckerf8c028a2017-10-17 09:20:57 +0100223 * but check for QP >= 1 nonetheless. */
Hanno Beckerb82a5b52017-10-11 19:10:23 +0100224#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker705fc682017-10-10 17:57:02 +0100225 if( is_priv &&
226 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
227 {
228 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
229 }
230#endif
231
232 return( 0 );
233}
234
Hanno Beckerf9e184b2017-10-10 16:49:26 +0100235int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100236{
237 int ret = 0;
Jack Lloyd8c2631b2020-01-23 17:23:52 -0500238 int have_N, have_P, have_Q, have_D, have_E;
239#if !defined(MBEDTLS_RSA_NO_CRT)
240 int have_DP, have_DQ, have_QP;
241#endif
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500242 int n_missing, pq_missing, d_missing, is_pub, is_priv;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100243
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500244 RSA_VALIDATE_RET( ctx != NULL );
245
246 have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
247 have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
248 have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
249 have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
250 have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
Jack Lloyd8c2631b2020-01-23 17:23:52 -0500251
252#if !defined(MBEDTLS_RSA_NO_CRT)
Jack Lloyd80cc8112020-01-22 17:34:29 -0500253 have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
254 have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
255 have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
Jack Lloyd8c2631b2020-01-23 17:23:52 -0500256#endif
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100257
Hanno Becker617c1ae2017-08-23 14:11:24 +0100258 /*
259 * Check whether provided parameters are enough
260 * to deduce all others. The following incomplete
261 * parameter sets for private keys are supported:
262 *
263 * (1) P, Q missing.
264 * (2) D and potentially N missing.
265 *
266 */
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100267
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500268 n_missing = have_P && have_Q && have_D && have_E;
269 pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
270 d_missing = have_P && have_Q && !have_D && have_E;
271 is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
Hanno Becker2cca6f32017-09-29 11:46:40 +0100272
273 /* These three alternatives are mutually exclusive */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500274 is_priv = n_missing || pq_missing || d_missing;
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100275
Hanno Becker617c1ae2017-08-23 14:11:24 +0100276 if( !is_priv && !is_pub )
277 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
278
279 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100280 * Step 1: Deduce N if P, Q are provided.
281 */
282
283 if( !have_N && have_P && have_Q )
284 {
285 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
286 &ctx->Q ) ) != 0 )
287 {
Chris Jonesb7d02e02021-04-01 17:40:03 +0100288 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker2cca6f32017-09-29 11:46:40 +0100289 }
290
291 ctx->len = mbedtls_mpi_size( &ctx->N );
292 }
293
294 /*
295 * Step 2: Deduce and verify all remaining core parameters.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100296 */
297
298 if( pq_missing )
299 {
Hanno Beckerc36aab62017-10-17 09:15:06 +0100300 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
Hanno Becker617c1ae2017-08-23 14:11:24 +0100301 &ctx->P, &ctx->Q );
302 if( ret != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +0100303 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100304
305 }
306 else if( d_missing )
307 {
Hanno Becker8ba6ce42017-10-03 14:36:26 +0100308 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
309 &ctx->Q,
310 &ctx->E,
311 &ctx->D ) ) != 0 )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100312 {
Chris Jonesb7d02e02021-04-01 17:40:03 +0100313 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100314 }
315 }
Hanno Becker617c1ae2017-08-23 14:11:24 +0100316
Hanno Becker617c1ae2017-08-23 14:11:24 +0100317 /*
Hanno Becker2cca6f32017-09-29 11:46:40 +0100318 * Step 3: Deduce all additional parameters specific
Hanno Beckere8674892017-10-10 17:56:14 +0100319 * to our current RSA implementation.
Hanno Becker617c1ae2017-08-23 14:11:24 +0100320 */
321
Hanno Becker23344b52017-08-23 07:43:27 +0100322#if !defined(MBEDTLS_RSA_NO_CRT)
Jack Lloyd2e9eef42020-01-28 14:43:52 -0500323 if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
Hanno Becker617c1ae2017-08-23 14:11:24 +0100324 {
325 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
326 &ctx->DP, &ctx->DQ, &ctx->QP );
327 if( ret != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +0100328 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100329 }
Hanno Becker23344b52017-08-23 07:43:27 +0100330#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100331
332 /*
Hanno Becker705fc682017-10-10 17:57:02 +0100333 * Step 3: Basic sanity checks
Hanno Becker617c1ae2017-08-23 14:11:24 +0100334 */
335
Hanno Beckerebd2c022017-10-12 10:54:53 +0100336 return( rsa_check_context( ctx, is_priv, 1 ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100337}
338
Hanno Becker617c1ae2017-08-23 14:11:24 +0100339int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
340 unsigned char *N, size_t N_len,
341 unsigned char *P, size_t P_len,
342 unsigned char *Q, size_t Q_len,
343 unsigned char *D, size_t D_len,
344 unsigned char *E, size_t E_len )
345{
346 int ret = 0;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500347 int is_priv;
348 RSA_VALIDATE_RET( ctx != NULL );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100349
350 /* Check if key is private or public */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500351 is_priv =
Hanno Becker617c1ae2017-08-23 14:11:24 +0100352 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
353 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
354 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
355 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
356 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
357
358 if( !is_priv )
359 {
360 /* If we're trying to export private parameters for a public key,
361 * something must be wrong. */
362 if( P != NULL || Q != NULL || D != NULL )
363 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
364
365 }
366
367 if( N != NULL )
368 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
369
370 if( P != NULL )
371 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
372
373 if( Q != NULL )
374 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
375
376 if( D != NULL )
377 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
378
379 if( E != NULL )
380 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100381
382cleanup:
383
384 return( ret );
385}
386
Hanno Becker617c1ae2017-08-23 14:11:24 +0100387int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
388 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
389 mbedtls_mpi *D, mbedtls_mpi *E )
390{
Janos Follath24eed8d2019-11-22 13:21:35 +0000391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500392 int is_priv;
393 RSA_VALIDATE_RET( ctx != NULL );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100394
395 /* Check if key is private or public */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500396 is_priv =
Hanno Becker617c1ae2017-08-23 14:11:24 +0100397 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
398 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
399 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
400 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
401 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
402
403 if( !is_priv )
404 {
405 /* If we're trying to export private parameters for a public key,
406 * something must be wrong. */
407 if( P != NULL || Q != NULL || D != NULL )
408 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
409
410 }
411
412 /* Export all requested core parameters. */
413
414 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
415 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
416 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
417 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
418 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
419 {
420 return( ret );
421 }
422
423 return( 0 );
424}
425
426/*
427 * Export CRT parameters
428 * This must also be implemented if CRT is not used, for being able to
429 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
430 * can be used in this case.
431 */
432int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
433 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
434{
Janos Follath24eed8d2019-11-22 13:21:35 +0000435 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500436 int is_priv;
437 RSA_VALIDATE_RET( ctx != NULL );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100438
439 /* Check if key is private or public */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500440 is_priv =
Hanno Becker617c1ae2017-08-23 14:11:24 +0100441 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
442 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
443 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
444 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
445 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
446
447 if( !is_priv )
448 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
449
Hanno Beckerdc95c892017-08-23 06:57:02 +0100450#if !defined(MBEDTLS_RSA_NO_CRT)
Hanno Becker617c1ae2017-08-23 14:11:24 +0100451 /* Export all requested blinding parameters. */
Hanno Becker617c1ae2017-08-23 14:11:24 +0100452 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
453 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
454 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
455 {
Chris Jonesb7d02e02021-04-01 17:40:03 +0100456 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100457 }
Hanno Beckerdc95c892017-08-23 06:57:02 +0100458#else
459 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
460 DP, DQ, QP ) ) != 0 )
461 {
Chris Jonesb7d02e02021-04-01 17:40:03 +0100462 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
Hanno Beckerdc95c892017-08-23 06:57:02 +0100463 }
464#endif
Hanno Becker617c1ae2017-08-23 14:11:24 +0100465
466 return( 0 );
467}
Hanno Beckere2e8b8d2017-08-23 14:06:45 +0100468
Paul Bakker5121ce52009-01-03 21:22:43 +0000469/*
470 * Initialize an RSA context
471 */
Ronald Cronc1905a12021-06-05 11:11:14 +0200472void mbedtls_rsa_init( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000473{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500474 RSA_VALIDATE( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Ronald Cronc1905a12021-06-05 11:11:14 +0200478 ctx->padding = MBEDTLS_RSA_PKCS_V15;
479 ctx->hash_id = MBEDTLS_MD_NONE;
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#if defined(MBEDTLS_THREADING_C)
Gilles Peskineeb940592021-02-01 17:57:41 +0100482 /* Set ctx->ver to nonzero to indicate that the mutex has been
483 * initialized and will need to be freed. */
484 ctx->ver = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +0200486#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000487}
488
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100489/*
490 * Set padding for an existing RSA context
491 */
Ronald Cronea7631b2021-06-03 18:51:59 +0200492int mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
493 mbedtls_md_type_t hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100494{
Ronald Cron3a0375f2021-06-08 10:22:28 +0200495 switch( padding )
496 {
497#if defined(MBEDTLS_PKCS1_V15)
498 case MBEDTLS_RSA_PKCS_V15:
499 break;
500#endif
501
502#if defined(MBEDTLS_PKCS1_V21)
503 case MBEDTLS_RSA_PKCS_V21:
504 break;
505#endif
506 default:
507 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
508 }
Ronald Cronea7631b2021-06-03 18:51:59 +0200509
Manuel Pégourié-Gonnard3356b892022-07-05 10:25:06 +0200510#if defined(MBEDTLS_PKCS1_V21)
Ronald Cronea7631b2021-06-03 18:51:59 +0200511 if( ( padding == MBEDTLS_RSA_PKCS_V21 ) &&
512 ( hash_id != MBEDTLS_MD_NONE ) )
513 {
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +0200514 /* Just make sure this hash is supported in this build. */
Przemek Stekiel712bb9c2022-07-29 11:12:00 +0200515 if( mbedtls_hash_info_psa_from_md( hash_id ) == PSA_ALG_NONE )
Ronald Cronea7631b2021-06-03 18:51:59 +0200516 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
517 }
Manuel Pégourié-Gonnard3356b892022-07-05 10:25:06 +0200518#endif /* MBEDTLS_PKCS1_V21 */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500519
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100520 ctx->padding = padding;
521 ctx->hash_id = hash_id;
Ronald Cronea7631b2021-06-03 18:51:59 +0200522
523 return( 0 );
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +0100524}
525
Hanno Becker617c1ae2017-08-23 14:11:24 +0100526/*
527 * Get length in bytes of RSA modulus
528 */
529
530size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
531{
Hanno Becker2f8f06a2017-09-29 11:47:26 +0100532 return( ctx->len );
Hanno Becker617c1ae2017-08-23 14:11:24 +0100533}
534
535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
538/*
539 * Generate an RSA keypair
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800540 *
541 * This generation method follows the RSA key pair generation procedure of
542 * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000545 int (*f_rng)(void *, unsigned char *, size_t),
546 void *p_rng,
547 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +0000548{
Janos Follath24eed8d2019-11-22 13:21:35 +0000549 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jethro Beekman97f95c92018-02-13 15:50:36 -0800550 mbedtls_mpi H, G, L;
Janos Follathb8fc1b02018-09-03 15:37:01 +0100551 int prime_quality = 0;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500552 RSA_VALIDATE_RET( ctx != NULL );
553 RSA_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
Janos Follathb8fc1b02018-09-03 15:37:01 +0100555 /*
556 * If the modulus is 1024 bit long or shorter, then the security strength of
557 * the RSA algorithm is less than or equal to 80 bits and therefore an error
558 * rate of 2^-80 is sufficient.
559 */
560 if( nbits > 1024 )
561 prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
562
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100563 mbedtls_mpi_init( &H );
564 mbedtls_mpi_init( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800565 mbedtls_mpi_init( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
Gilles Peskine5e40a7c2021-02-02 21:06:10 +0100567 if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
568 {
569 ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
570 goto cleanup;
571 }
572
Paul Bakker5121ce52009-01-03 21:22:43 +0000573 /*
574 * find primes P and Q with Q < P so that:
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800575 * 1. |P-Q| > 2^( nbits / 2 - 100 )
576 * 2. GCD( E, (P-1)*(Q-1) ) == 1
577 * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 do
582 {
Janos Follathb8fc1b02018-09-03 15:37:01 +0100583 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1,
584 prime_quality, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
Janos Follathb8fc1b02018-09-03 15:37:01 +0100586 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1,
587 prime_quality, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800589 /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
590 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
591 if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 continue;
593
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800594 /* not required by any standards, but some users rely on the fact that P > Q */
595 if( H.s < 0 )
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100596 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Janos Follathef441782016-09-21 13:18:12 +0100597
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100598 /* Temporarily replace P,Q by P-1, Q-1 */
599 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
600 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
601 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800602
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800603 /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800605 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
606 continue;
607
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800608 /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
Jethro Beekman97f95c92018-02-13 15:50:36 -0800609 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
610 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
611 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
612
613 if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
614 continue;
615
616 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 }
Jethro Beekman97f95c92018-02-13 15:50:36 -0800618 while( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100620 /* Restore P,Q */
621 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
622 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
623
Jethro Beekmanc645bfe2018-02-14 19:27:13 -0800624 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
625
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100626 ctx->len = mbedtls_mpi_size( &ctx->N );
627
Jethro Beekman97f95c92018-02-13 15:50:36 -0800628#if !defined(MBEDTLS_RSA_NO_CRT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 * DP = D mod (P - 1)
631 * DQ = D mod (Q - 1)
632 * QP = Q^-1 mod P
633 */
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100634 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
635 &ctx->DP, &ctx->DQ, &ctx->QP ) );
636#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Hanno Becker83aad1f2017-08-23 06:45:10 +0100638 /* Double-check */
639 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641cleanup:
642
Hanno Beckerbee3aae2017-08-23 06:59:15 +0100643 mbedtls_mpi_free( &H );
644 mbedtls_mpi_free( &G );
Jethro Beekman97f95c92018-02-13 15:50:36 -0800645 mbedtls_mpi_free( &L );
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
647 if( ret != 0 )
648 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_rsa_free( ctx );
Chris Jones74392092021-04-01 16:00:01 +0100650
Gilles Peskine5e40a7c2021-02-02 21:06:10 +0100651 if( ( -ret & ~0x7f ) == 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +0100652 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret );
Gilles Peskine5e40a7c2021-02-02 21:06:10 +0100653 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 }
655
Paul Bakker48377d92013-08-30 12:06:24 +0200656 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657}
658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
661/*
662 * Check a public RSA key
663 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000665{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500666 RSA_VALIDATE_RET( ctx != NULL );
667
Hanno Beckerebd2c022017-10-12 10:54:53 +0100668 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d9f2009-07-10 22:38:58 +0000670
Hanno Becker3a760a12018-01-05 08:14:49 +0000671 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
Hanno Becker98838b02017-10-02 13:16:10 +0100672 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100674 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
Hanno Becker705fc682017-10-10 17:57:02 +0100676 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
677 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
Hanno Becker98838b02017-10-02 13:16:10 +0100679 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Hanno Becker98838b02017-10-02 13:16:10 +0100681 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683 return( 0 );
684}
685
686/*
Hanno Becker705fc682017-10-10 17:57:02 +0100687 * Check for the consistency of all fields in an RSA private key context
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000690{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500691 RSA_VALIDATE_RET( ctx != NULL );
692
Hanno Becker705fc682017-10-10 17:57:02 +0100693 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
Hanno Beckerebd2c022017-10-12 10:54:53 +0100694 rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 {
Hanno Becker98838b02017-10-02 13:16:10 +0100696 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 }
Paul Bakker48377d92013-08-30 12:06:24 +0200698
Hanno Becker98838b02017-10-02 13:16:10 +0100699 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
Hanno Beckerb269a852017-08-25 08:03:21 +0100700 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 {
Hanno Beckerb269a852017-08-25 08:03:21 +0100702 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000704
Hanno Beckerb269a852017-08-25 08:03:21 +0100705#if !defined(MBEDTLS_RSA_NO_CRT)
706 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
707 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
708 {
709 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
710 }
711#endif
Paul Bakker6c591fa2011-05-05 11:49:20 +0000712
713 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000714}
715
716/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100717 * Check if contexts holding a public and private key match
718 */
Hanno Becker98838b02017-10-02 13:16:10 +0100719int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
720 const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100721{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500722 RSA_VALIDATE_RET( pub != NULL );
723 RSA_VALIDATE_RET( prv != NULL );
724
Hanno Becker98838b02017-10-02 13:16:10 +0100725 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100727 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100729 }
730
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
732 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100733 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100735 }
736
737 return( 0 );
738}
739
740/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 * Do an RSA public key operation
742 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000744 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000745 unsigned char *output )
746{
Janos Follath24eed8d2019-11-22 13:21:35 +0000747 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000748 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_mpi T;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500750 RSA_VALIDATE_RET( ctx != NULL );
751 RSA_VALIDATE_RET( input != NULL );
752 RSA_VALIDATE_RET( output != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Hanno Beckerebd2c022017-10-12 10:54:53 +0100754 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
Hanno Becker705fc682017-10-10 17:57:02 +0100755 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
756
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200759#if defined(MBEDTLS_THREADING_C)
760 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
761 return( ret );
762#endif
763
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000767 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200768 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
769 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 }
771
772 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
774 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000775
776cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200778 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
779 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +0100780#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000781
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000783
784 if( ret != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +0100785 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
787 return( 0 );
788}
789
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200790/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200791 * Generate or update blinding values, see section 10 of:
792 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200793 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200794 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200795 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200796static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200797 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
798{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200799 int ret, count = 0;
Manuel Pégourié-Gonnard750d3c72020-06-26 11:19:12 +0200800 mbedtls_mpi R;
801
802 mbedtls_mpi_init( &R );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200803
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200804 if( ctx->Vf.p != NULL )
805 {
806 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
808 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
809 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
810 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200811
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200812 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200813 }
814
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200815 /* Unblinding value: Vf = random number, invertible mod N */
816 do {
817 if( count++ > 10 )
Manuel Pégourié-Gonnarde288ec02020-07-16 09:23:30 +0200818 {
819 ret = MBEDTLS_ERR_RSA_RNG_FAILED;
820 goto cleanup;
821 }
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200822
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200824
Manuel Pégourié-Gonnard78683962020-07-16 09:48:54 +0200825 /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
Manuel Pégourié-Gonnard750d3c72020-06-26 11:19:12 +0200826 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
827 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
828 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
829
Manuel Pégourié-Gonnard78683962020-07-16 09:48:54 +0200830 /* At this point, Vi is invertible mod N if and only if both Vf and R
831 * are invertible mod N. If one of them isn't, we don't need to know
832 * which one, we just loop and choose new values for both of them.
833 * (Each iteration succeeds with overwhelming probability.) */
Manuel Pégourié-Gonnard750d3c72020-06-26 11:19:12 +0200834 ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
Peter Kolbusca8b8e72020-09-24 11:11:50 -0500835 if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
Manuel Pégourié-Gonnardb3e3d792020-06-26 11:03:19 +0200836 goto cleanup;
837
Peter Kolbusca8b8e72020-09-24 11:11:50 -0500838 } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
839
840 /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
841 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
842 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200843
Manuel Pégourié-Gonnard78683962020-07-16 09:48:54 +0200844 /* Blinding value: Vi = Vf^(-e) mod N
Manuel Pégourié-Gonnard750d3c72020-06-26 11:19:12 +0200845 * (Vi already contains Vf^-1 at this point) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 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 +0200847
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200848
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200849cleanup:
Manuel Pégourié-Gonnard750d3c72020-06-26 11:19:12 +0200850 mbedtls_mpi_free( &R );
851
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200852 return( ret );
853}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200854
Paul Bakker5121ce52009-01-03 21:22:43 +0000855/*
Janos Follathe81102e2017-03-22 13:38:28 +0000856 * Exponent blinding supposed to prevent side-channel attacks using multiple
857 * traces of measurements to recover the RSA key. The more collisions are there,
858 * the more bits of the key can be recovered. See [3].
859 *
860 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800861 * observations on average.
Janos Follathe81102e2017-03-22 13:38:28 +0000862 *
863 * For example with 28 byte blinding to achieve 2 collisions the adversary has
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800864 * to make 2^112 observations on average.
Janos Follathe81102e2017-03-22 13:38:28 +0000865 *
866 * (With the currently (as of 2017 April) known best algorithms breaking 2048
867 * bit RSA requires approximately as much time as trying out 2^112 random keys.
868 * Thus in this sense with 28 byte blinding the security is not reduced by
869 * side-channel attacks like the one in [3])
870 *
871 * This countermeasure does not help if the key recovery is possible with a
872 * single trace.
873 */
874#define RSA_EXPONENT_BLINDING 28
875
876/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000877 * Do an RSA private key operation
878 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200880 int (*f_rng)(void *, unsigned char *, size_t),
881 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000882 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000883 unsigned char *output )
884{
Janos Follath24eed8d2019-11-22 13:21:35 +0000885 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000886 size_t olen;
Hanno Becker06811ce2017-05-03 15:10:34 +0100887
888 /* Temporary holding the result */
889 mbedtls_mpi T;
890
891 /* Temporaries holding P-1, Q-1 and the
892 * exponent blinding factor, respectively. */
Janos Follathf9203b42017-03-22 15:13:15 +0000893 mbedtls_mpi P1, Q1, R;
Hanno Becker06811ce2017-05-03 15:10:34 +0100894
895#if !defined(MBEDTLS_RSA_NO_CRT)
896 /* Temporaries holding the results mod p resp. mod q. */
897 mbedtls_mpi TP, TQ;
898
899 /* Temporaries holding the blinded exponents for
900 * the mod p resp. mod q computation (if used). */
Janos Follathf9203b42017-03-22 15:13:15 +0000901 mbedtls_mpi DP_blind, DQ_blind;
Hanno Becker06811ce2017-05-03 15:10:34 +0100902
903 /* Pointers to actual exponents to be used - either the unblinded
904 * or the blinded ones, depending on the presence of a PRNG. */
Janos Follathf9203b42017-03-22 15:13:15 +0000905 mbedtls_mpi *DP = &ctx->DP;
906 mbedtls_mpi *DQ = &ctx->DQ;
Hanno Becker06811ce2017-05-03 15:10:34 +0100907#else
908 /* Temporary holding the blinded exponent (if used). */
909 mbedtls_mpi D_blind;
910
911 /* Pointer to actual exponent to be used - either the unblinded
912 * or the blinded one, depending on the presence of a PRNG. */
913 mbedtls_mpi *D = &ctx->D;
Hanno Becker43f94722017-08-25 11:50:00 +0100914#endif /* MBEDTLS_RSA_NO_CRT */
Hanno Becker06811ce2017-05-03 15:10:34 +0100915
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100916 /* Temporaries holding the initial input and the double
917 * checked result; should be the same in the end. */
918 mbedtls_mpi I, C;
Paul Bakker5121ce52009-01-03 21:22:43 +0000919
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500920 RSA_VALIDATE_RET( ctx != NULL );
921 RSA_VALIDATE_RET( input != NULL );
922 RSA_VALIDATE_RET( output != NULL );
923
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200924 if( f_rng == NULL )
925 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
926
927 if( rsa_check_context( ctx, 1 /* private key checks */,
928 1 /* blinding on */ ) != 0 )
Hanno Beckerebd2c022017-10-12 10:54:53 +0100929 {
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100930 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Beckerebd2c022017-10-12 10:54:53 +0100931 }
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100932
Hanno Becker06811ce2017-05-03 15:10:34 +0100933#if defined(MBEDTLS_THREADING_C)
934 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
935 return( ret );
936#endif
Janos Follathf9203b42017-03-22 15:13:15 +0000937
Hanno Becker06811ce2017-05-03 15:10:34 +0100938 /* MPI Initialization */
Hanno Becker06811ce2017-05-03 15:10:34 +0100939 mbedtls_mpi_init( &T );
940
941 mbedtls_mpi_init( &P1 );
942 mbedtls_mpi_init( &Q1 );
943 mbedtls_mpi_init( &R );
Janos Follathf9203b42017-03-22 15:13:15 +0000944
Janos Follathe81102e2017-03-22 13:38:28 +0000945#if defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200946 mbedtls_mpi_init( &D_blind );
Janos Follathf9203b42017-03-22 15:13:15 +0000947#else
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200948 mbedtls_mpi_init( &DP_blind );
949 mbedtls_mpi_init( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +0000950#endif
951
Hanno Becker06811ce2017-05-03 15:10:34 +0100952#if !defined(MBEDTLS_RSA_NO_CRT)
953 mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200954#endif
955
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100956 mbedtls_mpi_init( &I );
957 mbedtls_mpi_init( &C );
Hanno Becker06811ce2017-05-03 15:10:34 +0100958
959 /* End of MPI initialization */
960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
962 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000963 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200964 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
965 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 }
967
Hanno Beckerc6075cc2017-08-25 11:45:35 +0100968 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
Hanno Becker06811ce2017-05-03 15:10:34 +0100969
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200970 /*
971 * Blinding
972 * T = T * Vi mod N
973 */
974 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
975 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
976 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000977
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200978 /*
979 * Exponent blinding
980 */
981 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
982 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000983
Janos Follathf9203b42017-03-22 15:13:15 +0000984#if defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200985 /*
986 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
987 */
988 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
989 f_rng, p_rng ) );
990 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
991 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
992 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
Janos Follathe81102e2017-03-22 13:38:28 +0000993
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200994 D = &D_blind;
Janos Follathf9203b42017-03-22 15:13:15 +0000995#else
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +0200996 /*
997 * DP_blind = ( P - 1 ) * R + DP
998 */
999 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1000 f_rng, p_rng ) );
1001 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1002 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1003 &ctx->DP ) );
Janos Follathf9203b42017-03-22 15:13:15 +00001004
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001005 DP = &DP_blind;
Janos Follathf9203b42017-03-22 15:13:15 +00001006
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001007 /*
1008 * DQ_blind = ( Q - 1 ) * R + DQ
1009 */
1010 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1011 f_rng, p_rng ) );
1012 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1013 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1014 &ctx->DQ ) );
Janos Follathf9203b42017-03-22 15:13:15 +00001015
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001016 DQ = &DQ_blind;
Janos Follathe81102e2017-03-22 13:38:28 +00001017#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019#if defined(MBEDTLS_RSA_NO_CRT)
Janos Follathe81102e2017-03-22 13:38:28 +00001020 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +01001021#else
Paul Bakkeraab30c12013-08-30 11:00:25 +02001022 /*
Janos Follathe81102e2017-03-22 13:38:28 +00001023 * Faster decryption using the CRT
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 *
Hanno Becker06811ce2017-05-03 15:10:34 +01001025 * TP = input ^ dP mod P
1026 * TQ = input ^ dQ mod Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 */
Hanno Becker06811ce2017-05-03 15:10:34 +01001028
1029 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
1030 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001031
1032 /*
Hanno Becker06811ce2017-05-03 15:10:34 +01001033 * T = (TP - TQ) * (Q^-1 mod P) mod P
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 */
Hanno Becker06811ce2017-05-03 15:10:34 +01001035 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
1036 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
1037 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001038
1039 /*
Hanno Becker06811ce2017-05-03 15:10:34 +01001040 * T = TQ + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 */
Hanno Becker06811ce2017-05-03 15:10:34 +01001042 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
1043 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +02001045
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001046 /*
1047 * Unblind
1048 * T = T * Vf mod N
1049 */
1050 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
1051 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001052
Hanno Becker2dec5e82017-10-03 07:49:52 +01001053 /* Verify the result to prevent glitching attacks. */
1054 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
1055 &ctx->N, &ctx->RN ) );
Hanno Beckerc6075cc2017-08-25 11:45:35 +01001056 if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
Hanno Becker06811ce2017-05-03 15:10:34 +01001057 {
Hanno Becker06811ce2017-05-03 15:10:34 +01001058 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
1059 goto cleanup;
1060 }
Hanno Becker06811ce2017-05-03 15:10:34 +01001061
Paul Bakker5121ce52009-01-03 21:22:43 +00001062 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001064
1065cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +02001067 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1068 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +02001069#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +02001070
Hanno Becker06811ce2017-05-03 15:10:34 +01001071 mbedtls_mpi_free( &P1 );
1072 mbedtls_mpi_free( &Q1 );
1073 mbedtls_mpi_free( &R );
Janos Follathf9203b42017-03-22 15:13:15 +00001074
Janos Follathe81102e2017-03-22 13:38:28 +00001075#if defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001076 mbedtls_mpi_free( &D_blind );
Janos Follathf9203b42017-03-22 15:13:15 +00001077#else
Manuel Pégourié-Gonnardf0359042021-06-15 11:29:26 +02001078 mbedtls_mpi_free( &DP_blind );
1079 mbedtls_mpi_free( &DQ_blind );
Janos Follathe81102e2017-03-22 13:38:28 +00001080#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001081
Hanno Becker06811ce2017-05-03 15:10:34 +01001082 mbedtls_mpi_free( &T );
1083
1084#if !defined(MBEDTLS_RSA_NO_CRT)
1085 mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
1086#endif
1087
Hanno Beckerc6075cc2017-08-25 11:45:35 +01001088 mbedtls_mpi_free( &C );
1089 mbedtls_mpi_free( &I );
Hanno Becker06811ce2017-05-03 15:10:34 +01001090
Gilles Peskineae3741e2020-11-25 00:10:31 +01001091 if( ret != 0 && ret >= -0x007f )
Chris Jonesb7d02e02021-04-01 17:40:03 +01001092 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001093
Gilles Peskineae3741e2020-11-25 00:10:31 +01001094 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001095}
1096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +00001098/**
1099 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1100 *
Paul Bakkerb125ed82011-11-10 13:33:51 +00001101 * \param dst buffer to mask
1102 * \param dlen length of destination buffer
1103 * \param src source of the mask generation
1104 * \param slen length of the source buffer
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001105 * \param md_alg message digest to use
Paul Bakker9dcc3222011-03-08 14:16:06 +00001106 */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001107static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001108 size_t slen, mbedtls_md_type_t md_alg )
Paul Bakker9dcc3222011-03-08 14:16:06 +00001109{
Paul Bakker9dcc3222011-03-08 14:16:06 +00001110 unsigned char counter[4];
1111 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +00001112 unsigned int hlen;
1113 size_t i, use_len;
Przemek Stekiel40afdd22022-09-06 13:08:28 +02001114 unsigned char mask[MBEDTLS_HASH_MAX_SIZE];
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001115#if defined(MBEDTLS_MD_C)
Andres Amaya Garcia94682d12017-07-20 14:26:37 +01001116 int ret = 0;
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001117 const mbedtls_md_info_t *md_info;
1118 mbedtls_md_context_t md_ctx;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001119
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001120 mbedtls_md_init( &md_ctx );
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001121 md_info = mbedtls_md_info_from_type( md_alg );
1122 if( md_info == NULL )
1123 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1124
1125 mbedtls_md_init( &md_ctx );
1126 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1127 goto exit;
1128
1129 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001130#else
1131 psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
1132 psa_algorithm_t alg = mbedtls_psa_translate_md( md_alg );
1133 psa_status_t status = PSA_SUCCESS;
1134 size_t out_len;
1135
1136 hlen = PSA_HASH_LENGTH( alg );
1137#endif
1138
1139 memset( mask, 0, sizeof( mask ) );
1140 memset( counter, 0, 4 );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001141
Simon Butcher02037452016-03-01 21:19:12 +00001142 /* Generate and apply dbMask */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001143 p = dst;
1144
1145 while( dlen > 0 )
1146 {
1147 use_len = hlen;
1148 if( dlen < hlen )
1149 use_len = dlen;
1150
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001151#if defined(MBEDTLS_MD_C)
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001152 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001153 goto exit;
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001154 if( ( ret = mbedtls_md_update( &md_ctx, src, slen ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001155 goto exit;
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001156 if( ( ret = mbedtls_md_update( &md_ctx, counter, 4 ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001157 goto exit;
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001158 if( ( ret = mbedtls_md_finish( &md_ctx, mask ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001159 goto exit;
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001160#else
1161 if( ( status = psa_hash_setup( &op, alg ) ) != PSA_SUCCESS )
1162 goto exit;
1163 if( ( status = psa_hash_update( &op, src, slen ) ) != PSA_SUCCESS )
1164 goto exit;
1165 if( ( status = psa_hash_update( &op, counter, 4 ) ) != PSA_SUCCESS )
1166 goto exit;
1167 status = psa_hash_finish( &op, mask, sizeof( mask ), &out_len );
1168 if( status != PSA_SUCCESS )
1169 goto exit;
1170#endif
Paul Bakker9dcc3222011-03-08 14:16:06 +00001171
1172 for( i = 0; i < use_len; ++i )
1173 *p++ ^= mask[i];
1174
1175 counter[3]++;
1176
1177 dlen -= use_len;
1178 }
Gilles Peskine18ac7162017-05-05 19:24:06 +02001179
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001180exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05001181 mbedtls_platform_zeroize( mask, sizeof( mask ) );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001182#if defined(MBEDTLS_MD_C)
1183 mbedtls_md_free( &md_ctx );
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001184
1185 return( ret );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001186#else
1187 psa_hash_abort( &op );
1188
Przemek Stekiel2aae0402022-07-29 11:20:07 +02001189 return( mbedtls_md_error_from_psa( status ) );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001190#endif
Paul Bakker9dcc3222011-03-08 14:16:06 +00001191}
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001192
1193/**
1194 * Generate Hash(M') as in RFC 8017 page 43 points 5 and 6.
1195 *
1196 * \param hash the input hash
1197 * \param hlen length of the input hash
1198 * \param salt the input salt
1199 * \param slen length of the input salt
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001200 * \param out the output buffer - must be large enough for \p md_alg
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001201 * \param md_alg message digest to use
1202 */
1203static int hash_mprime( const unsigned char *hash, size_t hlen,
1204 const unsigned char *salt, size_t slen,
1205 unsigned char *out, mbedtls_md_type_t md_alg )
1206{
1207 const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001208
1209#if defined(MBEDTLS_MD_C)
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001210 mbedtls_md_context_t md_ctx;
Przemek Stekielf98b57f2022-07-29 11:27:46 +02001211 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001212
1213 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
1214 if( md_info == NULL )
1215 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1216
1217 mbedtls_md_init( &md_ctx );
1218 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1219 goto exit;
1220 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
1221 goto exit;
1222 if( ( ret = mbedtls_md_update( &md_ctx, zeros, sizeof( zeros ) ) ) != 0 )
1223 goto exit;
1224 if( ( ret = mbedtls_md_update( &md_ctx, hash, hlen ) ) != 0 )
1225 goto exit;
1226 if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
1227 goto exit;
1228 if( ( ret = mbedtls_md_finish( &md_ctx, out ) ) != 0 )
1229 goto exit;
1230
1231exit:
1232 mbedtls_md_free( &md_ctx );
1233
1234 return( ret );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001235#else
1236 psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
1237 psa_algorithm_t alg = mbedtls_psa_translate_md( md_alg );
Przemek Stekielf98b57f2022-07-29 11:27:46 +02001238 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED ;
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001239 size_t out_size = PSA_HASH_LENGTH( alg );
1240 size_t out_len;
1241
1242 if( ( status = psa_hash_setup( &op, alg ) ) != PSA_SUCCESS )
1243 goto exit;
1244 if( ( status = psa_hash_update( &op, zeros, sizeof( zeros ) ) ) != PSA_SUCCESS )
1245 goto exit;
1246 if( ( status = psa_hash_update( &op, hash, hlen ) ) != PSA_SUCCESS )
1247 goto exit;
1248 if( ( status = psa_hash_update( &op, salt, slen ) ) != PSA_SUCCESS )
1249 goto exit;
1250 status = psa_hash_finish( &op, out, out_size, &out_len );
1251 if( status != PSA_SUCCESS )
1252 goto exit;
1253
1254exit:
1255 psa_hash_abort( &op );
1256
Przemek Stekiel2aae0402022-07-29 11:20:07 +02001257 return( mbedtls_md_error_from_psa( status ) );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001258#endif /* !MBEDTLS_MD_C */
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001259}
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001260
1261/**
1262 * Compute a hash.
1263 *
1264 * \param md_alg algorithm to use
1265 * \param input input message to hash
1266 * \param ilen input length
1267 * \param output the output buffer - must be large enough for \p md_alg
1268 */
1269static int compute_hash( mbedtls_md_type_t md_alg,
1270 const unsigned char *input, size_t ilen,
1271 unsigned char *output )
1272{
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001273#if defined(MBEDTLS_MD_C)
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001274 const mbedtls_md_info_t *md_info;
1275
1276 md_info = mbedtls_md_info_from_type( md_alg );
1277 if( md_info == NULL )
1278 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1279
1280 return( mbedtls_md( md_info, input, ilen, output ) );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001281#else
1282 psa_algorithm_t alg = mbedtls_psa_translate_md( md_alg );
1283 psa_status_t status;
1284 size_t out_size = PSA_HASH_LENGTH( alg );
1285 size_t out_len;
1286
1287 status = psa_hash_compute( alg, input, ilen, output, out_size, &out_len );
1288
Przemek Stekiel2aae0402022-07-29 11:20:07 +02001289 return( mbedtls_md_error_from_psa( status ) );
Manuel Pégourié-Gonnard077ba842022-07-27 10:42:31 +02001290#endif /* !MBEDTLS_MD_C */
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001291}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +01001295/*
1296 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1297 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001299 int (*f_rng)(void *, unsigned char *, size_t),
1300 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001301 const unsigned char *label, size_t label_len,
1302 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001303 const unsigned char *input,
1304 unsigned char *output )
1305{
1306 size_t olen;
Janos Follath24eed8d2019-11-22 13:21:35 +00001307 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb3869132013-02-28 17:21:01 +01001308 unsigned char *p = output;
1309 unsigned int hlen;
Paul Bakkerb3869132013-02-28 17:21:01 +01001310
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001311 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001312 RSA_VALIDATE_RET( output != NULL );
Jaeden Amerofb236732019-02-08 13:11:59 +00001313 RSA_VALIDATE_RET( ilen == 0 || input != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001314 RSA_VALIDATE_RET( label_len == 0 || label != NULL );
1315
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001316 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001318
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02001319 hlen = mbedtls_hash_info_get_size( (mbedtls_md_type_t) ctx->hash_id );
1320 if( hlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001322
1323 olen = ctx->len;
Paul Bakkerb3869132013-02-28 17:21:01 +01001324
Simon Butcher02037452016-03-01 21:19:12 +00001325 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001326 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001328
1329 memset( output, 0, olen );
1330
1331 *p++ = 0;
1332
Simon Butcher02037452016-03-01 21:19:12 +00001333 /* Generate a random octet string seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001334 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +01001335 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001336
1337 p += hlen;
1338
Simon Butcher02037452016-03-01 21:19:12 +00001339 /* Construct DB */
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001340 ret = compute_hash( (mbedtls_md_type_t) ctx->hash_id, label, label_len, p );
1341 if( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001342 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001343 p += hlen;
1344 p += olen - 2 * hlen - 2 - ilen;
1345 *p++ = 1;
Gilles Peskine004f87b2018-07-06 15:47:54 +02001346 if( ilen != 0 )
1347 memcpy( p, input, ilen );
Paul Bakkerb3869132013-02-28 17:21:01 +01001348
Simon Butcher02037452016-03-01 21:19:12 +00001349 /* maskedDB: Apply dbMask to DB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001350 if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001351 ctx->hash_id ) ) != 0 )
Manuel Pégourié-Gonnardf3a67552022-07-15 12:16:42 +02001352 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001353
Simon Butcher02037452016-03-01 21:19:12 +00001354 /* maskedSeed: Apply seedMask to seed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001355 if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001356 ctx->hash_id ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001357 return( ret );
1358
Thomas Daubney141700f2021-05-13 19:06:10 +01001359 return( mbedtls_rsa_public( ctx, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001360}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001361#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001364/*
1365 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1366 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001368 int (*f_rng)(void *, unsigned char *, size_t),
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001369 void *p_rng, size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001370 const unsigned char *input,
1371 unsigned char *output )
1372{
1373 size_t nb_pad, olen;
Janos Follath24eed8d2019-11-22 13:21:35 +00001374 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb3869132013-02-28 17:21:01 +01001375 unsigned char *p = output;
1376
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001377 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001378 RSA_VALIDATE_RET( output != NULL );
Jaeden Amerofb236732019-02-08 13:11:59 +00001379 RSA_VALIDATE_RET( ilen == 0 || input != NULL );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001380
Paul Bakkerb3869132013-02-28 17:21:01 +01001381 olen = ctx->len;
Manuel Pégourié-Gonnard370717b2016-02-11 10:35:13 +01001382
Simon Butcher02037452016-03-01 21:19:12 +00001383 /* first comparison checks for overflow */
Janos Follatheddfe8f2016-02-08 14:52:29 +00001384 if( ilen + 11 < ilen || olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001385 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001386
1387 nb_pad = olen - 3 - ilen;
1388
1389 *p++ = 0;
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001390
1391 if( f_rng == NULL )
1392 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1393
1394 *p++ = MBEDTLS_RSA_CRYPT;
1395
1396 while( nb_pad-- > 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001397 {
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001398 int rng_dl = 100;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001399
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001400 do {
1401 ret = f_rng( p_rng, p, 1 );
1402 } while( *p == 0 && --rng_dl && ret == 0 );
Paul Bakkerb3869132013-02-28 17:21:01 +01001403
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001404 /* Check if RNG failed to generate data */
1405 if( rng_dl == 0 || ret != 0 )
1406 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001407
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001408 p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001409 }
1410
1411 *p++ = 0;
Gilles Peskine004f87b2018-07-06 15:47:54 +02001412 if( ilen != 0 )
1413 memcpy( p, input, ilen );
Paul Bakkerb3869132013-02-28 17:21:01 +01001414
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001415 return( mbedtls_rsa_public( ctx, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +01001416}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001417#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001418
Paul Bakker5121ce52009-01-03 21:22:43 +00001419/*
1420 * Add the message padding, then do an RSA operation
1421 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001423 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +00001424 void *p_rng,
Thomas Daubney21772772021-05-13 17:30:32 +01001425 size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001426 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001427 unsigned char *output )
1428{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001429 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001430 RSA_VALIDATE_RET( output != NULL );
Jaeden Amerofb236732019-02-08 13:11:59 +00001431 RSA_VALIDATE_RET( ilen == 0 || input != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001432
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 switch( ctx->padding )
1434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435#if defined(MBEDTLS_PKCS1_V15)
1436 case MBEDTLS_RSA_PKCS_V15:
Thomas Daubney21772772021-05-13 17:30:32 +01001437 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng,
Thomas Daubney53e4ac62021-05-13 18:26:49 +01001438 ilen, input, output );
Paul Bakker48377d92013-08-30 12:06:24 +02001439#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441#if defined(MBEDTLS_PKCS1_V21)
1442 case MBEDTLS_RSA_PKCS_V21:
Thomas Daubney141700f2021-05-13 19:06:10 +01001443 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, NULL, 0,
Thomas Daubney21772772021-05-13 17:30:32 +01001444 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001445#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001446
1447 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001449 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001450}
1451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001453/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001454 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +00001455 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001456int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001457 int (*f_rng)(void *, unsigned char *, size_t),
1458 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +01001459 const unsigned char *label, size_t label_len,
1460 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001461 const unsigned char *input,
1462 unsigned char *output,
1463 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +00001464{
Janos Follath24eed8d2019-11-22 13:21:35 +00001465 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001466 size_t ilen, i, pad_len;
1467 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Przemek Stekiel40afdd22022-09-06 13:08:28 +02001469 unsigned char lhash[MBEDTLS_HASH_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00001470 unsigned int hlen;
Paul Bakkerb3869132013-02-28 17:21:01 +01001471
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001472 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001473 RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1474 RSA_VALIDATE_RET( label_len == 0 || label != NULL );
1475 RSA_VALIDATE_RET( input != NULL );
1476 RSA_VALIDATE_RET( olen != NULL );
1477
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001478 /*
1479 * Parameters sanity checks
1480 */
Thomas Daubneyd21e0b72021-05-06 11:41:09 +01001481 if( ctx->padding != MBEDTLS_RSA_PKCS_V21 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001483
1484 ilen = ctx->len;
1485
Paul Bakker27fdf462011-06-09 13:55:13 +00001486 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001488
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02001489 hlen = mbedtls_hash_info_get_size( (mbedtls_md_type_t) ctx->hash_id );
1490 if( hlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001492
Janos Follathc17cda12016-02-11 11:08:18 +00001493 // checking for integer underflow
1494 if( 2 * hlen + 2 > ilen )
1495 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1496
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001497 /*
1498 * RSA operation
1499 */
Thomas Daubneyd21e0b72021-05-06 11:41:09 +01001500 ret = mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001501
1502 if( ret != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001503 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00001504
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001505 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001506 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001507 */
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001508 /* seed: Apply seedMask to maskedSeed */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001509 if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001510 ctx->hash_id ) ) != 0 ||
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001511 /* DB: Apply dbMask to maskedDB */
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001512 ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02001513 ctx->hash_id ) ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001514 {
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001515 goto cleanup;
1516 }
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001517
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001518 /* Generate lHash */
Manuel Pégourié-Gonnard35c09e42022-07-15 13:10:54 +02001519 ret = compute_hash( (mbedtls_md_type_t) ctx->hash_id,
1520 label, label_len, lhash );
1521 if( ret != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01001522 goto cleanup;
1523
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001524 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001525 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001526 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001527 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001528 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001529
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001530 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001531
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001532 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +01001533
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +01001534 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001535 for( i = 0; i < hlen; i++ )
1536 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +01001537
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001538 /* Get zero-padding len, but always read till end of buffer
1539 * (minus one, for the 01 byte) */
1540 pad_len = 0;
1541 pad_done = 0;
1542 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1543 {
1544 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +01001545 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001546 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001547
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001548 p += pad_len;
1549 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +01001550
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +01001551 /*
1552 * The only information "leaked" is whether the padding was correct or not
1553 * (eg, no data is copied if it was not correct). This meets the
1554 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1555 * the different error conditions.
1556 */
1557 if( bad != 0 )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001558 {
1559 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1560 goto cleanup;
1561 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001562
Paul Bakker66d5d072014-06-17 16:39:18 +02001563 if( ilen - ( p - buf ) > output_max_len )
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001564 {
1565 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1566 goto cleanup;
1567 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001568
1569 *olen = ilen - (p - buf);
Gilles Peskine004f87b2018-07-06 15:47:54 +02001570 if( *olen != 0 )
1571 memcpy( output, p, *olen );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001572 ret = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001573
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001574cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05001575 mbedtls_platform_zeroize( buf, sizeof( buf ) );
1576 mbedtls_platform_zeroize( lhash, sizeof( lhash ) );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001577
1578 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001579}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001581
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001582#if defined(MBEDTLS_PKCS1_V15)
gabor-mezei-armbef600f2021-09-26 15:20:48 +02001583/*
1584 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1585 */
1586int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
1587 int (*f_rng)(void *, unsigned char *, size_t),
1588 void *p_rng,
1589 size_t *olen,
1590 const unsigned char *input,
1591 unsigned char *output,
1592 size_t output_max_len )
1593{
1594 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1595 size_t ilen;
1596 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1597
1598 RSA_VALIDATE_RET( ctx != NULL );
1599 RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1600 RSA_VALIDATE_RET( input != NULL );
1601 RSA_VALIDATE_RET( olen != NULL );
1602
1603 ilen = ctx->len;
1604
1605 if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1606 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1607
1608 if( ilen < 16 || ilen > sizeof( buf ) )
1609 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1610
1611 ret = mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
1612
1613 if( ret != 0 )
1614 goto cleanup;
1615
Gabor Mezei90437e32021-10-20 11:59:27 +02001616 ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( buf, ilen,
Gabor Mezei63bbba52021-10-18 16:17:57 +02001617 output, output_max_len, olen );
gabor-mezei-armbef600f2021-09-26 15:20:48 +02001618
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001619cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05001620 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine4a7f6a02017-03-23 14:37:37 +01001621
1622 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001623}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001624#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001625
1626/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001627 * Do an RSA operation, then remove the message padding
1628 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001629int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001630 int (*f_rng)(void *, unsigned char *, size_t),
1631 void *p_rng,
Thomas Daubneyc7feaf32021-05-07 14:02:43 +01001632 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001633 const unsigned char *input,
1634 unsigned char *output,
1635 size_t output_max_len)
1636{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001637 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001638 RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1639 RSA_VALIDATE_RET( input != NULL );
1640 RSA_VALIDATE_RET( olen != NULL );
1641
Paul Bakkerb3869132013-02-28 17:21:01 +01001642 switch( ctx->padding )
1643 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001644#if defined(MBEDTLS_PKCS1_V15)
1645 case MBEDTLS_RSA_PKCS_V15:
Thomas Daubney34733082021-05-12 09:24:29 +01001646 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, olen,
Paul Bakker548957d2013-08-30 10:30:02 +02001647 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +02001648#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001650#if defined(MBEDTLS_PKCS1_V21)
1651 case MBEDTLS_RSA_PKCS_V21:
Thomas Daubneyd21e0b72021-05-06 11:41:09 +01001652 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +02001653 olen, input, output,
1654 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +01001655#endif
1656
1657 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001658 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001659 }
1660}
1661
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001662#if defined(MBEDTLS_PKCS1_V21)
Cédric Meuterf3fab332020-04-25 11:30:45 +02001663static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +01001664 int (*f_rng)(void *, unsigned char *, size_t),
1665 void *p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001666 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001667 unsigned int hashlen,
1668 const unsigned char *hash,
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001669 int saltlen,
Paul Bakkerb3869132013-02-28 17:21:01 +01001670 unsigned char *sig )
1671{
1672 size_t olen;
1673 unsigned char *p = sig;
Cédric Meuter668a78d2020-04-30 11:57:04 +02001674 unsigned char *salt = NULL;
Jaeden Amero3725bb22018-09-07 19:12:36 +01001675 size_t slen, min_slen, hlen, offset = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +00001676 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb3869132013-02-28 17:21:01 +01001677 size_t msb;
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001678
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001679 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001680 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
1681 hashlen == 0 ) ||
1682 hash != NULL );
1683 RSA_VALIDATE_RET( sig != NULL );
Paul Bakkerb3869132013-02-28 17:21:01 +01001684
Thomas Daubneyd58ed582021-05-21 11:50:39 +01001685 if( ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1686 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1687
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +02001688 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001689 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001690
1691 olen = ctx->len;
1692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001693 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001694 {
Simon Butcher02037452016-03-01 21:19:12 +00001695 /* Gather length of hash to sign */
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02001696 size_t exp_hashlen = mbedtls_hash_info_get_size( md_alg );
1697 if( exp_hashlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001698 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001699
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02001700 if( hashlen != exp_hashlen )
Gilles Peskine6e3187b2021-06-22 18:39:53 +02001701 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001702 }
1703
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02001704 hlen = mbedtls_hash_info_get_size( (mbedtls_md_type_t) ctx->hash_id );
1705 if( hlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001706 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001707
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001708 if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY)
1709 {
Cédric Meuter010ddc22020-04-25 09:24:11 +02001710 /* Calculate the largest possible salt length, up to the hash size.
1711 * Normally this is the hash length, which is the maximum salt length
1712 * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001713 * enough room, use the maximum salt length that fits. The constraint is
1714 * that the hash length plus the salt length plus 2 bytes must be at most
1715 * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
1716 * (PKCS#1 v2.2) §9.1.1 step 3. */
1717 min_slen = hlen - 2;
1718 if( olen < hlen + min_slen + 2 )
1719 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1720 else if( olen >= hlen + hlen + 2 )
1721 slen = hlen;
1722 else
1723 slen = olen - hlen - 2;
1724 }
Cédric Meuter46bad332021-01-10 12:57:19 +01001725 else if ( (saltlen < 0) || (saltlen + hlen + 2 > olen) )
Cédric Meuter010ddc22020-04-25 09:24:11 +02001726 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001727 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Cédric Meuter010ddc22020-04-25 09:24:11 +02001728 }
Jaeden Amero3725bb22018-09-07 19:12:36 +01001729 else
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001730 {
Cédric Meuter010ddc22020-04-25 09:24:11 +02001731 slen = (size_t) saltlen;
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001732 }
Paul Bakkerb3869132013-02-28 17:21:01 +01001733
1734 memset( sig, 0, olen );
1735
Simon Butcher02037452016-03-01 21:19:12 +00001736 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001737 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Jaeden Amero3725bb22018-09-07 19:12:36 +01001738 p += olen - hlen - slen - 2;
Paul Bakkerb3869132013-02-28 17:21:01 +01001739 *p++ = 0x01;
Cédric Meuter668a78d2020-04-30 11:57:04 +02001740
1741 /* Generate salt of length slen in place in the encoded message */
1742 salt = p;
1743 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Chris Jonesb7d02e02021-04-01 17:40:03 +01001744 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
Cédric Meuter668a78d2020-04-30 11:57:04 +02001745
Paul Bakkerb3869132013-02-28 17:21:01 +01001746 p += slen;
1747
Simon Butcher02037452016-03-01 21:19:12 +00001748 /* Generate H = Hash( M' ) */
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001749 ret = hash_mprime( hash, hashlen, salt, slen, p, ctx->hash_id );
1750 if( ret != 0 )
1751 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001752
Simon Butcher02037452016-03-01 21:19:12 +00001753 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01001754 if( msb % 8 == 0 )
1755 offset = 1;
1756
Simon Butcher02037452016-03-01 21:19:12 +00001757 /* maskedDB: Apply dbMask to DB */
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02001758 ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
1759 ctx->hash_id );
1760 if( ret != 0 )
1761 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001762
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001763 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +01001764 sig[0] &= 0xFF >> ( olen * 8 - msb );
1765
1766 p += hlen;
1767 *p++ = 0xBC;
1768
Thomas Daubneycad59ed2021-05-19 15:04:08 +01001769 return mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig );
Paul Bakkerb3869132013-02-28 17:21:01 +01001770}
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001771
1772/*
Cédric Meuterf3fab332020-04-25 11:30:45 +02001773 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
1774 * the option to pass in the salt length.
1775 */
1776int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
1777 int (*f_rng)(void *, unsigned char *, size_t),
1778 void *p_rng,
1779 mbedtls_md_type_t md_alg,
1780 unsigned int hashlen,
1781 const unsigned char *hash,
1782 int saltlen,
1783 unsigned char *sig )
1784{
Thomas Daubneycad59ed2021-05-19 15:04:08 +01001785 return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, md_alg,
Cédric Meuterf3fab332020-04-25 11:30:45 +02001786 hashlen, hash, saltlen, sig );
1787}
1788
1789
1790/*
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001791 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1792 */
1793int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
1794 int (*f_rng)(void *, unsigned char *, size_t),
1795 void *p_rng,
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001796 mbedtls_md_type_t md_alg,
1797 unsigned int hashlen,
1798 const unsigned char *hash,
1799 unsigned char *sig )
1800{
Thomas Daubneycad59ed2021-05-19 15:04:08 +01001801 return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, md_alg,
Cédric Meuterf3fab332020-04-25 11:30:45 +02001802 hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig );
Cedric Meuter8aa4d752020-04-21 12:49:11 +02001803}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001804#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001806#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001807/*
1808 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1809 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001810
1811/* Construct a PKCS v1.5 encoding of a hashed message
1812 *
1813 * This is used both for signature generation and verification.
1814 *
1815 * Parameters:
1816 * - md_alg: Identifies the hash algorithm used to generate the given hash;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001817 * MBEDTLS_MD_NONE if raw data is signed.
Gilles Peskine6e3187b2021-06-22 18:39:53 +02001818 * - hashlen: Length of hash. Must match md_alg if that's not NONE.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001819 * - hash: Buffer containing the hashed message or the raw data.
1820 * - dst_len: Length of the encoded message.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001821 * - dst: Buffer to hold the encoded message.
1822 *
1823 * Assumptions:
Gilles Peskine6e3187b2021-06-22 18:39:53 +02001824 * - hash has size hashlen.
Hanno Beckere58d38c2017-09-27 17:09:00 +01001825 * - dst points to a buffer of size at least dst_len.
Hanno Beckerfdf38032017-09-06 12:35:55 +01001826 *
1827 */
1828static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
1829 unsigned int hashlen,
1830 const unsigned char *hash,
Hanno Beckere58d38c2017-09-27 17:09:00 +01001831 size_t dst_len,
Hanno Beckerfdf38032017-09-06 12:35:55 +01001832 unsigned char *dst )
1833{
1834 size_t oid_size = 0;
Hanno Beckere58d38c2017-09-27 17:09:00 +01001835 size_t nb_pad = dst_len;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001836 unsigned char *p = dst;
1837 const char *oid = NULL;
1838
1839 /* Are we signing hashed or raw data? */
1840 if( md_alg != MBEDTLS_MD_NONE )
1841 {
Manuel Pégourié-Gonnard47728842022-07-18 13:00:40 +02001842 unsigned char md_size = mbedtls_hash_info_get_size( md_alg );
Manuel Pégourié-Gonnardf493f2a2022-07-05 17:41:05 +02001843 if( md_size == 0 )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001844 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1845
1846 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1847 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1848
Manuel Pégourié-Gonnardf493f2a2022-07-05 17:41:05 +02001849 if( hashlen != md_size )
Gilles Peskine6e3187b2021-06-22 18:39:53 +02001850 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001851
1852 /* Double-check that 8 + hashlen + oid_size can be used as a
1853 * 1-byte ASN.1 length encoding and that there's no overflow. */
1854 if( 8 + hashlen + oid_size >= 0x80 ||
1855 10 + hashlen < hashlen ||
1856 10 + hashlen + oid_size < 10 + hashlen )
1857 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1858
1859 /*
1860 * Static bounds check:
1861 * - Need 10 bytes for five tag-length pairs.
1862 * (Insist on 1-byte length encodings to protect against variants of
1863 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
1864 * - Need hashlen bytes for hash
1865 * - Need oid_size bytes for hash alg OID.
1866 */
1867 if( nb_pad < 10 + hashlen + oid_size )
1868 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1869 nb_pad -= 10 + hashlen + oid_size;
1870 }
1871 else
1872 {
1873 if( nb_pad < hashlen )
1874 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1875
1876 nb_pad -= hashlen;
1877 }
1878
Hanno Becker2b2f8982017-09-27 17:10:03 +01001879 /* Need space for signature header and padding delimiter (3 bytes),
1880 * and 8 bytes for the minimal padding */
1881 if( nb_pad < 3 + 8 )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001882 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1883 nb_pad -= 3;
1884
1885 /* Now nb_pad is the amount of memory to be filled
Hanno Becker2b2f8982017-09-27 17:10:03 +01001886 * with padding, and at least 8 bytes long. */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001887
1888 /* Write signature header and padding */
1889 *p++ = 0;
1890 *p++ = MBEDTLS_RSA_SIGN;
1891 memset( p, 0xFF, nb_pad );
1892 p += nb_pad;
1893 *p++ = 0;
1894
1895 /* Are we signing raw data? */
1896 if( md_alg == MBEDTLS_MD_NONE )
1897 {
1898 memcpy( p, hash, hashlen );
1899 return( 0 );
1900 }
1901
1902 /* Signing hashed data, add corresponding ASN.1 structure
1903 *
1904 * DigestInfo ::= SEQUENCE {
1905 * digestAlgorithm DigestAlgorithmIdentifier,
1906 * digest Digest }
1907 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1908 * Digest ::= OCTET STRING
1909 *
1910 * Schematic:
1911 * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
1912 * TAG-NULL + LEN [ NULL ] ]
1913 * TAG-OCTET + LEN [ HASH ] ]
1914 */
1915 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001916 *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001917 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Hanno Becker87ae1972018-01-15 15:27:56 +00001918 *p++ = (unsigned char)( 0x04 + oid_size );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001919 *p++ = MBEDTLS_ASN1_OID;
Hanno Becker87ae1972018-01-15 15:27:56 +00001920 *p++ = (unsigned char) oid_size;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001921 memcpy( p, oid, oid_size );
1922 p += oid_size;
1923 *p++ = MBEDTLS_ASN1_NULL;
1924 *p++ = 0x00;
1925 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Hanno Becker87ae1972018-01-15 15:27:56 +00001926 *p++ = (unsigned char) hashlen;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001927 memcpy( p, hash, hashlen );
1928 p += hashlen;
1929
1930 /* Just a sanity-check, should be automatic
1931 * after the initial bounds check. */
Hanno Beckere58d38c2017-09-27 17:09:00 +01001932 if( p != dst + dst_len )
Hanno Beckerfdf38032017-09-06 12:35:55 +01001933 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05001934 mbedtls_platform_zeroize( dst, dst_len );
Hanno Beckerfdf38032017-09-06 12:35:55 +01001935 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1936 }
1937
1938 return( 0 );
1939}
1940
Paul Bakkerb3869132013-02-28 17:21:01 +01001941/*
1942 * Do an RSA operation to sign the message digest
1943 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001944int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001945 int (*f_rng)(void *, unsigned char *, size_t),
1946 void *p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001947 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001948 unsigned int hashlen,
1949 const unsigned char *hash,
1950 unsigned char *sig )
1951{
Janos Follath24eed8d2019-11-22 13:21:35 +00001952 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckerfdf38032017-09-06 12:35:55 +01001953 unsigned char *sig_try = NULL, *verif = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01001954
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001955 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05001956 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
1957 hashlen == 0 ) ||
1958 hash != NULL );
1959 RSA_VALIDATE_RET( sig != NULL );
1960
Thomas Daubneyd58ed582021-05-21 11:50:39 +01001961 if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1962 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1963
Hanno Beckerfdf38032017-09-06 12:35:55 +01001964 /*
1965 * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
1966 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001967
Hanno Beckerfdf38032017-09-06 12:35:55 +01001968 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
1969 ctx->len, sig ) ) != 0 )
1970 return( ret );
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001971
Hanno Beckerfdf38032017-09-06 12:35:55 +01001972 /* Private key operation
1973 *
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001974 * In order to prevent Lenstra's attack, make the signature in a
1975 * temporary buffer and check it before returning it.
1976 */
Hanno Beckerfdf38032017-09-06 12:35:55 +01001977
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001978 sig_try = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001979 if( sig_try == NULL )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001980 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1981
Hanno Beckerfdf38032017-09-06 12:35:55 +01001982 verif = mbedtls_calloc( 1, ctx->len );
Simon Butcher1285ab52016-01-01 21:42:47 +00001983 if( verif == NULL )
1984 {
1985 mbedtls_free( sig_try );
1986 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1987 }
1988
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001989 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
1990 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
1991
Gabor Mezei90437e32021-10-20 11:59:27 +02001992 if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001993 {
1994 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
1995 goto cleanup;
1996 }
1997
1998 memcpy( sig, sig_try, ctx->len );
1999
2000cleanup:
Gilles Peskine14d5fef2021-12-13 12:37:55 +01002001 mbedtls_platform_zeroize( sig_try, ctx->len );
2002 mbedtls_platform_zeroize( verif, ctx->len );
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002003 mbedtls_free( sig_try );
2004 mbedtls_free( verif );
2005
Gilles Peskine14d5fef2021-12-13 12:37:55 +01002006 if( ret != 0 )
2007 memset( sig, '!', ctx->len );
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02002008 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01002009}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002010#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002011
2012/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002013 * Do an RSA operation to sign the message digest
2014 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002016 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00002017 void *p_rng,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002018 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00002019 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00002020 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00002021 unsigned char *sig )
2022{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002023 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002024 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2025 hashlen == 0 ) ||
2026 hash != NULL );
2027 RSA_VALIDATE_RET( sig != NULL );
2028
Paul Bakker5121ce52009-01-03 21:22:43 +00002029 switch( ctx->padding )
2030 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002031#if defined(MBEDTLS_PKCS1_V15)
2032 case MBEDTLS_RSA_PKCS_V15:
Thomas Daubney52654982021-05-18 16:54:00 +01002033 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng,
Thomas Daubney140184d2021-05-18 16:04:07 +01002034 md_alg, hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002035#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002037#if defined(MBEDTLS_PKCS1_V21)
2038 case MBEDTLS_RSA_PKCS_V21:
Thomas Daubneyde9fdc42021-05-18 17:10:04 +01002039 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, md_alg,
2040 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002041#endif
2042
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002044 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002046}
2047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002048#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00002049/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002050 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002053 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002054 unsigned int hashlen,
2055 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002057 int expected_salt_len,
2058 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00002059{
Janos Follath24eed8d2019-11-22 13:21:35 +00002060 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakkerb3869132013-02-28 17:21:01 +01002061 size_t siglen;
2062 unsigned char *p;
Gilles Peskine6a54b022017-10-17 19:02:13 +02002063 unsigned char *hash_start;
Przemek Stekiel40afdd22022-09-06 13:08:28 +02002064 unsigned char result[MBEDTLS_HASH_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +00002065 unsigned int hlen;
Gilles Peskine6a54b022017-10-17 19:02:13 +02002066 size_t observed_salt_len, msb;
Leonid Rozenboima3008e72022-04-21 17:28:18 -07002067 unsigned char buf[MBEDTLS_MPI_MAX_SIZE] = {0};
Paul Bakkerb3869132013-02-28 17:21:01 +01002068
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002069 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002070 RSA_VALIDATE_RET( sig != NULL );
2071 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2072 hashlen == 0 ) ||
2073 hash != NULL );
2074
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 siglen = ctx->len;
2076
Paul Bakker27fdf462011-06-09 13:55:13 +00002077 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002078 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002079
Thomas Daubney782a7f52021-05-19 12:27:35 +01002080 ret = mbedtls_rsa_public( ctx, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
2082 if( ret != 0 )
2083 return( ret );
2084
2085 p = buf;
2086
Paul Bakkerb3869132013-02-28 17:21:01 +01002087 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002088 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002089
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002090 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 {
Simon Butcher02037452016-03-01 21:19:12 +00002092 /* Gather length of hash to sign */
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02002093 size_t exp_hashlen = mbedtls_hash_info_get_size( md_alg );
2094 if( exp_hashlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02002096
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02002097 if( hashlen != exp_hashlen )
Gilles Peskine6e3187b2021-06-22 18:39:53 +02002098 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01002099 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002100
Manuel Pégourié-Gonnardfaa3b4e2022-07-15 13:18:15 +02002101 hlen = mbedtls_hash_info_get_size( mgf1_hash_id );
2102 if( hlen == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002104
Simon Butcher02037452016-03-01 21:19:12 +00002105 /*
2106 * Note: EMSA-PSS verification is over the length of N - 1 bits
2107 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002108 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002109
Gilles Peskineb00b0da2017-10-19 15:23:49 +02002110 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
2111 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2112
Simon Butcher02037452016-03-01 21:19:12 +00002113 /* Compensate for boundary condition when applying mask */
Paul Bakkerb3869132013-02-28 17:21:01 +01002114 if( msb % 8 == 0 )
2115 {
2116 p++;
2117 siglen -= 1;
2118 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00002119
Gilles Peskine139108a2017-10-18 19:03:42 +02002120 if( siglen < hlen + 2 )
2121 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2122 hash_start = p + siglen - hlen - 1;
2123
Manuel Pégourié-Gonnard259c2132022-07-15 12:09:08 +02002124 ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, mgf1_hash_id );
Jaeden Amero66954e12018-01-25 16:05:54 +00002125 if( ret != 0 )
Manuel Pégourié-Gonnardf3a67552022-07-15 12:16:42 +02002126 return( ret );
Paul Bakker02303e82013-01-03 11:08:31 +01002127
Paul Bakkerb3869132013-02-28 17:21:01 +01002128 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002129
Gilles Peskine6a54b022017-10-17 19:02:13 +02002130 while( p < hash_start - 1 && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01002131 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002132
Gilles Peskine91048a32017-10-19 17:46:14 +02002133 if( *p++ != 0x01 )
Manuel Pégourié-Gonnardf3a67552022-07-15 12:16:42 +02002134 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker9dcc3222011-03-08 14:16:06 +00002135
Gilles Peskine6a54b022017-10-17 19:02:13 +02002136 observed_salt_len = hash_start - p;
Paul Bakker9dcc3222011-03-08 14:16:06 +00002137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002138 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Gilles Peskine6a54b022017-10-17 19:02:13 +02002139 observed_salt_len != (size_t) expected_salt_len )
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002140 {
Manuel Pégourié-Gonnardf3a67552022-07-15 12:16:42 +02002141 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002142 }
2143
Simon Butcher02037452016-03-01 21:19:12 +00002144 /*
2145 * Generate H = Hash( M' )
2146 */
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02002147 ret = hash_mprime( hash, hashlen, p, observed_salt_len,
2148 result, mgf1_hash_id );
2149 if( ret != 0 )
2150 return( ret );
Paul Bakker53019ae2011-03-25 13:58:48 +00002151
Jaeden Amero66954e12018-01-25 16:05:54 +00002152 if( memcmp( hash_start, result, hlen ) != 0 )
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02002153 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01002154
Manuel Pégourié-Gonnardf701acc2022-07-15 12:49:14 +02002155 return( 0 );
Paul Bakkerb3869132013-02-28 17:21:01 +01002156}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002157
2158/*
2159 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2160 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002161int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002162 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002163 unsigned int hashlen,
2164 const unsigned char *hash,
2165 const unsigned char *sig )
2166{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002167 mbedtls_md_type_t mgf1_hash_id;
2168 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002169 RSA_VALIDATE_RET( sig != NULL );
2170 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2171 hashlen == 0 ) ||
2172 hash != NULL );
2173
2174 mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002176 : md_alg;
2177
Thomas Daubney9e65f792021-05-19 12:18:58 +01002178 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx,
Thomas Daubney5ee4cc02021-05-19 12:07:42 +01002179 md_alg, hashlen, hash,
2180 mgf1_hash_id,
2181 MBEDTLS_RSA_SALT_LEN_ANY,
2182 sig ) );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02002183
2184}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01002186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01002188/*
2189 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2190 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002191int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002192 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002193 unsigned int hashlen,
2194 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002195 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002196{
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002197 int ret = 0;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002198 size_t sig_len;
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002199 unsigned char *encoded = NULL, *encoded_expected = NULL;
Paul Bakkerb3869132013-02-28 17:21:01 +01002200
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002201 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002202 RSA_VALIDATE_RET( sig != NULL );
2203 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2204 hashlen == 0 ) ||
2205 hash != NULL );
2206
2207 sig_len = ctx->len;
2208
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002209 /*
2210 * Prepare expected PKCS1 v1.5 encoding of hash.
2211 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002212
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002213 if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL ||
2214 ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
2215 {
2216 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2217 goto cleanup;
2218 }
2219
2220 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
2221 encoded_expected ) ) != 0 )
2222 goto cleanup;
2223
2224 /*
2225 * Apply RSA primitive to get what should be PKCS1 encoded hash.
2226 */
Paul Bakkerb3869132013-02-28 17:21:01 +01002227
Thomas Daubney41e4ce42021-05-19 15:10:05 +01002228 ret = mbedtls_rsa_public( ctx, sig, encoded );
Paul Bakkerb3869132013-02-28 17:21:01 +01002229 if( ret != 0 )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002230 goto cleanup;
Paul Bakkerc70b9822013-04-07 22:00:46 +02002231
Simon Butcher02037452016-03-01 21:19:12 +00002232 /*
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002233 * Compare
Simon Butcher02037452016-03-01 21:19:12 +00002234 */
Paul Bakkerc70b9822013-04-07 22:00:46 +02002235
Gabor Mezei90437e32021-10-20 11:59:27 +02002236 if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
gabor-mezei-arm46025642021-07-19 15:19:19 +02002237 sig_len ) ) != 0 )
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002238 {
2239 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2240 goto cleanup;
2241 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002242
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002243cleanup:
Paul Bakkerc70b9822013-04-07 22:00:46 +02002244
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002245 if( encoded != NULL )
2246 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05002247 mbedtls_platform_zeroize( encoded, sig_len );
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002248 mbedtls_free( encoded );
2249 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002250
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002251 if( encoded_expected != NULL )
2252 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05002253 mbedtls_platform_zeroize( encoded_expected, sig_len );
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002254 mbedtls_free( encoded_expected );
2255 }
Paul Bakkerc70b9822013-04-07 22:00:46 +02002256
Hanno Becker64a8c0a2017-09-06 12:39:49 +01002257 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002258}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002260
2261/*
Paul Bakkerb3869132013-02-28 17:21:01 +01002262 * Do an RSA operation and check the message digest
2263 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002264int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002265 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01002266 unsigned int hashlen,
2267 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02002268 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01002269{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002270 RSA_VALIDATE_RET( ctx != NULL );
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002271 RSA_VALIDATE_RET( sig != NULL );
2272 RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2273 hashlen == 0 ) ||
2274 hash != NULL );
2275
Paul Bakkerb3869132013-02-28 17:21:01 +01002276 switch( ctx->padding )
2277 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002278#if defined(MBEDTLS_PKCS1_V15)
2279 case MBEDTLS_RSA_PKCS_V15:
Thomas Daubney2e126252021-05-19 11:48:53 +01002280 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, md_alg,
2281 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02002282#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01002283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002284#if defined(MBEDTLS_PKCS1_V21)
2285 case MBEDTLS_RSA_PKCS_V21:
Thomas Daubney5ee4cc02021-05-19 12:07:42 +01002286 return mbedtls_rsa_rsassa_pss_verify( ctx, md_alg,
2287 hashlen, hash, sig );
Paul Bakkerb3869132013-02-28 17:21:01 +01002288#endif
2289
2290 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002291 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01002292 }
2293}
2294
2295/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002296 * Copy the components of an RSA key
2297 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002298int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002299{
Janos Follath24eed8d2019-11-22 13:21:35 +00002300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002301 RSA_VALIDATE_RET( dst != NULL );
2302 RSA_VALIDATE_RET( src != NULL );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002303
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002304 dst->len = src->len;
2305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002306 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2307 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002308
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002309 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2310 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2311 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002312
2313#if !defined(MBEDTLS_RSA_NO_CRT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002314 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2315 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2316 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2318 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Hanno Becker33c30a02017-08-23 07:00:22 +01002319#endif
2320
2321 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002323 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2324 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02002325
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002326 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01002327 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002328
2329cleanup:
2330 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002331 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02002332
2333 return( ret );
2334}
2335
2336/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002337 * Free the components of an RSA key
2338 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002339void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00002340{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002341 if( ctx == NULL )
2342 return;
2343
2344 mbedtls_mpi_free( &ctx->Vi );
2345 mbedtls_mpi_free( &ctx->Vf );
2346 mbedtls_mpi_free( &ctx->RN );
2347 mbedtls_mpi_free( &ctx->D );
2348 mbedtls_mpi_free( &ctx->Q );
2349 mbedtls_mpi_free( &ctx->P );
2350 mbedtls_mpi_free( &ctx->E );
2351 mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002352
Hanno Becker33c30a02017-08-23 07:00:22 +01002353#if !defined(MBEDTLS_RSA_NO_CRT)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002354 mbedtls_mpi_free( &ctx->RQ );
2355 mbedtls_mpi_free( &ctx->RP );
2356 mbedtls_mpi_free( &ctx->QP );
2357 mbedtls_mpi_free( &ctx->DQ );
Hanno Becker33c30a02017-08-23 07:00:22 +01002358 mbedtls_mpi_free( &ctx->DP );
2359#endif /* MBEDTLS_RSA_NO_CRT */
2360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002361#if defined(MBEDTLS_THREADING_C)
Gilles Peskineeb940592021-02-01 17:57:41 +01002362 /* Free the mutex, but only if it hasn't been freed already. */
2363 if( ctx->ver != 0 )
2364 {
2365 mbedtls_mutex_free( &ctx->mutex );
2366 ctx->ver = 0;
2367 }
Paul Bakkerc9965dc2013-09-29 14:58:17 +02002368#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002369}
2370
Hanno Beckerab377312017-08-23 16:24:51 +01002371#endif /* !MBEDTLS_RSA_ALT */
2372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002373#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002374
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002375#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00002376
2377/*
2378 * Example RSA-1024 keypair, for test purposes
2379 */
2380#define KEY_LEN 128
2381
2382#define RSA_N "9292758453063D803DD603D5E777D788" \
2383 "8ED1D5BF35786190FA2F23EBC0848AEA" \
2384 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2385 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2386 "93A89813FBF3C4F8066D2D800F7C38A8" \
2387 "1AE31942917403FF4946B0A83D3D3E05" \
2388 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2389 "5E94BB77B07507233A0BC7BAC8F90F79"
2390
2391#define RSA_E "10001"
2392
2393#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2394 "66CA472BC44D253102F8B4A9D3BFA750" \
2395 "91386C0077937FE33FA3252D28855837" \
2396 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2397 "DF79C5CE07EE72C7F123142198164234" \
2398 "CABB724CF78B8173B9F880FC86322407" \
2399 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2400 "071513A1E85B5DFA031F21ECAE91A34D"
2401
2402#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2403 "2C01CAD19EA484A87EA4377637E75500" \
2404 "FCB2005C5C7DD6EC4AC023CDA285D796" \
2405 "C3D9E75E1EFC42488BB4F1D13AC30A57"
2406
2407#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2408 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2409 "910E4168387E3C30AA1E00C339A79508" \
2410 "8452DD96A9A5EA5D9DCA68DA636032AF"
2411
Paul Bakker5121ce52009-01-03 21:22:43 +00002412#define PT_LEN 24
2413#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2414 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002416#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002417static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00002418{
gufe44c2620da2020-08-03 17:56:50 +02002419#if !defined(__OpenBSD__) && !defined(__NetBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00002420 size_t i;
2421
Paul Bakker545570e2010-07-18 09:00:25 +00002422 if( rng_state != NULL )
2423 rng_state = NULL;
2424
Paul Bakkera3d195c2011-11-27 21:07:34 +00002425 for( i = 0; i < len; ++i )
2426 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02002427#else
2428 if( rng_state != NULL )
2429 rng_state = NULL;
2430
2431 arc4random_buf( output, len );
gufe44c2620da2020-08-03 17:56:50 +02002432#endif /* !OpenBSD && !NetBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02002433
Paul Bakkera3d195c2011-11-27 21:07:34 +00002434 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00002435}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002436#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00002437
Paul Bakker5121ce52009-01-03 21:22:43 +00002438/*
2439 * Checkup routine
2440 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002441int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002442{
Paul Bakker3d8fb632014-04-17 12:42:41 +02002443 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002444#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00002445 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002446 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00002447 unsigned char rsa_plaintext[PT_LEN];
2448 unsigned char rsa_decrypted[PT_LEN];
2449 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002450#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00002451 unsigned char sha1sum[20];
2452#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002453
Hanno Becker3a701162017-08-22 13:52:43 +01002454 mbedtls_mpi K;
2455
2456 mbedtls_mpi_init( &K );
Ronald Cronc1905a12021-06-05 11:11:14 +02002457 mbedtls_rsa_init( &rsa );
Paul Bakker5121ce52009-01-03 21:22:43 +00002458
Hanno Becker3a701162017-08-22 13:52:43 +01002459 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2460 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2461 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2462 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2463 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2464 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2465 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2466 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2467 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2468 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2469
Hanno Becker7f25f852017-10-10 16:56:22 +01002470 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002471
2472 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002473 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002475 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2476 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002477 {
2478 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002479 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002480
Hanno Becker5bc87292017-05-03 15:09:31 +01002481 ret = 1;
2482 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002483 }
2484
2485 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002486 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002487
2488 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2489
Thomas Daubney21772772021-05-13 17:30:32 +01002490 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL,
Hanno Becker98838b02017-10-02 13:16:10 +01002491 PT_LEN, rsa_plaintext,
2492 rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002493 {
2494 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002496
Hanno Becker5bc87292017-05-03 15:09:31 +01002497 ret = 1;
2498 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002499 }
2500
2501 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002502 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002503
Thomas Daubneyc7feaf32021-05-07 14:02:43 +01002504 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL,
Hanno Becker98838b02017-10-02 13:16:10 +01002505 &len, rsa_ciphertext, rsa_decrypted,
2506 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002507 {
2508 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002509 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002510
Hanno Becker5bc87292017-05-03 15:09:31 +01002511 ret = 1;
2512 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002513 }
2514
2515 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2516 {
2517 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002518 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002519
Hanno Becker5bc87292017-05-03 15:09:31 +01002520 ret = 1;
2521 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002522 }
2523
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002524 if( verbose != 0 )
2525 mbedtls_printf( "passed\n" );
2526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002527#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00002528 if( verbose != 0 )
Brian Murray930a3702016-05-18 14:38:02 -07002529 mbedtls_printf( " PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002530
TRodziewicz26371e42021-06-08 16:45:41 +02002531 if( mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
Andres Amaya Garcia698089e2017-06-28 11:46:46 +01002532 {
2533 if( verbose != 0 )
2534 mbedtls_printf( "failed\n" );
2535
2536 return( 1 );
2537 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002538
Hanno Becker98838b02017-10-02 13:16:10 +01002539 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
Gilles Peskine6e3187b2021-06-22 18:39:53 +02002540 MBEDTLS_MD_SHA1, 20,
Hanno Becker98838b02017-10-02 13:16:10 +01002541 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002542 {
2543 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002544 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002545
Hanno Becker5bc87292017-05-03 15:09:31 +01002546 ret = 1;
2547 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002548 }
2549
2550 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002551 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002552
Gilles Peskine6e3187b2021-06-22 18:39:53 +02002553 if( mbedtls_rsa_pkcs1_verify( &rsa, MBEDTLS_MD_SHA1, 20,
Hanno Becker98838b02017-10-02 13:16:10 +01002554 sha1sum, rsa_ciphertext ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002555 {
2556 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002557 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002558
Hanno Becker5bc87292017-05-03 15:09:31 +01002559 ret = 1;
2560 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002561 }
2562
2563 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002564 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002565#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00002566
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02002567 if( verbose != 0 )
2568 mbedtls_printf( "\n" );
2569
Paul Bakker3d8fb632014-04-17 12:42:41 +02002570cleanup:
Hanno Becker3a701162017-08-22 13:52:43 +01002571 mbedtls_mpi_free( &K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002572 mbedtls_rsa_free( &rsa );
2573#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02002574 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002575#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02002576 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002577}
2578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002579#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002581#endif /* MBEDTLS_RSA_C */