mbed TLS Build

Dependents:   Slave-prot-prod

Committer:
markrad
Date:
Thu Jan 05 00:18:44 2017 +0000
Revision:
0:cdf462088d13
Initial commit

Who changed what in which revision?

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