mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /*
ansond 0:137634ff4186 2 * The RSA public-key cryptosystem
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 9 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 10 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 11 * (at your option) any later version.
ansond 0:137634ff4186 12 *
ansond 0:137634ff4186 13 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 16 * GNU General Public License for more details.
ansond 0:137634ff4186 17 *
ansond 0:137634ff4186 18 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 19 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 21 */
ansond 0:137634ff4186 22 /*
ansond 0:137634ff4186 23 * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
ansond 0:137634ff4186 24 *
ansond 0:137634ff4186 25 * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
ansond 0:137634ff4186 26 * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
ansond 0:137634ff4186 27 */
ansond 0:137634ff4186 28
ansond 0:137634ff4186 29 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 30 #include "polarssl/config.h"
ansond 0:137634ff4186 31 #else
ansond 0:137634ff4186 32 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 33 #endif
ansond 0:137634ff4186 34
ansond 0:137634ff4186 35 #if defined(POLARSSL_RSA_C)
ansond 0:137634ff4186 36
ansond 0:137634ff4186 37 #include "polarssl/rsa.h"
ansond 0:137634ff4186 38 #include "polarssl/oid.h"
ansond 0:137634ff4186 39
ansond 0:137634ff4186 40 #include <string.h>
ansond 0:137634ff4186 41
ansond 0:137634ff4186 42 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 43 #include "polarssl/md.h"
ansond 0:137634ff4186 44 #endif
ansond 0:137634ff4186 45
ansond 0:137634ff4186 46 #if defined(POLARSSL_PKCS1_V15) && !defined(__OpenBSD__)
ansond 0:137634ff4186 47 #include <stdlib.h>
ansond 0:137634ff4186 48 #endif
ansond 0:137634ff4186 49
ansond 0:137634ff4186 50 #if defined(POLARSSL_PLATFORM_C)
ansond 0:137634ff4186 51 #include "polarssl/platform.h"
ansond 0:137634ff4186 52 #else
ansond 0:137634ff4186 53 #include <stdio.h>
ansond 0:137634ff4186 54 #define polarssl_printf printf
ansond 0:137634ff4186 55 #endif
ansond 0:137634ff4186 56
ansond 0:137634ff4186 57 /*
ansond 0:137634ff4186 58 * Initialize an RSA context
ansond 0:137634ff4186 59 */
ansond 0:137634ff4186 60 void rsa_init( rsa_context *ctx,
ansond 0:137634ff4186 61 int padding,
ansond 0:137634ff4186 62 int hash_id )
ansond 0:137634ff4186 63 {
ansond 0:137634ff4186 64 memset( ctx, 0, sizeof( rsa_context ) );
ansond 0:137634ff4186 65
ansond 0:137634ff4186 66 rsa_set_padding( ctx, padding, hash_id );
ansond 0:137634ff4186 67
ansond 0:137634ff4186 68 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 69 polarssl_mutex_init( &ctx->mutex );
ansond 0:137634ff4186 70 #endif
ansond 0:137634ff4186 71 }
ansond 0:137634ff4186 72
ansond 0:137634ff4186 73 /*
ansond 0:137634ff4186 74 * Set padding for an existing RSA context
ansond 0:137634ff4186 75 */
ansond 0:137634ff4186 76 void rsa_set_padding( rsa_context *ctx, int padding, int hash_id )
ansond 0:137634ff4186 77 {
ansond 0:137634ff4186 78 ctx->padding = padding;
ansond 0:137634ff4186 79 ctx->hash_id = hash_id;
ansond 0:137634ff4186 80 }
ansond 0:137634ff4186 81
ansond 0:137634ff4186 82 #if defined(POLARSSL_GENPRIME)
ansond 0:137634ff4186 83
ansond 0:137634ff4186 84 /*
ansond 0:137634ff4186 85 * Generate an RSA keypair
ansond 0:137634ff4186 86 */
ansond 0:137634ff4186 87 int rsa_gen_key( rsa_context *ctx,
ansond 0:137634ff4186 88 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 89 void *p_rng,
ansond 0:137634ff4186 90 unsigned int nbits, int exponent )
ansond 0:137634ff4186 91 {
ansond 0:137634ff4186 92 int ret;
ansond 0:137634ff4186 93 mpi P1, Q1, H, G;
ansond 0:137634ff4186 94
ansond 0:137634ff4186 95 if( f_rng == NULL || nbits < 128 || exponent < 3 )
ansond 0:137634ff4186 96 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 97
ansond 0:137634ff4186 98 mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &G );
ansond 0:137634ff4186 99
ansond 0:137634ff4186 100 /*
ansond 0:137634ff4186 101 * find primes P and Q with Q < P so that:
ansond 0:137634ff4186 102 * GCD( E, (P-1)*(Q-1) ) == 1
ansond 0:137634ff4186 103 */
ansond 0:137634ff4186 104 MPI_CHK( mpi_lset( &ctx->E, exponent ) );
ansond 0:137634ff4186 105
ansond 0:137634ff4186 106 do
ansond 0:137634ff4186 107 {
ansond 0:137634ff4186 108 MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
ansond 0:137634ff4186 109 f_rng, p_rng ) );
ansond 0:137634ff4186 110
ansond 0:137634ff4186 111 MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
ansond 0:137634ff4186 112 f_rng, p_rng ) );
ansond 0:137634ff4186 113
ansond 0:137634ff4186 114 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
ansond 0:137634ff4186 115 mpi_swap( &ctx->P, &ctx->Q );
ansond 0:137634ff4186 116
ansond 0:137634ff4186 117 if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
ansond 0:137634ff4186 118 continue;
ansond 0:137634ff4186 119
ansond 0:137634ff4186 120 MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
ansond 0:137634ff4186 121 if( mpi_msb( &ctx->N ) != nbits )
ansond 0:137634ff4186 122 continue;
ansond 0:137634ff4186 123
ansond 0:137634ff4186 124 MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
ansond 0:137634ff4186 125 MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
ansond 0:137634ff4186 126 MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
ansond 0:137634ff4186 127 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
ansond 0:137634ff4186 128 }
ansond 0:137634ff4186 129 while( mpi_cmp_int( &G, 1 ) != 0 );
ansond 0:137634ff4186 130
ansond 0:137634ff4186 131 /*
ansond 0:137634ff4186 132 * D = E^-1 mod ((P-1)*(Q-1))
ansond 0:137634ff4186 133 * DP = D mod (P - 1)
ansond 0:137634ff4186 134 * DQ = D mod (Q - 1)
ansond 0:137634ff4186 135 * QP = Q^-1 mod P
ansond 0:137634ff4186 136 */
ansond 0:137634ff4186 137 MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
ansond 0:137634ff4186 138 MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
ansond 0:137634ff4186 139 MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
ansond 0:137634ff4186 140 MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
ansond 0:137634ff4186 141
ansond 0:137634ff4186 142 ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
ansond 0:137634ff4186 143
ansond 0:137634ff4186 144 cleanup:
ansond 0:137634ff4186 145
ansond 0:137634ff4186 146 mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &G );
ansond 0:137634ff4186 147
ansond 0:137634ff4186 148 if( ret != 0 )
ansond 0:137634ff4186 149 {
ansond 0:137634ff4186 150 rsa_free( ctx );
ansond 0:137634ff4186 151 return( POLARSSL_ERR_RSA_KEY_GEN_FAILED + ret );
ansond 0:137634ff4186 152 }
ansond 0:137634ff4186 153
ansond 0:137634ff4186 154 return( 0 );
ansond 0:137634ff4186 155 }
ansond 0:137634ff4186 156
ansond 0:137634ff4186 157 #endif /* POLARSSL_GENPRIME */
ansond 0:137634ff4186 158
ansond 0:137634ff4186 159 /*
ansond 0:137634ff4186 160 * Check a public RSA key
ansond 0:137634ff4186 161 */
ansond 0:137634ff4186 162 int rsa_check_pubkey( const rsa_context *ctx )
ansond 0:137634ff4186 163 {
ansond 0:137634ff4186 164 if( !ctx->N.p || !ctx->E.p )
ansond 0:137634ff4186 165 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 166
ansond 0:137634ff4186 167 if( ( ctx->N.p[0] & 1 ) == 0 ||
ansond 0:137634ff4186 168 ( ctx->E.p[0] & 1 ) == 0 )
ansond 0:137634ff4186 169 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 170
ansond 0:137634ff4186 171 if( mpi_msb( &ctx->N ) < 128 ||
ansond 0:137634ff4186 172 mpi_msb( &ctx->N ) > POLARSSL_MPI_MAX_BITS )
ansond 0:137634ff4186 173 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 174
ansond 0:137634ff4186 175 if( mpi_msb( &ctx->E ) < 2 ||
ansond 0:137634ff4186 176 mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
ansond 0:137634ff4186 177 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 178
ansond 0:137634ff4186 179 return( 0 );
ansond 0:137634ff4186 180 }
ansond 0:137634ff4186 181
ansond 0:137634ff4186 182 /*
ansond 0:137634ff4186 183 * Check a private RSA key
ansond 0:137634ff4186 184 */
ansond 0:137634ff4186 185 int rsa_check_privkey( const rsa_context *ctx )
ansond 0:137634ff4186 186 {
ansond 0:137634ff4186 187 int ret;
ansond 0:137634ff4186 188 mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;
ansond 0:137634ff4186 189
ansond 0:137634ff4186 190 if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
ansond 0:137634ff4186 191 return( ret );
ansond 0:137634ff4186 192
ansond 0:137634ff4186 193 if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
ansond 0:137634ff4186 194 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 195
ansond 0:137634ff4186 196 mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 );
ansond 0:137634ff4186 197 mpi_init( &H ); mpi_init( &I ); mpi_init( &G ); mpi_init( &G2 );
ansond 0:137634ff4186 198 mpi_init( &L1 ); mpi_init( &L2 ); mpi_init( &DP ); mpi_init( &DQ );
ansond 0:137634ff4186 199 mpi_init( &QP );
ansond 0:137634ff4186 200
ansond 0:137634ff4186 201 MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
ansond 0:137634ff4186 202 MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
ansond 0:137634ff4186 203 MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
ansond 0:137634ff4186 204 MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
ansond 0:137634ff4186 205 MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
ansond 0:137634ff4186 206 MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
ansond 0:137634ff4186 207
ansond 0:137634ff4186 208 MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
ansond 0:137634ff4186 209 MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
ansond 0:137634ff4186 210 MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
ansond 0:137634ff4186 211
ansond 0:137634ff4186 212 MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
ansond 0:137634ff4186 213 MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
ansond 0:137634ff4186 214 MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
ansond 0:137634ff4186 215 /*
ansond 0:137634ff4186 216 * Check for a valid PKCS1v2 private key
ansond 0:137634ff4186 217 */
ansond 0:137634ff4186 218 if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
ansond 0:137634ff4186 219 mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
ansond 0:137634ff4186 220 mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
ansond 0:137634ff4186 221 mpi_cmp_mpi( &QP, &ctx->QP ) != 0 ||
ansond 0:137634ff4186 222 mpi_cmp_int( &L2, 0 ) != 0 ||
ansond 0:137634ff4186 223 mpi_cmp_int( &I, 1 ) != 0 ||
ansond 0:137634ff4186 224 mpi_cmp_int( &G, 1 ) != 0 )
ansond 0:137634ff4186 225 {
ansond 0:137634ff4186 226 ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED;
ansond 0:137634ff4186 227 }
ansond 0:137634ff4186 228
ansond 0:137634ff4186 229 cleanup:
ansond 0:137634ff4186 230 mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 );
ansond 0:137634ff4186 231 mpi_free( &H ); mpi_free( &I ); mpi_free( &G ); mpi_free( &G2 );
ansond 0:137634ff4186 232 mpi_free( &L1 ); mpi_free( &L2 ); mpi_free( &DP ); mpi_free( &DQ );
ansond 0:137634ff4186 233 mpi_free( &QP );
ansond 0:137634ff4186 234
ansond 0:137634ff4186 235 if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED )
ansond 0:137634ff4186 236 return( ret );
ansond 0:137634ff4186 237
ansond 0:137634ff4186 238 if( ret != 0 )
ansond 0:137634ff4186 239 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED + ret );
ansond 0:137634ff4186 240
ansond 0:137634ff4186 241 return( 0 );
ansond 0:137634ff4186 242 }
ansond 0:137634ff4186 243
ansond 0:137634ff4186 244 /*
ansond 0:137634ff4186 245 * Check if contexts holding a public and private key match
ansond 0:137634ff4186 246 */
ansond 0:137634ff4186 247 int rsa_check_pub_priv( const rsa_context *pub, const rsa_context *prv )
ansond 0:137634ff4186 248 {
ansond 0:137634ff4186 249 if( rsa_check_pubkey( pub ) != 0 ||
ansond 0:137634ff4186 250 rsa_check_privkey( prv ) != 0 )
ansond 0:137634ff4186 251 {
ansond 0:137634ff4186 252 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 253 }
ansond 0:137634ff4186 254
ansond 0:137634ff4186 255 if( mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
ansond 0:137634ff4186 256 mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
ansond 0:137634ff4186 257 {
ansond 0:137634ff4186 258 return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
ansond 0:137634ff4186 259 }
ansond 0:137634ff4186 260
ansond 0:137634ff4186 261 return( 0 );
ansond 0:137634ff4186 262 }
ansond 0:137634ff4186 263
ansond 0:137634ff4186 264 /*
ansond 0:137634ff4186 265 * Do an RSA public key operation
ansond 0:137634ff4186 266 */
ansond 0:137634ff4186 267 int rsa_public( rsa_context *ctx,
ansond 0:137634ff4186 268 const unsigned char *input,
ansond 0:137634ff4186 269 unsigned char *output )
ansond 0:137634ff4186 270 {
ansond 0:137634ff4186 271 int ret;
ansond 0:137634ff4186 272 size_t olen;
ansond 0:137634ff4186 273 mpi T;
ansond 0:137634ff4186 274
ansond 0:137634ff4186 275 mpi_init( &T );
ansond 0:137634ff4186 276
ansond 0:137634ff4186 277 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
ansond 0:137634ff4186 278
ansond 0:137634ff4186 279 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
ansond 0:137634ff4186 280 {
ansond 0:137634ff4186 281 mpi_free( &T );
ansond 0:137634ff4186 282 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 283 }
ansond 0:137634ff4186 284
ansond 0:137634ff4186 285 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 286 polarssl_mutex_lock( &ctx->mutex );
ansond 0:137634ff4186 287 #endif
ansond 0:137634ff4186 288
ansond 0:137634ff4186 289 olen = ctx->len;
ansond 0:137634ff4186 290 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
ansond 0:137634ff4186 291 MPI_CHK( mpi_write_binary( &T, output, olen ) );
ansond 0:137634ff4186 292
ansond 0:137634ff4186 293 cleanup:
ansond 0:137634ff4186 294 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 295 polarssl_mutex_unlock( &ctx->mutex );
ansond 0:137634ff4186 296 #endif
ansond 0:137634ff4186 297
ansond 0:137634ff4186 298 mpi_free( &T );
ansond 0:137634ff4186 299
ansond 0:137634ff4186 300 if( ret != 0 )
ansond 0:137634ff4186 301 return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret );
ansond 0:137634ff4186 302
ansond 0:137634ff4186 303 return( 0 );
ansond 0:137634ff4186 304 }
ansond 0:137634ff4186 305
ansond 0:137634ff4186 306 /*
ansond 0:137634ff4186 307 * Generate or update blinding values, see section 10 of:
ansond 0:137634ff4186 308 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
ansond 0:137634ff4186 309 * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer
ansond 0:137634ff4186 310 * Berlin Heidelberg, 1996. p. 104-113.
ansond 0:137634ff4186 311 */
ansond 0:137634ff4186 312 static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf,
ansond 0:137634ff4186 313 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
ansond 0:137634ff4186 314 {
ansond 0:137634ff4186 315 int ret, count = 0;
ansond 0:137634ff4186 316
ansond 0:137634ff4186 317 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 318 polarssl_mutex_lock( &ctx->mutex );
ansond 0:137634ff4186 319 #endif
ansond 0:137634ff4186 320
ansond 0:137634ff4186 321 if( ctx->Vf.p != NULL )
ansond 0:137634ff4186 322 {
ansond 0:137634ff4186 323 /* We already have blinding values, just update them by squaring */
ansond 0:137634ff4186 324 MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
ansond 0:137634ff4186 325 MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
ansond 0:137634ff4186 326 MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
ansond 0:137634ff4186 327 MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
ansond 0:137634ff4186 328
ansond 0:137634ff4186 329 goto done;
ansond 0:137634ff4186 330 }
ansond 0:137634ff4186 331
ansond 0:137634ff4186 332 /* Unblinding value: Vf = random number, invertible mod N */
ansond 0:137634ff4186 333 do {
ansond 0:137634ff4186 334 if( count++ > 10 )
ansond 0:137634ff4186 335 return( POLARSSL_ERR_RSA_RNG_FAILED );
ansond 0:137634ff4186 336
ansond 0:137634ff4186 337 MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
ansond 0:137634ff4186 338 MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
ansond 0:137634ff4186 339 } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
ansond 0:137634ff4186 340
ansond 0:137634ff4186 341 /* Blinding value: Vi = Vf^(-e) mod N */
ansond 0:137634ff4186 342 MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
ansond 0:137634ff4186 343 MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
ansond 0:137634ff4186 344
ansond 0:137634ff4186 345 done:
ansond 0:137634ff4186 346 if( Vi != &ctx->Vi )
ansond 0:137634ff4186 347 {
ansond 0:137634ff4186 348 MPI_CHK( mpi_copy( Vi, &ctx->Vi ) );
ansond 0:137634ff4186 349 MPI_CHK( mpi_copy( Vf, &ctx->Vf ) );
ansond 0:137634ff4186 350 }
ansond 0:137634ff4186 351
ansond 0:137634ff4186 352 cleanup:
ansond 0:137634ff4186 353 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 354 polarssl_mutex_unlock( &ctx->mutex );
ansond 0:137634ff4186 355 #endif
ansond 0:137634ff4186 356
ansond 0:137634ff4186 357 return( ret );
ansond 0:137634ff4186 358 }
ansond 0:137634ff4186 359
ansond 0:137634ff4186 360 /*
ansond 0:137634ff4186 361 * Do an RSA private key operation
ansond 0:137634ff4186 362 */
ansond 0:137634ff4186 363 int rsa_private( rsa_context *ctx,
ansond 0:137634ff4186 364 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 365 void *p_rng,
ansond 0:137634ff4186 366 const unsigned char *input,
ansond 0:137634ff4186 367 unsigned char *output )
ansond 0:137634ff4186 368 {
ansond 0:137634ff4186 369 int ret;
ansond 0:137634ff4186 370 size_t olen;
ansond 0:137634ff4186 371 mpi T, T1, T2;
ansond 0:137634ff4186 372 mpi *Vi, *Vf;
ansond 0:137634ff4186 373
ansond 0:137634ff4186 374 /*
ansond 0:137634ff4186 375 * When using the Chinese Remainder Theorem, we use blinding values.
ansond 0:137634ff4186 376 * Without threading, we just read them directly from the context,
ansond 0:137634ff4186 377 * otherwise we make a local copy in order to reduce locking contention.
ansond 0:137634ff4186 378 */
ansond 0:137634ff4186 379 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 380 mpi Vi_copy, Vf_copy;
ansond 0:137634ff4186 381
ansond 0:137634ff4186 382 mpi_init( &Vi_copy ); mpi_init( &Vf_copy );
ansond 0:137634ff4186 383 Vi = &Vi_copy;
ansond 0:137634ff4186 384 Vf = &Vf_copy;
ansond 0:137634ff4186 385 #else
ansond 0:137634ff4186 386 Vi = &ctx->Vi;
ansond 0:137634ff4186 387 Vf = &ctx->Vf;
ansond 0:137634ff4186 388 #endif
ansond 0:137634ff4186 389
ansond 0:137634ff4186 390 mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
ansond 0:137634ff4186 391
ansond 0:137634ff4186 392 MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
ansond 0:137634ff4186 393 if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
ansond 0:137634ff4186 394 {
ansond 0:137634ff4186 395 mpi_free( &T );
ansond 0:137634ff4186 396 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 397 }
ansond 0:137634ff4186 398
ansond 0:137634ff4186 399 if( f_rng != NULL )
ansond 0:137634ff4186 400 {
ansond 0:137634ff4186 401 /*
ansond 0:137634ff4186 402 * Blinding
ansond 0:137634ff4186 403 * T = T * Vi mod N
ansond 0:137634ff4186 404 */
ansond 0:137634ff4186 405 MPI_CHK( rsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) );
ansond 0:137634ff4186 406 MPI_CHK( mpi_mul_mpi( &T, &T, Vi ) );
ansond 0:137634ff4186 407 MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
ansond 0:137634ff4186 408 }
ansond 0:137634ff4186 409
ansond 0:137634ff4186 410 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 411 polarssl_mutex_lock( &ctx->mutex );
ansond 0:137634ff4186 412 #endif
ansond 0:137634ff4186 413
ansond 0:137634ff4186 414 #if defined(POLARSSL_RSA_NO_CRT)
ansond 0:137634ff4186 415 MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
ansond 0:137634ff4186 416 #else
ansond 0:137634ff4186 417 /*
ansond 0:137634ff4186 418 * faster decryption using the CRT
ansond 0:137634ff4186 419 *
ansond 0:137634ff4186 420 * T1 = input ^ dP mod P
ansond 0:137634ff4186 421 * T2 = input ^ dQ mod Q
ansond 0:137634ff4186 422 */
ansond 0:137634ff4186 423 MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
ansond 0:137634ff4186 424 MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
ansond 0:137634ff4186 425
ansond 0:137634ff4186 426 /*
ansond 0:137634ff4186 427 * T = (T1 - T2) * (Q^-1 mod P) mod P
ansond 0:137634ff4186 428 */
ansond 0:137634ff4186 429 MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
ansond 0:137634ff4186 430 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
ansond 0:137634ff4186 431 MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
ansond 0:137634ff4186 432
ansond 0:137634ff4186 433 /*
ansond 0:137634ff4186 434 * T = T2 + T * Q
ansond 0:137634ff4186 435 */
ansond 0:137634ff4186 436 MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
ansond 0:137634ff4186 437 MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
ansond 0:137634ff4186 438 #endif /* POLARSSL_RSA_NO_CRT */
ansond 0:137634ff4186 439
ansond 0:137634ff4186 440 if( f_rng != NULL )
ansond 0:137634ff4186 441 {
ansond 0:137634ff4186 442 /*
ansond 0:137634ff4186 443 * Unblind
ansond 0:137634ff4186 444 * T = T * Vf mod N
ansond 0:137634ff4186 445 */
ansond 0:137634ff4186 446 MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) );
ansond 0:137634ff4186 447 MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
ansond 0:137634ff4186 448 }
ansond 0:137634ff4186 449
ansond 0:137634ff4186 450 olen = ctx->len;
ansond 0:137634ff4186 451 MPI_CHK( mpi_write_binary( &T, output, olen ) );
ansond 0:137634ff4186 452
ansond 0:137634ff4186 453 cleanup:
ansond 0:137634ff4186 454 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 455 polarssl_mutex_unlock( &ctx->mutex );
ansond 0:137634ff4186 456 mpi_free( &Vi_copy ); mpi_free( &Vf_copy );
ansond 0:137634ff4186 457 #endif
ansond 0:137634ff4186 458 mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
ansond 0:137634ff4186 459
ansond 0:137634ff4186 460 if( ret != 0 )
ansond 0:137634ff4186 461 return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret );
ansond 0:137634ff4186 462
ansond 0:137634ff4186 463 return( 0 );
ansond 0:137634ff4186 464 }
ansond 0:137634ff4186 465
ansond 0:137634ff4186 466 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 467 /**
ansond 0:137634ff4186 468 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
ansond 0:137634ff4186 469 *
ansond 0:137634ff4186 470 * \param dst buffer to mask
ansond 0:137634ff4186 471 * \param dlen length of destination buffer
ansond 0:137634ff4186 472 * \param src source of the mask generation
ansond 0:137634ff4186 473 * \param slen length of the source buffer
ansond 0:137634ff4186 474 * \param md_ctx message digest context to use
ansond 0:137634ff4186 475 */
ansond 0:137634ff4186 476 static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
ansond 0:137634ff4186 477 size_t slen, md_context_t *md_ctx )
ansond 0:137634ff4186 478 {
ansond 0:137634ff4186 479 unsigned char mask[POLARSSL_MD_MAX_SIZE];
ansond 0:137634ff4186 480 unsigned char counter[4];
ansond 0:137634ff4186 481 unsigned char *p;
ansond 0:137634ff4186 482 unsigned int hlen;
ansond 0:137634ff4186 483 size_t i, use_len;
ansond 0:137634ff4186 484
ansond 0:137634ff4186 485 memset( mask, 0, POLARSSL_MD_MAX_SIZE );
ansond 0:137634ff4186 486 memset( counter, 0, 4 );
ansond 0:137634ff4186 487
ansond 0:137634ff4186 488 hlen = md_ctx->md_info->size;
ansond 0:137634ff4186 489
ansond 0:137634ff4186 490 // Generate and apply dbMask
ansond 0:137634ff4186 491 //
ansond 0:137634ff4186 492 p = dst;
ansond 0:137634ff4186 493
ansond 0:137634ff4186 494 while( dlen > 0 )
ansond 0:137634ff4186 495 {
ansond 0:137634ff4186 496 use_len = hlen;
ansond 0:137634ff4186 497 if( dlen < hlen )
ansond 0:137634ff4186 498 use_len = dlen;
ansond 0:137634ff4186 499
ansond 0:137634ff4186 500 md_starts( md_ctx );
ansond 0:137634ff4186 501 md_update( md_ctx, src, slen );
ansond 0:137634ff4186 502 md_update( md_ctx, counter, 4 );
ansond 0:137634ff4186 503 md_finish( md_ctx, mask );
ansond 0:137634ff4186 504
ansond 0:137634ff4186 505 for( i = 0; i < use_len; ++i )
ansond 0:137634ff4186 506 *p++ ^= mask[i];
ansond 0:137634ff4186 507
ansond 0:137634ff4186 508 counter[3]++;
ansond 0:137634ff4186 509
ansond 0:137634ff4186 510 dlen -= use_len;
ansond 0:137634ff4186 511 }
ansond 0:137634ff4186 512 }
ansond 0:137634ff4186 513 #endif /* POLARSSL_PKCS1_V21 */
ansond 0:137634ff4186 514
ansond 0:137634ff4186 515 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 516 /*
ansond 0:137634ff4186 517 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
ansond 0:137634ff4186 518 */
ansond 0:137634ff4186 519 int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
ansond 0:137634ff4186 520 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 521 void *p_rng,
ansond 0:137634ff4186 522 int mode,
ansond 0:137634ff4186 523 const unsigned char *label, size_t label_len,
ansond 0:137634ff4186 524 size_t ilen,
ansond 0:137634ff4186 525 const unsigned char *input,
ansond 0:137634ff4186 526 unsigned char *output )
ansond 0:137634ff4186 527 {
ansond 0:137634ff4186 528 size_t olen;
ansond 0:137634ff4186 529 int ret;
ansond 0:137634ff4186 530 unsigned char *p = output;
ansond 0:137634ff4186 531 unsigned int hlen;
ansond 0:137634ff4186 532 const md_info_t *md_info;
ansond 0:137634ff4186 533 md_context_t md_ctx;
ansond 0:137634ff4186 534
ansond 0:137634ff4186 535 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
ansond 0:137634ff4186 536 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 537
ansond 0:137634ff4186 538 if( f_rng == NULL )
ansond 0:137634ff4186 539 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 540
ansond 0:137634ff4186 541 md_info = md_info_from_type( (md_type_t) ctx->hash_id );
ansond 0:137634ff4186 542 if( md_info == NULL )
ansond 0:137634ff4186 543 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 544
ansond 0:137634ff4186 545 olen = ctx->len;
ansond 0:137634ff4186 546 hlen = md_get_size( md_info );
ansond 0:137634ff4186 547
ansond 0:137634ff4186 548 if( olen < ilen + 2 * hlen + 2 )
ansond 0:137634ff4186 549 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 550
ansond 0:137634ff4186 551 memset( output, 0, olen );
ansond 0:137634ff4186 552
ansond 0:137634ff4186 553 *p++ = 0;
ansond 0:137634ff4186 554
ansond 0:137634ff4186 555 // Generate a random octet string seed
ansond 0:137634ff4186 556 //
ansond 0:137634ff4186 557 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
ansond 0:137634ff4186 558 return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
ansond 0:137634ff4186 559
ansond 0:137634ff4186 560 p += hlen;
ansond 0:137634ff4186 561
ansond 0:137634ff4186 562 // Construct DB
ansond 0:137634ff4186 563 //
ansond 0:137634ff4186 564 md( md_info, label, label_len, p );
ansond 0:137634ff4186 565 p += hlen;
ansond 0:137634ff4186 566 p += olen - 2 * hlen - 2 - ilen;
ansond 0:137634ff4186 567 *p++ = 1;
ansond 0:137634ff4186 568 memcpy( p, input, ilen );
ansond 0:137634ff4186 569
ansond 0:137634ff4186 570 md_init( &md_ctx );
ansond 0:137634ff4186 571 md_init_ctx( &md_ctx, md_info );
ansond 0:137634ff4186 572
ansond 0:137634ff4186 573 // maskedDB: Apply dbMask to DB
ansond 0:137634ff4186 574 //
ansond 0:137634ff4186 575 mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
ansond 0:137634ff4186 576 &md_ctx );
ansond 0:137634ff4186 577
ansond 0:137634ff4186 578 // maskedSeed: Apply seedMask to seed
ansond 0:137634ff4186 579 //
ansond 0:137634ff4186 580 mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
ansond 0:137634ff4186 581 &md_ctx );
ansond 0:137634ff4186 582
ansond 0:137634ff4186 583 md_free( &md_ctx );
ansond 0:137634ff4186 584
ansond 0:137634ff4186 585 return( ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 586 ? rsa_public( ctx, output, output )
ansond 0:137634ff4186 587 : rsa_private( ctx, f_rng, p_rng, output, output ) );
ansond 0:137634ff4186 588 }
ansond 0:137634ff4186 589 #endif /* POLARSSL_PKCS1_V21 */
ansond 0:137634ff4186 590
ansond 0:137634ff4186 591 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 592 /*
ansond 0:137634ff4186 593 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
ansond 0:137634ff4186 594 */
ansond 0:137634ff4186 595 int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
ansond 0:137634ff4186 596 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 597 void *p_rng,
ansond 0:137634ff4186 598 int mode, size_t ilen,
ansond 0:137634ff4186 599 const unsigned char *input,
ansond 0:137634ff4186 600 unsigned char *output )
ansond 0:137634ff4186 601 {
ansond 0:137634ff4186 602 size_t nb_pad, olen;
ansond 0:137634ff4186 603 int ret;
ansond 0:137634ff4186 604 unsigned char *p = output;
ansond 0:137634ff4186 605
ansond 0:137634ff4186 606 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
ansond 0:137634ff4186 607 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 608
ansond 0:137634ff4186 609 if( f_rng == NULL )
ansond 0:137634ff4186 610 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 611
ansond 0:137634ff4186 612 olen = ctx->len;
ansond 0:137634ff4186 613
ansond 0:137634ff4186 614 if( olen < ilen + 11 )
ansond 0:137634ff4186 615 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 616
ansond 0:137634ff4186 617 nb_pad = olen - 3 - ilen;
ansond 0:137634ff4186 618
ansond 0:137634ff4186 619 *p++ = 0;
ansond 0:137634ff4186 620 if( mode == RSA_PUBLIC )
ansond 0:137634ff4186 621 {
ansond 0:137634ff4186 622 *p++ = RSA_CRYPT;
ansond 0:137634ff4186 623
ansond 0:137634ff4186 624 while( nb_pad-- > 0 )
ansond 0:137634ff4186 625 {
ansond 0:137634ff4186 626 int rng_dl = 100;
ansond 0:137634ff4186 627
ansond 0:137634ff4186 628 do {
ansond 0:137634ff4186 629 ret = f_rng( p_rng, p, 1 );
ansond 0:137634ff4186 630 } while( *p == 0 && --rng_dl && ret == 0 );
ansond 0:137634ff4186 631
ansond 0:137634ff4186 632 // Check if RNG failed to generate data
ansond 0:137634ff4186 633 //
ansond 0:137634ff4186 634 if( rng_dl == 0 || ret != 0 )
ansond 0:137634ff4186 635 return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
ansond 0:137634ff4186 636
ansond 0:137634ff4186 637 p++;
ansond 0:137634ff4186 638 }
ansond 0:137634ff4186 639 }
ansond 0:137634ff4186 640 else
ansond 0:137634ff4186 641 {
ansond 0:137634ff4186 642 *p++ = RSA_SIGN;
ansond 0:137634ff4186 643
ansond 0:137634ff4186 644 while( nb_pad-- > 0 )
ansond 0:137634ff4186 645 *p++ = 0xFF;
ansond 0:137634ff4186 646 }
ansond 0:137634ff4186 647
ansond 0:137634ff4186 648 *p++ = 0;
ansond 0:137634ff4186 649 memcpy( p, input, ilen );
ansond 0:137634ff4186 650
ansond 0:137634ff4186 651 return( ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 652 ? rsa_public( ctx, output, output )
ansond 0:137634ff4186 653 : rsa_private( ctx, f_rng, p_rng, output, output ) );
ansond 0:137634ff4186 654 }
ansond 0:137634ff4186 655 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 656
ansond 0:137634ff4186 657 /*
ansond 0:137634ff4186 658 * Add the message padding, then do an RSA operation
ansond 0:137634ff4186 659 */
ansond 0:137634ff4186 660 int rsa_pkcs1_encrypt( rsa_context *ctx,
ansond 0:137634ff4186 661 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 662 void *p_rng,
ansond 0:137634ff4186 663 int mode, size_t ilen,
ansond 0:137634ff4186 664 const unsigned char *input,
ansond 0:137634ff4186 665 unsigned char *output )
ansond 0:137634ff4186 666 {
ansond 0:137634ff4186 667 switch( ctx->padding )
ansond 0:137634ff4186 668 {
ansond 0:137634ff4186 669 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 670 case RSA_PKCS_V15:
ansond 0:137634ff4186 671 return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
ansond 0:137634ff4186 672 input, output );
ansond 0:137634ff4186 673 #endif
ansond 0:137634ff4186 674
ansond 0:137634ff4186 675 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 676 case RSA_PKCS_V21:
ansond 0:137634ff4186 677 return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
ansond 0:137634ff4186 678 ilen, input, output );
ansond 0:137634ff4186 679 #endif
ansond 0:137634ff4186 680
ansond 0:137634ff4186 681 default:
ansond 0:137634ff4186 682 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 683 }
ansond 0:137634ff4186 684 }
ansond 0:137634ff4186 685
ansond 0:137634ff4186 686 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 687 /*
ansond 0:137634ff4186 688 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
ansond 0:137634ff4186 689 */
ansond 0:137634ff4186 690 int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
ansond 0:137634ff4186 691 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 692 void *p_rng,
ansond 0:137634ff4186 693 int mode,
ansond 0:137634ff4186 694 const unsigned char *label, size_t label_len,
ansond 0:137634ff4186 695 size_t *olen,
ansond 0:137634ff4186 696 const unsigned char *input,
ansond 0:137634ff4186 697 unsigned char *output,
ansond 0:137634ff4186 698 size_t output_max_len )
ansond 0:137634ff4186 699 {
ansond 0:137634ff4186 700 int ret;
ansond 0:137634ff4186 701 size_t ilen, i, pad_len;
ansond 0:137634ff4186 702 unsigned char *p, bad, pad_done;
ansond 0:137634ff4186 703 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
ansond 0:137634ff4186 704 unsigned char lhash[POLARSSL_MD_MAX_SIZE];
ansond 0:137634ff4186 705 unsigned int hlen;
ansond 0:137634ff4186 706 const md_info_t *md_info;
ansond 0:137634ff4186 707 md_context_t md_ctx;
ansond 0:137634ff4186 708
ansond 0:137634ff4186 709 /*
ansond 0:137634ff4186 710 * Parameters sanity checks
ansond 0:137634ff4186 711 */
ansond 0:137634ff4186 712 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
ansond 0:137634ff4186 713 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 714
ansond 0:137634ff4186 715 ilen = ctx->len;
ansond 0:137634ff4186 716
ansond 0:137634ff4186 717 if( ilen < 16 || ilen > sizeof( buf ) )
ansond 0:137634ff4186 718 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 719
ansond 0:137634ff4186 720 md_info = md_info_from_type( (md_type_t) ctx->hash_id );
ansond 0:137634ff4186 721 if( md_info == NULL )
ansond 0:137634ff4186 722 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 723
ansond 0:137634ff4186 724 /*
ansond 0:137634ff4186 725 * RSA operation
ansond 0:137634ff4186 726 */
ansond 0:137634ff4186 727 ret = ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 728 ? rsa_public( ctx, input, buf )
ansond 0:137634ff4186 729 : rsa_private( ctx, f_rng, p_rng, input, buf );
ansond 0:137634ff4186 730
ansond 0:137634ff4186 731 if( ret != 0 )
ansond 0:137634ff4186 732 return( ret );
ansond 0:137634ff4186 733
ansond 0:137634ff4186 734 /*
ansond 0:137634ff4186 735 * Unmask data and generate lHash
ansond 0:137634ff4186 736 */
ansond 0:137634ff4186 737 hlen = md_get_size( md_info );
ansond 0:137634ff4186 738
ansond 0:137634ff4186 739 md_init( &md_ctx );
ansond 0:137634ff4186 740 md_init_ctx( &md_ctx, md_info );
ansond 0:137634ff4186 741
ansond 0:137634ff4186 742 /* Generate lHash */
ansond 0:137634ff4186 743 md( md_info, label, label_len, lhash );
ansond 0:137634ff4186 744
ansond 0:137634ff4186 745 /* seed: Apply seedMask to maskedSeed */
ansond 0:137634ff4186 746 mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
ansond 0:137634ff4186 747 &md_ctx );
ansond 0:137634ff4186 748
ansond 0:137634ff4186 749 /* DB: Apply dbMask to maskedDB */
ansond 0:137634ff4186 750 mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
ansond 0:137634ff4186 751 &md_ctx );
ansond 0:137634ff4186 752
ansond 0:137634ff4186 753 md_free( &md_ctx );
ansond 0:137634ff4186 754
ansond 0:137634ff4186 755 /*
ansond 0:137634ff4186 756 * Check contents, in "constant-time"
ansond 0:137634ff4186 757 */
ansond 0:137634ff4186 758 p = buf;
ansond 0:137634ff4186 759 bad = 0;
ansond 0:137634ff4186 760
ansond 0:137634ff4186 761 bad |= *p++; /* First byte must be 0 */
ansond 0:137634ff4186 762
ansond 0:137634ff4186 763 p += hlen; /* Skip seed */
ansond 0:137634ff4186 764
ansond 0:137634ff4186 765 /* Check lHash */
ansond 0:137634ff4186 766 for( i = 0; i < hlen; i++ )
ansond 0:137634ff4186 767 bad |= lhash[i] ^ *p++;
ansond 0:137634ff4186 768
ansond 0:137634ff4186 769 /* Get zero-padding len, but always read till end of buffer
ansond 0:137634ff4186 770 * (minus one, for the 01 byte) */
ansond 0:137634ff4186 771 pad_len = 0;
ansond 0:137634ff4186 772 pad_done = 0;
ansond 0:137634ff4186 773 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
ansond 0:137634ff4186 774 {
ansond 0:137634ff4186 775 pad_done |= p[i];
ansond 0:137634ff4186 776 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
ansond 0:137634ff4186 777 }
ansond 0:137634ff4186 778
ansond 0:137634ff4186 779 p += pad_len;
ansond 0:137634ff4186 780 bad |= *p++ ^ 0x01;
ansond 0:137634ff4186 781
ansond 0:137634ff4186 782 /*
ansond 0:137634ff4186 783 * The only information "leaked" is whether the padding was correct or not
ansond 0:137634ff4186 784 * (eg, no data is copied if it was not correct). This meets the
ansond 0:137634ff4186 785 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
ansond 0:137634ff4186 786 * the different error conditions.
ansond 0:137634ff4186 787 */
ansond 0:137634ff4186 788 if( bad != 0 )
ansond 0:137634ff4186 789 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 790
ansond 0:137634ff4186 791 if( ilen - ( p - buf ) > output_max_len )
ansond 0:137634ff4186 792 return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
ansond 0:137634ff4186 793
ansond 0:137634ff4186 794 *olen = ilen - (p - buf);
ansond 0:137634ff4186 795 memcpy( output, p, *olen );
ansond 0:137634ff4186 796
ansond 0:137634ff4186 797 return( 0 );
ansond 0:137634ff4186 798 }
ansond 0:137634ff4186 799 #endif /* POLARSSL_PKCS1_V21 */
ansond 0:137634ff4186 800
ansond 0:137634ff4186 801 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 802 /*
ansond 0:137634ff4186 803 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
ansond 0:137634ff4186 804 */
ansond 0:137634ff4186 805 int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
ansond 0:137634ff4186 806 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 807 void *p_rng,
ansond 0:137634ff4186 808 int mode, size_t *olen,
ansond 0:137634ff4186 809 const unsigned char *input,
ansond 0:137634ff4186 810 unsigned char *output,
ansond 0:137634ff4186 811 size_t output_max_len)
ansond 0:137634ff4186 812 {
ansond 0:137634ff4186 813 int ret;
ansond 0:137634ff4186 814 size_t ilen, pad_count = 0, i;
ansond 0:137634ff4186 815 unsigned char *p, bad, pad_done = 0;
ansond 0:137634ff4186 816 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
ansond 0:137634ff4186 817
ansond 0:137634ff4186 818 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
ansond 0:137634ff4186 819 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 820
ansond 0:137634ff4186 821 ilen = ctx->len;
ansond 0:137634ff4186 822
ansond 0:137634ff4186 823 if( ilen < 16 || ilen > sizeof( buf ) )
ansond 0:137634ff4186 824 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 825
ansond 0:137634ff4186 826 ret = ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 827 ? rsa_public( ctx, input, buf )
ansond 0:137634ff4186 828 : rsa_private( ctx, f_rng, p_rng, input, buf );
ansond 0:137634ff4186 829
ansond 0:137634ff4186 830 if( ret != 0 )
ansond 0:137634ff4186 831 return( ret );
ansond 0:137634ff4186 832
ansond 0:137634ff4186 833 p = buf;
ansond 0:137634ff4186 834 bad = 0;
ansond 0:137634ff4186 835
ansond 0:137634ff4186 836 /*
ansond 0:137634ff4186 837 * Check and get padding len in "constant-time"
ansond 0:137634ff4186 838 */
ansond 0:137634ff4186 839 bad |= *p++; /* First byte must be 0 */
ansond 0:137634ff4186 840
ansond 0:137634ff4186 841 /* This test does not depend on secret data */
ansond 0:137634ff4186 842 if( mode == RSA_PRIVATE )
ansond 0:137634ff4186 843 {
ansond 0:137634ff4186 844 bad |= *p++ ^ RSA_CRYPT;
ansond 0:137634ff4186 845
ansond 0:137634ff4186 846 /* Get padding len, but always read till end of buffer
ansond 0:137634ff4186 847 * (minus one, for the 00 byte) */
ansond 0:137634ff4186 848 for( i = 0; i < ilen - 3; i++ )
ansond 0:137634ff4186 849 {
ansond 0:137634ff4186 850 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
ansond 0:137634ff4186 851 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
ansond 0:137634ff4186 852 }
ansond 0:137634ff4186 853
ansond 0:137634ff4186 854 p += pad_count;
ansond 0:137634ff4186 855 bad |= *p++; /* Must be zero */
ansond 0:137634ff4186 856 }
ansond 0:137634ff4186 857 else
ansond 0:137634ff4186 858 {
ansond 0:137634ff4186 859 bad |= *p++ ^ RSA_SIGN;
ansond 0:137634ff4186 860
ansond 0:137634ff4186 861 /* Get padding len, but always read till end of buffer
ansond 0:137634ff4186 862 * (minus one, for the 00 byte) */
ansond 0:137634ff4186 863 for( i = 0; i < ilen - 3; i++ )
ansond 0:137634ff4186 864 {
ansond 0:137634ff4186 865 pad_done |= ( p[i] != 0xFF );
ansond 0:137634ff4186 866 pad_count += ( pad_done == 0 );
ansond 0:137634ff4186 867 }
ansond 0:137634ff4186 868
ansond 0:137634ff4186 869 p += pad_count;
ansond 0:137634ff4186 870 bad |= *p++; /* Must be zero */
ansond 0:137634ff4186 871 }
ansond 0:137634ff4186 872
ansond 0:137634ff4186 873 if( bad )
ansond 0:137634ff4186 874 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 875
ansond 0:137634ff4186 876 if( ilen - ( p - buf ) > output_max_len )
ansond 0:137634ff4186 877 return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
ansond 0:137634ff4186 878
ansond 0:137634ff4186 879 *olen = ilen - (p - buf);
ansond 0:137634ff4186 880 memcpy( output, p, *olen );
ansond 0:137634ff4186 881
ansond 0:137634ff4186 882 return( 0 );
ansond 0:137634ff4186 883 }
ansond 0:137634ff4186 884 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 885
ansond 0:137634ff4186 886 /*
ansond 0:137634ff4186 887 * Do an RSA operation, then remove the message padding
ansond 0:137634ff4186 888 */
ansond 0:137634ff4186 889 int rsa_pkcs1_decrypt( rsa_context *ctx,
ansond 0:137634ff4186 890 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 891 void *p_rng,
ansond 0:137634ff4186 892 int mode, size_t *olen,
ansond 0:137634ff4186 893 const unsigned char *input,
ansond 0:137634ff4186 894 unsigned char *output,
ansond 0:137634ff4186 895 size_t output_max_len)
ansond 0:137634ff4186 896 {
ansond 0:137634ff4186 897 switch( ctx->padding )
ansond 0:137634ff4186 898 {
ansond 0:137634ff4186 899 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 900 case RSA_PKCS_V15:
ansond 0:137634ff4186 901 return rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
ansond 0:137634ff4186 902 input, output, output_max_len );
ansond 0:137634ff4186 903 #endif
ansond 0:137634ff4186 904
ansond 0:137634ff4186 905 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 906 case RSA_PKCS_V21:
ansond 0:137634ff4186 907 return rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
ansond 0:137634ff4186 908 olen, input, output,
ansond 0:137634ff4186 909 output_max_len );
ansond 0:137634ff4186 910 #endif
ansond 0:137634ff4186 911
ansond 0:137634ff4186 912 default:
ansond 0:137634ff4186 913 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 914 }
ansond 0:137634ff4186 915 }
ansond 0:137634ff4186 916
ansond 0:137634ff4186 917 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 918 /*
ansond 0:137634ff4186 919 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
ansond 0:137634ff4186 920 */
ansond 0:137634ff4186 921 int rsa_rsassa_pss_sign( rsa_context *ctx,
ansond 0:137634ff4186 922 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 923 void *p_rng,
ansond 0:137634ff4186 924 int mode,
ansond 0:137634ff4186 925 md_type_t md_alg,
ansond 0:137634ff4186 926 unsigned int hashlen,
ansond 0:137634ff4186 927 const unsigned char *hash,
ansond 0:137634ff4186 928 unsigned char *sig )
ansond 0:137634ff4186 929 {
ansond 0:137634ff4186 930 size_t olen;
ansond 0:137634ff4186 931 unsigned char *p = sig;
ansond 0:137634ff4186 932 unsigned char salt[POLARSSL_MD_MAX_SIZE];
ansond 0:137634ff4186 933 unsigned int slen, hlen, offset = 0;
ansond 0:137634ff4186 934 int ret;
ansond 0:137634ff4186 935 size_t msb;
ansond 0:137634ff4186 936 const md_info_t *md_info;
ansond 0:137634ff4186 937 md_context_t md_ctx;
ansond 0:137634ff4186 938
ansond 0:137634ff4186 939 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
ansond 0:137634ff4186 940 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 941
ansond 0:137634ff4186 942 if( f_rng == NULL )
ansond 0:137634ff4186 943 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 944
ansond 0:137634ff4186 945 olen = ctx->len;
ansond 0:137634ff4186 946
ansond 0:137634ff4186 947 if( md_alg != POLARSSL_MD_NONE )
ansond 0:137634ff4186 948 {
ansond 0:137634ff4186 949 // Gather length of hash to sign
ansond 0:137634ff4186 950 //
ansond 0:137634ff4186 951 md_info = md_info_from_type( md_alg );
ansond 0:137634ff4186 952 if( md_info == NULL )
ansond 0:137634ff4186 953 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 954
ansond 0:137634ff4186 955 hashlen = md_get_size( md_info );
ansond 0:137634ff4186 956 }
ansond 0:137634ff4186 957
ansond 0:137634ff4186 958 md_info = md_info_from_type( (md_type_t) ctx->hash_id );
ansond 0:137634ff4186 959 if( md_info == NULL )
ansond 0:137634ff4186 960 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 961
ansond 0:137634ff4186 962 hlen = md_get_size( md_info );
ansond 0:137634ff4186 963 slen = hlen;
ansond 0:137634ff4186 964
ansond 0:137634ff4186 965 if( olen < hlen + slen + 2 )
ansond 0:137634ff4186 966 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 967
ansond 0:137634ff4186 968 memset( sig, 0, olen );
ansond 0:137634ff4186 969
ansond 0:137634ff4186 970 // Generate salt of length slen
ansond 0:137634ff4186 971 //
ansond 0:137634ff4186 972 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
ansond 0:137634ff4186 973 return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
ansond 0:137634ff4186 974
ansond 0:137634ff4186 975 // Note: EMSA-PSS encoding is over the length of N - 1 bits
ansond 0:137634ff4186 976 //
ansond 0:137634ff4186 977 msb = mpi_msb( &ctx->N ) - 1;
ansond 0:137634ff4186 978 p += olen - hlen * 2 - 2;
ansond 0:137634ff4186 979 *p++ = 0x01;
ansond 0:137634ff4186 980 memcpy( p, salt, slen );
ansond 0:137634ff4186 981 p += slen;
ansond 0:137634ff4186 982
ansond 0:137634ff4186 983 md_init( &md_ctx );
ansond 0:137634ff4186 984 md_init_ctx( &md_ctx, md_info );
ansond 0:137634ff4186 985
ansond 0:137634ff4186 986 // Generate H = Hash( M' )
ansond 0:137634ff4186 987 //
ansond 0:137634ff4186 988 md_starts( &md_ctx );
ansond 0:137634ff4186 989 md_update( &md_ctx, p, 8 );
ansond 0:137634ff4186 990 md_update( &md_ctx, hash, hashlen );
ansond 0:137634ff4186 991 md_update( &md_ctx, salt, slen );
ansond 0:137634ff4186 992 md_finish( &md_ctx, p );
ansond 0:137634ff4186 993
ansond 0:137634ff4186 994 // Compensate for boundary condition when applying mask
ansond 0:137634ff4186 995 //
ansond 0:137634ff4186 996 if( msb % 8 == 0 )
ansond 0:137634ff4186 997 offset = 1;
ansond 0:137634ff4186 998
ansond 0:137634ff4186 999 // maskedDB: Apply dbMask to DB
ansond 0:137634ff4186 1000 //
ansond 0:137634ff4186 1001 mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
ansond 0:137634ff4186 1002
ansond 0:137634ff4186 1003 md_free( &md_ctx );
ansond 0:137634ff4186 1004
ansond 0:137634ff4186 1005 msb = mpi_msb( &ctx->N ) - 1;
ansond 0:137634ff4186 1006 sig[0] &= 0xFF >> ( olen * 8 - msb );
ansond 0:137634ff4186 1007
ansond 0:137634ff4186 1008 p += hlen;
ansond 0:137634ff4186 1009 *p++ = 0xBC;
ansond 0:137634ff4186 1010
ansond 0:137634ff4186 1011 return( ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 1012 ? rsa_public( ctx, sig, sig )
ansond 0:137634ff4186 1013 : rsa_private( ctx, f_rng, p_rng, sig, sig ) );
ansond 0:137634ff4186 1014 }
ansond 0:137634ff4186 1015 #endif /* POLARSSL_PKCS1_V21 */
ansond 0:137634ff4186 1016
ansond 0:137634ff4186 1017 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1018 /*
ansond 0:137634ff4186 1019 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
ansond 0:137634ff4186 1020 */
ansond 0:137634ff4186 1021 /*
ansond 0:137634ff4186 1022 * Do an RSA operation to sign the message digest
ansond 0:137634ff4186 1023 */
ansond 0:137634ff4186 1024 int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
ansond 0:137634ff4186 1025 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1026 void *p_rng,
ansond 0:137634ff4186 1027 int mode,
ansond 0:137634ff4186 1028 md_type_t md_alg,
ansond 0:137634ff4186 1029 unsigned int hashlen,
ansond 0:137634ff4186 1030 const unsigned char *hash,
ansond 0:137634ff4186 1031 unsigned char *sig )
ansond 0:137634ff4186 1032 {
ansond 0:137634ff4186 1033 size_t nb_pad, olen, oid_size = 0;
ansond 0:137634ff4186 1034 unsigned char *p = sig;
ansond 0:137634ff4186 1035 const char *oid = NULL;
ansond 0:137634ff4186 1036
ansond 0:137634ff4186 1037 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
ansond 0:137634ff4186 1038 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1039
ansond 0:137634ff4186 1040 olen = ctx->len;
ansond 0:137634ff4186 1041 nb_pad = olen - 3;
ansond 0:137634ff4186 1042
ansond 0:137634ff4186 1043 if( md_alg != POLARSSL_MD_NONE )
ansond 0:137634ff4186 1044 {
ansond 0:137634ff4186 1045 const md_info_t *md_info = md_info_from_type( md_alg );
ansond 0:137634ff4186 1046 if( md_info == NULL )
ansond 0:137634ff4186 1047 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1048
ansond 0:137634ff4186 1049 if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
ansond 0:137634ff4186 1050 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1051
ansond 0:137634ff4186 1052 nb_pad -= 10 + oid_size;
ansond 0:137634ff4186 1053
ansond 0:137634ff4186 1054 hashlen = md_get_size( md_info );
ansond 0:137634ff4186 1055 }
ansond 0:137634ff4186 1056
ansond 0:137634ff4186 1057 nb_pad -= hashlen;
ansond 0:137634ff4186 1058
ansond 0:137634ff4186 1059 if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
ansond 0:137634ff4186 1060 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1061
ansond 0:137634ff4186 1062 *p++ = 0;
ansond 0:137634ff4186 1063 *p++ = RSA_SIGN;
ansond 0:137634ff4186 1064 memset( p, 0xFF, nb_pad );
ansond 0:137634ff4186 1065 p += nb_pad;
ansond 0:137634ff4186 1066 *p++ = 0;
ansond 0:137634ff4186 1067
ansond 0:137634ff4186 1068 if( md_alg == POLARSSL_MD_NONE )
ansond 0:137634ff4186 1069 {
ansond 0:137634ff4186 1070 memcpy( p, hash, hashlen );
ansond 0:137634ff4186 1071 }
ansond 0:137634ff4186 1072 else
ansond 0:137634ff4186 1073 {
ansond 0:137634ff4186 1074 /*
ansond 0:137634ff4186 1075 * DigestInfo ::= SEQUENCE {
ansond 0:137634ff4186 1076 * digestAlgorithm DigestAlgorithmIdentifier,
ansond 0:137634ff4186 1077 * digest Digest }
ansond 0:137634ff4186 1078 *
ansond 0:137634ff4186 1079 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
ansond 0:137634ff4186 1080 *
ansond 0:137634ff4186 1081 * Digest ::= OCTET STRING
ansond 0:137634ff4186 1082 */
ansond 0:137634ff4186 1083 *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
ansond 0:137634ff4186 1084 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
ansond 0:137634ff4186 1085 *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
ansond 0:137634ff4186 1086 *p++ = (unsigned char) ( 0x04 + oid_size );
ansond 0:137634ff4186 1087 *p++ = ASN1_OID;
ansond 0:137634ff4186 1088 *p++ = oid_size & 0xFF;
ansond 0:137634ff4186 1089 memcpy( p, oid, oid_size );
ansond 0:137634ff4186 1090 p += oid_size;
ansond 0:137634ff4186 1091 *p++ = ASN1_NULL;
ansond 0:137634ff4186 1092 *p++ = 0x00;
ansond 0:137634ff4186 1093 *p++ = ASN1_OCTET_STRING;
ansond 0:137634ff4186 1094 *p++ = hashlen;
ansond 0:137634ff4186 1095 memcpy( p, hash, hashlen );
ansond 0:137634ff4186 1096 }
ansond 0:137634ff4186 1097
ansond 0:137634ff4186 1098 return( ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 1099 ? rsa_public( ctx, sig, sig )
ansond 0:137634ff4186 1100 : rsa_private( ctx, f_rng, p_rng, sig, sig ) );
ansond 0:137634ff4186 1101 }
ansond 0:137634ff4186 1102 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 1103
ansond 0:137634ff4186 1104 /*
ansond 0:137634ff4186 1105 * Do an RSA operation to sign the message digest
ansond 0:137634ff4186 1106 */
ansond 0:137634ff4186 1107 int rsa_pkcs1_sign( rsa_context *ctx,
ansond 0:137634ff4186 1108 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1109 void *p_rng,
ansond 0:137634ff4186 1110 int mode,
ansond 0:137634ff4186 1111 md_type_t md_alg,
ansond 0:137634ff4186 1112 unsigned int hashlen,
ansond 0:137634ff4186 1113 const unsigned char *hash,
ansond 0:137634ff4186 1114 unsigned char *sig )
ansond 0:137634ff4186 1115 {
ansond 0:137634ff4186 1116 switch( ctx->padding )
ansond 0:137634ff4186 1117 {
ansond 0:137634ff4186 1118 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1119 case RSA_PKCS_V15:
ansond 0:137634ff4186 1120 return rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
ansond 0:137634ff4186 1121 hashlen, hash, sig );
ansond 0:137634ff4186 1122 #endif
ansond 0:137634ff4186 1123
ansond 0:137634ff4186 1124 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 1125 case RSA_PKCS_V21:
ansond 0:137634ff4186 1126 return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
ansond 0:137634ff4186 1127 hashlen, hash, sig );
ansond 0:137634ff4186 1128 #endif
ansond 0:137634ff4186 1129
ansond 0:137634ff4186 1130 default:
ansond 0:137634ff4186 1131 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1132 }
ansond 0:137634ff4186 1133 }
ansond 0:137634ff4186 1134
ansond 0:137634ff4186 1135 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 1136 /*
ansond 0:137634ff4186 1137 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
ansond 0:137634ff4186 1138 */
ansond 0:137634ff4186 1139 int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
ansond 0:137634ff4186 1140 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1141 void *p_rng,
ansond 0:137634ff4186 1142 int mode,
ansond 0:137634ff4186 1143 md_type_t md_alg,
ansond 0:137634ff4186 1144 unsigned int hashlen,
ansond 0:137634ff4186 1145 const unsigned char *hash,
ansond 0:137634ff4186 1146 md_type_t mgf1_hash_id,
ansond 0:137634ff4186 1147 int expected_salt_len,
ansond 0:137634ff4186 1148 const unsigned char *sig )
ansond 0:137634ff4186 1149 {
ansond 0:137634ff4186 1150 int ret;
ansond 0:137634ff4186 1151 size_t siglen;
ansond 0:137634ff4186 1152 unsigned char *p;
ansond 0:137634ff4186 1153 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
ansond 0:137634ff4186 1154 unsigned char result[POLARSSL_MD_MAX_SIZE];
ansond 0:137634ff4186 1155 unsigned char zeros[8];
ansond 0:137634ff4186 1156 unsigned int hlen;
ansond 0:137634ff4186 1157 size_t slen, msb;
ansond 0:137634ff4186 1158 const md_info_t *md_info;
ansond 0:137634ff4186 1159 md_context_t md_ctx;
ansond 0:137634ff4186 1160
ansond 0:137634ff4186 1161 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
ansond 0:137634ff4186 1162 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1163
ansond 0:137634ff4186 1164 siglen = ctx->len;
ansond 0:137634ff4186 1165
ansond 0:137634ff4186 1166 if( siglen < 16 || siglen > sizeof( buf ) )
ansond 0:137634ff4186 1167 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1168
ansond 0:137634ff4186 1169 ret = ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 1170 ? rsa_public( ctx, sig, buf )
ansond 0:137634ff4186 1171 : rsa_private( ctx, f_rng, p_rng, sig, buf );
ansond 0:137634ff4186 1172
ansond 0:137634ff4186 1173 if( ret != 0 )
ansond 0:137634ff4186 1174 return( ret );
ansond 0:137634ff4186 1175
ansond 0:137634ff4186 1176 p = buf;
ansond 0:137634ff4186 1177
ansond 0:137634ff4186 1178 if( buf[siglen - 1] != 0xBC )
ansond 0:137634ff4186 1179 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1180
ansond 0:137634ff4186 1181 if( md_alg != POLARSSL_MD_NONE )
ansond 0:137634ff4186 1182 {
ansond 0:137634ff4186 1183 // Gather length of hash to sign
ansond 0:137634ff4186 1184 //
ansond 0:137634ff4186 1185 md_info = md_info_from_type( md_alg );
ansond 0:137634ff4186 1186 if( md_info == NULL )
ansond 0:137634ff4186 1187 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1188
ansond 0:137634ff4186 1189 hashlen = md_get_size( md_info );
ansond 0:137634ff4186 1190 }
ansond 0:137634ff4186 1191
ansond 0:137634ff4186 1192 md_info = md_info_from_type( mgf1_hash_id );
ansond 0:137634ff4186 1193 if( md_info == NULL )
ansond 0:137634ff4186 1194 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1195
ansond 0:137634ff4186 1196 hlen = md_get_size( md_info );
ansond 0:137634ff4186 1197 slen = siglen - hlen - 1; /* Currently length of salt + padding */
ansond 0:137634ff4186 1198
ansond 0:137634ff4186 1199 memset( zeros, 0, 8 );
ansond 0:137634ff4186 1200
ansond 0:137634ff4186 1201 // Note: EMSA-PSS verification is over the length of N - 1 bits
ansond 0:137634ff4186 1202 //
ansond 0:137634ff4186 1203 msb = mpi_msb( &ctx->N ) - 1;
ansond 0:137634ff4186 1204
ansond 0:137634ff4186 1205 // Compensate for boundary condition when applying mask
ansond 0:137634ff4186 1206 //
ansond 0:137634ff4186 1207 if( msb % 8 == 0 )
ansond 0:137634ff4186 1208 {
ansond 0:137634ff4186 1209 p++;
ansond 0:137634ff4186 1210 siglen -= 1;
ansond 0:137634ff4186 1211 }
ansond 0:137634ff4186 1212 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
ansond 0:137634ff4186 1213 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1214
ansond 0:137634ff4186 1215 md_init( &md_ctx );
ansond 0:137634ff4186 1216 md_init_ctx( &md_ctx, md_info );
ansond 0:137634ff4186 1217
ansond 0:137634ff4186 1218 mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
ansond 0:137634ff4186 1219
ansond 0:137634ff4186 1220 buf[0] &= 0xFF >> ( siglen * 8 - msb );
ansond 0:137634ff4186 1221
ansond 0:137634ff4186 1222 while( p < buf + siglen && *p == 0 )
ansond 0:137634ff4186 1223 p++;
ansond 0:137634ff4186 1224
ansond 0:137634ff4186 1225 if( p == buf + siglen ||
ansond 0:137634ff4186 1226 *p++ != 0x01 )
ansond 0:137634ff4186 1227 {
ansond 0:137634ff4186 1228 md_free( &md_ctx );
ansond 0:137634ff4186 1229 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1230 }
ansond 0:137634ff4186 1231
ansond 0:137634ff4186 1232 /* Actual salt len */
ansond 0:137634ff4186 1233 slen -= p - buf;
ansond 0:137634ff4186 1234
ansond 0:137634ff4186 1235 if( expected_salt_len != RSA_SALT_LEN_ANY &&
ansond 0:137634ff4186 1236 slen != (size_t) expected_salt_len )
ansond 0:137634ff4186 1237 {
ansond 0:137634ff4186 1238 md_free( &md_ctx );
ansond 0:137634ff4186 1239 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1240 }
ansond 0:137634ff4186 1241
ansond 0:137634ff4186 1242 // Generate H = Hash( M' )
ansond 0:137634ff4186 1243 //
ansond 0:137634ff4186 1244 md_starts( &md_ctx );
ansond 0:137634ff4186 1245 md_update( &md_ctx, zeros, 8 );
ansond 0:137634ff4186 1246 md_update( &md_ctx, hash, hashlen );
ansond 0:137634ff4186 1247 md_update( &md_ctx, p, slen );
ansond 0:137634ff4186 1248 md_finish( &md_ctx, result );
ansond 0:137634ff4186 1249
ansond 0:137634ff4186 1250 md_free( &md_ctx );
ansond 0:137634ff4186 1251
ansond 0:137634ff4186 1252 if( memcmp( p + slen, result, hlen ) == 0 )
ansond 0:137634ff4186 1253 return( 0 );
ansond 0:137634ff4186 1254 else
ansond 0:137634ff4186 1255 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1256 }
ansond 0:137634ff4186 1257
ansond 0:137634ff4186 1258 /*
ansond 0:137634ff4186 1259 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
ansond 0:137634ff4186 1260 */
ansond 0:137634ff4186 1261 int rsa_rsassa_pss_verify( rsa_context *ctx,
ansond 0:137634ff4186 1262 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1263 void *p_rng,
ansond 0:137634ff4186 1264 int mode,
ansond 0:137634ff4186 1265 md_type_t md_alg,
ansond 0:137634ff4186 1266 unsigned int hashlen,
ansond 0:137634ff4186 1267 const unsigned char *hash,
ansond 0:137634ff4186 1268 const unsigned char *sig )
ansond 0:137634ff4186 1269 {
ansond 0:137634ff4186 1270 md_type_t mgf1_hash_id = ( ctx->hash_id != POLARSSL_MD_NONE )
ansond 0:137634ff4186 1271 ? (md_type_t) ctx->hash_id
ansond 0:137634ff4186 1272 : md_alg;
ansond 0:137634ff4186 1273
ansond 0:137634ff4186 1274 return( rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
ansond 0:137634ff4186 1275 md_alg, hashlen, hash,
ansond 0:137634ff4186 1276 mgf1_hash_id, RSA_SALT_LEN_ANY,
ansond 0:137634ff4186 1277 sig ) );
ansond 0:137634ff4186 1278
ansond 0:137634ff4186 1279 }
ansond 0:137634ff4186 1280 #endif /* POLARSSL_PKCS1_V21 */
ansond 0:137634ff4186 1281
ansond 0:137634ff4186 1282 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1283 /*
ansond 0:137634ff4186 1284 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
ansond 0:137634ff4186 1285 */
ansond 0:137634ff4186 1286 int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
ansond 0:137634ff4186 1287 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1288 void *p_rng,
ansond 0:137634ff4186 1289 int mode,
ansond 0:137634ff4186 1290 md_type_t md_alg,
ansond 0:137634ff4186 1291 unsigned int hashlen,
ansond 0:137634ff4186 1292 const unsigned char *hash,
ansond 0:137634ff4186 1293 const unsigned char *sig )
ansond 0:137634ff4186 1294 {
ansond 0:137634ff4186 1295 int ret;
ansond 0:137634ff4186 1296 size_t len, siglen, asn1_len;
ansond 0:137634ff4186 1297 unsigned char *p, *end;
ansond 0:137634ff4186 1298 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
ansond 0:137634ff4186 1299 md_type_t msg_md_alg;
ansond 0:137634ff4186 1300 const md_info_t *md_info;
ansond 0:137634ff4186 1301 asn1_buf oid;
ansond 0:137634ff4186 1302
ansond 0:137634ff4186 1303 if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
ansond 0:137634ff4186 1304 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1305
ansond 0:137634ff4186 1306 siglen = ctx->len;
ansond 0:137634ff4186 1307
ansond 0:137634ff4186 1308 if( siglen < 16 || siglen > sizeof( buf ) )
ansond 0:137634ff4186 1309 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1310
ansond 0:137634ff4186 1311 ret = ( mode == RSA_PUBLIC )
ansond 0:137634ff4186 1312 ? rsa_public( ctx, sig, buf )
ansond 0:137634ff4186 1313 : rsa_private( ctx, f_rng, p_rng, sig, buf );
ansond 0:137634ff4186 1314
ansond 0:137634ff4186 1315 if( ret != 0 )
ansond 0:137634ff4186 1316 return( ret );
ansond 0:137634ff4186 1317
ansond 0:137634ff4186 1318 p = buf;
ansond 0:137634ff4186 1319
ansond 0:137634ff4186 1320 if( *p++ != 0 || *p++ != RSA_SIGN )
ansond 0:137634ff4186 1321 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1322
ansond 0:137634ff4186 1323 while( *p != 0 )
ansond 0:137634ff4186 1324 {
ansond 0:137634ff4186 1325 if( p >= buf + siglen - 1 || *p != 0xFF )
ansond 0:137634ff4186 1326 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1327 p++;
ansond 0:137634ff4186 1328 }
ansond 0:137634ff4186 1329 p++;
ansond 0:137634ff4186 1330
ansond 0:137634ff4186 1331 len = siglen - ( p - buf );
ansond 0:137634ff4186 1332
ansond 0:137634ff4186 1333 if( len == hashlen && md_alg == POLARSSL_MD_NONE )
ansond 0:137634ff4186 1334 {
ansond 0:137634ff4186 1335 if( memcmp( p, hash, hashlen ) == 0 )
ansond 0:137634ff4186 1336 return( 0 );
ansond 0:137634ff4186 1337 else
ansond 0:137634ff4186 1338 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1339 }
ansond 0:137634ff4186 1340
ansond 0:137634ff4186 1341 md_info = md_info_from_type( md_alg );
ansond 0:137634ff4186 1342 if( md_info == NULL )
ansond 0:137634ff4186 1343 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
ansond 0:137634ff4186 1344 hashlen = md_get_size( md_info );
ansond 0:137634ff4186 1345
ansond 0:137634ff4186 1346 end = p + len;
ansond 0:137634ff4186 1347
ansond 0:137634ff4186 1348 // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
ansond 0:137634ff4186 1349 //
ansond 0:137634ff4186 1350 if( ( ret = asn1_get_tag( &p, end, &asn1_len,
ansond 0:137634ff4186 1351 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
ansond 0:137634ff4186 1352 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1353
ansond 0:137634ff4186 1354 if( asn1_len + 2 != len )
ansond 0:137634ff4186 1355 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1356
ansond 0:137634ff4186 1357 if( ( ret = asn1_get_tag( &p, end, &asn1_len,
ansond 0:137634ff4186 1358 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
ansond 0:137634ff4186 1359 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1360
ansond 0:137634ff4186 1361 if( asn1_len + 6 + hashlen != len )
ansond 0:137634ff4186 1362 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1363
ansond 0:137634ff4186 1364 if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 )
ansond 0:137634ff4186 1365 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1366
ansond 0:137634ff4186 1367 oid.p = p;
ansond 0:137634ff4186 1368 p += oid.len;
ansond 0:137634ff4186 1369
ansond 0:137634ff4186 1370 if( oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
ansond 0:137634ff4186 1371 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1372
ansond 0:137634ff4186 1373 if( md_alg != msg_md_alg )
ansond 0:137634ff4186 1374 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1375
ansond 0:137634ff4186 1376 /*
ansond 0:137634ff4186 1377 * assume the algorithm parameters must be NULL
ansond 0:137634ff4186 1378 */
ansond 0:137634ff4186 1379 if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 )
ansond 0:137634ff4186 1380 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1381
ansond 0:137634ff4186 1382 if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 )
ansond 0:137634ff4186 1383 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1384
ansond 0:137634ff4186 1385 if( asn1_len != hashlen )
ansond 0:137634ff4186 1386 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1387
ansond 0:137634ff4186 1388 if( memcmp( p, hash, hashlen ) != 0 )
ansond 0:137634ff4186 1389 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1390
ansond 0:137634ff4186 1391 p += hashlen;
ansond 0:137634ff4186 1392
ansond 0:137634ff4186 1393 if( p != end )
ansond 0:137634ff4186 1394 return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ansond 0:137634ff4186 1395
ansond 0:137634ff4186 1396 return( 0 );
ansond 0:137634ff4186 1397 }
ansond 0:137634ff4186 1398 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 1399
ansond 0:137634ff4186 1400 /*
ansond 0:137634ff4186 1401 * Do an RSA operation and check the message digest
ansond 0:137634ff4186 1402 */
ansond 0:137634ff4186 1403 int rsa_pkcs1_verify( rsa_context *ctx,
ansond 0:137634ff4186 1404 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 1405 void *p_rng,
ansond 0:137634ff4186 1406 int mode,
ansond 0:137634ff4186 1407 md_type_t md_alg,
ansond 0:137634ff4186 1408 unsigned int hashlen,
ansond 0:137634ff4186 1409 const unsigned char *hash,
ansond 0:137634ff4186 1410 const unsigned char *sig )
ansond 0:137634ff4186 1411 {
ansond 0:137634ff4186 1412 switch( ctx->padding )
ansond 0:137634ff4186 1413 {
ansond 0:137634ff4186 1414 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1415 case RSA_PKCS_V15:
ansond 0:137634ff4186 1416 return rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
ansond 0:137634ff4186 1417 hashlen, hash, sig );
ansond 0:137634ff4186 1418 #endif
ansond 0:137634ff4186 1419
ansond 0:137634ff4186 1420 #if defined(POLARSSL_PKCS1_V21)
ansond 0:137634ff4186 1421 case RSA_PKCS_V21:
ansond 0:137634ff4186 1422 return rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
ansond 0:137634ff4186 1423 hashlen, hash, sig );
ansond 0:137634ff4186 1424 #endif
ansond 0:137634ff4186 1425
ansond 0:137634ff4186 1426 default:
ansond 0:137634ff4186 1427 return( POLARSSL_ERR_RSA_INVALID_PADDING );
ansond 0:137634ff4186 1428 }
ansond 0:137634ff4186 1429 }
ansond 0:137634ff4186 1430
ansond 0:137634ff4186 1431 /*
ansond 0:137634ff4186 1432 * Copy the components of an RSA key
ansond 0:137634ff4186 1433 */
ansond 0:137634ff4186 1434 int rsa_copy( rsa_context *dst, const rsa_context *src )
ansond 0:137634ff4186 1435 {
ansond 0:137634ff4186 1436 int ret;
ansond 0:137634ff4186 1437
ansond 0:137634ff4186 1438 dst->ver = src->ver;
ansond 0:137634ff4186 1439 dst->len = src->len;
ansond 0:137634ff4186 1440
ansond 0:137634ff4186 1441 MPI_CHK( mpi_copy( &dst->N, &src->N ) );
ansond 0:137634ff4186 1442 MPI_CHK( mpi_copy( &dst->E, &src->E ) );
ansond 0:137634ff4186 1443
ansond 0:137634ff4186 1444 MPI_CHK( mpi_copy( &dst->D, &src->D ) );
ansond 0:137634ff4186 1445 MPI_CHK( mpi_copy( &dst->P, &src->P ) );
ansond 0:137634ff4186 1446 MPI_CHK( mpi_copy( &dst->Q, &src->Q ) );
ansond 0:137634ff4186 1447 MPI_CHK( mpi_copy( &dst->DP, &src->DP ) );
ansond 0:137634ff4186 1448 MPI_CHK( mpi_copy( &dst->DQ, &src->DQ ) );
ansond 0:137634ff4186 1449 MPI_CHK( mpi_copy( &dst->QP, &src->QP ) );
ansond 0:137634ff4186 1450
ansond 0:137634ff4186 1451 MPI_CHK( mpi_copy( &dst->RN, &src->RN ) );
ansond 0:137634ff4186 1452 MPI_CHK( mpi_copy( &dst->RP, &src->RP ) );
ansond 0:137634ff4186 1453 MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) );
ansond 0:137634ff4186 1454
ansond 0:137634ff4186 1455 MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) );
ansond 0:137634ff4186 1456 MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) );
ansond 0:137634ff4186 1457
ansond 0:137634ff4186 1458 dst->padding = src->padding;
ansond 0:137634ff4186 1459 dst->hash_id = src->hash_id;
ansond 0:137634ff4186 1460
ansond 0:137634ff4186 1461 cleanup:
ansond 0:137634ff4186 1462 if( ret != 0 )
ansond 0:137634ff4186 1463 rsa_free( dst );
ansond 0:137634ff4186 1464
ansond 0:137634ff4186 1465 return( ret );
ansond 0:137634ff4186 1466 }
ansond 0:137634ff4186 1467
ansond 0:137634ff4186 1468 /*
ansond 0:137634ff4186 1469 * Free the components of an RSA key
ansond 0:137634ff4186 1470 */
ansond 0:137634ff4186 1471 void rsa_free( rsa_context *ctx )
ansond 0:137634ff4186 1472 {
ansond 0:137634ff4186 1473 mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf );
ansond 0:137634ff4186 1474 mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
ansond 0:137634ff4186 1475 mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
ansond 0:137634ff4186 1476 mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D );
ansond 0:137634ff4186 1477 mpi_free( &ctx->E ); mpi_free( &ctx->N );
ansond 0:137634ff4186 1478
ansond 0:137634ff4186 1479 #if defined(POLARSSL_THREADING_C)
ansond 0:137634ff4186 1480 polarssl_mutex_free( &ctx->mutex );
ansond 0:137634ff4186 1481 #endif
ansond 0:137634ff4186 1482 }
ansond 0:137634ff4186 1483
ansond 0:137634ff4186 1484 #if defined(POLARSSL_SELF_TEST)
ansond 0:137634ff4186 1485
ansond 0:137634ff4186 1486 #include "polarssl/sha1.h"
ansond 0:137634ff4186 1487
ansond 0:137634ff4186 1488 /*
ansond 0:137634ff4186 1489 * Example RSA-1024 keypair, for test purposes
ansond 0:137634ff4186 1490 */
ansond 0:137634ff4186 1491 #define KEY_LEN 128
ansond 0:137634ff4186 1492
ansond 0:137634ff4186 1493 #define RSA_N "9292758453063D803DD603D5E777D788" \
ansond 0:137634ff4186 1494 "8ED1D5BF35786190FA2F23EBC0848AEA" \
ansond 0:137634ff4186 1495 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
ansond 0:137634ff4186 1496 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
ansond 0:137634ff4186 1497 "93A89813FBF3C4F8066D2D800F7C38A8" \
ansond 0:137634ff4186 1498 "1AE31942917403FF4946B0A83D3D3E05" \
ansond 0:137634ff4186 1499 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
ansond 0:137634ff4186 1500 "5E94BB77B07507233A0BC7BAC8F90F79"
ansond 0:137634ff4186 1501
ansond 0:137634ff4186 1502 #define RSA_E "10001"
ansond 0:137634ff4186 1503
ansond 0:137634ff4186 1504 #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
ansond 0:137634ff4186 1505 "66CA472BC44D253102F8B4A9D3BFA750" \
ansond 0:137634ff4186 1506 "91386C0077937FE33FA3252D28855837" \
ansond 0:137634ff4186 1507 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
ansond 0:137634ff4186 1508 "DF79C5CE07EE72C7F123142198164234" \
ansond 0:137634ff4186 1509 "CABB724CF78B8173B9F880FC86322407" \
ansond 0:137634ff4186 1510 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
ansond 0:137634ff4186 1511 "071513A1E85B5DFA031F21ECAE91A34D"
ansond 0:137634ff4186 1512
ansond 0:137634ff4186 1513 #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
ansond 0:137634ff4186 1514 "2C01CAD19EA484A87EA4377637E75500" \
ansond 0:137634ff4186 1515 "FCB2005C5C7DD6EC4AC023CDA285D796" \
ansond 0:137634ff4186 1516 "C3D9E75E1EFC42488BB4F1D13AC30A57"
ansond 0:137634ff4186 1517
ansond 0:137634ff4186 1518 #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
ansond 0:137634ff4186 1519 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
ansond 0:137634ff4186 1520 "910E4168387E3C30AA1E00C339A79508" \
ansond 0:137634ff4186 1521 "8452DD96A9A5EA5D9DCA68DA636032AF"
ansond 0:137634ff4186 1522
ansond 0:137634ff4186 1523 #define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
ansond 0:137634ff4186 1524 "3C94D22288ACD763FD8E5600ED4A702D" \
ansond 0:137634ff4186 1525 "F84198A5F06C2E72236AE490C93F07F8" \
ansond 0:137634ff4186 1526 "3CC559CD27BC2D1CA488811730BB5725"
ansond 0:137634ff4186 1527
ansond 0:137634ff4186 1528 #define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
ansond 0:137634ff4186 1529 "D8AAEA56749EA28623272E4F7D0592AF" \
ansond 0:137634ff4186 1530 "7C1F1313CAC9471B5C523BFE592F517B" \
ansond 0:137634ff4186 1531 "407A1BD76C164B93DA2D32A383E58357"
ansond 0:137634ff4186 1532
ansond 0:137634ff4186 1533 #define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
ansond 0:137634ff4186 1534 "F38D18D2B2F0E2DD275AA977E2BF4411" \
ansond 0:137634ff4186 1535 "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
ansond 0:137634ff4186 1536 "A74206CEC169D74BF5A8C50D6F48EA08"
ansond 0:137634ff4186 1537
ansond 0:137634ff4186 1538 #define PT_LEN 24
ansond 0:137634ff4186 1539 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
ansond 0:137634ff4186 1540 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
ansond 0:137634ff4186 1541
ansond 0:137634ff4186 1542 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1543 static int myrand( void *rng_state, unsigned char *output, size_t len )
ansond 0:137634ff4186 1544 {
ansond 0:137634ff4186 1545 #if !defined(__OpenBSD__)
ansond 0:137634ff4186 1546 size_t i;
ansond 0:137634ff4186 1547
ansond 0:137634ff4186 1548 if( rng_state != NULL )
ansond 0:137634ff4186 1549 rng_state = NULL;
ansond 0:137634ff4186 1550
ansond 0:137634ff4186 1551 for( i = 0; i < len; ++i )
ansond 0:137634ff4186 1552 output[i] = rand();
ansond 0:137634ff4186 1553 #else
ansond 0:137634ff4186 1554 if( rng_state != NULL )
ansond 0:137634ff4186 1555 rng_state = NULL;
ansond 0:137634ff4186 1556
ansond 0:137634ff4186 1557 arc4random_buf( output, len );
ansond 0:137634ff4186 1558 #endif /* !OpenBSD */
ansond 0:137634ff4186 1559
ansond 0:137634ff4186 1560 return( 0 );
ansond 0:137634ff4186 1561 }
ansond 0:137634ff4186 1562 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 1563
ansond 0:137634ff4186 1564 /*
ansond 0:137634ff4186 1565 * Checkup routine
ansond 0:137634ff4186 1566 */
ansond 0:137634ff4186 1567 int rsa_self_test( int verbose )
ansond 0:137634ff4186 1568 {
ansond 0:137634ff4186 1569 int ret = 0;
ansond 0:137634ff4186 1570 #if defined(POLARSSL_PKCS1_V15)
ansond 0:137634ff4186 1571 size_t len;
ansond 0:137634ff4186 1572 rsa_context rsa;
ansond 0:137634ff4186 1573 unsigned char rsa_plaintext[PT_LEN];
ansond 0:137634ff4186 1574 unsigned char rsa_decrypted[PT_LEN];
ansond 0:137634ff4186 1575 unsigned char rsa_ciphertext[KEY_LEN];
ansond 0:137634ff4186 1576 #if defined(POLARSSL_SHA1_C)
ansond 0:137634ff4186 1577 unsigned char sha1sum[20];
ansond 0:137634ff4186 1578 #endif
ansond 0:137634ff4186 1579
ansond 0:137634ff4186 1580 rsa_init( &rsa, RSA_PKCS_V15, 0 );
ansond 0:137634ff4186 1581
ansond 0:137634ff4186 1582 rsa.len = KEY_LEN;
ansond 0:137634ff4186 1583 MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) );
ansond 0:137634ff4186 1584 MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) );
ansond 0:137634ff4186 1585 MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) );
ansond 0:137634ff4186 1586 MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) );
ansond 0:137634ff4186 1587 MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) );
ansond 0:137634ff4186 1588 MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) );
ansond 0:137634ff4186 1589 MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) );
ansond 0:137634ff4186 1590 MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) );
ansond 0:137634ff4186 1591
ansond 0:137634ff4186 1592 if( verbose != 0 )
ansond 0:137634ff4186 1593 polarssl_printf( " RSA key validation: " );
ansond 0:137634ff4186 1594
ansond 0:137634ff4186 1595 if( rsa_check_pubkey( &rsa ) != 0 ||
ansond 0:137634ff4186 1596 rsa_check_privkey( &rsa ) != 0 )
ansond 0:137634ff4186 1597 {
ansond 0:137634ff4186 1598 if( verbose != 0 )
ansond 0:137634ff4186 1599 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1600
ansond 0:137634ff4186 1601 return( 1 );
ansond 0:137634ff4186 1602 }
ansond 0:137634ff4186 1603
ansond 0:137634ff4186 1604 if( verbose != 0 )
ansond 0:137634ff4186 1605 polarssl_printf( "passed\n PKCS#1 encryption : " );
ansond 0:137634ff4186 1606
ansond 0:137634ff4186 1607 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
ansond 0:137634ff4186 1608
ansond 0:137634ff4186 1609 if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN,
ansond 0:137634ff4186 1610 rsa_plaintext, rsa_ciphertext ) != 0 )
ansond 0:137634ff4186 1611 {
ansond 0:137634ff4186 1612 if( verbose != 0 )
ansond 0:137634ff4186 1613 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1614
ansond 0:137634ff4186 1615 return( 1 );
ansond 0:137634ff4186 1616 }
ansond 0:137634ff4186 1617
ansond 0:137634ff4186 1618 if( verbose != 0 )
ansond 0:137634ff4186 1619 polarssl_printf( "passed\n PKCS#1 decryption : " );
ansond 0:137634ff4186 1620
ansond 0:137634ff4186 1621 if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len,
ansond 0:137634ff4186 1622 rsa_ciphertext, rsa_decrypted,
ansond 0:137634ff4186 1623 sizeof(rsa_decrypted) ) != 0 )
ansond 0:137634ff4186 1624 {
ansond 0:137634ff4186 1625 if( verbose != 0 )
ansond 0:137634ff4186 1626 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1627
ansond 0:137634ff4186 1628 return( 1 );
ansond 0:137634ff4186 1629 }
ansond 0:137634ff4186 1630
ansond 0:137634ff4186 1631 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
ansond 0:137634ff4186 1632 {
ansond 0:137634ff4186 1633 if( verbose != 0 )
ansond 0:137634ff4186 1634 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1635
ansond 0:137634ff4186 1636 return( 1 );
ansond 0:137634ff4186 1637 }
ansond 0:137634ff4186 1638
ansond 0:137634ff4186 1639 #if defined(POLARSSL_SHA1_C)
ansond 0:137634ff4186 1640 if( verbose != 0 )
ansond 0:137634ff4186 1641 polarssl_printf( "passed\n PKCS#1 data sign : " );
ansond 0:137634ff4186 1642
ansond 0:137634ff4186 1643 sha1( rsa_plaintext, PT_LEN, sha1sum );
ansond 0:137634ff4186 1644
ansond 0:137634ff4186 1645 if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0,
ansond 0:137634ff4186 1646 sha1sum, rsa_ciphertext ) != 0 )
ansond 0:137634ff4186 1647 {
ansond 0:137634ff4186 1648 if( verbose != 0 )
ansond 0:137634ff4186 1649 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1650
ansond 0:137634ff4186 1651 return( 1 );
ansond 0:137634ff4186 1652 }
ansond 0:137634ff4186 1653
ansond 0:137634ff4186 1654 if( verbose != 0 )
ansond 0:137634ff4186 1655 polarssl_printf( "passed\n PKCS#1 sig. verify: " );
ansond 0:137634ff4186 1656
ansond 0:137634ff4186 1657 if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0,
ansond 0:137634ff4186 1658 sha1sum, rsa_ciphertext ) != 0 )
ansond 0:137634ff4186 1659 {
ansond 0:137634ff4186 1660 if( verbose != 0 )
ansond 0:137634ff4186 1661 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 1662
ansond 0:137634ff4186 1663 return( 1 );
ansond 0:137634ff4186 1664 }
ansond 0:137634ff4186 1665
ansond 0:137634ff4186 1666 if( verbose != 0 )
ansond 0:137634ff4186 1667 polarssl_printf( "passed\n\n" );
ansond 0:137634ff4186 1668 #endif /* POLARSSL_SHA1_C */
ansond 0:137634ff4186 1669
ansond 0:137634ff4186 1670 cleanup:
ansond 0:137634ff4186 1671 rsa_free( &rsa );
ansond 0:137634ff4186 1672 #else /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 1673 ((void) verbose);
ansond 0:137634ff4186 1674 #endif /* POLARSSL_PKCS1_V15 */
ansond 0:137634ff4186 1675 return( ret );
ansond 0:137634ff4186 1676 }
ansond 0:137634ff4186 1677
ansond 0:137634ff4186 1678 #endif /* POLARSSL_SELF_TEST */
ansond 0:137634ff4186 1679
ansond 0:137634ff4186 1680 #endif /* POLARSSL_RSA_C */
ansond 0:137634ff4186 1681