Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

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