mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Committer:
Christopher Haster
Date:
Fri Jan 22 16:44:49 2016 -0600
Revision:
1:24750b9ad5ef
Initial move of mbedtls to mercurial

Who changed what in which revision?

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