1c2c66affSColin Finck /*
2c2c66affSColin Finck * The RSA public-key cryptosystem
3c2c66affSColin Finck *
4218e2596SThomas Faber * Copyright The Mbed TLS Contributors
5e57126f5SThomas Faber * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6e57126f5SThomas Faber *
7e57126f5SThomas Faber * This file is provided under the Apache License 2.0, or the
8e57126f5SThomas Faber * GNU General Public License v2.0 or later.
9e57126f5SThomas Faber *
10e57126f5SThomas Faber * **********
11e57126f5SThomas Faber * Apache License 2.0:
12e57126f5SThomas Faber *
13e57126f5SThomas Faber * Licensed under the Apache License, Version 2.0 (the "License"); you may
14e57126f5SThomas Faber * not use this file except in compliance with the License.
15e57126f5SThomas Faber * You may obtain a copy of the License at
16e57126f5SThomas Faber *
17e57126f5SThomas Faber * http://www.apache.org/licenses/LICENSE-2.0
18e57126f5SThomas Faber *
19e57126f5SThomas Faber * Unless required by applicable law or agreed to in writing, software
20e57126f5SThomas Faber * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21e57126f5SThomas Faber * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22e57126f5SThomas Faber * See the License for the specific language governing permissions and
23e57126f5SThomas Faber * limitations under the License.
24e57126f5SThomas Faber *
25e57126f5SThomas Faber * **********
26e57126f5SThomas Faber *
27e57126f5SThomas Faber * **********
28e57126f5SThomas Faber * GNU General Public License v2.0 or later:
29c2c66affSColin Finck *
30c2c66affSColin Finck * This program is free software; you can redistribute it and/or modify
31c2c66affSColin Finck * it under the terms of the GNU General Public License as published by
32c2c66affSColin Finck * the Free Software Foundation; either version 2 of the License, or
33c2c66affSColin Finck * (at your option) any later version.
34c2c66affSColin Finck *
35c2c66affSColin Finck * This program is distributed in the hope that it will be useful,
36c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
37c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38c2c66affSColin Finck * GNU General Public License for more details.
39c2c66affSColin Finck *
40c2c66affSColin Finck * You should have received a copy of the GNU General Public License along
41c2c66affSColin Finck * with this program; if not, write to the Free Software Foundation, Inc.,
42c2c66affSColin Finck * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43c2c66affSColin Finck *
44e57126f5SThomas Faber * **********
45c2c66affSColin Finck */
46d9e6c9b5SThomas Faber
47c2c66affSColin Finck /*
48c2c66affSColin Finck * The following sources were referenced in the design of this implementation
49c2c66affSColin Finck * of the RSA algorithm:
50c2c66affSColin Finck *
51c2c66affSColin Finck * [1] A method for obtaining digital signatures and public-key cryptosystems
52c2c66affSColin Finck * R Rivest, A Shamir, and L Adleman
53c2c66affSColin Finck * http://people.csail.mit.edu/rivest/pubs.html#RSA78
54c2c66affSColin Finck *
55c2c66affSColin Finck * [2] Handbook of Applied Cryptography - 1997, Chapter 8
56c2c66affSColin Finck * Menezes, van Oorschot and Vanstone
57c2c66affSColin Finck *
58c2c66affSColin Finck * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
59c2c66affSColin Finck * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
60c2c66affSColin Finck * Stefan Mangard
61c2c66affSColin Finck * https://arxiv.org/abs/1702.08719v2
62c2c66affSColin Finck *
63c2c66affSColin Finck */
64c2c66affSColin Finck
65c2c66affSColin Finck #if !defined(MBEDTLS_CONFIG_FILE)
66c2c66affSColin Finck #include "mbedtls/config.h"
67c2c66affSColin Finck #else
68c2c66affSColin Finck #include MBEDTLS_CONFIG_FILE
69c2c66affSColin Finck #endif
70c2c66affSColin Finck
71c2c66affSColin Finck #if defined(MBEDTLS_RSA_C)
72c2c66affSColin Finck
73c2c66affSColin Finck #include "mbedtls/rsa.h"
74d9e6c9b5SThomas Faber #include "mbedtls/rsa_internal.h"
75c2c66affSColin Finck #include "mbedtls/oid.h"
76*cbda039fSThomas Faber #include "mbedtls/platform_util.h"
77c2c66affSColin Finck
78c2c66affSColin Finck #include <string.h>
79c2c66affSColin Finck
80c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
81c2c66affSColin Finck #include "mbedtls/md.h"
82c2c66affSColin Finck #endif
83c2c66affSColin Finck
84218e2596SThomas Faber #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
85c2c66affSColin Finck #include <stdlib.h>
86c2c66affSColin Finck #endif
87c2c66affSColin Finck
88c2c66affSColin Finck #if defined(MBEDTLS_PLATFORM_C)
89c2c66affSColin Finck #include "mbedtls/platform.h"
90c2c66affSColin Finck #else
91c2c66affSColin Finck #include <stdio.h>
92c2c66affSColin Finck #define mbedtls_printf printf
93c2c66affSColin Finck #define mbedtls_calloc calloc
94c2c66affSColin Finck #define mbedtls_free free
95c2c66affSColin Finck #endif
96c2c66affSColin Finck
97d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_ALT)
98d9e6c9b5SThomas Faber
99*cbda039fSThomas Faber /* Parameter validation macros */
100*cbda039fSThomas Faber #define RSA_VALIDATE_RET( cond ) \
101*cbda039fSThomas Faber MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
102*cbda039fSThomas Faber #define RSA_VALIDATE( cond ) \
103*cbda039fSThomas Faber MBEDTLS_INTERNAL_VALIDATE( cond )
104c2c66affSColin Finck
105d9e6c9b5SThomas Faber #if defined(MBEDTLS_PKCS1_V15)
106d9e6c9b5SThomas Faber /* constant-time buffer comparison */
mbedtls_safer_memcmp(const void * a,const void * b,size_t n)107d9e6c9b5SThomas Faber static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
108d9e6c9b5SThomas Faber {
109d9e6c9b5SThomas Faber size_t i;
110d9e6c9b5SThomas Faber const unsigned char *A = (const unsigned char *) a;
111d9e6c9b5SThomas Faber const unsigned char *B = (const unsigned char *) b;
112d9e6c9b5SThomas Faber unsigned char diff = 0;
113d9e6c9b5SThomas Faber
114d9e6c9b5SThomas Faber for( i = 0; i < n; i++ )
115d9e6c9b5SThomas Faber diff |= A[i] ^ B[i];
116d9e6c9b5SThomas Faber
117d9e6c9b5SThomas Faber return( diff );
118d9e6c9b5SThomas Faber }
119d9e6c9b5SThomas Faber #endif /* MBEDTLS_PKCS1_V15 */
120d9e6c9b5SThomas Faber
mbedtls_rsa_import(mbedtls_rsa_context * ctx,const mbedtls_mpi * N,const mbedtls_mpi * P,const mbedtls_mpi * Q,const mbedtls_mpi * D,const mbedtls_mpi * E)121d9e6c9b5SThomas Faber int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
122d9e6c9b5SThomas Faber const mbedtls_mpi *N,
123d9e6c9b5SThomas Faber const mbedtls_mpi *P, const mbedtls_mpi *Q,
124d9e6c9b5SThomas Faber const mbedtls_mpi *D, const mbedtls_mpi *E )
125d9e6c9b5SThomas Faber {
126d9e6c9b5SThomas Faber int ret;
127*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
128d9e6c9b5SThomas Faber
129d9e6c9b5SThomas Faber if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
130d9e6c9b5SThomas Faber ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
131d9e6c9b5SThomas Faber ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
132d9e6c9b5SThomas Faber ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
133d9e6c9b5SThomas Faber ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
134d9e6c9b5SThomas Faber {
135d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
136d9e6c9b5SThomas Faber }
137d9e6c9b5SThomas Faber
138d9e6c9b5SThomas Faber if( N != NULL )
139d9e6c9b5SThomas Faber ctx->len = mbedtls_mpi_size( &ctx->N );
140d9e6c9b5SThomas Faber
141d9e6c9b5SThomas Faber return( 0 );
142d9e6c9b5SThomas Faber }
143d9e6c9b5SThomas Faber
mbedtls_rsa_import_raw(mbedtls_rsa_context * ctx,unsigned char const * N,size_t N_len,unsigned char const * P,size_t P_len,unsigned char const * Q,size_t Q_len,unsigned char const * D,size_t D_len,unsigned char const * E,size_t E_len)144d9e6c9b5SThomas Faber int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
145d9e6c9b5SThomas Faber unsigned char const *N, size_t N_len,
146d9e6c9b5SThomas Faber unsigned char const *P, size_t P_len,
147d9e6c9b5SThomas Faber unsigned char const *Q, size_t Q_len,
148d9e6c9b5SThomas Faber unsigned char const *D, size_t D_len,
149d9e6c9b5SThomas Faber unsigned char const *E, size_t E_len )
150d9e6c9b5SThomas Faber {
151d9e6c9b5SThomas Faber int ret = 0;
152*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
153d9e6c9b5SThomas Faber
154d9e6c9b5SThomas Faber if( N != NULL )
155d9e6c9b5SThomas Faber {
156d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
157d9e6c9b5SThomas Faber ctx->len = mbedtls_mpi_size( &ctx->N );
158d9e6c9b5SThomas Faber }
159d9e6c9b5SThomas Faber
160d9e6c9b5SThomas Faber if( P != NULL )
161d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
162d9e6c9b5SThomas Faber
163d9e6c9b5SThomas Faber if( Q != NULL )
164d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
165d9e6c9b5SThomas Faber
166d9e6c9b5SThomas Faber if( D != NULL )
167d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
168d9e6c9b5SThomas Faber
169d9e6c9b5SThomas Faber if( E != NULL )
170d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
171d9e6c9b5SThomas Faber
172d9e6c9b5SThomas Faber cleanup:
173d9e6c9b5SThomas Faber
174d9e6c9b5SThomas Faber if( ret != 0 )
175d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
176d9e6c9b5SThomas Faber
177d9e6c9b5SThomas Faber return( 0 );
178d9e6c9b5SThomas Faber }
179d9e6c9b5SThomas Faber
180d9e6c9b5SThomas Faber /*
181d9e6c9b5SThomas Faber * Checks whether the context fields are set in such a way
182d9e6c9b5SThomas Faber * that the RSA primitives will be able to execute without error.
183d9e6c9b5SThomas Faber * It does *not* make guarantees for consistency of the parameters.
184d9e6c9b5SThomas Faber */
rsa_check_context(mbedtls_rsa_context const * ctx,int is_priv,int blinding_needed)185d9e6c9b5SThomas Faber static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
186d9e6c9b5SThomas Faber int blinding_needed )
187d9e6c9b5SThomas Faber {
188d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
189d9e6c9b5SThomas Faber /* blinding_needed is only used for NO_CRT to decide whether
190d9e6c9b5SThomas Faber * P,Q need to be present or not. */
191d9e6c9b5SThomas Faber ((void) blinding_needed);
192d9e6c9b5SThomas Faber #endif
193d9e6c9b5SThomas Faber
194d9e6c9b5SThomas Faber if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
195d9e6c9b5SThomas Faber ctx->len > MBEDTLS_MPI_MAX_SIZE )
196d9e6c9b5SThomas Faber {
197d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
198d9e6c9b5SThomas Faber }
199d9e6c9b5SThomas Faber
200d9e6c9b5SThomas Faber /*
201d9e6c9b5SThomas Faber * 1. Modular exponentiation needs positive, odd moduli.
202d9e6c9b5SThomas Faber */
203d9e6c9b5SThomas Faber
204d9e6c9b5SThomas Faber /* Modular exponentiation wrt. N is always used for
205d9e6c9b5SThomas Faber * RSA public key operations. */
206d9e6c9b5SThomas Faber if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
207d9e6c9b5SThomas Faber mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
208d9e6c9b5SThomas Faber {
209d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
210d9e6c9b5SThomas Faber }
211d9e6c9b5SThomas Faber
212d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
213d9e6c9b5SThomas Faber /* Modular exponentiation for P and Q is only
214d9e6c9b5SThomas Faber * used for private key operations and if CRT
215d9e6c9b5SThomas Faber * is used. */
216d9e6c9b5SThomas Faber if( is_priv &&
217d9e6c9b5SThomas Faber ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
218d9e6c9b5SThomas Faber mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
219d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
220d9e6c9b5SThomas Faber mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
221d9e6c9b5SThomas Faber {
222d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
223d9e6c9b5SThomas Faber }
224d9e6c9b5SThomas Faber #endif /* !MBEDTLS_RSA_NO_CRT */
225d9e6c9b5SThomas Faber
226d9e6c9b5SThomas Faber /*
227d9e6c9b5SThomas Faber * 2. Exponents must be positive
228d9e6c9b5SThomas Faber */
229d9e6c9b5SThomas Faber
230d9e6c9b5SThomas Faber /* Always need E for public key operations */
231d9e6c9b5SThomas Faber if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
232d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
233d9e6c9b5SThomas Faber
234d9e6c9b5SThomas Faber #if defined(MBEDTLS_RSA_NO_CRT)
235d9e6c9b5SThomas Faber /* For private key operations, use D or DP & DQ
236d9e6c9b5SThomas Faber * as (unblinded) exponents. */
237d9e6c9b5SThomas Faber if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
238d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
239d9e6c9b5SThomas Faber #else
240d9e6c9b5SThomas Faber if( is_priv &&
241d9e6c9b5SThomas Faber ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
242d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
243d9e6c9b5SThomas Faber {
244d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
245d9e6c9b5SThomas Faber }
246d9e6c9b5SThomas Faber #endif /* MBEDTLS_RSA_NO_CRT */
247d9e6c9b5SThomas Faber
248d9e6c9b5SThomas Faber /* Blinding shouldn't make exponents negative either,
249d9e6c9b5SThomas Faber * so check that P, Q >= 1 if that hasn't yet been
250d9e6c9b5SThomas Faber * done as part of 1. */
251d9e6c9b5SThomas Faber #if defined(MBEDTLS_RSA_NO_CRT)
252d9e6c9b5SThomas Faber if( is_priv && blinding_needed &&
253d9e6c9b5SThomas Faber ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
254d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
255d9e6c9b5SThomas Faber {
256d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
257d9e6c9b5SThomas Faber }
258d9e6c9b5SThomas Faber #endif
259d9e6c9b5SThomas Faber
260d9e6c9b5SThomas Faber /* It wouldn't lead to an error if it wasn't satisfied,
261d9e6c9b5SThomas Faber * but check for QP >= 1 nonetheless. */
262d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
263d9e6c9b5SThomas Faber if( is_priv &&
264d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
265d9e6c9b5SThomas Faber {
266d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
267d9e6c9b5SThomas Faber }
268d9e6c9b5SThomas Faber #endif
269d9e6c9b5SThomas Faber
270d9e6c9b5SThomas Faber return( 0 );
271d9e6c9b5SThomas Faber }
272d9e6c9b5SThomas Faber
mbedtls_rsa_complete(mbedtls_rsa_context * ctx)273d9e6c9b5SThomas Faber int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
274d9e6c9b5SThomas Faber {
275d9e6c9b5SThomas Faber int ret = 0;
276*cbda039fSThomas Faber int have_N, have_P, have_Q, have_D, have_E;
277*cbda039fSThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
278*cbda039fSThomas Faber int have_DP, have_DQ, have_QP;
279*cbda039fSThomas Faber #endif
280*cbda039fSThomas Faber int n_missing, pq_missing, d_missing, is_pub, is_priv;
281d9e6c9b5SThomas Faber
282*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
283*cbda039fSThomas Faber
284*cbda039fSThomas Faber have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
285*cbda039fSThomas Faber have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
286*cbda039fSThomas Faber have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
287*cbda039fSThomas Faber have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
288*cbda039fSThomas Faber have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
289d9e6c9b5SThomas Faber
2901b00a1f5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
291*cbda039fSThomas Faber have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
292*cbda039fSThomas Faber have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
293*cbda039fSThomas Faber have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
2941b00a1f5SThomas Faber #endif
2951b00a1f5SThomas Faber
296d9e6c9b5SThomas Faber /*
297d9e6c9b5SThomas Faber * Check whether provided parameters are enough
298d9e6c9b5SThomas Faber * to deduce all others. The following incomplete
299d9e6c9b5SThomas Faber * parameter sets for private keys are supported:
300d9e6c9b5SThomas Faber *
301d9e6c9b5SThomas Faber * (1) P, Q missing.
302d9e6c9b5SThomas Faber * (2) D and potentially N missing.
303d9e6c9b5SThomas Faber *
304d9e6c9b5SThomas Faber */
305d9e6c9b5SThomas Faber
306*cbda039fSThomas Faber n_missing = have_P && have_Q && have_D && have_E;
307*cbda039fSThomas Faber pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
308*cbda039fSThomas Faber d_missing = have_P && have_Q && !have_D && have_E;
309*cbda039fSThomas Faber is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
310d9e6c9b5SThomas Faber
311d9e6c9b5SThomas Faber /* These three alternatives are mutually exclusive */
312*cbda039fSThomas Faber is_priv = n_missing || pq_missing || d_missing;
313d9e6c9b5SThomas Faber
314d9e6c9b5SThomas Faber if( !is_priv && !is_pub )
315d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
316d9e6c9b5SThomas Faber
317d9e6c9b5SThomas Faber /*
318d9e6c9b5SThomas Faber * Step 1: Deduce N if P, Q are provided.
319d9e6c9b5SThomas Faber */
320d9e6c9b5SThomas Faber
321d9e6c9b5SThomas Faber if( !have_N && have_P && have_Q )
322d9e6c9b5SThomas Faber {
323d9e6c9b5SThomas Faber if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
324d9e6c9b5SThomas Faber &ctx->Q ) ) != 0 )
325d9e6c9b5SThomas Faber {
326d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
327d9e6c9b5SThomas Faber }
328d9e6c9b5SThomas Faber
329d9e6c9b5SThomas Faber ctx->len = mbedtls_mpi_size( &ctx->N );
330d9e6c9b5SThomas Faber }
331d9e6c9b5SThomas Faber
332d9e6c9b5SThomas Faber /*
333d9e6c9b5SThomas Faber * Step 2: Deduce and verify all remaining core parameters.
334d9e6c9b5SThomas Faber */
335d9e6c9b5SThomas Faber
336d9e6c9b5SThomas Faber if( pq_missing )
337d9e6c9b5SThomas Faber {
338d9e6c9b5SThomas Faber ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
339d9e6c9b5SThomas Faber &ctx->P, &ctx->Q );
340d9e6c9b5SThomas Faber if( ret != 0 )
341d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
342d9e6c9b5SThomas Faber
343d9e6c9b5SThomas Faber }
344d9e6c9b5SThomas Faber else if( d_missing )
345d9e6c9b5SThomas Faber {
346d9e6c9b5SThomas Faber if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
347d9e6c9b5SThomas Faber &ctx->Q,
348d9e6c9b5SThomas Faber &ctx->E,
349d9e6c9b5SThomas Faber &ctx->D ) ) != 0 )
350d9e6c9b5SThomas Faber {
351d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
352d9e6c9b5SThomas Faber }
353d9e6c9b5SThomas Faber }
354d9e6c9b5SThomas Faber
355d9e6c9b5SThomas Faber /*
356d9e6c9b5SThomas Faber * Step 3: Deduce all additional parameters specific
357d9e6c9b5SThomas Faber * to our current RSA implementation.
358d9e6c9b5SThomas Faber */
359d9e6c9b5SThomas Faber
360d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
3611b00a1f5SThomas Faber if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
362d9e6c9b5SThomas Faber {
363d9e6c9b5SThomas Faber ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
364d9e6c9b5SThomas Faber &ctx->DP, &ctx->DQ, &ctx->QP );
365d9e6c9b5SThomas Faber if( ret != 0 )
366d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
367d9e6c9b5SThomas Faber }
368d9e6c9b5SThomas Faber #endif /* MBEDTLS_RSA_NO_CRT */
369d9e6c9b5SThomas Faber
370d9e6c9b5SThomas Faber /*
371d9e6c9b5SThomas Faber * Step 3: Basic sanity checks
372d9e6c9b5SThomas Faber */
373d9e6c9b5SThomas Faber
374d9e6c9b5SThomas Faber return( rsa_check_context( ctx, is_priv, 1 ) );
375d9e6c9b5SThomas Faber }
376d9e6c9b5SThomas Faber
mbedtls_rsa_export_raw(const mbedtls_rsa_context * ctx,unsigned char * N,size_t N_len,unsigned char * P,size_t P_len,unsigned char * Q,size_t Q_len,unsigned char * D,size_t D_len,unsigned char * E,size_t E_len)377d9e6c9b5SThomas Faber int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
378d9e6c9b5SThomas Faber unsigned char *N, size_t N_len,
379d9e6c9b5SThomas Faber unsigned char *P, size_t P_len,
380d9e6c9b5SThomas Faber unsigned char *Q, size_t Q_len,
381d9e6c9b5SThomas Faber unsigned char *D, size_t D_len,
382d9e6c9b5SThomas Faber unsigned char *E, size_t E_len )
383d9e6c9b5SThomas Faber {
384d9e6c9b5SThomas Faber int ret = 0;
385*cbda039fSThomas Faber int is_priv;
386*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
387d9e6c9b5SThomas Faber
388d9e6c9b5SThomas Faber /* Check if key is private or public */
389*cbda039fSThomas Faber is_priv =
390d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
391d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
392d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
393d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
394d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
395d9e6c9b5SThomas Faber
396d9e6c9b5SThomas Faber if( !is_priv )
397d9e6c9b5SThomas Faber {
398d9e6c9b5SThomas Faber /* If we're trying to export private parameters for a public key,
399d9e6c9b5SThomas Faber * something must be wrong. */
400d9e6c9b5SThomas Faber if( P != NULL || Q != NULL || D != NULL )
401d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
402d9e6c9b5SThomas Faber
403d9e6c9b5SThomas Faber }
404d9e6c9b5SThomas Faber
405d9e6c9b5SThomas Faber if( N != NULL )
406d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
407d9e6c9b5SThomas Faber
408d9e6c9b5SThomas Faber if( P != NULL )
409d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
410d9e6c9b5SThomas Faber
411d9e6c9b5SThomas Faber if( Q != NULL )
412d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
413d9e6c9b5SThomas Faber
414d9e6c9b5SThomas Faber if( D != NULL )
415d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
416d9e6c9b5SThomas Faber
417d9e6c9b5SThomas Faber if( E != NULL )
418d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
419d9e6c9b5SThomas Faber
420d9e6c9b5SThomas Faber cleanup:
421d9e6c9b5SThomas Faber
422d9e6c9b5SThomas Faber return( ret );
423d9e6c9b5SThomas Faber }
424d9e6c9b5SThomas Faber
mbedtls_rsa_export(const mbedtls_rsa_context * ctx,mbedtls_mpi * N,mbedtls_mpi * P,mbedtls_mpi * Q,mbedtls_mpi * D,mbedtls_mpi * E)425d9e6c9b5SThomas Faber int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
426d9e6c9b5SThomas Faber mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
427d9e6c9b5SThomas Faber mbedtls_mpi *D, mbedtls_mpi *E )
428d9e6c9b5SThomas Faber {
429d9e6c9b5SThomas Faber int ret;
430*cbda039fSThomas Faber int is_priv;
431*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
432d9e6c9b5SThomas Faber
433d9e6c9b5SThomas Faber /* Check if key is private or public */
434*cbda039fSThomas Faber is_priv =
435d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
436d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
437d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
438d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
439d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
440d9e6c9b5SThomas Faber
441d9e6c9b5SThomas Faber if( !is_priv )
442d9e6c9b5SThomas Faber {
443d9e6c9b5SThomas Faber /* If we're trying to export private parameters for a public key,
444d9e6c9b5SThomas Faber * something must be wrong. */
445d9e6c9b5SThomas Faber if( P != NULL || Q != NULL || D != NULL )
446d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
447d9e6c9b5SThomas Faber
448d9e6c9b5SThomas Faber }
449d9e6c9b5SThomas Faber
450d9e6c9b5SThomas Faber /* Export all requested core parameters. */
451d9e6c9b5SThomas Faber
452d9e6c9b5SThomas Faber if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
453d9e6c9b5SThomas Faber ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
454d9e6c9b5SThomas Faber ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
455d9e6c9b5SThomas Faber ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
456d9e6c9b5SThomas Faber ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
457d9e6c9b5SThomas Faber {
458d9e6c9b5SThomas Faber return( ret );
459d9e6c9b5SThomas Faber }
460d9e6c9b5SThomas Faber
461d9e6c9b5SThomas Faber return( 0 );
462d9e6c9b5SThomas Faber }
463d9e6c9b5SThomas Faber
464d9e6c9b5SThomas Faber /*
465d9e6c9b5SThomas Faber * Export CRT parameters
466d9e6c9b5SThomas Faber * This must also be implemented if CRT is not used, for being able to
467d9e6c9b5SThomas Faber * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
468d9e6c9b5SThomas Faber * can be used in this case.
469d9e6c9b5SThomas Faber */
mbedtls_rsa_export_crt(const mbedtls_rsa_context * ctx,mbedtls_mpi * DP,mbedtls_mpi * DQ,mbedtls_mpi * QP)470d9e6c9b5SThomas Faber int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
471d9e6c9b5SThomas Faber mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
472d9e6c9b5SThomas Faber {
473d9e6c9b5SThomas Faber int ret;
474*cbda039fSThomas Faber int is_priv;
475*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
476d9e6c9b5SThomas Faber
477d9e6c9b5SThomas Faber /* Check if key is private or public */
478*cbda039fSThomas Faber is_priv =
479d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
480d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
481d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
482d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
483d9e6c9b5SThomas Faber mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
484d9e6c9b5SThomas Faber
485d9e6c9b5SThomas Faber if( !is_priv )
486d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
487d9e6c9b5SThomas Faber
488d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
489d9e6c9b5SThomas Faber /* Export all requested blinding parameters. */
490d9e6c9b5SThomas Faber if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
491d9e6c9b5SThomas Faber ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
492d9e6c9b5SThomas Faber ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
493d9e6c9b5SThomas Faber {
494d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
495d9e6c9b5SThomas Faber }
496d9e6c9b5SThomas Faber #else
497d9e6c9b5SThomas Faber if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
498d9e6c9b5SThomas Faber DP, DQ, QP ) ) != 0 )
499d9e6c9b5SThomas Faber {
500d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
501d9e6c9b5SThomas Faber }
502d9e6c9b5SThomas Faber #endif
503d9e6c9b5SThomas Faber
504d9e6c9b5SThomas Faber return( 0 );
505d9e6c9b5SThomas Faber }
506d9e6c9b5SThomas Faber
507c2c66affSColin Finck /*
508c2c66affSColin Finck * Initialize an RSA context
509c2c66affSColin Finck */
mbedtls_rsa_init(mbedtls_rsa_context * ctx,int padding,int hash_id)510c2c66affSColin Finck void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
511c2c66affSColin Finck int padding,
512c2c66affSColin Finck int hash_id )
513c2c66affSColin Finck {
514*cbda039fSThomas Faber RSA_VALIDATE( ctx != NULL );
515*cbda039fSThomas Faber RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
516*cbda039fSThomas Faber padding == MBEDTLS_RSA_PKCS_V21 );
517*cbda039fSThomas Faber
518c2c66affSColin Finck memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
519c2c66affSColin Finck
520c2c66affSColin Finck mbedtls_rsa_set_padding( ctx, padding, hash_id );
521c2c66affSColin Finck
522c2c66affSColin Finck #if defined(MBEDTLS_THREADING_C)
523a01a8faaSThomas Faber /* Set ctx->ver to nonzero to indicate that the mutex has been
524a01a8faaSThomas Faber * initialized and will need to be freed. */
525a01a8faaSThomas Faber ctx->ver = 1;
526c2c66affSColin Finck mbedtls_mutex_init( &ctx->mutex );
527c2c66affSColin Finck #endif
528c2c66affSColin Finck }
529c2c66affSColin Finck
530c2c66affSColin Finck /*
531c2c66affSColin Finck * Set padding for an existing RSA context
532c2c66affSColin Finck */
mbedtls_rsa_set_padding(mbedtls_rsa_context * ctx,int padding,int hash_id)533*cbda039fSThomas Faber void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
534*cbda039fSThomas Faber int hash_id )
535c2c66affSColin Finck {
536*cbda039fSThomas Faber RSA_VALIDATE( ctx != NULL );
537*cbda039fSThomas Faber RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
538*cbda039fSThomas Faber padding == MBEDTLS_RSA_PKCS_V21 );
539*cbda039fSThomas Faber
540c2c66affSColin Finck ctx->padding = padding;
541c2c66affSColin Finck ctx->hash_id = hash_id;
542c2c66affSColin Finck }
543c2c66affSColin Finck
544d9e6c9b5SThomas Faber /*
545d9e6c9b5SThomas Faber * Get length in bytes of RSA modulus
546d9e6c9b5SThomas Faber */
547d9e6c9b5SThomas Faber
mbedtls_rsa_get_len(const mbedtls_rsa_context * ctx)548d9e6c9b5SThomas Faber size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
549d9e6c9b5SThomas Faber {
550d9e6c9b5SThomas Faber return( ctx->len );
551d9e6c9b5SThomas Faber }
552d9e6c9b5SThomas Faber
553d9e6c9b5SThomas Faber
554c2c66affSColin Finck #if defined(MBEDTLS_GENPRIME)
555c2c66affSColin Finck
556c2c66affSColin Finck /*
557c2c66affSColin Finck * Generate an RSA keypair
558*cbda039fSThomas Faber *
559*cbda039fSThomas Faber * This generation method follows the RSA key pair generation procedure of
560*cbda039fSThomas Faber * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
561c2c66affSColin Finck */
mbedtls_rsa_gen_key(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,unsigned int nbits,int exponent)562c2c66affSColin Finck int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
563c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
564c2c66affSColin Finck void *p_rng,
565c2c66affSColin Finck unsigned int nbits, int exponent )
566c2c66affSColin Finck {
567c2c66affSColin Finck int ret;
568*cbda039fSThomas Faber mbedtls_mpi H, G, L;
569*cbda039fSThomas Faber int prime_quality = 0;
570*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
571*cbda039fSThomas Faber RSA_VALIDATE_RET( f_rng != NULL );
572*cbda039fSThomas Faber
573*cbda039fSThomas Faber /*
574*cbda039fSThomas Faber * If the modulus is 1024 bit long or shorter, then the security strength of
575*cbda039fSThomas Faber * the RSA algorithm is less than or equal to 80 bits and therefore an error
576*cbda039fSThomas Faber * rate of 2^-80 is sufficient.
577*cbda039fSThomas Faber */
578*cbda039fSThomas Faber if( nbits > 1024 )
579*cbda039fSThomas Faber prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
580c2c66affSColin Finck
581d9e6c9b5SThomas Faber mbedtls_mpi_init( &H );
582d9e6c9b5SThomas Faber mbedtls_mpi_init( &G );
583*cbda039fSThomas Faber mbedtls_mpi_init( &L );
584c2c66affSColin Finck
585*cbda039fSThomas Faber if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
586a01a8faaSThomas Faber {
587a01a8faaSThomas Faber ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
588a01a8faaSThomas Faber goto cleanup;
589a01a8faaSThomas Faber }
590a01a8faaSThomas Faber
591c2c66affSColin Finck /*
592c2c66affSColin Finck * find primes P and Q with Q < P so that:
593*cbda039fSThomas Faber * 1. |P-Q| > 2^( nbits / 2 - 100 )
594*cbda039fSThomas Faber * 2. GCD( E, (P-1)*(Q-1) ) == 1
595*cbda039fSThomas Faber * 3. E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
596c2c66affSColin Finck */
597c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
598c2c66affSColin Finck
599c2c66affSColin Finck do
600c2c66affSColin Finck {
601*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1,
602*cbda039fSThomas Faber prime_quality, f_rng, p_rng ) );
603c2c66affSColin Finck
604*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1,
605*cbda039fSThomas Faber prime_quality, f_rng, p_rng ) );
606c2c66affSColin Finck
607*cbda039fSThomas Faber /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
608*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
609*cbda039fSThomas Faber if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
610c2c66affSColin Finck continue;
611c2c66affSColin Finck
612*cbda039fSThomas Faber /* not required by any standards, but some users rely on the fact that P > Q */
613*cbda039fSThomas Faber if( H.s < 0 )
614c2c66affSColin Finck mbedtls_mpi_swap( &ctx->P, &ctx->Q );
615c2c66affSColin Finck
616d9e6c9b5SThomas Faber /* Temporarily replace P,Q by P-1, Q-1 */
617d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
618d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
619d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
620*cbda039fSThomas Faber
621*cbda039fSThomas Faber /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
622c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
623*cbda039fSThomas Faber if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
624*cbda039fSThomas Faber continue;
625*cbda039fSThomas Faber
626*cbda039fSThomas Faber /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
627*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
628*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
629*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
630*cbda039fSThomas Faber
631*cbda039fSThomas Faber if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
632*cbda039fSThomas Faber continue;
633*cbda039fSThomas Faber
634*cbda039fSThomas Faber break;
635c2c66affSColin Finck }
636*cbda039fSThomas Faber while( 1 );
637c2c66affSColin Finck
638d9e6c9b5SThomas Faber /* Restore P,Q */
639d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
640d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
641d9e6c9b5SThomas Faber
642*cbda039fSThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
643*cbda039fSThomas Faber
644d9e6c9b5SThomas Faber ctx->len = mbedtls_mpi_size( &ctx->N );
645d9e6c9b5SThomas Faber
646*cbda039fSThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
647c2c66affSColin Finck /*
648c2c66affSColin Finck * DP = D mod (P - 1)
649c2c66affSColin Finck * DQ = D mod (Q - 1)
650c2c66affSColin Finck * QP = Q^-1 mod P
651c2c66affSColin Finck */
652d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
653d9e6c9b5SThomas Faber &ctx->DP, &ctx->DQ, &ctx->QP ) );
654d9e6c9b5SThomas Faber #endif /* MBEDTLS_RSA_NO_CRT */
655d9e6c9b5SThomas Faber
656d9e6c9b5SThomas Faber /* Double-check */
657d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
658c2c66affSColin Finck
659c2c66affSColin Finck cleanup:
660c2c66affSColin Finck
661d9e6c9b5SThomas Faber mbedtls_mpi_free( &H );
662d9e6c9b5SThomas Faber mbedtls_mpi_free( &G );
663*cbda039fSThomas Faber mbedtls_mpi_free( &L );
664c2c66affSColin Finck
665c2c66affSColin Finck if( ret != 0 )
666c2c66affSColin Finck {
667c2c66affSColin Finck mbedtls_rsa_free( ctx );
668a01a8faaSThomas Faber if( ( -ret & ~0x7f ) == 0 )
669a01a8faaSThomas Faber ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
670a01a8faaSThomas Faber return( ret );
671c2c66affSColin Finck }
672c2c66affSColin Finck
673c2c66affSColin Finck return( 0 );
674c2c66affSColin Finck }
675c2c66affSColin Finck
676c2c66affSColin Finck #endif /* MBEDTLS_GENPRIME */
677c2c66affSColin Finck
678c2c66affSColin Finck /*
679c2c66affSColin Finck * Check a public RSA key
680c2c66affSColin Finck */
mbedtls_rsa_check_pubkey(const mbedtls_rsa_context * ctx)681c2c66affSColin Finck int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
682c2c66affSColin Finck {
683*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
684*cbda039fSThomas Faber
685d9e6c9b5SThomas Faber if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
686c2c66affSColin Finck return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
687c2c66affSColin Finck
688d9e6c9b5SThomas Faber if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
689d9e6c9b5SThomas Faber {
690c2c66affSColin Finck return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
691d9e6c9b5SThomas Faber }
692c2c66affSColin Finck
693d9e6c9b5SThomas Faber if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
694d9e6c9b5SThomas Faber mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
695c2c66affSColin Finck mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
696d9e6c9b5SThomas Faber {
697c2c66affSColin Finck return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
698d9e6c9b5SThomas Faber }
699c2c66affSColin Finck
700c2c66affSColin Finck return( 0 );
701c2c66affSColin Finck }
702c2c66affSColin Finck
703c2c66affSColin Finck /*
704d9e6c9b5SThomas Faber * Check for the consistency of all fields in an RSA private key context
705c2c66affSColin Finck */
mbedtls_rsa_check_privkey(const mbedtls_rsa_context * ctx)706c2c66affSColin Finck int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
707c2c66affSColin Finck {
708*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
709*cbda039fSThomas Faber
710d9e6c9b5SThomas Faber if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
711d9e6c9b5SThomas Faber rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
712c2c66affSColin Finck {
713d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
714c2c66affSColin Finck }
715c2c66affSColin Finck
716d9e6c9b5SThomas Faber if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
717d9e6c9b5SThomas Faber &ctx->D, &ctx->E, NULL, NULL ) != 0 )
718d9e6c9b5SThomas Faber {
719d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
720d9e6c9b5SThomas Faber }
721c2c66affSColin Finck
722d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
723d9e6c9b5SThomas Faber else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
724d9e6c9b5SThomas Faber &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
725d9e6c9b5SThomas Faber {
726d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
727d9e6c9b5SThomas Faber }
728d9e6c9b5SThomas Faber #endif
729c2c66affSColin Finck
730c2c66affSColin Finck return( 0 );
731c2c66affSColin Finck }
732c2c66affSColin Finck
733c2c66affSColin Finck /*
734c2c66affSColin Finck * Check if contexts holding a public and private key match
735c2c66affSColin Finck */
mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context * pub,const mbedtls_rsa_context * prv)736d9e6c9b5SThomas Faber int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
737d9e6c9b5SThomas Faber const mbedtls_rsa_context *prv )
738c2c66affSColin Finck {
739*cbda039fSThomas Faber RSA_VALIDATE_RET( pub != NULL );
740*cbda039fSThomas Faber RSA_VALIDATE_RET( prv != NULL );
741*cbda039fSThomas Faber
742c2c66affSColin Finck if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
743c2c66affSColin Finck mbedtls_rsa_check_privkey( prv ) != 0 )
744c2c66affSColin Finck {
745c2c66affSColin Finck return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
746c2c66affSColin Finck }
747c2c66affSColin Finck
748c2c66affSColin Finck if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
749c2c66affSColin Finck mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
750c2c66affSColin Finck {
751c2c66affSColin Finck return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
752c2c66affSColin Finck }
753c2c66affSColin Finck
754c2c66affSColin Finck return( 0 );
755c2c66affSColin Finck }
756c2c66affSColin Finck
757c2c66affSColin Finck /*
758c2c66affSColin Finck * Do an RSA public key operation
759c2c66affSColin Finck */
mbedtls_rsa_public(mbedtls_rsa_context * ctx,const unsigned char * input,unsigned char * output)760c2c66affSColin Finck int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
761c2c66affSColin Finck const unsigned char *input,
762c2c66affSColin Finck unsigned char *output )
763c2c66affSColin Finck {
764c2c66affSColin Finck int ret;
765c2c66affSColin Finck size_t olen;
766c2c66affSColin Finck mbedtls_mpi T;
767*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
768*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
769*cbda039fSThomas Faber RSA_VALIDATE_RET( output != NULL );
770c2c66affSColin Finck
771d9e6c9b5SThomas Faber if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
772d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
773d9e6c9b5SThomas Faber
774c2c66affSColin Finck mbedtls_mpi_init( &T );
775c2c66affSColin Finck
776c2c66affSColin Finck #if defined(MBEDTLS_THREADING_C)
777c2c66affSColin Finck if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
778c2c66affSColin Finck return( ret );
779c2c66affSColin Finck #endif
780c2c66affSColin Finck
781c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
782c2c66affSColin Finck
783c2c66affSColin Finck if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
784c2c66affSColin Finck {
785c2c66affSColin Finck ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
786c2c66affSColin Finck goto cleanup;
787c2c66affSColin Finck }
788c2c66affSColin Finck
789c2c66affSColin Finck olen = ctx->len;
790c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
791c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
792c2c66affSColin Finck
793c2c66affSColin Finck cleanup:
794c2c66affSColin Finck #if defined(MBEDTLS_THREADING_C)
795c2c66affSColin Finck if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
796c2c66affSColin Finck return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
797c2c66affSColin Finck #endif
798c2c66affSColin Finck
799c2c66affSColin Finck mbedtls_mpi_free( &T );
800c2c66affSColin Finck
801c2c66affSColin Finck if( ret != 0 )
802c2c66affSColin Finck return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
803c2c66affSColin Finck
804c2c66affSColin Finck return( 0 );
805c2c66affSColin Finck }
806c2c66affSColin Finck
807c2c66affSColin Finck /*
808c2c66affSColin Finck * Generate or update blinding values, see section 10 of:
809c2c66affSColin Finck * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
810c2c66affSColin Finck * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
811c2c66affSColin Finck * Berlin Heidelberg, 1996. p. 104-113.
812c2c66affSColin Finck */
rsa_prepare_blinding(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)813c2c66affSColin Finck static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
814c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
815c2c66affSColin Finck {
816c2c66affSColin Finck int ret, count = 0;
817218e2596SThomas Faber mbedtls_mpi R;
818218e2596SThomas Faber
819218e2596SThomas Faber mbedtls_mpi_init( &R );
820c2c66affSColin Finck
821c2c66affSColin Finck if( ctx->Vf.p != NULL )
822c2c66affSColin Finck {
823c2c66affSColin Finck /* We already have blinding values, just update them by squaring */
824c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
825c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
826c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
827c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
828c2c66affSColin Finck
829c2c66affSColin Finck goto cleanup;
830c2c66affSColin Finck }
831c2c66affSColin Finck
832c2c66affSColin Finck /* Unblinding value: Vf = random number, invertible mod N */
833c2c66affSColin Finck do {
834c2c66affSColin Finck if( count++ > 10 )
835218e2596SThomas Faber {
836218e2596SThomas Faber ret = MBEDTLS_ERR_RSA_RNG_FAILED;
837218e2596SThomas Faber goto cleanup;
838218e2596SThomas Faber }
839c2c66affSColin Finck
840c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
841c2c66affSColin Finck
842218e2596SThomas Faber /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
843218e2596SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
844218e2596SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
845218e2596SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
846218e2596SThomas Faber
847218e2596SThomas Faber /* At this point, Vi is invertible mod N if and only if both Vf and R
848218e2596SThomas Faber * are invertible mod N. If one of them isn't, we don't need to know
849218e2596SThomas Faber * which one, we just loop and choose new values for both of them.
850218e2596SThomas Faber * (Each iteration succeeds with overwhelming probability.) */
851218e2596SThomas Faber ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
8522e53fc8eSThomas Faber if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
853218e2596SThomas Faber goto cleanup;
854218e2596SThomas Faber
8552e53fc8eSThomas Faber } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
8562e53fc8eSThomas Faber
857218e2596SThomas Faber /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
858218e2596SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
859218e2596SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
860218e2596SThomas Faber
861218e2596SThomas Faber /* Blinding value: Vi = Vf^(-e) mod N
862218e2596SThomas Faber * (Vi already contains Vf^-1 at this point) */
863c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
864c2c66affSColin Finck
865c2c66affSColin Finck
866c2c66affSColin Finck cleanup:
867218e2596SThomas Faber mbedtls_mpi_free( &R );
868218e2596SThomas Faber
869c2c66affSColin Finck return( ret );
870c2c66affSColin Finck }
871c2c66affSColin Finck
872c2c66affSColin Finck /*
873c2c66affSColin Finck * Exponent blinding supposed to prevent side-channel attacks using multiple
874c2c66affSColin Finck * traces of measurements to recover the RSA key. The more collisions are there,
875c2c66affSColin Finck * the more bits of the key can be recovered. See [3].
876c2c66affSColin Finck *
877c2c66affSColin Finck * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
878c2c66affSColin Finck * observations on avarage.
879c2c66affSColin Finck *
880c2c66affSColin Finck * For example with 28 byte blinding to achieve 2 collisions the adversary has
881c2c66affSColin Finck * to make 2^112 observations on avarage.
882c2c66affSColin Finck *
883c2c66affSColin Finck * (With the currently (as of 2017 April) known best algorithms breaking 2048
884c2c66affSColin Finck * bit RSA requires approximately as much time as trying out 2^112 random keys.
885c2c66affSColin Finck * Thus in this sense with 28 byte blinding the security is not reduced by
886c2c66affSColin Finck * side-channel attacks like the one in [3])
887c2c66affSColin Finck *
888c2c66affSColin Finck * This countermeasure does not help if the key recovery is possible with a
889c2c66affSColin Finck * single trace.
890c2c66affSColin Finck */
891c2c66affSColin Finck #define RSA_EXPONENT_BLINDING 28
892c2c66affSColin Finck
893c2c66affSColin Finck /*
894c2c66affSColin Finck * Do an RSA private key operation
895c2c66affSColin Finck */
mbedtls_rsa_private(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,const unsigned char * input,unsigned char * output)896c2c66affSColin Finck int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
897c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
898c2c66affSColin Finck void *p_rng,
899c2c66affSColin Finck const unsigned char *input,
900c2c66affSColin Finck unsigned char *output )
901c2c66affSColin Finck {
902c2c66affSColin Finck int ret;
903c2c66affSColin Finck size_t olen;
904d9e6c9b5SThomas Faber
905d9e6c9b5SThomas Faber /* Temporary holding the result */
906d9e6c9b5SThomas Faber mbedtls_mpi T;
907d9e6c9b5SThomas Faber
908d9e6c9b5SThomas Faber /* Temporaries holding P-1, Q-1 and the
909d9e6c9b5SThomas Faber * exponent blinding factor, respectively. */
910c2c66affSColin Finck mbedtls_mpi P1, Q1, R;
911d9e6c9b5SThomas Faber
912d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
913d9e6c9b5SThomas Faber /* Temporaries holding the results mod p resp. mod q. */
914d9e6c9b5SThomas Faber mbedtls_mpi TP, TQ;
915d9e6c9b5SThomas Faber
916d9e6c9b5SThomas Faber /* Temporaries holding the blinded exponents for
917d9e6c9b5SThomas Faber * the mod p resp. mod q computation (if used). */
918c2c66affSColin Finck mbedtls_mpi DP_blind, DQ_blind;
919d9e6c9b5SThomas Faber
920d9e6c9b5SThomas Faber /* Pointers to actual exponents to be used - either the unblinded
921d9e6c9b5SThomas Faber * or the blinded ones, depending on the presence of a PRNG. */
922c2c66affSColin Finck mbedtls_mpi *DP = &ctx->DP;
923c2c66affSColin Finck mbedtls_mpi *DQ = &ctx->DQ;
924d9e6c9b5SThomas Faber #else
925d9e6c9b5SThomas Faber /* Temporary holding the blinded exponent (if used). */
926d9e6c9b5SThomas Faber mbedtls_mpi D_blind;
927d9e6c9b5SThomas Faber
928d9e6c9b5SThomas Faber /* Pointer to actual exponent to be used - either the unblinded
929d9e6c9b5SThomas Faber * or the blinded one, depending on the presence of a PRNG. */
930d9e6c9b5SThomas Faber mbedtls_mpi *D = &ctx->D;
931d9e6c9b5SThomas Faber #endif /* MBEDTLS_RSA_NO_CRT */
932d9e6c9b5SThomas Faber
933d9e6c9b5SThomas Faber /* Temporaries holding the initial input and the double
934d9e6c9b5SThomas Faber * checked result; should be the same in the end. */
935d9e6c9b5SThomas Faber mbedtls_mpi I, C;
936d9e6c9b5SThomas Faber
937*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
938*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
939*cbda039fSThomas Faber RSA_VALIDATE_RET( output != NULL );
940*cbda039fSThomas Faber
941d9e6c9b5SThomas Faber if( rsa_check_context( ctx, 1 /* private key checks */,
942d9e6c9b5SThomas Faber f_rng != NULL /* blinding y/n */ ) != 0 )
943d9e6c9b5SThomas Faber {
944d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
945d9e6c9b5SThomas Faber }
946d9e6c9b5SThomas Faber
947d9e6c9b5SThomas Faber #if defined(MBEDTLS_THREADING_C)
948d9e6c9b5SThomas Faber if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
949d9e6c9b5SThomas Faber return( ret );
950c2c66affSColin Finck #endif
951c2c66affSColin Finck
952d9e6c9b5SThomas Faber /* MPI Initialization */
953d9e6c9b5SThomas Faber mbedtls_mpi_init( &T );
954c2c66affSColin Finck
955d9e6c9b5SThomas Faber mbedtls_mpi_init( &P1 );
956d9e6c9b5SThomas Faber mbedtls_mpi_init( &Q1 );
957d9e6c9b5SThomas Faber mbedtls_mpi_init( &R );
958c2c66affSColin Finck
959c2c66affSColin Finck if( f_rng != NULL )
960c2c66affSColin Finck {
961c2c66affSColin Finck #if defined(MBEDTLS_RSA_NO_CRT)
962c2c66affSColin Finck mbedtls_mpi_init( &D_blind );
963c2c66affSColin Finck #else
964c2c66affSColin Finck mbedtls_mpi_init( &DP_blind );
965c2c66affSColin Finck mbedtls_mpi_init( &DQ_blind );
966c2c66affSColin Finck #endif
967c2c66affSColin Finck }
968c2c66affSColin Finck
969d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
970d9e6c9b5SThomas Faber mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
971c2c66affSColin Finck #endif
972c2c66affSColin Finck
973d9e6c9b5SThomas Faber mbedtls_mpi_init( &I );
974d9e6c9b5SThomas Faber mbedtls_mpi_init( &C );
975d9e6c9b5SThomas Faber
976d9e6c9b5SThomas Faber /* End of MPI initialization */
977d9e6c9b5SThomas Faber
978c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
979c2c66affSColin Finck if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
980c2c66affSColin Finck {
981c2c66affSColin Finck ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
982c2c66affSColin Finck goto cleanup;
983c2c66affSColin Finck }
984c2c66affSColin Finck
985d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
986d9e6c9b5SThomas Faber
987c2c66affSColin Finck if( f_rng != NULL )
988c2c66affSColin Finck {
989c2c66affSColin Finck /*
990c2c66affSColin Finck * Blinding
991c2c66affSColin Finck * T = T * Vi mod N
992c2c66affSColin Finck */
993c2c66affSColin Finck MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
994c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
995c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
996c2c66affSColin Finck
997c2c66affSColin Finck /*
998c2c66affSColin Finck * Exponent blinding
999c2c66affSColin Finck */
1000c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
1001c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
1002c2c66affSColin Finck
1003c2c66affSColin Finck #if defined(MBEDTLS_RSA_NO_CRT)
1004c2c66affSColin Finck /*
1005c2c66affSColin Finck * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
1006c2c66affSColin Finck */
1007c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1008c2c66affSColin Finck f_rng, p_rng ) );
1009c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
1010c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
1011c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
1012c2c66affSColin Finck
1013c2c66affSColin Finck D = &D_blind;
1014c2c66affSColin Finck #else
1015c2c66affSColin Finck /*
1016c2c66affSColin Finck * DP_blind = ( P - 1 ) * R + DP
1017c2c66affSColin Finck */
1018c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1019c2c66affSColin Finck f_rng, p_rng ) );
1020c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
1021c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
1022c2c66affSColin Finck &ctx->DP ) );
1023c2c66affSColin Finck
1024c2c66affSColin Finck DP = &DP_blind;
1025c2c66affSColin Finck
1026c2c66affSColin Finck /*
1027c2c66affSColin Finck * DQ_blind = ( Q - 1 ) * R + DQ
1028c2c66affSColin Finck */
1029c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
1030c2c66affSColin Finck f_rng, p_rng ) );
1031c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
1032c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
1033c2c66affSColin Finck &ctx->DQ ) );
1034c2c66affSColin Finck
1035c2c66affSColin Finck DQ = &DQ_blind;
1036c2c66affSColin Finck #endif /* MBEDTLS_RSA_NO_CRT */
1037c2c66affSColin Finck }
1038c2c66affSColin Finck
1039c2c66affSColin Finck #if defined(MBEDTLS_RSA_NO_CRT)
1040c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
1041c2c66affSColin Finck #else
1042c2c66affSColin Finck /*
1043c2c66affSColin Finck * Faster decryption using the CRT
1044c2c66affSColin Finck *
1045d9e6c9b5SThomas Faber * TP = input ^ dP mod P
1046d9e6c9b5SThomas Faber * TQ = input ^ dQ mod Q
1047c2c66affSColin Finck */
1048d9e6c9b5SThomas Faber
1049d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
1050d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
1051c2c66affSColin Finck
1052c2c66affSColin Finck /*
1053d9e6c9b5SThomas Faber * T = (TP - TQ) * (Q^-1 mod P) mod P
1054c2c66affSColin Finck */
1055d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
1056d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
1057d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
1058c2c66affSColin Finck
1059c2c66affSColin Finck /*
1060d9e6c9b5SThomas Faber * T = TQ + T * Q
1061c2c66affSColin Finck */
1062d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
1063d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
1064c2c66affSColin Finck #endif /* MBEDTLS_RSA_NO_CRT */
1065c2c66affSColin Finck
1066c2c66affSColin Finck if( f_rng != NULL )
1067c2c66affSColin Finck {
1068c2c66affSColin Finck /*
1069c2c66affSColin Finck * Unblind
1070c2c66affSColin Finck * T = T * Vf mod N
1071c2c66affSColin Finck */
1072c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
1073c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
1074c2c66affSColin Finck }
1075c2c66affSColin Finck
1076d9e6c9b5SThomas Faber /* Verify the result to prevent glitching attacks. */
1077d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
1078d9e6c9b5SThomas Faber &ctx->N, &ctx->RN ) );
1079d9e6c9b5SThomas Faber if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
1080d9e6c9b5SThomas Faber {
1081d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
1082d9e6c9b5SThomas Faber goto cleanup;
1083d9e6c9b5SThomas Faber }
1084d9e6c9b5SThomas Faber
1085c2c66affSColin Finck olen = ctx->len;
1086c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
1087c2c66affSColin Finck
1088c2c66affSColin Finck cleanup:
1089c2c66affSColin Finck #if defined(MBEDTLS_THREADING_C)
1090c2c66affSColin Finck if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
1091c2c66affSColin Finck return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
1092c2c66affSColin Finck #endif
1093c2c66affSColin Finck
1094d9e6c9b5SThomas Faber mbedtls_mpi_free( &P1 );
1095d9e6c9b5SThomas Faber mbedtls_mpi_free( &Q1 );
1096d9e6c9b5SThomas Faber mbedtls_mpi_free( &R );
1097c2c66affSColin Finck
1098c2c66affSColin Finck if( f_rng != NULL )
1099c2c66affSColin Finck {
1100c2c66affSColin Finck #if defined(MBEDTLS_RSA_NO_CRT)
1101c2c66affSColin Finck mbedtls_mpi_free( &D_blind );
1102c2c66affSColin Finck #else
1103c2c66affSColin Finck mbedtls_mpi_free( &DP_blind );
1104c2c66affSColin Finck mbedtls_mpi_free( &DQ_blind );
1105c2c66affSColin Finck #endif
1106c2c66affSColin Finck }
1107c2c66affSColin Finck
1108d9e6c9b5SThomas Faber mbedtls_mpi_free( &T );
1109d9e6c9b5SThomas Faber
1110d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
1111d9e6c9b5SThomas Faber mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
1112d9e6c9b5SThomas Faber #endif
1113d9e6c9b5SThomas Faber
1114d9e6c9b5SThomas Faber mbedtls_mpi_free( &C );
1115d9e6c9b5SThomas Faber mbedtls_mpi_free( &I );
1116d9e6c9b5SThomas Faber
1117a01a8faaSThomas Faber if( ret != 0 && ret >= -0x007f )
1118c2c66affSColin Finck return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
1119c2c66affSColin Finck
1120a01a8faaSThomas Faber return( ret );
1121c2c66affSColin Finck }
1122c2c66affSColin Finck
1123c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1124c2c66affSColin Finck /**
1125c2c66affSColin Finck * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
1126c2c66affSColin Finck *
1127c2c66affSColin Finck * \param dst buffer to mask
1128c2c66affSColin Finck * \param dlen length of destination buffer
1129c2c66affSColin Finck * \param src source of the mask generation
1130c2c66affSColin Finck * \param slen length of the source buffer
1131c2c66affSColin Finck * \param md_ctx message digest context to use
1132c2c66affSColin Finck */
mgf_mask(unsigned char * dst,size_t dlen,unsigned char * src,size_t slen,mbedtls_md_context_t * md_ctx)1133d9e6c9b5SThomas Faber static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
1134c2c66affSColin Finck size_t slen, mbedtls_md_context_t *md_ctx )
1135c2c66affSColin Finck {
1136c2c66affSColin Finck unsigned char mask[MBEDTLS_MD_MAX_SIZE];
1137c2c66affSColin Finck unsigned char counter[4];
1138c2c66affSColin Finck unsigned char *p;
1139c2c66affSColin Finck unsigned int hlen;
1140c2c66affSColin Finck size_t i, use_len;
1141d9e6c9b5SThomas Faber int ret = 0;
1142c2c66affSColin Finck
1143c2c66affSColin Finck memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
1144c2c66affSColin Finck memset( counter, 0, 4 );
1145c2c66affSColin Finck
1146c2c66affSColin Finck hlen = mbedtls_md_get_size( md_ctx->md_info );
1147c2c66affSColin Finck
1148c2c66affSColin Finck /* Generate and apply dbMask */
1149c2c66affSColin Finck p = dst;
1150c2c66affSColin Finck
1151c2c66affSColin Finck while( dlen > 0 )
1152c2c66affSColin Finck {
1153c2c66affSColin Finck use_len = hlen;
1154c2c66affSColin Finck if( dlen < hlen )
1155c2c66affSColin Finck use_len = dlen;
1156c2c66affSColin Finck
1157d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
1158d9e6c9b5SThomas Faber goto exit;
1159d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
1160d9e6c9b5SThomas Faber goto exit;
1161d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
1162d9e6c9b5SThomas Faber goto exit;
1163d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
1164d9e6c9b5SThomas Faber goto exit;
1165c2c66affSColin Finck
1166c2c66affSColin Finck for( i = 0; i < use_len; ++i )
1167c2c66affSColin Finck *p++ ^= mask[i];
1168c2c66affSColin Finck
1169c2c66affSColin Finck counter[3]++;
1170c2c66affSColin Finck
1171c2c66affSColin Finck dlen -= use_len;
1172c2c66affSColin Finck }
1173c2c66affSColin Finck
1174d9e6c9b5SThomas Faber exit:
1175*cbda039fSThomas Faber mbedtls_platform_zeroize( mask, sizeof( mask ) );
1176d9e6c9b5SThomas Faber
1177d9e6c9b5SThomas Faber return( ret );
1178c2c66affSColin Finck }
1179c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V21 */
1180c2c66affSColin Finck
1181c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1182c2c66affSColin Finck /*
1183c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
1184c2c66affSColin Finck */
mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,const unsigned char * label,size_t label_len,size_t ilen,const unsigned char * input,unsigned char * output)1185c2c66affSColin Finck int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
1186c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1187c2c66affSColin Finck void *p_rng,
1188c2c66affSColin Finck int mode,
1189c2c66affSColin Finck const unsigned char *label, size_t label_len,
1190c2c66affSColin Finck size_t ilen,
1191c2c66affSColin Finck const unsigned char *input,
1192c2c66affSColin Finck unsigned char *output )
1193c2c66affSColin Finck {
1194c2c66affSColin Finck size_t olen;
1195c2c66affSColin Finck int ret;
1196c2c66affSColin Finck unsigned char *p = output;
1197c2c66affSColin Finck unsigned int hlen;
1198c2c66affSColin Finck const mbedtls_md_info_t *md_info;
1199c2c66affSColin Finck mbedtls_md_context_t md_ctx;
1200c2c66affSColin Finck
1201*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1202*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1203*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1204*cbda039fSThomas Faber RSA_VALIDATE_RET( output != NULL );
1205*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1206*cbda039fSThomas Faber RSA_VALIDATE_RET( label_len == 0 || label != NULL );
1207*cbda039fSThomas Faber
1208c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1209c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1210c2c66affSColin Finck
1211c2c66affSColin Finck if( f_rng == NULL )
1212c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1213c2c66affSColin Finck
1214c2c66affSColin Finck md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
1215c2c66affSColin Finck if( md_info == NULL )
1216c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1217c2c66affSColin Finck
1218c2c66affSColin Finck olen = ctx->len;
1219c2c66affSColin Finck hlen = mbedtls_md_get_size( md_info );
1220c2c66affSColin Finck
1221c2c66affSColin Finck /* first comparison checks for overflow */
1222c2c66affSColin Finck if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
1223c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1224c2c66affSColin Finck
1225c2c66affSColin Finck memset( output, 0, olen );
1226c2c66affSColin Finck
1227c2c66affSColin Finck *p++ = 0;
1228c2c66affSColin Finck
1229c2c66affSColin Finck /* Generate a random octet string seed */
1230c2c66affSColin Finck if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
1231c2c66affSColin Finck return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
1232c2c66affSColin Finck
1233c2c66affSColin Finck p += hlen;
1234c2c66affSColin Finck
1235c2c66affSColin Finck /* Construct DB */
1236d9e6c9b5SThomas Faber if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
1237d9e6c9b5SThomas Faber return( ret );
1238c2c66affSColin Finck p += hlen;
1239c2c66affSColin Finck p += olen - 2 * hlen - 2 - ilen;
1240c2c66affSColin Finck *p++ = 1;
1241c2c66affSColin Finck memcpy( p, input, ilen );
1242c2c66affSColin Finck
1243c2c66affSColin Finck mbedtls_md_init( &md_ctx );
1244c2c66affSColin Finck if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1245d9e6c9b5SThomas Faber goto exit;
1246c2c66affSColin Finck
1247c2c66affSColin Finck /* maskedDB: Apply dbMask to DB */
1248d9e6c9b5SThomas Faber if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
1249d9e6c9b5SThomas Faber &md_ctx ) ) != 0 )
1250d9e6c9b5SThomas Faber goto exit;
1251c2c66affSColin Finck
1252c2c66affSColin Finck /* maskedSeed: Apply seedMask to seed */
1253d9e6c9b5SThomas Faber if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
1254d9e6c9b5SThomas Faber &md_ctx ) ) != 0 )
1255d9e6c9b5SThomas Faber goto exit;
1256c2c66affSColin Finck
1257d9e6c9b5SThomas Faber exit:
1258c2c66affSColin Finck mbedtls_md_free( &md_ctx );
1259c2c66affSColin Finck
1260d9e6c9b5SThomas Faber if( ret != 0 )
1261d9e6c9b5SThomas Faber return( ret );
1262d9e6c9b5SThomas Faber
1263c2c66affSColin Finck return( ( mode == MBEDTLS_RSA_PUBLIC )
1264c2c66affSColin Finck ? mbedtls_rsa_public( ctx, output, output )
1265c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
1266c2c66affSColin Finck }
1267c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V21 */
1268c2c66affSColin Finck
1269c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
1270c2c66affSColin Finck /*
1271c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
1272c2c66affSColin Finck */
mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,size_t ilen,const unsigned char * input,unsigned char * output)1273c2c66affSColin Finck int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
1274c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1275c2c66affSColin Finck void *p_rng,
1276c2c66affSColin Finck int mode, size_t ilen,
1277c2c66affSColin Finck const unsigned char *input,
1278c2c66affSColin Finck unsigned char *output )
1279c2c66affSColin Finck {
1280c2c66affSColin Finck size_t nb_pad, olen;
1281c2c66affSColin Finck int ret;
1282c2c66affSColin Finck unsigned char *p = output;
1283c2c66affSColin Finck
1284*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1285*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1286*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1287*cbda039fSThomas Faber RSA_VALIDATE_RET( output != NULL );
1288*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1289c2c66affSColin Finck
1290*cbda039fSThomas Faber if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1291c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1292c2c66affSColin Finck
1293c2c66affSColin Finck olen = ctx->len;
1294c2c66affSColin Finck
1295c2c66affSColin Finck /* first comparison checks for overflow */
1296c2c66affSColin Finck if( ilen + 11 < ilen || olen < ilen + 11 )
1297c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1298c2c66affSColin Finck
1299c2c66affSColin Finck nb_pad = olen - 3 - ilen;
1300c2c66affSColin Finck
1301c2c66affSColin Finck *p++ = 0;
1302c2c66affSColin Finck if( mode == MBEDTLS_RSA_PUBLIC )
1303c2c66affSColin Finck {
1304*cbda039fSThomas Faber if( f_rng == NULL )
1305*cbda039fSThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1306*cbda039fSThomas Faber
1307c2c66affSColin Finck *p++ = MBEDTLS_RSA_CRYPT;
1308c2c66affSColin Finck
1309c2c66affSColin Finck while( nb_pad-- > 0 )
1310c2c66affSColin Finck {
1311c2c66affSColin Finck int rng_dl = 100;
1312c2c66affSColin Finck
1313c2c66affSColin Finck do {
1314c2c66affSColin Finck ret = f_rng( p_rng, p, 1 );
1315c2c66affSColin Finck } while( *p == 0 && --rng_dl && ret == 0 );
1316c2c66affSColin Finck
1317c2c66affSColin Finck /* Check if RNG failed to generate data */
1318c2c66affSColin Finck if( rng_dl == 0 || ret != 0 )
1319c2c66affSColin Finck return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
1320c2c66affSColin Finck
1321c2c66affSColin Finck p++;
1322c2c66affSColin Finck }
1323c2c66affSColin Finck }
1324c2c66affSColin Finck else
1325c2c66affSColin Finck {
1326c2c66affSColin Finck *p++ = MBEDTLS_RSA_SIGN;
1327c2c66affSColin Finck
1328c2c66affSColin Finck while( nb_pad-- > 0 )
1329c2c66affSColin Finck *p++ = 0xFF;
1330c2c66affSColin Finck }
1331c2c66affSColin Finck
1332c2c66affSColin Finck *p++ = 0;
1333c2c66affSColin Finck memcpy( p, input, ilen );
1334c2c66affSColin Finck
1335c2c66affSColin Finck return( ( mode == MBEDTLS_RSA_PUBLIC )
1336c2c66affSColin Finck ? mbedtls_rsa_public( ctx, output, output )
1337c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
1338c2c66affSColin Finck }
1339c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
1340c2c66affSColin Finck
1341c2c66affSColin Finck /*
1342c2c66affSColin Finck * Add the message padding, then do an RSA operation
1343c2c66affSColin Finck */
mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,size_t ilen,const unsigned char * input,unsigned char * output)1344c2c66affSColin Finck int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
1345c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1346c2c66affSColin Finck void *p_rng,
1347c2c66affSColin Finck int mode, size_t ilen,
1348c2c66affSColin Finck const unsigned char *input,
1349c2c66affSColin Finck unsigned char *output )
1350c2c66affSColin Finck {
1351*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1352*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1353*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1354*cbda039fSThomas Faber RSA_VALIDATE_RET( output != NULL );
1355*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1356*cbda039fSThomas Faber
1357c2c66affSColin Finck switch( ctx->padding )
1358c2c66affSColin Finck {
1359c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
1360c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V15:
1361c2c66affSColin Finck return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
1362c2c66affSColin Finck input, output );
1363c2c66affSColin Finck #endif
1364c2c66affSColin Finck
1365c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1366c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V21:
1367c2c66affSColin Finck return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
1368c2c66affSColin Finck ilen, input, output );
1369c2c66affSColin Finck #endif
1370c2c66affSColin Finck
1371c2c66affSColin Finck default:
1372c2c66affSColin Finck return( MBEDTLS_ERR_RSA_INVALID_PADDING );
1373c2c66affSColin Finck }
1374c2c66affSColin Finck }
1375c2c66affSColin Finck
1376c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1377c2c66affSColin Finck /*
1378c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
1379c2c66affSColin Finck */
mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,const unsigned char * label,size_t label_len,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1380c2c66affSColin Finck int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
1381c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1382c2c66affSColin Finck void *p_rng,
1383c2c66affSColin Finck int mode,
1384c2c66affSColin Finck const unsigned char *label, size_t label_len,
1385c2c66affSColin Finck size_t *olen,
1386c2c66affSColin Finck const unsigned char *input,
1387c2c66affSColin Finck unsigned char *output,
1388c2c66affSColin Finck size_t output_max_len )
1389c2c66affSColin Finck {
1390c2c66affSColin Finck int ret;
1391c2c66affSColin Finck size_t ilen, i, pad_len;
1392c2c66affSColin Finck unsigned char *p, bad, pad_done;
1393c2c66affSColin Finck unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1394c2c66affSColin Finck unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
1395c2c66affSColin Finck unsigned int hlen;
1396c2c66affSColin Finck const mbedtls_md_info_t *md_info;
1397c2c66affSColin Finck mbedtls_md_context_t md_ctx;
1398c2c66affSColin Finck
1399*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1400*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1401*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1402*cbda039fSThomas Faber RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1403*cbda039fSThomas Faber RSA_VALIDATE_RET( label_len == 0 || label != NULL );
1404*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1405*cbda039fSThomas Faber RSA_VALIDATE_RET( olen != NULL );
1406*cbda039fSThomas Faber
1407c2c66affSColin Finck /*
1408c2c66affSColin Finck * Parameters sanity checks
1409c2c66affSColin Finck */
1410c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1411c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1412c2c66affSColin Finck
1413c2c66affSColin Finck ilen = ctx->len;
1414c2c66affSColin Finck
1415c2c66affSColin Finck if( ilen < 16 || ilen > sizeof( buf ) )
1416c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1417c2c66affSColin Finck
1418c2c66affSColin Finck md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
1419c2c66affSColin Finck if( md_info == NULL )
1420c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1421c2c66affSColin Finck
1422c2c66affSColin Finck hlen = mbedtls_md_get_size( md_info );
1423c2c66affSColin Finck
1424c2c66affSColin Finck // checking for integer underflow
1425c2c66affSColin Finck if( 2 * hlen + 2 > ilen )
1426c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1427c2c66affSColin Finck
1428c2c66affSColin Finck /*
1429c2c66affSColin Finck * RSA operation
1430c2c66affSColin Finck */
1431c2c66affSColin Finck ret = ( mode == MBEDTLS_RSA_PUBLIC )
1432c2c66affSColin Finck ? mbedtls_rsa_public( ctx, input, buf )
1433c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
1434c2c66affSColin Finck
1435c2c66affSColin Finck if( ret != 0 )
1436c2c66affSColin Finck goto cleanup;
1437c2c66affSColin Finck
1438c2c66affSColin Finck /*
1439c2c66affSColin Finck * Unmask data and generate lHash
1440c2c66affSColin Finck */
1441c2c66affSColin Finck mbedtls_md_init( &md_ctx );
1442c2c66affSColin Finck if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1443c2c66affSColin Finck {
1444c2c66affSColin Finck mbedtls_md_free( &md_ctx );
1445c2c66affSColin Finck goto cleanup;
1446c2c66affSColin Finck }
1447c2c66affSColin Finck
1448c2c66affSColin Finck /* seed: Apply seedMask to maskedSeed */
1449d9e6c9b5SThomas Faber if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
1450d9e6c9b5SThomas Faber &md_ctx ) ) != 0 ||
1451c2c66affSColin Finck /* DB: Apply dbMask to maskedDB */
1452d9e6c9b5SThomas Faber ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
1453d9e6c9b5SThomas Faber &md_ctx ) ) != 0 )
1454d9e6c9b5SThomas Faber {
1455d9e6c9b5SThomas Faber mbedtls_md_free( &md_ctx );
1456d9e6c9b5SThomas Faber goto cleanup;
1457d9e6c9b5SThomas Faber }
1458c2c66affSColin Finck
1459c2c66affSColin Finck mbedtls_md_free( &md_ctx );
1460c2c66affSColin Finck
1461d9e6c9b5SThomas Faber /* Generate lHash */
1462d9e6c9b5SThomas Faber if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
1463d9e6c9b5SThomas Faber goto cleanup;
1464d9e6c9b5SThomas Faber
1465c2c66affSColin Finck /*
1466c2c66affSColin Finck * Check contents, in "constant-time"
1467c2c66affSColin Finck */
1468c2c66affSColin Finck p = buf;
1469c2c66affSColin Finck bad = 0;
1470c2c66affSColin Finck
1471c2c66affSColin Finck bad |= *p++; /* First byte must be 0 */
1472c2c66affSColin Finck
1473c2c66affSColin Finck p += hlen; /* Skip seed */
1474c2c66affSColin Finck
1475c2c66affSColin Finck /* Check lHash */
1476c2c66affSColin Finck for( i = 0; i < hlen; i++ )
1477c2c66affSColin Finck bad |= lhash[i] ^ *p++;
1478c2c66affSColin Finck
1479c2c66affSColin Finck /* Get zero-padding len, but always read till end of buffer
1480c2c66affSColin Finck * (minus one, for the 01 byte) */
1481c2c66affSColin Finck pad_len = 0;
1482c2c66affSColin Finck pad_done = 0;
1483c2c66affSColin Finck for( i = 0; i < ilen - 2 * hlen - 2; i++ )
1484c2c66affSColin Finck {
1485c2c66affSColin Finck pad_done |= p[i];
1486c2c66affSColin Finck pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
1487c2c66affSColin Finck }
1488c2c66affSColin Finck
1489c2c66affSColin Finck p += pad_len;
1490c2c66affSColin Finck bad |= *p++ ^ 0x01;
1491c2c66affSColin Finck
1492c2c66affSColin Finck /*
1493c2c66affSColin Finck * The only information "leaked" is whether the padding was correct or not
1494c2c66affSColin Finck * (eg, no data is copied if it was not correct). This meets the
1495c2c66affSColin Finck * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
1496c2c66affSColin Finck * the different error conditions.
1497c2c66affSColin Finck */
1498c2c66affSColin Finck if( bad != 0 )
1499c2c66affSColin Finck {
1500c2c66affSColin Finck ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
1501c2c66affSColin Finck goto cleanup;
1502c2c66affSColin Finck }
1503c2c66affSColin Finck
1504c2c66affSColin Finck if( ilen - ( p - buf ) > output_max_len )
1505c2c66affSColin Finck {
1506c2c66affSColin Finck ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
1507c2c66affSColin Finck goto cleanup;
1508c2c66affSColin Finck }
1509c2c66affSColin Finck
1510c2c66affSColin Finck *olen = ilen - (p - buf);
1511c2c66affSColin Finck memcpy( output, p, *olen );
1512c2c66affSColin Finck ret = 0;
1513c2c66affSColin Finck
1514c2c66affSColin Finck cleanup:
1515*cbda039fSThomas Faber mbedtls_platform_zeroize( buf, sizeof( buf ) );
1516*cbda039fSThomas Faber mbedtls_platform_zeroize( lhash, sizeof( lhash ) );
1517c2c66affSColin Finck
1518c2c66affSColin Finck return( ret );
1519c2c66affSColin Finck }
1520c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V21 */
1521c2c66affSColin Finck
1522c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
15230ba5bc40SThomas Faber /** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
15240ba5bc40SThomas Faber *
15250ba5bc40SThomas Faber * \param value The value to analyze.
15260ba5bc40SThomas Faber * \return Zero if \p value is zero, otherwise all-bits-one.
15270ba5bc40SThomas Faber */
all_or_nothing_int(unsigned value)15280ba5bc40SThomas Faber static unsigned all_or_nothing_int( unsigned value )
15290ba5bc40SThomas Faber {
15300ba5bc40SThomas Faber /* MSVC has a warning about unary minus on unsigned, but this is
15310ba5bc40SThomas Faber * well-defined and precisely what we want to do here */
15320ba5bc40SThomas Faber #if defined(_MSC_VER)
15330ba5bc40SThomas Faber #pragma warning( push )
15340ba5bc40SThomas Faber #pragma warning( disable : 4146 )
15350ba5bc40SThomas Faber #endif
15360ba5bc40SThomas Faber return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
15370ba5bc40SThomas Faber #if defined(_MSC_VER)
15380ba5bc40SThomas Faber #pragma warning( pop )
15390ba5bc40SThomas Faber #endif
15400ba5bc40SThomas Faber }
15410ba5bc40SThomas Faber
15420ba5bc40SThomas Faber /** Check whether a size is out of bounds, without branches.
15430ba5bc40SThomas Faber *
15440ba5bc40SThomas Faber * This is equivalent to `size > max`, but is likely to be compiled to
15450ba5bc40SThomas Faber * to code using bitwise operation rather than a branch.
15460ba5bc40SThomas Faber *
15470ba5bc40SThomas Faber * \param size Size to check.
15480ba5bc40SThomas Faber * \param max Maximum desired value for \p size.
15490ba5bc40SThomas Faber * \return \c 0 if `size <= max`.
15500ba5bc40SThomas Faber * \return \c 1 if `size > max`.
15510ba5bc40SThomas Faber */
size_greater_than(size_t size,size_t max)15520ba5bc40SThomas Faber static unsigned size_greater_than( size_t size, size_t max )
15530ba5bc40SThomas Faber {
15540ba5bc40SThomas Faber /* Return the sign bit (1 for negative) of (max - size). */
15550ba5bc40SThomas Faber return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
15560ba5bc40SThomas Faber }
15570ba5bc40SThomas Faber
15580ba5bc40SThomas Faber /** Choose between two integer values, without branches.
15590ba5bc40SThomas Faber *
15600ba5bc40SThomas Faber * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
15610ba5bc40SThomas Faber * to code using bitwise operation rather than a branch.
15620ba5bc40SThomas Faber *
15630ba5bc40SThomas Faber * \param cond Condition to test.
15640ba5bc40SThomas Faber * \param if1 Value to use if \p cond is nonzero.
15650ba5bc40SThomas Faber * \param if0 Value to use if \p cond is zero.
15660ba5bc40SThomas Faber * \return \c if1 if \p cond is nonzero, otherwise \c if0.
15670ba5bc40SThomas Faber */
if_int(unsigned cond,unsigned if1,unsigned if0)15680ba5bc40SThomas Faber static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
15690ba5bc40SThomas Faber {
15700ba5bc40SThomas Faber unsigned mask = all_or_nothing_int( cond );
15710ba5bc40SThomas Faber return( ( mask & if1 ) | (~mask & if0 ) );
15720ba5bc40SThomas Faber }
15730ba5bc40SThomas Faber
15740ba5bc40SThomas Faber /** Shift some data towards the left inside a buffer without leaking
15750ba5bc40SThomas Faber * the length of the data through side channels.
15760ba5bc40SThomas Faber *
15770ba5bc40SThomas Faber * `mem_move_to_left(start, total, offset)` is functionally equivalent to
15780ba5bc40SThomas Faber * ```
15790ba5bc40SThomas Faber * memmove(start, start + offset, total - offset);
15800ba5bc40SThomas Faber * memset(start + offset, 0, total - offset);
15810ba5bc40SThomas Faber * ```
15820ba5bc40SThomas Faber * but it strives to use a memory access pattern (and thus total timing)
15830ba5bc40SThomas Faber * that does not depend on \p offset. This timing independence comes at
15840ba5bc40SThomas Faber * the expense of performance.
15850ba5bc40SThomas Faber *
15860ba5bc40SThomas Faber * \param start Pointer to the start of the buffer.
15870ba5bc40SThomas Faber * \param total Total size of the buffer.
15880ba5bc40SThomas Faber * \param offset Offset from which to copy \p total - \p offset bytes.
15890ba5bc40SThomas Faber */
mem_move_to_left(void * start,size_t total,size_t offset)15900ba5bc40SThomas Faber static void mem_move_to_left( void *start,
15910ba5bc40SThomas Faber size_t total,
15920ba5bc40SThomas Faber size_t offset )
15930ba5bc40SThomas Faber {
15940ba5bc40SThomas Faber volatile unsigned char *buf = start;
15950ba5bc40SThomas Faber size_t i, n;
15960ba5bc40SThomas Faber if( total == 0 )
15970ba5bc40SThomas Faber return;
15980ba5bc40SThomas Faber for( i = 0; i < total; i++ )
15990ba5bc40SThomas Faber {
16000ba5bc40SThomas Faber unsigned no_op = size_greater_than( total - offset, i );
16010ba5bc40SThomas Faber /* The first `total - offset` passes are a no-op. The last
16020ba5bc40SThomas Faber * `offset` passes shift the data one byte to the left and
16030ba5bc40SThomas Faber * zero out the last byte. */
16040ba5bc40SThomas Faber for( n = 0; n < total - 1; n++ )
16050ba5bc40SThomas Faber {
16060ba5bc40SThomas Faber unsigned char current = buf[n];
16070ba5bc40SThomas Faber unsigned char next = buf[n+1];
16080ba5bc40SThomas Faber buf[n] = if_int( no_op, current, next );
16090ba5bc40SThomas Faber }
16100ba5bc40SThomas Faber buf[total-1] = if_int( no_op, buf[total-1], 0 );
16110ba5bc40SThomas Faber }
16120ba5bc40SThomas Faber }
16130ba5bc40SThomas Faber
1614c2c66affSColin Finck /*
1615c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
1616c2c66affSColin Finck */
mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1617c2c66affSColin Finck int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
1618c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1619c2c66affSColin Finck void *p_rng,
1620c2c66affSColin Finck int mode, size_t *olen,
1621c2c66affSColin Finck const unsigned char *input,
1622c2c66affSColin Finck unsigned char *output,
1623c2c66affSColin Finck size_t output_max_len )
1624c2c66affSColin Finck {
1625c2c66affSColin Finck int ret;
1626*cbda039fSThomas Faber size_t ilen, i, plaintext_max_size;
1627c2c66affSColin Finck unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
16280ba5bc40SThomas Faber /* The following variables take sensitive values: their value must
16290ba5bc40SThomas Faber * not leak into the observable behavior of the function other than
16300ba5bc40SThomas Faber * the designated outputs (output, olen, return value). Otherwise
16310ba5bc40SThomas Faber * this would open the execution of the function to
16320ba5bc40SThomas Faber * side-channel-based variants of the Bleichenbacher padding oracle
16330ba5bc40SThomas Faber * attack. Potential side channels include overall timing, memory
16340ba5bc40SThomas Faber * access patterns (especially visible to an adversary who has access
16350ba5bc40SThomas Faber * to a shared memory cache), and branches (especially visible to
16360ba5bc40SThomas Faber * an adversary who has access to a shared code cache or to a shared
16370ba5bc40SThomas Faber * branch predictor). */
16380ba5bc40SThomas Faber size_t pad_count = 0;
16390ba5bc40SThomas Faber unsigned bad = 0;
16400ba5bc40SThomas Faber unsigned char pad_done = 0;
16410ba5bc40SThomas Faber size_t plaintext_size = 0;
16420ba5bc40SThomas Faber unsigned output_too_large;
1643c2c66affSColin Finck
1644*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1645*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1646*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1647*cbda039fSThomas Faber RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1648*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1649*cbda039fSThomas Faber RSA_VALIDATE_RET( olen != NULL );
1650*cbda039fSThomas Faber
1651*cbda039fSThomas Faber ilen = ctx->len;
1652*cbda039fSThomas Faber plaintext_max_size = ( output_max_len > ilen - 11 ?
1653*cbda039fSThomas Faber ilen - 11 :
1654*cbda039fSThomas Faber output_max_len );
1655*cbda039fSThomas Faber
1656c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1657c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1658c2c66affSColin Finck
1659c2c66affSColin Finck if( ilen < 16 || ilen > sizeof( buf ) )
1660c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1661c2c66affSColin Finck
1662c2c66affSColin Finck ret = ( mode == MBEDTLS_RSA_PUBLIC )
1663c2c66affSColin Finck ? mbedtls_rsa_public( ctx, input, buf )
1664c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
1665c2c66affSColin Finck
1666c2c66affSColin Finck if( ret != 0 )
1667c2c66affSColin Finck goto cleanup;
1668c2c66affSColin Finck
16690ba5bc40SThomas Faber /* Check and get padding length in constant time and constant
16700ba5bc40SThomas Faber * memory trace. The first byte must be 0. */
16710ba5bc40SThomas Faber bad |= buf[0];
1672c2c66affSColin Finck
1673c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE )
1674c2c66affSColin Finck {
16750ba5bc40SThomas Faber /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
16760ba5bc40SThomas Faber * where PS must be at least 8 nonzero bytes. */
16770ba5bc40SThomas Faber bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
1678c2c66affSColin Finck
16790ba5bc40SThomas Faber /* Read the whole buffer. Set pad_done to nonzero if we find
16800ba5bc40SThomas Faber * the 0x00 byte and remember the padding length in pad_count. */
16810ba5bc40SThomas Faber for( i = 2; i < ilen; i++ )
1682c2c66affSColin Finck {
16830ba5bc40SThomas Faber pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
1684c2c66affSColin Finck pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
1685c2c66affSColin Finck }
1686c2c66affSColin Finck }
1687c2c66affSColin Finck else
1688c2c66affSColin Finck {
16890ba5bc40SThomas Faber /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
16900ba5bc40SThomas Faber * where PS must be at least 8 bytes with the value 0xFF. */
16910ba5bc40SThomas Faber bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
1692c2c66affSColin Finck
16930ba5bc40SThomas Faber /* Read the whole buffer. Set pad_done to nonzero if we find
16940ba5bc40SThomas Faber * the 0x00 byte and remember the padding length in pad_count.
16950ba5bc40SThomas Faber * If there's a non-0xff byte in the padding, the padding is bad. */
16960ba5bc40SThomas Faber for( i = 2; i < ilen; i++ )
1697c2c66affSColin Finck {
16980ba5bc40SThomas Faber pad_done |= if_int( buf[i], 0, 1 );
16990ba5bc40SThomas Faber pad_count += if_int( pad_done, 0, 1 );
17000ba5bc40SThomas Faber bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
17010ba5bc40SThomas Faber }
1702c2c66affSColin Finck }
1703c2c66affSColin Finck
17040ba5bc40SThomas Faber /* If pad_done is still zero, there's no data, only unfinished padding. */
17050ba5bc40SThomas Faber bad |= if_int( pad_done, 0, 1 );
1706c2c66affSColin Finck
17070ba5bc40SThomas Faber /* There must be at least 8 bytes of padding. */
17080ba5bc40SThomas Faber bad |= size_greater_than( 8, pad_count );
1709c2c66affSColin Finck
17100ba5bc40SThomas Faber /* If the padding is valid, set plaintext_size to the number of
17110ba5bc40SThomas Faber * remaining bytes after stripping the padding. If the padding
17120ba5bc40SThomas Faber * is invalid, avoid leaking this fact through the size of the
17130ba5bc40SThomas Faber * output: use the maximum message size that fits in the output
17140ba5bc40SThomas Faber * buffer. Do it without branches to avoid leaking the padding
17150ba5bc40SThomas Faber * validity through timing. RSA keys are small enough that all the
17160ba5bc40SThomas Faber * size_t values involved fit in unsigned int. */
17170ba5bc40SThomas Faber plaintext_size = if_int( bad,
17180ba5bc40SThomas Faber (unsigned) plaintext_max_size,
17190ba5bc40SThomas Faber (unsigned) ( ilen - pad_count - 3 ) );
1720c2c66affSColin Finck
17210ba5bc40SThomas Faber /* Set output_too_large to 0 if the plaintext fits in the output
17220ba5bc40SThomas Faber * buffer and to 1 otherwise. */
17230ba5bc40SThomas Faber output_too_large = size_greater_than( plaintext_size,
17240ba5bc40SThomas Faber plaintext_max_size );
1725c2c66affSColin Finck
17260ba5bc40SThomas Faber /* Set ret without branches to avoid timing attacks. Return:
17270ba5bc40SThomas Faber * - INVALID_PADDING if the padding is bad (bad != 0).
17280ba5bc40SThomas Faber * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
17290ba5bc40SThomas Faber * plaintext does not fit in the output buffer.
17300ba5bc40SThomas Faber * - 0 if the padding is correct. */
17310ba5bc40SThomas Faber ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
17320ba5bc40SThomas Faber if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
17330ba5bc40SThomas Faber 0 ) );
17340ba5bc40SThomas Faber
17350ba5bc40SThomas Faber /* If the padding is bad or the plaintext is too large, zero the
17360ba5bc40SThomas Faber * data that we're about to copy to the output buffer.
17370ba5bc40SThomas Faber * We need to copy the same amount of data
17380ba5bc40SThomas Faber * from the same buffer whether the padding is good or not to
17390ba5bc40SThomas Faber * avoid leaking the padding validity through overall timing or
17400ba5bc40SThomas Faber * through memory or cache access patterns. */
17410ba5bc40SThomas Faber bad = all_or_nothing_int( bad | output_too_large );
17420ba5bc40SThomas Faber for( i = 11; i < ilen; i++ )
17430ba5bc40SThomas Faber buf[i] &= ~bad;
17440ba5bc40SThomas Faber
17450ba5bc40SThomas Faber /* If the plaintext is too large, truncate it to the buffer size.
17460ba5bc40SThomas Faber * Copy anyway to avoid revealing the length through timing, because
17470ba5bc40SThomas Faber * revealing the length is as bad as revealing the padding validity
17480ba5bc40SThomas Faber * for a Bleichenbacher attack. */
17490ba5bc40SThomas Faber plaintext_size = if_int( output_too_large,
17500ba5bc40SThomas Faber (unsigned) plaintext_max_size,
17510ba5bc40SThomas Faber (unsigned) plaintext_size );
17520ba5bc40SThomas Faber
17530ba5bc40SThomas Faber /* Move the plaintext to the leftmost position where it can start in
17540ba5bc40SThomas Faber * the working buffer, i.e. make it start plaintext_max_size from
17550ba5bc40SThomas Faber * the end of the buffer. Do this with a memory access trace that
17560ba5bc40SThomas Faber * does not depend on the plaintext size. After this move, the
17570ba5bc40SThomas Faber * starting location of the plaintext is no longer sensitive
17580ba5bc40SThomas Faber * information. */
17590ba5bc40SThomas Faber mem_move_to_left( buf + ilen - plaintext_max_size,
17600ba5bc40SThomas Faber plaintext_max_size,
17610ba5bc40SThomas Faber plaintext_max_size - plaintext_size );
17620ba5bc40SThomas Faber
17630ba5bc40SThomas Faber /* Finally copy the decrypted plaintext plus trailing zeros
17640ba5bc40SThomas Faber * into the output buffer. */
17650ba5bc40SThomas Faber memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
17660ba5bc40SThomas Faber
17670ba5bc40SThomas Faber /* Report the amount of data we copied to the output buffer. In case
17680ba5bc40SThomas Faber * of errors (bad padding or output too large), the value of *olen
17690ba5bc40SThomas Faber * when this function returns is not specified. Making it equivalent
17700ba5bc40SThomas Faber * to the good case limits the risks of leaking the padding validity. */
17710ba5bc40SThomas Faber *olen = plaintext_size;
1772c2c66affSColin Finck
1773c2c66affSColin Finck cleanup:
1774*cbda039fSThomas Faber mbedtls_platform_zeroize( buf, sizeof( buf ) );
1775c2c66affSColin Finck
1776c2c66affSColin Finck return( ret );
1777c2c66affSColin Finck }
1778c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
1779c2c66affSColin Finck
1780c2c66affSColin Finck /*
1781c2c66affSColin Finck * Do an RSA operation, then remove the message padding
1782c2c66affSColin Finck */
mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,size_t * olen,const unsigned char * input,unsigned char * output,size_t output_max_len)1783c2c66affSColin Finck int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
1784c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1785c2c66affSColin Finck void *p_rng,
1786c2c66affSColin Finck int mode, size_t *olen,
1787c2c66affSColin Finck const unsigned char *input,
1788c2c66affSColin Finck unsigned char *output,
1789c2c66affSColin Finck size_t output_max_len)
1790c2c66affSColin Finck {
1791*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1792*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1793*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1794*cbda039fSThomas Faber RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
1795*cbda039fSThomas Faber RSA_VALIDATE_RET( input != NULL );
1796*cbda039fSThomas Faber RSA_VALIDATE_RET( olen != NULL );
1797*cbda039fSThomas Faber
1798c2c66affSColin Finck switch( ctx->padding )
1799c2c66affSColin Finck {
1800c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
1801c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V15:
1802c2c66affSColin Finck return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
1803c2c66affSColin Finck input, output, output_max_len );
1804c2c66affSColin Finck #endif
1805c2c66affSColin Finck
1806c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1807c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V21:
1808c2c66affSColin Finck return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
1809c2c66affSColin Finck olen, input, output,
1810c2c66affSColin Finck output_max_len );
1811c2c66affSColin Finck #endif
1812c2c66affSColin Finck
1813c2c66affSColin Finck default:
1814c2c66affSColin Finck return( MBEDTLS_ERR_RSA_INVALID_PADDING );
1815c2c66affSColin Finck }
1816c2c66affSColin Finck }
1817c2c66affSColin Finck
1818c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
1819c2c66affSColin Finck /*
1820c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
1821c2c66affSColin Finck */
mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)1822c2c66affSColin Finck int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
1823c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
1824c2c66affSColin Finck void *p_rng,
1825c2c66affSColin Finck int mode,
1826c2c66affSColin Finck mbedtls_md_type_t md_alg,
1827c2c66affSColin Finck unsigned int hashlen,
1828c2c66affSColin Finck const unsigned char *hash,
1829c2c66affSColin Finck unsigned char *sig )
1830c2c66affSColin Finck {
1831c2c66affSColin Finck size_t olen;
1832c2c66affSColin Finck unsigned char *p = sig;
1833c2c66affSColin Finck unsigned char salt[MBEDTLS_MD_MAX_SIZE];
1834*cbda039fSThomas Faber size_t slen, min_slen, hlen, offset = 0;
1835c2c66affSColin Finck int ret;
1836c2c66affSColin Finck size_t msb;
1837c2c66affSColin Finck const mbedtls_md_info_t *md_info;
1838c2c66affSColin Finck mbedtls_md_context_t md_ctx;
1839*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
1840*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
1841*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
1842*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
1843*cbda039fSThomas Faber hashlen == 0 ) ||
1844*cbda039fSThomas Faber hash != NULL );
1845*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
1846c2c66affSColin Finck
1847c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1848c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1849c2c66affSColin Finck
1850c2c66affSColin Finck if( f_rng == NULL )
1851c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1852c2c66affSColin Finck
1853c2c66affSColin Finck olen = ctx->len;
1854c2c66affSColin Finck
1855c2c66affSColin Finck if( md_alg != MBEDTLS_MD_NONE )
1856c2c66affSColin Finck {
1857c2c66affSColin Finck /* Gather length of hash to sign */
1858c2c66affSColin Finck md_info = mbedtls_md_info_from_type( md_alg );
1859c2c66affSColin Finck if( md_info == NULL )
1860c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1861c2c66affSColin Finck
1862c2c66affSColin Finck hashlen = mbedtls_md_get_size( md_info );
1863c2c66affSColin Finck }
1864c2c66affSColin Finck
1865c2c66affSColin Finck md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
1866c2c66affSColin Finck if( md_info == NULL )
1867c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1868c2c66affSColin Finck
1869c2c66affSColin Finck hlen = mbedtls_md_get_size( md_info );
1870c2c66affSColin Finck
1871*cbda039fSThomas Faber /* Calculate the largest possible salt length. Normally this is the hash
1872*cbda039fSThomas Faber * length, which is the maximum length the salt can have. If there is not
1873*cbda039fSThomas Faber * enough room, use the maximum salt length that fits. The constraint is
1874*cbda039fSThomas Faber * that the hash length plus the salt length plus 2 bytes must be at most
1875*cbda039fSThomas Faber * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
1876*cbda039fSThomas Faber * (PKCS#1 v2.2) §9.1.1 step 3. */
1877*cbda039fSThomas Faber min_slen = hlen - 2;
1878*cbda039fSThomas Faber if( olen < hlen + min_slen + 2 )
1879c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1880*cbda039fSThomas Faber else if( olen >= hlen + hlen + 2 )
1881*cbda039fSThomas Faber slen = hlen;
1882*cbda039fSThomas Faber else
1883*cbda039fSThomas Faber slen = olen - hlen - 2;
1884c2c66affSColin Finck
1885c2c66affSColin Finck memset( sig, 0, olen );
1886c2c66affSColin Finck
1887c2c66affSColin Finck /* Generate salt of length slen */
1888c2c66affSColin Finck if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
1889c2c66affSColin Finck return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
1890c2c66affSColin Finck
1891c2c66affSColin Finck /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
1892c2c66affSColin Finck msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
1893*cbda039fSThomas Faber p += olen - hlen - slen - 2;
1894c2c66affSColin Finck *p++ = 0x01;
1895c2c66affSColin Finck memcpy( p, salt, slen );
1896c2c66affSColin Finck p += slen;
1897c2c66affSColin Finck
1898c2c66affSColin Finck mbedtls_md_init( &md_ctx );
1899c2c66affSColin Finck if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
1900d9e6c9b5SThomas Faber goto exit;
1901c2c66affSColin Finck
1902c2c66affSColin Finck /* Generate H = Hash( M' ) */
1903d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
1904d9e6c9b5SThomas Faber goto exit;
1905d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
1906d9e6c9b5SThomas Faber goto exit;
1907d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
1908d9e6c9b5SThomas Faber goto exit;
1909d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
1910d9e6c9b5SThomas Faber goto exit;
1911d9e6c9b5SThomas Faber if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
1912d9e6c9b5SThomas Faber goto exit;
1913c2c66affSColin Finck
1914c2c66affSColin Finck /* Compensate for boundary condition when applying mask */
1915c2c66affSColin Finck if( msb % 8 == 0 )
1916c2c66affSColin Finck offset = 1;
1917c2c66affSColin Finck
1918c2c66affSColin Finck /* maskedDB: Apply dbMask to DB */
1919d9e6c9b5SThomas Faber if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
1920d9e6c9b5SThomas Faber &md_ctx ) ) != 0 )
1921d9e6c9b5SThomas Faber goto exit;
1922c2c66affSColin Finck
1923c2c66affSColin Finck msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
1924c2c66affSColin Finck sig[0] &= 0xFF >> ( olen * 8 - msb );
1925c2c66affSColin Finck
1926c2c66affSColin Finck p += hlen;
1927c2c66affSColin Finck *p++ = 0xBC;
1928c2c66affSColin Finck
1929*cbda039fSThomas Faber mbedtls_platform_zeroize( salt, sizeof( salt ) );
1930d9e6c9b5SThomas Faber
1931d9e6c9b5SThomas Faber exit:
1932d9e6c9b5SThomas Faber mbedtls_md_free( &md_ctx );
1933d9e6c9b5SThomas Faber
1934d9e6c9b5SThomas Faber if( ret != 0 )
1935d9e6c9b5SThomas Faber return( ret );
1936d9e6c9b5SThomas Faber
1937c2c66affSColin Finck return( ( mode == MBEDTLS_RSA_PUBLIC )
1938c2c66affSColin Finck ? mbedtls_rsa_public( ctx, sig, sig )
1939c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
1940c2c66affSColin Finck }
1941c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V21 */
1942c2c66affSColin Finck
1943c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
1944c2c66affSColin Finck /*
1945c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
1946c2c66affSColin Finck */
1947d9e6c9b5SThomas Faber
1948d9e6c9b5SThomas Faber /* Construct a PKCS v1.5 encoding of a hashed message
1949d9e6c9b5SThomas Faber *
1950d9e6c9b5SThomas Faber * This is used both for signature generation and verification.
1951d9e6c9b5SThomas Faber *
1952d9e6c9b5SThomas Faber * Parameters:
1953d9e6c9b5SThomas Faber * - md_alg: Identifies the hash algorithm used to generate the given hash;
1954d9e6c9b5SThomas Faber * MBEDTLS_MD_NONE if raw data is signed.
1955d9e6c9b5SThomas Faber * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
1956d9e6c9b5SThomas Faber * - hash: Buffer containing the hashed message or the raw data.
1957d9e6c9b5SThomas Faber * - dst_len: Length of the encoded message.
1958d9e6c9b5SThomas Faber * - dst: Buffer to hold the encoded message.
1959d9e6c9b5SThomas Faber *
1960d9e6c9b5SThomas Faber * Assumptions:
1961d9e6c9b5SThomas Faber * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
1962d9e6c9b5SThomas Faber * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
1963d9e6c9b5SThomas Faber * - dst points to a buffer of size at least dst_len.
1964d9e6c9b5SThomas Faber *
1965d9e6c9b5SThomas Faber */
rsa_rsassa_pkcs1_v15_encode(mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,size_t dst_len,unsigned char * dst)1966d9e6c9b5SThomas Faber static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
1967d9e6c9b5SThomas Faber unsigned int hashlen,
1968d9e6c9b5SThomas Faber const unsigned char *hash,
1969d9e6c9b5SThomas Faber size_t dst_len,
1970d9e6c9b5SThomas Faber unsigned char *dst )
1971d9e6c9b5SThomas Faber {
1972d9e6c9b5SThomas Faber size_t oid_size = 0;
1973d9e6c9b5SThomas Faber size_t nb_pad = dst_len;
1974d9e6c9b5SThomas Faber unsigned char *p = dst;
1975d9e6c9b5SThomas Faber const char *oid = NULL;
1976d9e6c9b5SThomas Faber
1977d9e6c9b5SThomas Faber /* Are we signing hashed or raw data? */
1978d9e6c9b5SThomas Faber if( md_alg != MBEDTLS_MD_NONE )
1979d9e6c9b5SThomas Faber {
1980d9e6c9b5SThomas Faber const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
1981d9e6c9b5SThomas Faber if( md_info == NULL )
1982d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1983d9e6c9b5SThomas Faber
1984d9e6c9b5SThomas Faber if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1985d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1986d9e6c9b5SThomas Faber
1987d9e6c9b5SThomas Faber hashlen = mbedtls_md_get_size( md_info );
1988d9e6c9b5SThomas Faber
1989d9e6c9b5SThomas Faber /* Double-check that 8 + hashlen + oid_size can be used as a
1990d9e6c9b5SThomas Faber * 1-byte ASN.1 length encoding and that there's no overflow. */
1991d9e6c9b5SThomas Faber if( 8 + hashlen + oid_size >= 0x80 ||
1992d9e6c9b5SThomas Faber 10 + hashlen < hashlen ||
1993d9e6c9b5SThomas Faber 10 + hashlen + oid_size < 10 + hashlen )
1994d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1995d9e6c9b5SThomas Faber
1996d9e6c9b5SThomas Faber /*
1997d9e6c9b5SThomas Faber * Static bounds check:
1998d9e6c9b5SThomas Faber * - Need 10 bytes for five tag-length pairs.
1999d9e6c9b5SThomas Faber * (Insist on 1-byte length encodings to protect against variants of
2000d9e6c9b5SThomas Faber * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
2001d9e6c9b5SThomas Faber * - Need hashlen bytes for hash
2002d9e6c9b5SThomas Faber * - Need oid_size bytes for hash alg OID.
2003d9e6c9b5SThomas Faber */
2004d9e6c9b5SThomas Faber if( nb_pad < 10 + hashlen + oid_size )
2005d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2006d9e6c9b5SThomas Faber nb_pad -= 10 + hashlen + oid_size;
2007d9e6c9b5SThomas Faber }
2008d9e6c9b5SThomas Faber else
2009d9e6c9b5SThomas Faber {
2010d9e6c9b5SThomas Faber if( nb_pad < hashlen )
2011d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2012d9e6c9b5SThomas Faber
2013d9e6c9b5SThomas Faber nb_pad -= hashlen;
2014d9e6c9b5SThomas Faber }
2015d9e6c9b5SThomas Faber
2016d9e6c9b5SThomas Faber /* Need space for signature header and padding delimiter (3 bytes),
2017d9e6c9b5SThomas Faber * and 8 bytes for the minimal padding */
2018d9e6c9b5SThomas Faber if( nb_pad < 3 + 8 )
2019d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2020d9e6c9b5SThomas Faber nb_pad -= 3;
2021d9e6c9b5SThomas Faber
2022d9e6c9b5SThomas Faber /* Now nb_pad is the amount of memory to be filled
2023d9e6c9b5SThomas Faber * with padding, and at least 8 bytes long. */
2024d9e6c9b5SThomas Faber
2025d9e6c9b5SThomas Faber /* Write signature header and padding */
2026d9e6c9b5SThomas Faber *p++ = 0;
2027d9e6c9b5SThomas Faber *p++ = MBEDTLS_RSA_SIGN;
2028d9e6c9b5SThomas Faber memset( p, 0xFF, nb_pad );
2029d9e6c9b5SThomas Faber p += nb_pad;
2030d9e6c9b5SThomas Faber *p++ = 0;
2031d9e6c9b5SThomas Faber
2032d9e6c9b5SThomas Faber /* Are we signing raw data? */
2033d9e6c9b5SThomas Faber if( md_alg == MBEDTLS_MD_NONE )
2034d9e6c9b5SThomas Faber {
2035d9e6c9b5SThomas Faber memcpy( p, hash, hashlen );
2036d9e6c9b5SThomas Faber return( 0 );
2037d9e6c9b5SThomas Faber }
2038d9e6c9b5SThomas Faber
2039d9e6c9b5SThomas Faber /* Signing hashed data, add corresponding ASN.1 structure
2040d9e6c9b5SThomas Faber *
2041d9e6c9b5SThomas Faber * DigestInfo ::= SEQUENCE {
2042d9e6c9b5SThomas Faber * digestAlgorithm DigestAlgorithmIdentifier,
2043d9e6c9b5SThomas Faber * digest Digest }
2044d9e6c9b5SThomas Faber * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
2045d9e6c9b5SThomas Faber * Digest ::= OCTET STRING
2046d9e6c9b5SThomas Faber *
2047d9e6c9b5SThomas Faber * Schematic:
2048d9e6c9b5SThomas Faber * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
2049d9e6c9b5SThomas Faber * TAG-NULL + LEN [ NULL ] ]
2050d9e6c9b5SThomas Faber * TAG-OCTET + LEN [ HASH ] ]
2051d9e6c9b5SThomas Faber */
2052d9e6c9b5SThomas Faber *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
2053d9e6c9b5SThomas Faber *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
2054d9e6c9b5SThomas Faber *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
2055d9e6c9b5SThomas Faber *p++ = (unsigned char)( 0x04 + oid_size );
2056d9e6c9b5SThomas Faber *p++ = MBEDTLS_ASN1_OID;
2057d9e6c9b5SThomas Faber *p++ = (unsigned char) oid_size;
2058d9e6c9b5SThomas Faber memcpy( p, oid, oid_size );
2059d9e6c9b5SThomas Faber p += oid_size;
2060d9e6c9b5SThomas Faber *p++ = MBEDTLS_ASN1_NULL;
2061d9e6c9b5SThomas Faber *p++ = 0x00;
2062d9e6c9b5SThomas Faber *p++ = MBEDTLS_ASN1_OCTET_STRING;
2063d9e6c9b5SThomas Faber *p++ = (unsigned char) hashlen;
2064d9e6c9b5SThomas Faber memcpy( p, hash, hashlen );
2065d9e6c9b5SThomas Faber p += hashlen;
2066d9e6c9b5SThomas Faber
2067d9e6c9b5SThomas Faber /* Just a sanity-check, should be automatic
2068d9e6c9b5SThomas Faber * after the initial bounds check. */
2069d9e6c9b5SThomas Faber if( p != dst + dst_len )
2070d9e6c9b5SThomas Faber {
2071*cbda039fSThomas Faber mbedtls_platform_zeroize( dst, dst_len );
2072d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2073d9e6c9b5SThomas Faber }
2074d9e6c9b5SThomas Faber
2075d9e6c9b5SThomas Faber return( 0 );
2076d9e6c9b5SThomas Faber }
2077d9e6c9b5SThomas Faber
2078c2c66affSColin Finck /*
2079c2c66affSColin Finck * Do an RSA operation to sign the message digest
2080c2c66affSColin Finck */
mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)2081c2c66affSColin Finck int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
2082c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2083c2c66affSColin Finck void *p_rng,
2084c2c66affSColin Finck int mode,
2085c2c66affSColin Finck mbedtls_md_type_t md_alg,
2086c2c66affSColin Finck unsigned int hashlen,
2087c2c66affSColin Finck const unsigned char *hash,
2088c2c66affSColin Finck unsigned char *sig )
2089c2c66affSColin Finck {
2090c2c66affSColin Finck int ret;
2091d9e6c9b5SThomas Faber unsigned char *sig_try = NULL, *verif = NULL;
2092c2c66affSColin Finck
2093*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2094*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2095*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2096*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2097*cbda039fSThomas Faber hashlen == 0 ) ||
2098*cbda039fSThomas Faber hash != NULL );
2099*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2100*cbda039fSThomas Faber
2101c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2102c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2103c2c66affSColin Finck
2104c2c66affSColin Finck /*
2105d9e6c9b5SThomas Faber * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
2106c2c66affSColin Finck */
2107d9e6c9b5SThomas Faber
2108d9e6c9b5SThomas Faber if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
2109d9e6c9b5SThomas Faber ctx->len, sig ) ) != 0 )
2110d9e6c9b5SThomas Faber return( ret );
2111d9e6c9b5SThomas Faber
2112d9e6c9b5SThomas Faber /*
2113d9e6c9b5SThomas Faber * Call respective RSA primitive
2114d9e6c9b5SThomas Faber */
2115c2c66affSColin Finck
2116c2c66affSColin Finck if( mode == MBEDTLS_RSA_PUBLIC )
2117d9e6c9b5SThomas Faber {
2118d9e6c9b5SThomas Faber /* Skip verification on a public key operation */
2119c2c66affSColin Finck return( mbedtls_rsa_public( ctx, sig, sig ) );
2120d9e6c9b5SThomas Faber }
2121c2c66affSColin Finck
2122d9e6c9b5SThomas Faber /* Private key operation
2123d9e6c9b5SThomas Faber *
2124c2c66affSColin Finck * In order to prevent Lenstra's attack, make the signature in a
2125c2c66affSColin Finck * temporary buffer and check it before returning it.
2126c2c66affSColin Finck */
2127d9e6c9b5SThomas Faber
2128c2c66affSColin Finck sig_try = mbedtls_calloc( 1, ctx->len );
2129c2c66affSColin Finck if( sig_try == NULL )
2130c2c66affSColin Finck return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2131c2c66affSColin Finck
2132c2c66affSColin Finck verif = mbedtls_calloc( 1, ctx->len );
2133c2c66affSColin Finck if( verif == NULL )
2134c2c66affSColin Finck {
2135c2c66affSColin Finck mbedtls_free( sig_try );
2136c2c66affSColin Finck return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
2137c2c66affSColin Finck }
2138c2c66affSColin Finck
2139c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
2140c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
2141c2c66affSColin Finck
2142d9e6c9b5SThomas Faber if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
2143c2c66affSColin Finck {
2144c2c66affSColin Finck ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
2145c2c66affSColin Finck goto cleanup;
2146c2c66affSColin Finck }
2147c2c66affSColin Finck
2148c2c66affSColin Finck memcpy( sig, sig_try, ctx->len );
2149c2c66affSColin Finck
2150c2c66affSColin Finck cleanup:
2151c2c66affSColin Finck mbedtls_free( sig_try );
2152c2c66affSColin Finck mbedtls_free( verif );
2153c2c66affSColin Finck
2154c2c66affSColin Finck return( ret );
2155c2c66affSColin Finck }
2156c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
2157c2c66affSColin Finck
2158c2c66affSColin Finck /*
2159c2c66affSColin Finck * Do an RSA operation to sign the message digest
2160c2c66affSColin Finck */
mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,unsigned char * sig)2161c2c66affSColin Finck int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
2162c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2163c2c66affSColin Finck void *p_rng,
2164c2c66affSColin Finck int mode,
2165c2c66affSColin Finck mbedtls_md_type_t md_alg,
2166c2c66affSColin Finck unsigned int hashlen,
2167c2c66affSColin Finck const unsigned char *hash,
2168c2c66affSColin Finck unsigned char *sig )
2169c2c66affSColin Finck {
2170*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2171*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2172*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2173*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2174*cbda039fSThomas Faber hashlen == 0 ) ||
2175*cbda039fSThomas Faber hash != NULL );
2176*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2177*cbda039fSThomas Faber
2178c2c66affSColin Finck switch( ctx->padding )
2179c2c66affSColin Finck {
2180c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
2181c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V15:
2182c2c66affSColin Finck return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
2183c2c66affSColin Finck hashlen, hash, sig );
2184c2c66affSColin Finck #endif
2185c2c66affSColin Finck
2186c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
2187c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V21:
2188c2c66affSColin Finck return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
2189c2c66affSColin Finck hashlen, hash, sig );
2190c2c66affSColin Finck #endif
2191c2c66affSColin Finck
2192c2c66affSColin Finck default:
2193c2c66affSColin Finck return( MBEDTLS_ERR_RSA_INVALID_PADDING );
2194c2c66affSColin Finck }
2195c2c66affSColin Finck }
2196c2c66affSColin Finck
2197c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
2198c2c66affSColin Finck /*
2199c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2200c2c66affSColin Finck */
mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,mbedtls_md_type_t mgf1_hash_id,int expected_salt_len,const unsigned char * sig)2201c2c66affSColin Finck int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
2202c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2203c2c66affSColin Finck void *p_rng,
2204c2c66affSColin Finck int mode,
2205c2c66affSColin Finck mbedtls_md_type_t md_alg,
2206c2c66affSColin Finck unsigned int hashlen,
2207c2c66affSColin Finck const unsigned char *hash,
2208c2c66affSColin Finck mbedtls_md_type_t mgf1_hash_id,
2209c2c66affSColin Finck int expected_salt_len,
2210c2c66affSColin Finck const unsigned char *sig )
2211c2c66affSColin Finck {
2212c2c66affSColin Finck int ret;
2213c2c66affSColin Finck size_t siglen;
2214c2c66affSColin Finck unsigned char *p;
2215d9e6c9b5SThomas Faber unsigned char *hash_start;
2216c2c66affSColin Finck unsigned char result[MBEDTLS_MD_MAX_SIZE];
2217c2c66affSColin Finck unsigned char zeros[8];
2218c2c66affSColin Finck unsigned int hlen;
2219d9e6c9b5SThomas Faber size_t observed_salt_len, msb;
2220c2c66affSColin Finck const mbedtls_md_info_t *md_info;
2221c2c66affSColin Finck mbedtls_md_context_t md_ctx;
2222c2c66affSColin Finck unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
2223c2c66affSColin Finck
2224*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2225*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2226*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2227*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2228*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2229*cbda039fSThomas Faber hashlen == 0 ) ||
2230*cbda039fSThomas Faber hash != NULL );
2231*cbda039fSThomas Faber
2232c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
2233c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2234c2c66affSColin Finck
2235c2c66affSColin Finck siglen = ctx->len;
2236c2c66affSColin Finck
2237c2c66affSColin Finck if( siglen < 16 || siglen > sizeof( buf ) )
2238c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2239c2c66affSColin Finck
2240c2c66affSColin Finck ret = ( mode == MBEDTLS_RSA_PUBLIC )
2241c2c66affSColin Finck ? mbedtls_rsa_public( ctx, sig, buf )
2242c2c66affSColin Finck : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
2243c2c66affSColin Finck
2244c2c66affSColin Finck if( ret != 0 )
2245c2c66affSColin Finck return( ret );
2246c2c66affSColin Finck
2247c2c66affSColin Finck p = buf;
2248c2c66affSColin Finck
2249c2c66affSColin Finck if( buf[siglen - 1] != 0xBC )
2250c2c66affSColin Finck return( MBEDTLS_ERR_RSA_INVALID_PADDING );
2251c2c66affSColin Finck
2252c2c66affSColin Finck if( md_alg != MBEDTLS_MD_NONE )
2253c2c66affSColin Finck {
2254c2c66affSColin Finck /* Gather length of hash to sign */
2255c2c66affSColin Finck md_info = mbedtls_md_info_from_type( md_alg );
2256c2c66affSColin Finck if( md_info == NULL )
2257c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2258c2c66affSColin Finck
2259c2c66affSColin Finck hashlen = mbedtls_md_get_size( md_info );
2260c2c66affSColin Finck }
2261c2c66affSColin Finck
2262c2c66affSColin Finck md_info = mbedtls_md_info_from_type( mgf1_hash_id );
2263c2c66affSColin Finck if( md_info == NULL )
2264c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2265c2c66affSColin Finck
2266c2c66affSColin Finck hlen = mbedtls_md_get_size( md_info );
2267c2c66affSColin Finck
2268c2c66affSColin Finck memset( zeros, 0, 8 );
2269c2c66affSColin Finck
2270c2c66affSColin Finck /*
2271c2c66affSColin Finck * Note: EMSA-PSS verification is over the length of N - 1 bits
2272c2c66affSColin Finck */
2273c2c66affSColin Finck msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
2274c2c66affSColin Finck
2275d9e6c9b5SThomas Faber if( buf[0] >> ( 8 - siglen * 8 + msb ) )
2276d9e6c9b5SThomas Faber return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2277d9e6c9b5SThomas Faber
2278c2c66affSColin Finck /* Compensate for boundary condition when applying mask */
2279c2c66affSColin Finck if( msb % 8 == 0 )
2280c2c66affSColin Finck {
2281c2c66affSColin Finck p++;
2282c2c66affSColin Finck siglen -= 1;
2283c2c66affSColin Finck }
2284d9e6c9b5SThomas Faber
2285d9e6c9b5SThomas Faber if( siglen < hlen + 2 )
2286c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2287d9e6c9b5SThomas Faber hash_start = p + siglen - hlen - 1;
2288c2c66affSColin Finck
2289c2c66affSColin Finck mbedtls_md_init( &md_ctx );
2290c2c66affSColin Finck if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
2291d9e6c9b5SThomas Faber goto exit;
2292c2c66affSColin Finck
2293d9e6c9b5SThomas Faber ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
2294d9e6c9b5SThomas Faber if( ret != 0 )
2295d9e6c9b5SThomas Faber goto exit;
2296c2c66affSColin Finck
2297c2c66affSColin Finck buf[0] &= 0xFF >> ( siglen * 8 - msb );
2298c2c66affSColin Finck
2299d9e6c9b5SThomas Faber while( p < hash_start - 1 && *p == 0 )
2300c2c66affSColin Finck p++;
2301c2c66affSColin Finck
2302d9e6c9b5SThomas Faber if( *p++ != 0x01 )
2303c2c66affSColin Finck {
2304d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
2305d9e6c9b5SThomas Faber goto exit;
2306c2c66affSColin Finck }
2307c2c66affSColin Finck
2308d9e6c9b5SThomas Faber observed_salt_len = hash_start - p;
2309c2c66affSColin Finck
2310c2c66affSColin Finck if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
2311d9e6c9b5SThomas Faber observed_salt_len != (size_t) expected_salt_len )
2312c2c66affSColin Finck {
2313d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
2314d9e6c9b5SThomas Faber goto exit;
2315c2c66affSColin Finck }
2316c2c66affSColin Finck
2317c2c66affSColin Finck /*
2318c2c66affSColin Finck * Generate H = Hash( M' )
2319c2c66affSColin Finck */
2320d9e6c9b5SThomas Faber ret = mbedtls_md_starts( &md_ctx );
2321d9e6c9b5SThomas Faber if ( ret != 0 )
2322d9e6c9b5SThomas Faber goto exit;
2323d9e6c9b5SThomas Faber ret = mbedtls_md_update( &md_ctx, zeros, 8 );
2324d9e6c9b5SThomas Faber if ( ret != 0 )
2325d9e6c9b5SThomas Faber goto exit;
2326d9e6c9b5SThomas Faber ret = mbedtls_md_update( &md_ctx, hash, hashlen );
2327d9e6c9b5SThomas Faber if ( ret != 0 )
2328d9e6c9b5SThomas Faber goto exit;
2329d9e6c9b5SThomas Faber ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );
2330d9e6c9b5SThomas Faber if ( ret != 0 )
2331d9e6c9b5SThomas Faber goto exit;
2332d9e6c9b5SThomas Faber ret = mbedtls_md_finish( &md_ctx, result );
2333d9e6c9b5SThomas Faber if ( ret != 0 )
2334d9e6c9b5SThomas Faber goto exit;
2335c2c66affSColin Finck
2336d9e6c9b5SThomas Faber if( memcmp( hash_start, result, hlen ) != 0 )
2337d9e6c9b5SThomas Faber {
2338d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2339d9e6c9b5SThomas Faber goto exit;
2340d9e6c9b5SThomas Faber }
2341d9e6c9b5SThomas Faber
2342d9e6c9b5SThomas Faber exit:
2343c2c66affSColin Finck mbedtls_md_free( &md_ctx );
2344c2c66affSColin Finck
2345d9e6c9b5SThomas Faber return( ret );
2346c2c66affSColin Finck }
2347c2c66affSColin Finck
2348c2c66affSColin Finck /*
2349c2c66affSColin Finck * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
2350c2c66affSColin Finck */
mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2351c2c66affSColin Finck int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
2352c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2353c2c66affSColin Finck void *p_rng,
2354c2c66affSColin Finck int mode,
2355c2c66affSColin Finck mbedtls_md_type_t md_alg,
2356c2c66affSColin Finck unsigned int hashlen,
2357c2c66affSColin Finck const unsigned char *hash,
2358c2c66affSColin Finck const unsigned char *sig )
2359c2c66affSColin Finck {
2360*cbda039fSThomas Faber mbedtls_md_type_t mgf1_hash_id;
2361*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2362*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2363*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2364*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2365*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2366*cbda039fSThomas Faber hashlen == 0 ) ||
2367*cbda039fSThomas Faber hash != NULL );
2368*cbda039fSThomas Faber
2369*cbda039fSThomas Faber mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
2370c2c66affSColin Finck ? (mbedtls_md_type_t) ctx->hash_id
2371c2c66affSColin Finck : md_alg;
2372c2c66affSColin Finck
2373c2c66affSColin Finck return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
2374c2c66affSColin Finck md_alg, hashlen, hash,
2375c2c66affSColin Finck mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
2376c2c66affSColin Finck sig ) );
2377c2c66affSColin Finck
2378c2c66affSColin Finck }
2379c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V21 */
2380c2c66affSColin Finck
2381c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
2382c2c66affSColin Finck /*
2383c2c66affSColin Finck * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
2384c2c66affSColin Finck */
mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2385c2c66affSColin Finck int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
2386c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2387c2c66affSColin Finck void *p_rng,
2388c2c66affSColin Finck int mode,
2389c2c66affSColin Finck mbedtls_md_type_t md_alg,
2390c2c66affSColin Finck unsigned int hashlen,
2391c2c66affSColin Finck const unsigned char *hash,
2392c2c66affSColin Finck const unsigned char *sig )
2393c2c66affSColin Finck {
2394d9e6c9b5SThomas Faber int ret = 0;
2395*cbda039fSThomas Faber size_t sig_len;
2396d9e6c9b5SThomas Faber unsigned char *encoded = NULL, *encoded_expected = NULL;
2397c2c66affSColin Finck
2398*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2399*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2400*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2401*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2402*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2403*cbda039fSThomas Faber hashlen == 0 ) ||
2404*cbda039fSThomas Faber hash != NULL );
2405*cbda039fSThomas Faber
2406*cbda039fSThomas Faber sig_len = ctx->len;
2407*cbda039fSThomas Faber
2408c2c66affSColin Finck if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
2409c2c66affSColin Finck return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
2410c2c66affSColin Finck
2411d9e6c9b5SThomas Faber /*
2412d9e6c9b5SThomas Faber * Prepare expected PKCS1 v1.5 encoding of hash.
2413d9e6c9b5SThomas Faber */
2414c2c66affSColin Finck
2415d9e6c9b5SThomas Faber if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL ||
2416d9e6c9b5SThomas Faber ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
2417d9e6c9b5SThomas Faber {
2418d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2419d9e6c9b5SThomas Faber goto cleanup;
2420d9e6c9b5SThomas Faber }
2421d9e6c9b5SThomas Faber
2422d9e6c9b5SThomas Faber if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
2423d9e6c9b5SThomas Faber encoded_expected ) ) != 0 )
2424d9e6c9b5SThomas Faber goto cleanup;
2425d9e6c9b5SThomas Faber
2426d9e6c9b5SThomas Faber /*
2427d9e6c9b5SThomas Faber * Apply RSA primitive to get what should be PKCS1 encoded hash.
2428d9e6c9b5SThomas Faber */
2429c2c66affSColin Finck
2430c2c66affSColin Finck ret = ( mode == MBEDTLS_RSA_PUBLIC )
2431d9e6c9b5SThomas Faber ? mbedtls_rsa_public( ctx, sig, encoded )
2432d9e6c9b5SThomas Faber : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded );
2433c2c66affSColin Finck if( ret != 0 )
2434d9e6c9b5SThomas Faber goto cleanup;
2435d9e6c9b5SThomas Faber
2436d9e6c9b5SThomas Faber /*
2437d9e6c9b5SThomas Faber * Compare
2438d9e6c9b5SThomas Faber */
2439d9e6c9b5SThomas Faber
2440d9e6c9b5SThomas Faber if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
2441d9e6c9b5SThomas Faber sig_len ) ) != 0 )
2442d9e6c9b5SThomas Faber {
2443d9e6c9b5SThomas Faber ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
2444d9e6c9b5SThomas Faber goto cleanup;
2445d9e6c9b5SThomas Faber }
2446d9e6c9b5SThomas Faber
2447d9e6c9b5SThomas Faber cleanup:
2448d9e6c9b5SThomas Faber
2449d9e6c9b5SThomas Faber if( encoded != NULL )
2450d9e6c9b5SThomas Faber {
2451*cbda039fSThomas Faber mbedtls_platform_zeroize( encoded, sig_len );
2452d9e6c9b5SThomas Faber mbedtls_free( encoded );
2453d9e6c9b5SThomas Faber }
2454d9e6c9b5SThomas Faber
2455d9e6c9b5SThomas Faber if( encoded_expected != NULL )
2456d9e6c9b5SThomas Faber {
2457*cbda039fSThomas Faber mbedtls_platform_zeroize( encoded_expected, sig_len );
2458d9e6c9b5SThomas Faber mbedtls_free( encoded_expected );
2459d9e6c9b5SThomas Faber }
2460d9e6c9b5SThomas Faber
2461c2c66affSColin Finck return( ret );
2462c2c66affSColin Finck }
2463c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
2464c2c66affSColin Finck
2465c2c66affSColin Finck /*
2466c2c66affSColin Finck * Do an RSA operation and check the message digest
2467c2c66affSColin Finck */
mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context * ctx,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,int mode,mbedtls_md_type_t md_alg,unsigned int hashlen,const unsigned char * hash,const unsigned char * sig)2468c2c66affSColin Finck int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
2469c2c66affSColin Finck int (*f_rng)(void *, unsigned char *, size_t),
2470c2c66affSColin Finck void *p_rng,
2471c2c66affSColin Finck int mode,
2472c2c66affSColin Finck mbedtls_md_type_t md_alg,
2473c2c66affSColin Finck unsigned int hashlen,
2474c2c66affSColin Finck const unsigned char *hash,
2475c2c66affSColin Finck const unsigned char *sig )
2476c2c66affSColin Finck {
2477*cbda039fSThomas Faber RSA_VALIDATE_RET( ctx != NULL );
2478*cbda039fSThomas Faber RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
2479*cbda039fSThomas Faber mode == MBEDTLS_RSA_PUBLIC );
2480*cbda039fSThomas Faber RSA_VALIDATE_RET( sig != NULL );
2481*cbda039fSThomas Faber RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
2482*cbda039fSThomas Faber hashlen == 0 ) ||
2483*cbda039fSThomas Faber hash != NULL );
2484*cbda039fSThomas Faber
2485c2c66affSColin Finck switch( ctx->padding )
2486c2c66affSColin Finck {
2487c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
2488c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V15:
2489c2c66affSColin Finck return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
2490c2c66affSColin Finck hashlen, hash, sig );
2491c2c66affSColin Finck #endif
2492c2c66affSColin Finck
2493c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V21)
2494c2c66affSColin Finck case MBEDTLS_RSA_PKCS_V21:
2495c2c66affSColin Finck return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
2496c2c66affSColin Finck hashlen, hash, sig );
2497c2c66affSColin Finck #endif
2498c2c66affSColin Finck
2499c2c66affSColin Finck default:
2500c2c66affSColin Finck return( MBEDTLS_ERR_RSA_INVALID_PADDING );
2501c2c66affSColin Finck }
2502c2c66affSColin Finck }
2503c2c66affSColin Finck
2504c2c66affSColin Finck /*
2505c2c66affSColin Finck * Copy the components of an RSA key
2506c2c66affSColin Finck */
mbedtls_rsa_copy(mbedtls_rsa_context * dst,const mbedtls_rsa_context * src)2507c2c66affSColin Finck int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
2508c2c66affSColin Finck {
2509c2c66affSColin Finck int ret;
2510*cbda039fSThomas Faber RSA_VALIDATE_RET( dst != NULL );
2511*cbda039fSThomas Faber RSA_VALIDATE_RET( src != NULL );
2512c2c66affSColin Finck
2513c2c66affSColin Finck dst->len = src->len;
2514c2c66affSColin Finck
2515c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
2516c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
2517c2c66affSColin Finck
2518c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
2519c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
2520c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
2521d9e6c9b5SThomas Faber
2522d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
2523c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
2524c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
2525c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
2526c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
2527c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
2528d9e6c9b5SThomas Faber #endif
2529d9e6c9b5SThomas Faber
2530d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
2531c2c66affSColin Finck
2532c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
2533c2c66affSColin Finck MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
2534c2c66affSColin Finck
2535c2c66affSColin Finck dst->padding = src->padding;
2536c2c66affSColin Finck dst->hash_id = src->hash_id;
2537c2c66affSColin Finck
2538c2c66affSColin Finck cleanup:
2539c2c66affSColin Finck if( ret != 0 )
2540c2c66affSColin Finck mbedtls_rsa_free( dst );
2541c2c66affSColin Finck
2542c2c66affSColin Finck return( ret );
2543c2c66affSColin Finck }
2544c2c66affSColin Finck
2545c2c66affSColin Finck /*
2546c2c66affSColin Finck * Free the components of an RSA key
2547c2c66affSColin Finck */
mbedtls_rsa_free(mbedtls_rsa_context * ctx)2548c2c66affSColin Finck void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
2549c2c66affSColin Finck {
2550*cbda039fSThomas Faber if( ctx == NULL )
2551*cbda039fSThomas Faber return;
2552*cbda039fSThomas Faber
2553*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->Vi );
2554*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->Vf );
2555*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->RN );
2556*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->D );
2557*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->Q );
2558*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->P );
2559*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->E );
2560*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->N );
2561c2c66affSColin Finck
2562d9e6c9b5SThomas Faber #if !defined(MBEDTLS_RSA_NO_CRT)
2563*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->RQ );
2564*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->RP );
2565*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->QP );
2566*cbda039fSThomas Faber mbedtls_mpi_free( &ctx->DQ );
2567d9e6c9b5SThomas Faber mbedtls_mpi_free( &ctx->DP );
2568d9e6c9b5SThomas Faber #endif /* MBEDTLS_RSA_NO_CRT */
2569d9e6c9b5SThomas Faber
2570c2c66affSColin Finck #if defined(MBEDTLS_THREADING_C)
2571a01a8faaSThomas Faber /* Free the mutex, but only if it hasn't been freed already. */
2572a01a8faaSThomas Faber if( ctx->ver != 0 )
2573a01a8faaSThomas Faber {
2574c2c66affSColin Finck mbedtls_mutex_free( &ctx->mutex );
2575a01a8faaSThomas Faber ctx->ver = 0;
2576a01a8faaSThomas Faber }
2577c2c66affSColin Finck #endif
2578c2c66affSColin Finck }
2579c2c66affSColin Finck
2580d9e6c9b5SThomas Faber #endif /* !MBEDTLS_RSA_ALT */
2581d9e6c9b5SThomas Faber
2582c2c66affSColin Finck #if defined(MBEDTLS_SELF_TEST)
2583c2c66affSColin Finck
2584c2c66affSColin Finck #include "mbedtls/sha1.h"
2585c2c66affSColin Finck
2586c2c66affSColin Finck /*
2587c2c66affSColin Finck * Example RSA-1024 keypair, for test purposes
2588c2c66affSColin Finck */
2589c2c66affSColin Finck #define KEY_LEN 128
2590c2c66affSColin Finck
2591c2c66affSColin Finck #define RSA_N "9292758453063D803DD603D5E777D788" \
2592c2c66affSColin Finck "8ED1D5BF35786190FA2F23EBC0848AEA" \
2593c2c66affSColin Finck "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
2594c2c66affSColin Finck "7130B9CED7ACDF54CFC7555AC14EEBAB" \
2595c2c66affSColin Finck "93A89813FBF3C4F8066D2D800F7C38A8" \
2596c2c66affSColin Finck "1AE31942917403FF4946B0A83D3D3E05" \
2597c2c66affSColin Finck "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
2598c2c66affSColin Finck "5E94BB77B07507233A0BC7BAC8F90F79"
2599c2c66affSColin Finck
2600c2c66affSColin Finck #define RSA_E "10001"
2601c2c66affSColin Finck
2602c2c66affSColin Finck #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
2603c2c66affSColin Finck "66CA472BC44D253102F8B4A9D3BFA750" \
2604c2c66affSColin Finck "91386C0077937FE33FA3252D28855837" \
2605c2c66affSColin Finck "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
2606c2c66affSColin Finck "DF79C5CE07EE72C7F123142198164234" \
2607c2c66affSColin Finck "CABB724CF78B8173B9F880FC86322407" \
2608c2c66affSColin Finck "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
2609c2c66affSColin Finck "071513A1E85B5DFA031F21ECAE91A34D"
2610c2c66affSColin Finck
2611c2c66affSColin Finck #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
2612c2c66affSColin Finck "2C01CAD19EA484A87EA4377637E75500" \
2613c2c66affSColin Finck "FCB2005C5C7DD6EC4AC023CDA285D796" \
2614c2c66affSColin Finck "C3D9E75E1EFC42488BB4F1D13AC30A57"
2615c2c66affSColin Finck
2616c2c66affSColin Finck #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
2617c2c66affSColin Finck "E211C2B9E5DB1ED0BF61D0D9899620F4" \
2618c2c66affSColin Finck "910E4168387E3C30AA1E00C339A79508" \
2619c2c66affSColin Finck "8452DD96A9A5EA5D9DCA68DA636032AF"
2620c2c66affSColin Finck
2621c2c66affSColin Finck #define PT_LEN 24
2622c2c66affSColin Finck #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
2623c2c66affSColin Finck "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
2624c2c66affSColin Finck
2625c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
myrand(void * rng_state,unsigned char * output,size_t len)2626c2c66affSColin Finck static int myrand( void *rng_state, unsigned char *output, size_t len )
2627c2c66affSColin Finck {
2628218e2596SThomas Faber #if !defined(__OpenBSD__) && !defined(__NetBSD__)
2629c2c66affSColin Finck size_t i;
2630c2c66affSColin Finck
2631c2c66affSColin Finck if( rng_state != NULL )
2632c2c66affSColin Finck rng_state = NULL;
2633c2c66affSColin Finck
2634c2c66affSColin Finck for( i = 0; i < len; ++i )
2635c2c66affSColin Finck output[i] = rand();
2636c2c66affSColin Finck #else
2637c2c66affSColin Finck if( rng_state != NULL )
2638c2c66affSColin Finck rng_state = NULL;
2639c2c66affSColin Finck
2640c2c66affSColin Finck arc4random_buf( output, len );
2641218e2596SThomas Faber #endif /* !OpenBSD && !NetBSD */
2642c2c66affSColin Finck
2643c2c66affSColin Finck return( 0 );
2644c2c66affSColin Finck }
2645c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
2646c2c66affSColin Finck
2647c2c66affSColin Finck /*
2648c2c66affSColin Finck * Checkup routine
2649c2c66affSColin Finck */
mbedtls_rsa_self_test(int verbose)2650c2c66affSColin Finck int mbedtls_rsa_self_test( int verbose )
2651c2c66affSColin Finck {
2652c2c66affSColin Finck int ret = 0;
2653c2c66affSColin Finck #if defined(MBEDTLS_PKCS1_V15)
2654c2c66affSColin Finck size_t len;
2655c2c66affSColin Finck mbedtls_rsa_context rsa;
2656c2c66affSColin Finck unsigned char rsa_plaintext[PT_LEN];
2657c2c66affSColin Finck unsigned char rsa_decrypted[PT_LEN];
2658c2c66affSColin Finck unsigned char rsa_ciphertext[KEY_LEN];
2659c2c66affSColin Finck #if defined(MBEDTLS_SHA1_C)
2660c2c66affSColin Finck unsigned char sha1sum[20];
2661c2c66affSColin Finck #endif
2662c2c66affSColin Finck
2663d9e6c9b5SThomas Faber mbedtls_mpi K;
2664d9e6c9b5SThomas Faber
2665d9e6c9b5SThomas Faber mbedtls_mpi_init( &K );
2666c2c66affSColin Finck mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
2667c2c66affSColin Finck
2668d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
2669d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
2670d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
2671d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
2672d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
2673d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
2674d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
2675d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
2676d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
2677d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
2678d9e6c9b5SThomas Faber
2679d9e6c9b5SThomas Faber MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
2680c2c66affSColin Finck
2681c2c66affSColin Finck if( verbose != 0 )
2682c2c66affSColin Finck mbedtls_printf( " RSA key validation: " );
2683c2c66affSColin Finck
2684c2c66affSColin Finck if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
2685c2c66affSColin Finck mbedtls_rsa_check_privkey( &rsa ) != 0 )
2686c2c66affSColin Finck {
2687c2c66affSColin Finck if( verbose != 0 )
2688c2c66affSColin Finck mbedtls_printf( "failed\n" );
2689c2c66affSColin Finck
2690d9e6c9b5SThomas Faber ret = 1;
2691d9e6c9b5SThomas Faber goto cleanup;
2692c2c66affSColin Finck }
2693c2c66affSColin Finck
2694c2c66affSColin Finck if( verbose != 0 )
2695c2c66affSColin Finck mbedtls_printf( "passed\n PKCS#1 encryption : " );
2696c2c66affSColin Finck
2697c2c66affSColin Finck memcpy( rsa_plaintext, RSA_PT, PT_LEN );
2698c2c66affSColin Finck
2699d9e6c9b5SThomas Faber if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
2700d9e6c9b5SThomas Faber PT_LEN, rsa_plaintext,
2701d9e6c9b5SThomas Faber rsa_ciphertext ) != 0 )
2702c2c66affSColin Finck {
2703c2c66affSColin Finck if( verbose != 0 )
2704c2c66affSColin Finck mbedtls_printf( "failed\n" );
2705c2c66affSColin Finck
2706d9e6c9b5SThomas Faber ret = 1;
2707d9e6c9b5SThomas Faber goto cleanup;
2708c2c66affSColin Finck }
2709c2c66affSColin Finck
2710c2c66affSColin Finck if( verbose != 0 )
2711c2c66affSColin Finck mbedtls_printf( "passed\n PKCS#1 decryption : " );
2712c2c66affSColin Finck
2713d9e6c9b5SThomas Faber if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
2714d9e6c9b5SThomas Faber &len, rsa_ciphertext, rsa_decrypted,
2715c2c66affSColin Finck sizeof(rsa_decrypted) ) != 0 )
2716c2c66affSColin Finck {
2717c2c66affSColin Finck if( verbose != 0 )
2718c2c66affSColin Finck mbedtls_printf( "failed\n" );
2719c2c66affSColin Finck
2720d9e6c9b5SThomas Faber ret = 1;
2721d9e6c9b5SThomas Faber goto cleanup;
2722c2c66affSColin Finck }
2723c2c66affSColin Finck
2724c2c66affSColin Finck if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
2725c2c66affSColin Finck {
2726c2c66affSColin Finck if( verbose != 0 )
2727c2c66affSColin Finck mbedtls_printf( "failed\n" );
2728c2c66affSColin Finck
2729d9e6c9b5SThomas Faber ret = 1;
2730d9e6c9b5SThomas Faber goto cleanup;
2731c2c66affSColin Finck }
2732c2c66affSColin Finck
2733c2c66affSColin Finck if( verbose != 0 )
2734c2c66affSColin Finck mbedtls_printf( "passed\n" );
2735c2c66affSColin Finck
2736c2c66affSColin Finck #if defined(MBEDTLS_SHA1_C)
2737c2c66affSColin Finck if( verbose != 0 )
2738c2c66affSColin Finck mbedtls_printf( " PKCS#1 data sign : " );
2739c2c66affSColin Finck
2740d9e6c9b5SThomas Faber if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
2741c2c66affSColin Finck {
2742c2c66affSColin Finck if( verbose != 0 )
2743c2c66affSColin Finck mbedtls_printf( "failed\n" );
2744c2c66affSColin Finck
2745c2c66affSColin Finck return( 1 );
2746c2c66affSColin Finck }
2747c2c66affSColin Finck
2748d9e6c9b5SThomas Faber if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
2749d9e6c9b5SThomas Faber MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
2750c2c66affSColin Finck sha1sum, rsa_ciphertext ) != 0 )
2751c2c66affSColin Finck {
2752c2c66affSColin Finck if( verbose != 0 )
2753c2c66affSColin Finck mbedtls_printf( "failed\n" );
2754c2c66affSColin Finck
2755d9e6c9b5SThomas Faber ret = 1;
2756d9e6c9b5SThomas Faber goto cleanup;
2757d9e6c9b5SThomas Faber }
2758d9e6c9b5SThomas Faber
2759d9e6c9b5SThomas Faber if( verbose != 0 )
2760d9e6c9b5SThomas Faber mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
2761d9e6c9b5SThomas Faber
2762d9e6c9b5SThomas Faber if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
2763d9e6c9b5SThomas Faber MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
2764d9e6c9b5SThomas Faber sha1sum, rsa_ciphertext ) != 0 )
2765d9e6c9b5SThomas Faber {
2766d9e6c9b5SThomas Faber if( verbose != 0 )
2767d9e6c9b5SThomas Faber mbedtls_printf( "failed\n" );
2768d9e6c9b5SThomas Faber
2769d9e6c9b5SThomas Faber ret = 1;
2770d9e6c9b5SThomas Faber goto cleanup;
2771c2c66affSColin Finck }
2772c2c66affSColin Finck
2773c2c66affSColin Finck if( verbose != 0 )
2774c2c66affSColin Finck mbedtls_printf( "passed\n" );
2775c2c66affSColin Finck #endif /* MBEDTLS_SHA1_C */
2776c2c66affSColin Finck
2777c2c66affSColin Finck if( verbose != 0 )
2778c2c66affSColin Finck mbedtls_printf( "\n" );
2779c2c66affSColin Finck
2780c2c66affSColin Finck cleanup:
2781d9e6c9b5SThomas Faber mbedtls_mpi_free( &K );
2782c2c66affSColin Finck mbedtls_rsa_free( &rsa );
2783c2c66affSColin Finck #else /* MBEDTLS_PKCS1_V15 */
2784c2c66affSColin Finck ((void) verbose);
2785c2c66affSColin Finck #endif /* MBEDTLS_PKCS1_V15 */
2786c2c66affSColin Finck return( ret );
2787c2c66affSColin Finck }
2788c2c66affSColin Finck
2789c2c66affSColin Finck #endif /* MBEDTLS_SELF_TEST */
2790c2c66affSColin Finck
2791c2c66affSColin Finck #endif /* MBEDTLS_RSA_C */
2792