blob: 1f907b7645bed8341728688af26497c4d23b10a6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * The RSA public-key cryptosystem
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
23 *
24 * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_RSA_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/rsa.h"
37#include "mbedtls/oid.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_PKCS1_V21)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/md.h"
Paul Bakkerbb51f0c2012-08-23 07:46:58 +000043#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
Paul Bakker5121ce52009-01-03 21:22:43 +000046#include <stdlib.h>
Rich Evans00ab4702015-02-06 13:43:58 +000047#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010051#else
Rich Evans00ab4702015-02-06 13:43:58 +000052#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_printf printf
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +020054#define mbedtls_calloc calloc
55#define mbedtls_free free
Paul Bakker7dc4c442014-02-01 22:50:26 +010056#endif
57
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * Initialize an RSA context
60 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +000062 int padding,
Paul Bakker21eb2802010-08-16 11:10:02 +000063 int hash_id )
Paul Bakker5121ce52009-01-03 21:22:43 +000064{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +000066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067 mbedtls_rsa_set_padding( ctx, padding, hash_id );
Paul Bakkerc9965dc2013-09-29 14:58:17 +020068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_THREADING_C)
70 mbedtls_mutex_init( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +020071#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000072}
73
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +010074/*
75 * Set padding for an existing RSA context
76 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
Manuel Pégourié-Gonnard844a4c02014-03-10 21:55:35 +010078{
79 ctx->padding = padding;
80 ctx->hash_id = hash_id;
81}
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083#if defined(MBEDTLS_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000084
85/*
86 * Generate an RSA keypair
87 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +000089 int (*f_rng)(void *, unsigned char *, size_t),
90 void *p_rng,
91 unsigned int nbits, int exponent )
Paul Bakker5121ce52009-01-03 21:22:43 +000092{
93 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020094 mbedtls_mpi P1, Q1, H, G;
Paul Bakker5121ce52009-01-03 21:22:43 +000095
Paul Bakker21eb2802010-08-16 11:10:02 +000096 if( f_rng == NULL || nbits < 128 || exponent < 3 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
101 /*
102 * find primes P and Q with Q < P so that:
103 * GCD( E, (P-1)*(Q-1) ) == 1
104 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107 do
108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
Paul Bakker21eb2802010-08-16 11:10:02 +0000110 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
Paul Bakker21eb2802010-08-16 11:10:02 +0000113 f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
116 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000119 continue;
120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200122 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 continue;
124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
126 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
127 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
128 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000129 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200130 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000131
132 /*
133 * D = E^-1 mod ((P-1)*(Q-1))
134 * DP = D mod (P - 1)
135 * DQ = D mod (Q - 1)
136 * QP = Q^-1 mod P
137 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
139 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
140 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
141 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200143 ctx->len = ( mbedtls_mpi_bitlen( &ctx->N ) + 7 ) >> 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
145cleanup:
146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
149 if( ret != 0 )
150 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151 mbedtls_rsa_free( ctx );
152 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000153 }
154
Paul Bakker48377d92013-08-30 12:06:24 +0200155 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156}
157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +0000159
160/*
161 * Check a public RSA key
162 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000164{
Paul Bakker37940d92009-07-10 22:38:58 +0000165 if( !ctx->N.p || !ctx->E.p )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d92009-07-10 22:38:58 +0000167
Paul Bakker48377d92013-08-30 12:06:24 +0200168 if( ( ctx->N.p[0] & 1 ) == 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000169 ( ctx->E.p[0] & 1 ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200172 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 ||
173 mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000175
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200176 if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
178 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000179
180 return( 0 );
181}
182
183/*
184 * Check a private RSA key
185 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000187{
188 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;
Paul Bakker5121ce52009-01-03 21:22:43 +0000190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191 if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 return( ret );
193
Paul Bakker37940d92009-07-10 22:38:58 +0000194 if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Paul Bakker37940d92009-07-10 22:38:58 +0000196
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 );
198 mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I ); mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 );
199 mbedtls_mpi_init( &L1 ); mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ );
200 mbedtls_mpi_init( &QP );
Paul Bakker5121ce52009-01-03 21:22:43 +0000201
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
203 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
204 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
205 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
206 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
207 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) );
210 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) );
211 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) );
Paul Bakkerb572adf2010-07-18 08:29:32 +0000212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
214 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
215 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
Paul Bakkerb572adf2010-07-18 08:29:32 +0000216 /*
217 * Check for a valid PKCS1v2 private key
218 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219 if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
220 mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
221 mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
222 mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 ||
223 mbedtls_mpi_cmp_int( &L2, 0 ) != 0 ||
224 mbedtls_mpi_cmp_int( &I, 1 ) != 0 ||
225 mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000228 }
Paul Bakker48377d92013-08-30 12:06:24 +0200229
Paul Bakker5121ce52009-01-03 21:22:43 +0000230cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 );
232 mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I ); mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 );
233 mbedtls_mpi_free( &L1 ); mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ );
234 mbedtls_mpi_free( &QP );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
Paul Bakker9d781402011-05-09 16:17:09 +0000237 return( ret );
238
Paul Bakker6c591fa2011-05-05 11:49:20 +0000239 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000241
242 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000243}
244
245/*
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100246 * Check if contexts holding a public and private key match
247 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100249{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
251 mbedtls_rsa_check_privkey( prv ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100252 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100254 }
255
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
257 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100258 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100260 }
261
262 return( 0 );
263}
264
265/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000266 * Do an RSA public key operation
267 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000269 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 unsigned char *output )
271{
Paul Bakker23986e52011-04-24 08:57:21 +0000272 int ret;
273 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 mbedtls_mpi T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200278#if defined(MBEDTLS_THREADING_C)
279 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
280 return( ret );
281#endif
282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200287 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
288 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000289 }
290
291 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
293 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
295cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200297 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
298 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnard88fca3e2015-03-27 15:06:07 +0100299#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
303 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
306 return( 0 );
307}
308
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200309/*
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200310 * Generate or update blinding values, see section 10 of:
311 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200312 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200313 * Berlin Heidelberg, 1996. p. 104-113.
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200314 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200315static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200316 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
317{
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200318 int ret, count = 0;
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200319
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200320 if( ctx->Vf.p != NULL )
321 {
322 /* We already have blinding values, just update them by squaring */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
324 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
325 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
326 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200327
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200328 goto cleanup;
Manuel Pégourié-Gonnard8a109f12013-09-10 13:37:26 +0200329 }
330
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200331 /* Unblinding value: Vf = random number, invertible mod N */
332 do {
333 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 return( MBEDTLS_ERR_RSA_RNG_FAILED );
Manuel Pégourié-Gonnard4d89c7e2013-10-04 15:18:38 +0200335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
337 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
338 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200339
340 /* Blinding value: Vi = Vf^(-e) mod N */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
342 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200343
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200344
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200345cleanup:
346 return( ret );
347}
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200348
Paul Bakker5121ce52009-01-03 21:22:43 +0000349/*
350 * Do an RSA private key operation
351 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200353 int (*f_rng)(void *, unsigned char *, size_t),
354 void *p_rng,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000355 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 unsigned char *output )
357{
Paul Bakker23986e52011-04-24 08:57:21 +0000358 int ret;
359 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_mpi T, T1, T2;
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Manuel Pégourié-Gonnardfb84d382015-10-30 10:56:25 +0100362 /* Make sure we have private key info, prevent possible misuse */
363 if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL )
364 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200368#if defined(MBEDTLS_THREADING_C)
369 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
370 return( ret );
371#endif
372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
374 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375 {
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200376 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
377 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 }
379
Paul Bakkerf451bac2013-08-30 15:37:02 +0200380 if( f_rng != NULL )
381 {
382 /*
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200383 * Blinding
384 * T = T * Vi mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200385 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200386 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
387 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +0200389 }
Paul Bakkeraab30c12013-08-30 11:00:25 +0200390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391#if defined(MBEDTLS_RSA_NO_CRT)
392 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
Manuel Pégourié-Gonnarde10e06d2014-11-06 18:15:12 +0100393#else
Paul Bakkeraab30c12013-08-30 11:00:25 +0200394 /*
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 * faster decryption using the CRT
396 *
397 * T1 = input ^ dP mod P
398 * T2 = input ^ dQ mod Q
399 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
401 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
403 /*
404 * T = (T1 - T2) * (Q^-1 mod P) mod P
405 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
407 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
408 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410 /*
Paul Bakkerf451bac2013-08-30 15:37:02 +0200411 * T = T2 + T * Q
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
414 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
415#endif /* MBEDTLS_RSA_NO_CRT */
Paul Bakkeraab30c12013-08-30 11:00:25 +0200416
Paul Bakkerf451bac2013-08-30 15:37:02 +0200417 if( f_rng != NULL )
418 {
419 /*
420 * Unblind
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +0200421 * T = T * Vf mod N
Paul Bakkerf451bac2013-08-30 15:37:02 +0200422 */
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200423 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
Paul Bakkerf451bac2013-08-30 15:37:02 +0200425 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431#if defined(MBEDTLS_THREADING_C)
Manuel Pégourié-Gonnard4d04cdc2015-08-28 10:32:21 +0200432 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
433 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
Manuel Pégourié-Gonnardae102992013-10-04 17:07:12 +0200434#endif
Manuel Pégourié-Gonnard1385a282015-08-27 11:30:58 +0200435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 return( 0 );
442}
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker9dcc3222011-03-08 14:16:06 +0000445/**
446 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
447 *
Paul Bakkerb125ed82011-11-10 13:33:51 +0000448 * \param dst buffer to mask
449 * \param dlen length of destination buffer
450 * \param src source of the mask generation
451 * \param slen length of the source buffer
452 * \param md_ctx message digest context to use
Paul Bakker9dcc3222011-03-08 14:16:06 +0000453 */
Paul Bakker48377d92013-08-30 12:06:24 +0200454static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 size_t slen, mbedtls_md_context_t *md_ctx )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000456{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +0000458 unsigned char counter[4];
459 unsigned char *p;
Paul Bakker23986e52011-04-24 08:57:21 +0000460 unsigned int hlen;
461 size_t i, use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000464 memset( counter, 0, 4 );
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 hlen = mbedtls_md_get_size( md_ctx->md_info );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000467
468 // Generate and apply dbMask
469 //
470 p = dst;
471
472 while( dlen > 0 )
473 {
474 use_len = hlen;
475 if( dlen < hlen )
476 use_len = dlen;
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 mbedtls_md_starts( md_ctx );
479 mbedtls_md_update( md_ctx, src, slen );
480 mbedtls_md_update( md_ctx, counter, 4 );
481 mbedtls_md_finish( md_ctx, mask );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000482
483 for( i = 0; i < use_len; ++i )
484 *p++ ^= mask[i];
485
486 counter[3]++;
487
488 dlen -= use_len;
489 }
490}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker9dcc3222011-03-08 14:16:06 +0000492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +0100494/*
495 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
496 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +0100498 int (*f_rng)(void *, unsigned char *, size_t),
499 void *p_rng,
Paul Bakkera43231c2013-02-28 17:33:49 +0100500 int mode,
501 const unsigned char *label, size_t label_len,
502 size_t ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +0100503 const unsigned char *input,
504 unsigned char *output )
505{
506 size_t olen;
507 int ret;
508 unsigned char *p = output;
509 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 const mbedtls_md_info_t *md_info;
511 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +0100512
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
514 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +0200515
516 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +0100520 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100522
523 olen = ctx->len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +0100525
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +0200526 if( olen < ilen + 2 * hlen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100528
529 memset( output, 0, olen );
530
531 *p++ = 0;
532
533 // Generate a random octet string seed
534 //
535 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +0100537
538 p += hlen;
539
540 // Construct DB
541 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 mbedtls_md( md_info, label, label_len, p );
Paul Bakkerb3869132013-02-28 17:21:01 +0100543 p += hlen;
544 p += olen - 2 * hlen - 2 - ilen;
545 *p++ = 1;
546 memcpy( p, input, ilen );
547
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548 mbedtls_md_init( &md_ctx );
549 mbedtls_md_setup( &md_ctx, md_info, 0 );
Paul Bakkerb3869132013-02-28 17:21:01 +0100550
551 // maskedDB: Apply dbMask to DB
552 //
553 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
554 &md_ctx );
555
556 // maskedSeed: Apply seedMask to seed
557 //
558 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
559 &md_ctx );
560
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +0100562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 return( ( mode == MBEDTLS_RSA_PUBLIC )
564 ? mbedtls_rsa_public( ctx, output, output )
565 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +0100566}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +0100570/*
571 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
572 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +0100574 int (*f_rng)(void *, unsigned char *, size_t),
575 void *p_rng,
576 int mode, size_t ilen,
577 const unsigned char *input,
578 unsigned char *output )
579{
580 size_t nb_pad, olen;
581 int ret;
582 unsigned char *p = output;
583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
585 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +0200586
587 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100589
590 olen = ctx->len;
591
592 if( olen < ilen + 11 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100594
595 nb_pad = olen - 3 - ilen;
596
597 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 if( mode == MBEDTLS_RSA_PUBLIC )
Paul Bakkerb3869132013-02-28 17:21:01 +0100599 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 *p++ = MBEDTLS_RSA_CRYPT;
Paul Bakkerb3869132013-02-28 17:21:01 +0100601
602 while( nb_pad-- > 0 )
603 {
604 int rng_dl = 100;
605
606 do {
607 ret = f_rng( p_rng, p, 1 );
608 } while( *p == 0 && --rng_dl && ret == 0 );
609
610 // Check if RNG failed to generate data
611 //
Paul Bakker66d5d072014-06-17 16:39:18 +0200612 if( rng_dl == 0 || ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +0100614
615 p++;
616 }
617 }
618 else
619 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +0100621
622 while( nb_pad-- > 0 )
623 *p++ = 0xFF;
624 }
625
626 *p++ = 0;
627 memcpy( p, input, ilen );
628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 return( ( mode == MBEDTLS_RSA_PUBLIC )
630 ? mbedtls_rsa_public( ctx, output, output )
631 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
Paul Bakkerb3869132013-02-28 17:21:01 +0100632}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100634
Paul Bakker5121ce52009-01-03 21:22:43 +0000635/*
636 * Add the message padding, then do an RSA operation
637 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000639 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker21eb2802010-08-16 11:10:02 +0000640 void *p_rng,
Paul Bakker23986e52011-04-24 08:57:21 +0000641 int mode, size_t ilen,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000642 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +0000643 unsigned char *output )
644{
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 switch( ctx->padding )
646 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#if defined(MBEDTLS_PKCS1_V15)
648 case MBEDTLS_RSA_PKCS_V15:
649 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
Paul Bakkerb3869132013-02-28 17:21:01 +0100650 input, output );
Paul Bakker48377d92013-08-30 12:06:24 +0200651#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#if defined(MBEDTLS_PKCS1_V21)
654 case MBEDTLS_RSA_PKCS_V21:
655 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakkerb3869132013-02-28 17:21:01 +0100656 ilen, input, output );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000657#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
659 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000662}
663
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +0000665/*
Paul Bakkerb3869132013-02-28 17:21:01 +0100666 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200669 int (*f_rng)(void *, unsigned char *, size_t),
670 void *p_rng,
671 int mode,
Paul Bakkera43231c2013-02-28 17:33:49 +0100672 const unsigned char *label, size_t label_len,
673 size_t *olen,
Paul Bakkerb3869132013-02-28 17:21:01 +0100674 const unsigned char *input,
675 unsigned char *output,
676 size_t output_max_len )
Paul Bakker5121ce52009-01-03 21:22:43 +0000677{
Paul Bakker23986e52011-04-24 08:57:21 +0000678 int ret;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100679 size_t ilen, i, pad_len;
680 unsigned char *p, bad, pad_done;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
682 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
Paul Bakker23986e52011-04-24 08:57:21 +0000683 unsigned int hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 const mbedtls_md_info_t *md_info;
685 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +0100686
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100687 /*
688 * Parameters sanity checks
689 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
691 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693 ilen = ctx->len;
694
Paul Bakker27fdf462011-06-09 13:55:13 +0000695 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200696 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100699 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100701
702 /*
703 * RSA operation
704 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 ret = ( mode == MBEDTLS_RSA_PUBLIC )
706 ? mbedtls_rsa_public( ctx, input, buf )
707 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 if( ret != 0 )
710 return( ret );
711
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100712 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100713 * Unmask data and generate lHash
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100714 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200715 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 mbedtls_md_init( &md_ctx );
718 mbedtls_md_setup( &md_ctx, md_info, 0 );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100719
720 /* Generate lHash */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 mbedtls_md( md_info, label, label_len, lhash );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100722
723 /* seed: Apply seedMask to maskedSeed */
724 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
725 &md_ctx );
726
727 /* DB: Apply dbMask to maskedDB */
728 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
729 &md_ctx );
730
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 mbedtls_md_free( &md_ctx );
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100732
733 /*
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100734 * Check contents, in "constant-time"
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100735 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000736 p = buf;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100737 bad = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100739 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100740
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100741 p += hlen; /* Skip seed */
Paul Bakkerb3869132013-02-28 17:21:01 +0100742
Manuel Pégourié-Gonnarda5cfc352013-11-28 15:57:52 +0100743 /* Check lHash */
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100744 for( i = 0; i < hlen; i++ )
745 bad |= lhash[i] ^ *p++;
Paul Bakkerb3869132013-02-28 17:21:01 +0100746
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100747 /* Get zero-padding len, but always read till end of buffer
748 * (minus one, for the 01 byte) */
749 pad_len = 0;
750 pad_done = 0;
751 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
752 {
753 pad_done |= p[i];
Pascal Junodb99183d2015-03-11 16:49:45 +0100754 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100755 }
Paul Bakkerb3869132013-02-28 17:21:01 +0100756
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100757 p += pad_len;
758 bad |= *p++ ^ 0x01;
Paul Bakkerb3869132013-02-28 17:21:01 +0100759
Manuel Pégourié-Gonnardab44d7e2013-11-29 12:49:44 +0100760 /*
761 * The only information "leaked" is whether the padding was correct or not
762 * (eg, no data is copied if it was not correct). This meets the
763 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
764 * the different error conditions.
765 */
766 if( bad != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +0100768
Paul Bakker66d5d072014-06-17 16:39:18 +0200769 if( ilen - ( p - buf ) > output_max_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Paul Bakkerb3869132013-02-28 17:21:01 +0100771
772 *olen = ilen - (p - buf);
773 memcpy( output, p, *olen );
774
775 return( 0 );
776}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +0100780/*
781 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
782 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200784 int (*f_rng)(void *, unsigned char *, size_t),
785 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +0100786 int mode, size_t *olen,
787 const unsigned char *input,
788 unsigned char *output,
789 size_t output_max_len)
790{
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100791 int ret;
792 size_t ilen, pad_count = 0, i;
793 unsigned char *p, bad, pad_done = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +0100795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
797 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100798
799 ilen = ctx->len;
800
801 if( ilen < 16 || ilen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100803
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804 ret = ( mode == MBEDTLS_RSA_PUBLIC )
805 ? mbedtls_rsa_public( ctx, input, buf )
806 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +0100807
808 if( ret != 0 )
809 return( ret );
810
811 p = buf;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100812 bad = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +0100813
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100814 /*
815 * Check and get padding len in "constant-time"
816 */
817 bad |= *p++; /* First byte must be 0 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100818
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100819 /* This test does not depend on secret data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 if( mode == MBEDTLS_RSA_PRIVATE )
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100824 /* Get padding len, but always read till end of buffer
825 * (minus one, for the 00 byte) */
826 for( i = 0; i < ilen - 3; i++ )
827 {
Pascal Junodb99183d2015-03-11 16:49:45 +0100828 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
829 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100830 }
Paul Bakkere6ee41f2012-05-19 08:43:48 +0000831
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100832 p += pad_count;
833 bad |= *p++; /* Must be zero */
Paul Bakkerb3869132013-02-28 17:21:01 +0100834 }
835 else
836 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +0100838
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100839 /* Get padding len, but always read till end of buffer
840 * (minus one, for the 00 byte) */
841 for( i = 0; i < ilen - 3; i++ )
842 {
Manuel Pégourié-Gonnardfbf09152014-02-03 11:58:55 +0100843 pad_done |= ( p[i] != 0xFF );
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100844 pad_count += ( pad_done == 0 );
845 }
Paul Bakkerb3869132013-02-28 17:21:01 +0100846
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100847 p += pad_count;
848 bad |= *p++; /* Must be zero */
Paul Bakker5121ce52009-01-03 21:22:43 +0000849 }
850
Manuel Pégourié-Gonnard27290da2013-11-30 13:36:53 +0100851 if( bad )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker8804f692013-02-28 18:06:26 +0100853
Paul Bakker66d5d072014-06-17 16:39:18 +0200854 if( ilen - ( p - buf ) > output_max_len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
Paul Bakker060c5682009-01-12 21:48:39 +0000856
Paul Bakker27fdf462011-06-09 13:55:13 +0000857 *olen = ilen - (p - buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000858 memcpy( output, p, *olen );
859
860 return( 0 );
861}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
864/*
Paul Bakkerb3869132013-02-28 17:21:01 +0100865 * Do an RSA operation, then remove the message padding
866 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +0200868 int (*f_rng)(void *, unsigned char *, size_t),
869 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +0100870 int mode, size_t *olen,
871 const unsigned char *input,
872 unsigned char *output,
873 size_t output_max_len)
874{
875 switch( ctx->padding )
876 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877#if defined(MBEDTLS_PKCS1_V15)
878 case MBEDTLS_RSA_PKCS_V15:
879 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
Paul Bakker548957d2013-08-30 10:30:02 +0200880 input, output, output_max_len );
Paul Bakker48377d92013-08-30 12:06:24 +0200881#endif
Paul Bakkerb3869132013-02-28 17:21:01 +0100882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883#if defined(MBEDTLS_PKCS1_V21)
884 case MBEDTLS_RSA_PKCS_V21:
885 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
Paul Bakker548957d2013-08-30 10:30:02 +0200886 olen, input, output,
887 output_max_len );
Paul Bakkerb3869132013-02-28 17:21:01 +0100888#endif
889
890 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +0100892 }
893}
894
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895#if defined(MBEDTLS_PKCS1_V21)
Paul Bakkerb3869132013-02-28 17:21:01 +0100896/*
897 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
898 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
Paul Bakkerb3869132013-02-28 17:21:01 +0100900 int (*f_rng)(void *, unsigned char *, size_t),
901 void *p_rng,
902 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +0100904 unsigned int hashlen,
905 const unsigned char *hash,
906 unsigned char *sig )
907{
908 size_t olen;
909 unsigned char *p = sig;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
Paul Bakkerb3869132013-02-28 17:21:01 +0100911 unsigned int slen, hlen, offset = 0;
912 int ret;
913 size_t msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 const mbedtls_md_info_t *md_info;
915 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +0100916
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
918 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6d1d822014-06-02 16:47:02 +0200919
920 if( f_rng == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100922
923 olen = ctx->len;
924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +0100926 {
Paul Bakkerc70b9822013-04-07 22:00:46 +0200927 // Gather length of hash to sign
928 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +0200930 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +0200932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +0100934 }
935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +0100937 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940 hlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +0100941 slen = hlen;
942
943 if( olen < hlen + slen + 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +0100945
946 memset( sig, 0, olen );
947
Paul Bakkerb3869132013-02-28 17:21:01 +0100948 // Generate salt of length slen
949 //
950 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
Paul Bakkerb3869132013-02-28 17:21:01 +0100952
953 // Note: EMSA-PSS encoding is over the length of N - 1 bits
954 //
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200955 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +0100956 p += olen - hlen * 2 - 2;
957 *p++ = 0x01;
958 memcpy( p, salt, slen );
959 p += slen;
960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_md_init( &md_ctx );
962 mbedtls_md_setup( &md_ctx, md_info, 0 );
Paul Bakkerb3869132013-02-28 17:21:01 +0100963
964 // Generate H = Hash( M' )
965 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_md_starts( &md_ctx );
967 mbedtls_md_update( &md_ctx, p, 8 );
968 mbedtls_md_update( &md_ctx, hash, hashlen );
969 mbedtls_md_update( &md_ctx, salt, slen );
970 mbedtls_md_finish( &md_ctx, p );
Paul Bakkerb3869132013-02-28 17:21:01 +0100971
972 // Compensate for boundary condition when applying mask
973 //
974 if( msb % 8 == 0 )
975 offset = 1;
976
977 // maskedDB: Apply dbMask to DB
978 //
979 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 mbedtls_md_free( &md_ctx );
Paul Bakkerb3869132013-02-28 17:21:01 +0100982
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200983 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakkerb3869132013-02-28 17:21:01 +0100984 sig[0] &= 0xFF >> ( olen * 8 - msb );
985
986 p += hlen;
987 *p++ = 0xBC;
988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 return( ( mode == MBEDTLS_RSA_PUBLIC )
990 ? mbedtls_rsa_public( ctx, sig, sig )
991 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
Paul Bakkerb3869132013-02-28 17:21:01 +0100992}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakkerb3869132013-02-28 17:21:01 +0100994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +0100996/*
997 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
998 */
999/*
1000 * Do an RSA operation to sign the message digest
1001 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001003 int (*f_rng)(void *, unsigned char *, size_t),
1004 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001005 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001007 unsigned int hashlen,
1008 const unsigned char *hash,
1009 unsigned char *sig )
1010{
Paul Bakkerc70b9822013-04-07 22:00:46 +02001011 size_t nb_pad, olen, oid_size = 0;
Paul Bakkerb3869132013-02-28 17:21:01 +01001012 unsigned char *p = sig;
Paul Bakker21e081b2014-07-24 10:38:01 +02001013 const char *oid = NULL;
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001014 unsigned char *sig_try = NULL, *verif = NULL;
1015 size_t i;
1016 unsigned char diff;
1017 volatile unsigned char diff_no_optimize;
1018 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1021 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001022
1023 olen = ctx->len;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001024 nb_pad = olen - 3;
Paul Bakkerb3869132013-02-28 17:21:01 +01001025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001027 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001029 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
1033 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001034
Paul Bakkerc70b9822013-04-07 22:00:46 +02001035 nb_pad -= 10 + oid_size;
1036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001038 }
1039
Paul Bakkerc70b9822013-04-07 22:00:46 +02001040 nb_pad -= hashlen;
1041
Paul Bakkerb3869132013-02-28 17:21:01 +01001042 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001044
1045 *p++ = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 *p++ = MBEDTLS_RSA_SIGN;
Paul Bakkerb3869132013-02-28 17:21:01 +01001047 memset( p, 0xFF, nb_pad );
1048 p += nb_pad;
1049 *p++ = 0;
1050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 if( md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001052 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001053 memcpy( p, hash, hashlen );
1054 }
1055 else
1056 {
1057 /*
1058 * DigestInfo ::= SEQUENCE {
1059 * digestAlgorithm DigestAlgorithmIdentifier,
1060 * digest Digest }
1061 *
1062 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
1063 *
1064 * Digest ::= OCTET STRING
1065 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001067 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001069 *p++ = (unsigned char) ( 0x04 + oid_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 *p++ = MBEDTLS_ASN1_OID;
Paul Bakkerb9cfaa02013-10-11 18:58:55 +02001071 *p++ = oid_size & 0xFF;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001072 memcpy( p, oid, oid_size );
1073 p += oid_size;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074 *p++ = MBEDTLS_ASN1_NULL;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001075 *p++ = 0x00;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076 *p++ = MBEDTLS_ASN1_OCTET_STRING;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001077 *p++ = hashlen;
1078 memcpy( p, hash, hashlen );
Paul Bakkerb3869132013-02-28 17:21:01 +01001079 }
1080
Manuel Pégourié-Gonnard5f501042015-09-03 20:03:15 +02001081 if( mode == MBEDTLS_RSA_PUBLIC )
1082 return( mbedtls_rsa_public( ctx, sig, sig ) );
1083
1084 /*
1085 * In order to prevent Lenstra's attack, make the signature in a
1086 * temporary buffer and check it before returning it.
1087 */
1088 sig_try = mbedtls_calloc( 1, ctx->len );
1089 verif = mbedtls_calloc( 1, ctx->len );
1090 if( sig_try == NULL || verif == NULL )
1091 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
1092
1093 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
1094 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
1095
1096 /* Compare in constant time just in case */
1097 for( diff = 0, i = 0; i < ctx->len; i++ )
1098 diff |= verif[i] ^ sig[i];
1099 diff_no_optimize = diff;
1100
1101 if( diff_no_optimize != 0 )
1102 {
1103 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
1104 goto cleanup;
1105 }
1106
1107 memcpy( sig, sig_try, ctx->len );
1108
1109cleanup:
1110 mbedtls_free( sig_try );
1111 mbedtls_free( verif );
1112
1113 return( ret );
Paul Bakkerb3869132013-02-28 17:21:01 +01001114}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakkerb3869132013-02-28 17:21:01 +01001116
1117/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001118 * Do an RSA operation to sign the message digest
1119 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
Paul Bakkera3d195c2011-11-27 21:07:34 +00001121 int (*f_rng)(void *, unsigned char *, size_t),
Paul Bakker9dcc3222011-03-08 14:16:06 +00001122 void *p_rng,
Paul Bakker5121ce52009-01-03 21:22:43 +00001123 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124 mbedtls_md_type_t md_alg,
Paul Bakker23986e52011-04-24 08:57:21 +00001125 unsigned int hashlen,
Paul Bakkerff60ee62010-03-16 21:09:09 +00001126 const unsigned char *hash,
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 unsigned char *sig )
1128{
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 switch( ctx->padding )
1130 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131#if defined(MBEDTLS_PKCS1_V15)
1132 case MBEDTLS_RSA_PKCS_V15:
1133 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001134 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001135#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137#if defined(MBEDTLS_PKCS1_V21)
1138 case MBEDTLS_RSA_PKCS_V21:
1139 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001140 hashlen, hash, sig );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001141#endif
1142
Paul Bakker5121ce52009-01-03 21:22:43 +00001143 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001146}
1147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148#if defined(MBEDTLS_PKCS1_V21)
Paul Bakker5121ce52009-01-03 21:22:43 +00001149/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001150 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001153 int (*f_rng)(void *, unsigned char *, size_t),
1154 void *p_rng,
1155 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001156 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001157 unsigned int hashlen,
1158 const unsigned char *hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159 mbedtls_md_type_t mgf1_hash_id,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001160 int expected_salt_len,
1161 const unsigned char *sig )
Paul Bakker5121ce52009-01-03 21:22:43 +00001162{
Paul Bakker23986e52011-04-24 08:57:21 +00001163 int ret;
Paul Bakkerb3869132013-02-28 17:21:01 +01001164 size_t siglen;
1165 unsigned char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1167 unsigned char result[MBEDTLS_MD_MAX_SIZE];
Paul Bakker9dcc3222011-03-08 14:16:06 +00001168 unsigned char zeros[8];
Paul Bakker23986e52011-04-24 08:57:21 +00001169 unsigned int hlen;
1170 size_t slen, msb;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171 const mbedtls_md_info_t *md_info;
1172 mbedtls_md_context_t md_ctx;
Paul Bakkerb3869132013-02-28 17:21:01 +01001173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
1175 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001176
Paul Bakker5121ce52009-01-03 21:22:43 +00001177 siglen = ctx->len;
1178
Paul Bakker27fdf462011-06-09 13:55:13 +00001179 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1183 ? mbedtls_rsa_public( ctx, sig, buf )
1184 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
1186 if( ret != 0 )
1187 return( ret );
1188
1189 p = buf;
1190
Paul Bakkerb3869132013-02-28 17:21:01 +01001191 if( buf[siglen - 1] != 0xBC )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001193
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001194 if( md_alg != MBEDTLS_MD_NONE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001195 {
Paul Bakkerc70b9822013-04-07 22:00:46 +02001196 // Gather length of hash to sign
1197 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001199 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001200 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001201
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001202 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerb3869132013-02-28 17:21:01 +01001203 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
Paul Bakkerb3869132013-02-28 17:21:01 +01001206 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209 hlen = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001210 slen = siglen - hlen - 1; /* Currently length of salt + padding */
Paul Bakker9dcc3222011-03-08 14:16:06 +00001211
Paul Bakkerb3869132013-02-28 17:21:01 +01001212 memset( zeros, 0, 8 );
Paul Bakker53019ae2011-03-25 13:58:48 +00001213
Paul Bakkerb3869132013-02-28 17:21:01 +01001214 // Note: EMSA-PSS verification is over the length of N - 1 bits
1215 //
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001216 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001217
Paul Bakkerb3869132013-02-28 17:21:01 +01001218 // Compensate for boundary condition when applying mask
1219 //
1220 if( msb % 8 == 0 )
1221 {
1222 p++;
1223 siglen -= 1;
1224 }
1225 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001227
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001228 mbedtls_md_init( &md_ctx );
1229 mbedtls_md_setup( &md_ctx, md_info, 0 );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001230
Paul Bakkerb3869132013-02-28 17:21:01 +01001231 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
Paul Bakker02303e82013-01-03 11:08:31 +01001232
Paul Bakkerb3869132013-02-28 17:21:01 +01001233 buf[0] &= 0xFF >> ( siglen * 8 - msb );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001234
Paul Bakker4de44aa2013-12-31 11:43:01 +01001235 while( p < buf + siglen && *p == 0 )
Paul Bakkerb3869132013-02-28 17:21:01 +01001236 p++;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001237
Paul Bakkerb3869132013-02-28 17:21:01 +01001238 if( p == buf + siglen ||
1239 *p++ != 0x01 )
1240 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_md_free( &md_ctx );
1242 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001243 }
Paul Bakker9dcc3222011-03-08 14:16:06 +00001244
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001245 /* Actual salt len */
Paul Bakkerb3869132013-02-28 17:21:01 +01001246 slen -= p - buf;
Paul Bakker9dcc3222011-03-08 14:16:06 +00001247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001249 slen != (size_t) expected_salt_len )
1250 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 mbedtls_md_free( &md_ctx );
1252 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001253 }
1254
Paul Bakkerb3869132013-02-28 17:21:01 +01001255 // Generate H = Hash( M' )
1256 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001257 mbedtls_md_starts( &md_ctx );
1258 mbedtls_md_update( &md_ctx, zeros, 8 );
1259 mbedtls_md_update( &md_ctx, hash, hashlen );
1260 mbedtls_md_update( &md_ctx, p, slen );
1261 mbedtls_md_finish( &md_ctx, result );
Paul Bakker53019ae2011-03-25 13:58:48 +00001262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263 mbedtls_md_free( &md_ctx );
Paul Bakker9dcc3222011-03-08 14:16:06 +00001264
Paul Bakkerb3869132013-02-28 17:21:01 +01001265 if( memcmp( p + slen, result, hlen ) == 0 )
1266 return( 0 );
1267 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001268 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerb3869132013-02-28 17:21:01 +01001269}
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001270
1271/*
1272 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
1273 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001274int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001275 int (*f_rng)(void *, unsigned char *, size_t),
1276 void *p_rng,
1277 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001278 mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001279 unsigned int hashlen,
1280 const unsigned char *hash,
1281 const unsigned char *sig )
1282{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001283 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
1284 ? (mbedtls_md_type_t) ctx->hash_id
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001285 : md_alg;
1286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001287 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001288 md_alg, hashlen, hash,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001289 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
Manuel Pégourié-Gonnard5ec628a2014-06-03 11:44:06 +02001290 sig ) );
1291
1292}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293#endif /* MBEDTLS_PKCS1_V21 */
Paul Bakker40628ba2013-01-03 10:50:31 +01001294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001295#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkerb3869132013-02-28 17:21:01 +01001296/*
1297 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
1298 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001300 int (*f_rng)(void *, unsigned char *, size_t),
1301 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001302 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001303 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001304 unsigned int hashlen,
1305 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02001306 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01001307{
1308 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +02001309 size_t len, siglen, asn1_len;
1310 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001311 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1312 mbedtls_md_type_t msg_md_alg;
1313 const mbedtls_md_info_t *md_info;
1314 mbedtls_asn1_buf oid;
Paul Bakkerb3869132013-02-28 17:21:01 +01001315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001316 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
1317 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001318
1319 siglen = ctx->len;
1320
1321 if( siglen < 16 || siglen > sizeof( buf ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001322 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
Paul Bakkerb3869132013-02-28 17:21:01 +01001323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001324 ret = ( mode == MBEDTLS_RSA_PUBLIC )
1325 ? mbedtls_rsa_public( ctx, sig, buf )
1326 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
Paul Bakkerb3869132013-02-28 17:21:01 +01001327
1328 if( ret != 0 )
1329 return( ret );
1330
1331 p = buf;
1332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001333 if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN )
1334 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001335
1336 while( *p != 0 )
1337 {
1338 if( p >= buf + siglen - 1 || *p != 0xFF )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001339 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001340 p++;
1341 }
1342 p++;
1343
1344 len = siglen - ( p - buf );
1345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346 if( len == hashlen && md_alg == MBEDTLS_MD_NONE )
Paul Bakkerb3869132013-02-28 17:21:01 +01001347 {
1348 if( memcmp( p, hash, hashlen ) == 0 )
1349 return( 0 );
1350 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 }
1353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001354 md_info = mbedtls_md_info_from_type( md_alg );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001355 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
1357 hashlen = mbedtls_md_get_size( md_info );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001358
1359 end = p + len;
1360
1361 // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
1362 //
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
1364 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1365 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001366
1367 if( asn1_len + 2 != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001370 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
1371 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1372 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001373
1374 if( asn1_len + 6 + hashlen != len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377 if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
1378 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001379
1380 oid.p = p;
1381 p += oid.len;
1382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383 if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
1384 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001385
1386 if( md_alg != msg_md_alg )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001387 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001388
1389 /*
1390 * assume the algorithm parameters must be NULL
1391 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 )
1393 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001394
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001395 if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
1396 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001397
1398 if( asn1_len != hashlen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001400
1401 if( memcmp( p, hash, hashlen ) != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001403
1404 p += hashlen;
1405
1406 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407 return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
Paul Bakkerc70b9822013-04-07 22:00:46 +02001408
1409 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001410}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001412
1413/*
Paul Bakkerb3869132013-02-28 17:21:01 +01001414 * Do an RSA operation and check the message digest
1415 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
Paul Bakker548957d2013-08-30 10:30:02 +02001417 int (*f_rng)(void *, unsigned char *, size_t),
1418 void *p_rng,
Paul Bakkerb3869132013-02-28 17:21:01 +01001419 int mode,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 mbedtls_md_type_t md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001421 unsigned int hashlen,
1422 const unsigned char *hash,
Manuel Pégourié-Gonnardcc0a9d02013-08-12 11:34:35 +02001423 const unsigned char *sig )
Paul Bakkerb3869132013-02-28 17:21:01 +01001424{
1425 switch( ctx->padding )
1426 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427#if defined(MBEDTLS_PKCS1_V15)
1428 case MBEDTLS_RSA_PKCS_V15:
1429 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001430 hashlen, hash, sig );
Paul Bakker48377d92013-08-30 12:06:24 +02001431#endif
Paul Bakkerb3869132013-02-28 17:21:01 +01001432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433#if defined(MBEDTLS_PKCS1_V21)
1434 case MBEDTLS_RSA_PKCS_V21:
1435 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
Paul Bakkerb3869132013-02-28 17:21:01 +01001436 hashlen, hash, sig );
1437#endif
1438
1439 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001440 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
Paul Bakkerb3869132013-02-28 17:21:01 +01001441 }
1442}
1443
1444/*
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001445 * Copy the components of an RSA key
1446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001448{
1449 int ret;
1450
1451 dst->ver = src->ver;
1452 dst->len = src->len;
1453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001454 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
1455 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001457 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
1458 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
1459 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
1460 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
1461 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
1462 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
1465 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
1466 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
1469 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
Manuel Pégourié-Gonnardea53a552013-09-10 13:29:30 +02001470
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001471 dst->padding = src->padding;
Manuel Pégourié-Gonnardfdddac92014-03-25 15:58:35 +01001472 dst->hash_id = src->hash_id;
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001473
1474cleanup:
1475 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 mbedtls_rsa_free( dst );
Manuel Pégourié-Gonnard3053f5b2013-08-14 13:39:57 +02001477
1478 return( ret );
1479}
1480
1481/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001482 * Free the components of an RSA key
1483 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +00001485{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
1487 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RN );
1488 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP );
1489 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->D );
1490 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02001491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#if defined(MBEDTLS_THREADING_C)
1493 mbedtls_mutex_free( &ctx->mutex );
Paul Bakkerc9965dc2013-09-29 14:58:17 +02001494#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001495}
1496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001498
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00001499#include "mbedtls/sha1.h"
Paul Bakker5121ce52009-01-03 21:22:43 +00001500
1501/*
1502 * Example RSA-1024 keypair, for test purposes
1503 */
1504#define KEY_LEN 128
1505
1506#define RSA_N "9292758453063D803DD603D5E777D788" \
1507 "8ED1D5BF35786190FA2F23EBC0848AEA" \
1508 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
1509 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
1510 "93A89813FBF3C4F8066D2D800F7C38A8" \
1511 "1AE31942917403FF4946B0A83D3D3E05" \
1512 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
1513 "5E94BB77B07507233A0BC7BAC8F90F79"
1514
1515#define RSA_E "10001"
1516
1517#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
1518 "66CA472BC44D253102F8B4A9D3BFA750" \
1519 "91386C0077937FE33FA3252D28855837" \
1520 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
1521 "DF79C5CE07EE72C7F123142198164234" \
1522 "CABB724CF78B8173B9F880FC86322407" \
1523 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
1524 "071513A1E85B5DFA031F21ECAE91A34D"
1525
1526#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
1527 "2C01CAD19EA484A87EA4377637E75500" \
1528 "FCB2005C5C7DD6EC4AC023CDA285D796" \
1529 "C3D9E75E1EFC42488BB4F1D13AC30A57"
1530
1531#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
1532 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
1533 "910E4168387E3C30AA1E00C339A79508" \
1534 "8452DD96A9A5EA5D9DCA68DA636032AF"
1535
1536#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
1537 "3C94D22288ACD763FD8E5600ED4A702D" \
1538 "F84198A5F06C2E72236AE490C93F07F8" \
1539 "3CC559CD27BC2D1CA488811730BB5725"
1540
1541#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
1542 "D8AAEA56749EA28623272E4F7D0592AF" \
1543 "7C1F1313CAC9471B5C523BFE592F517B" \
1544 "407A1BD76C164B93DA2D32A383E58357"
1545
1546#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
1547 "F38D18D2B2F0E2DD275AA977E2BF4411" \
1548 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
1549 "A74206CEC169D74BF5A8C50D6F48EA08"
1550
1551#define PT_LEN 24
1552#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
1553 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
1554
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001555#if defined(MBEDTLS_PKCS1_V15)
Paul Bakkera3d195c2011-11-27 21:07:34 +00001556static int myrand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker545570e2010-07-18 09:00:25 +00001557{
Paul Bakkerf96f7b62014-04-30 16:02:38 +02001558#if !defined(__OpenBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +00001559 size_t i;
1560
Paul Bakker545570e2010-07-18 09:00:25 +00001561 if( rng_state != NULL )
1562 rng_state = NULL;
1563
Paul Bakkera3d195c2011-11-27 21:07:34 +00001564 for( i = 0; i < len; ++i )
1565 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +02001566#else
1567 if( rng_state != NULL )
1568 rng_state = NULL;
1569
1570 arc4random_buf( output, len );
1571#endif /* !OpenBSD */
Paul Bakker48377d92013-08-30 12:06:24 +02001572
Paul Bakkera3d195c2011-11-27 21:07:34 +00001573 return( 0 );
Paul Bakker545570e2010-07-18 09:00:25 +00001574}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker545570e2010-07-18 09:00:25 +00001576
Paul Bakker5121ce52009-01-03 21:22:43 +00001577/*
1578 * Checkup routine
1579 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580int mbedtls_rsa_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001581{
Paul Bakker3d8fb632014-04-17 12:42:41 +02001582 int ret = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583#if defined(MBEDTLS_PKCS1_V15)
Paul Bakker23986e52011-04-24 08:57:21 +00001584 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001585 mbedtls_rsa_context rsa;
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 unsigned char rsa_plaintext[PT_LEN];
1587 unsigned char rsa_decrypted[PT_LEN];
1588 unsigned char rsa_ciphertext[KEY_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589#if defined(MBEDTLS_SHA1_C)
Paul Bakker5690efc2011-05-26 13:16:06 +00001590 unsigned char sha1sum[20];
1591#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001593 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001594
1595 rsa.len = KEY_LEN;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.N , 16, RSA_N ) );
1597 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.E , 16, RSA_E ) );
1598 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.D , 16, RSA_D ) );
1599 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.P , 16, RSA_P ) );
1600 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.Q , 16, RSA_Q ) );
1601 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DP, 16, RSA_DP ) );
1602 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DQ, 16, RSA_DQ ) );
1603 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.QP, 16, RSA_QP ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001604
1605 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001606 mbedtls_printf( " RSA key validation: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00001607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001608 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
1609 mbedtls_rsa_check_privkey( &rsa ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001610 {
1611 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001613
1614 return( 1 );
1615 }
1616
1617 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001618 mbedtls_printf( "passed\n PKCS#1 encryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00001619
1620 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
1621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001622 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, PT_LEN,
Paul Bakker5121ce52009-01-03 21:22:43 +00001623 rsa_plaintext, rsa_ciphertext ) != 0 )
1624 {
1625 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001626 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001627
1628 return( 1 );
1629 }
1630
1631 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001632 mbedtls_printf( "passed\n PKCS#1 decryption : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00001633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001634 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, &len,
Paul Bakker060c5682009-01-12 21:48:39 +00001635 rsa_ciphertext, rsa_decrypted,
Paul Bakker23986e52011-04-24 08:57:21 +00001636 sizeof(rsa_decrypted) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001637 {
1638 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001639 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001640
1641 return( 1 );
1642 }
1643
1644 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
1645 {
1646 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001647 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001648
1649 return( 1 );
1650 }
1651
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02001652 if( verbose != 0 )
1653 mbedtls_printf( "passed\n" );
1654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001655#if defined(MBEDTLS_SHA1_C)
Paul Bakker5121ce52009-01-03 21:22:43 +00001656 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02001657 mbedtls_printf( "PKCS#1 data sign : " );
Paul Bakker5121ce52009-01-03 21:22:43 +00001658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001659 mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );
Paul Bakker5121ce52009-01-03 21:22:43 +00001660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001661 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
Paul Bakker5121ce52009-01-03 21:22:43 +00001662 sha1sum, rsa_ciphertext ) != 0 )
1663 {
1664 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001666
1667 return( 1 );
1668 }
1669
1670 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001671 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
Paul Bakker5121ce52009-01-03 21:22:43 +00001672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001673 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
Paul Bakker5121ce52009-01-03 21:22:43 +00001674 sha1sum, rsa_ciphertext ) != 0 )
1675 {
1676 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001677 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001678
1679 return( 1 );
1680 }
1681
1682 if( verbose != 0 )
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02001683 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684#endif /* MBEDTLS_SHA1_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00001685
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +02001686 if( verbose != 0 )
1687 mbedtls_printf( "\n" );
1688
Paul Bakker3d8fb632014-04-17 12:42:41 +02001689cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001690 mbedtls_rsa_free( &rsa );
1691#else /* MBEDTLS_PKCS1_V15 */
Paul Bakker3e41fe82013-09-15 17:42:50 +02001692 ((void) verbose);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001693#endif /* MBEDTLS_PKCS1_V15 */
Paul Bakker3d8fb632014-04-17 12:42:41 +02001694 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001695}
1696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001697#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00001698
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699#endif /* MBEDTLS_RSA_C */