BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

UserRevisionLine numberNew contents of line
borlanic 0:fbdae7e6d805 1 /*
borlanic 0:fbdae7e6d805 2 * The RSA public-key cryptosystem
borlanic 0:fbdae7e6d805 3 *
borlanic 0:fbdae7e6d805 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
borlanic 0:fbdae7e6d805 5 * SPDX-License-Identifier: Apache-2.0
borlanic 0:fbdae7e6d805 6 *
borlanic 0:fbdae7e6d805 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
borlanic 0:fbdae7e6d805 8 * not use this file except in compliance with the License.
borlanic 0:fbdae7e6d805 9 * You may obtain a copy of the License at
borlanic 0:fbdae7e6d805 10 *
borlanic 0:fbdae7e6d805 11 * http://www.apache.org/licenses/LICENSE-2.0
borlanic 0:fbdae7e6d805 12 *
borlanic 0:fbdae7e6d805 13 * Unless required by applicable law or agreed to in writing, software
borlanic 0:fbdae7e6d805 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
borlanic 0:fbdae7e6d805 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
borlanic 0:fbdae7e6d805 16 * See the License for the specific language governing permissions and
borlanic 0:fbdae7e6d805 17 * limitations under the License.
borlanic 0:fbdae7e6d805 18 *
borlanic 0:fbdae7e6d805 19 * This file is part of mbed TLS (https://tls.mbed.org)
borlanic 0:fbdae7e6d805 20 */
borlanic 0:fbdae7e6d805 21
borlanic 0:fbdae7e6d805 22 /*
borlanic 0:fbdae7e6d805 23 * The following sources were referenced in the design of this implementation
borlanic 0:fbdae7e6d805 24 * of the RSA algorithm:
borlanic 0:fbdae7e6d805 25 *
borlanic 0:fbdae7e6d805 26 * [1] A method for obtaining digital signatures and public-key cryptosystems
borlanic 0:fbdae7e6d805 27 * R Rivest, A Shamir, and L Adleman
borlanic 0:fbdae7e6d805 28 * http://people.csail.mit.edu/rivest/pubs.html#RSA78
borlanic 0:fbdae7e6d805 29 *
borlanic 0:fbdae7e6d805 30 * [2] Handbook of Applied Cryptography - 1997, Chapter 8
borlanic 0:fbdae7e6d805 31 * Menezes, van Oorschot and Vanstone
borlanic 0:fbdae7e6d805 32 *
borlanic 0:fbdae7e6d805 33 * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
borlanic 0:fbdae7e6d805 34 * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
borlanic 0:fbdae7e6d805 35 * Stefan Mangard
borlanic 0:fbdae7e6d805 36 * https://arxiv.org/abs/1702.08719v2
borlanic 0:fbdae7e6d805 37 *
borlanic 0:fbdae7e6d805 38 */
borlanic 0:fbdae7e6d805 39
borlanic 0:fbdae7e6d805 40 #if !defined(MBEDTLS_CONFIG_FILE)
borlanic 0:fbdae7e6d805 41 #include "mbedtls/config.h"
borlanic 0:fbdae7e6d805 42 #else
borlanic 0:fbdae7e6d805 43 #include MBEDTLS_CONFIG_FILE
borlanic 0:fbdae7e6d805 44 #endif
borlanic 0:fbdae7e6d805 45
borlanic 0:fbdae7e6d805 46 #if defined(MBEDTLS_RSA_C)
borlanic 0:fbdae7e6d805 47
borlanic 0:fbdae7e6d805 48 #include "mbedtls/rsa.h"
borlanic 0:fbdae7e6d805 49 #include "mbedtls/rsa_internal.h"
borlanic 0:fbdae7e6d805 50 #include "mbedtls/oid.h"
borlanic 0:fbdae7e6d805 51
borlanic 0:fbdae7e6d805 52 #include <string.h>
borlanic 0:fbdae7e6d805 53
borlanic 0:fbdae7e6d805 54 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 55 #include "mbedtls/md.h"
borlanic 0:fbdae7e6d805 56 #endif
borlanic 0:fbdae7e6d805 57
borlanic 0:fbdae7e6d805 58 #if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
borlanic 0:fbdae7e6d805 59 #include <stdlib.h>
borlanic 0:fbdae7e6d805 60 #endif
borlanic 0:fbdae7e6d805 61
borlanic 0:fbdae7e6d805 62 #if defined(MBEDTLS_PLATFORM_C)
borlanic 0:fbdae7e6d805 63 #include "mbedtls/platform.h"
borlanic 0:fbdae7e6d805 64 #else
borlanic 0:fbdae7e6d805 65 #include <stdio.h>
borlanic 0:fbdae7e6d805 66 #define mbedtls_printf printf
borlanic 0:fbdae7e6d805 67 #define mbedtls_calloc calloc
borlanic 0:fbdae7e6d805 68 #define mbedtls_free free
borlanic 0:fbdae7e6d805 69 #endif
borlanic 0:fbdae7e6d805 70
borlanic 0:fbdae7e6d805 71 #if !defined(MBEDTLS_RSA_ALT)
borlanic 0:fbdae7e6d805 72
borlanic 0:fbdae7e6d805 73 /* Implementation that should never be optimized out by the compiler */
borlanic 0:fbdae7e6d805 74 static void mbedtls_zeroize( void *v, size_t n ) {
borlanic 0:fbdae7e6d805 75 volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
borlanic 0:fbdae7e6d805 76 }
borlanic 0:fbdae7e6d805 77
borlanic 0:fbdae7e6d805 78 /* constant-time buffer comparison */
borlanic 0:fbdae7e6d805 79 static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
borlanic 0:fbdae7e6d805 80 {
borlanic 0:fbdae7e6d805 81 size_t i;
borlanic 0:fbdae7e6d805 82 const unsigned char *A = (const unsigned char *) a;
borlanic 0:fbdae7e6d805 83 const unsigned char *B = (const unsigned char *) b;
borlanic 0:fbdae7e6d805 84 unsigned char diff = 0;
borlanic 0:fbdae7e6d805 85
borlanic 0:fbdae7e6d805 86 for( i = 0; i < n; i++ )
borlanic 0:fbdae7e6d805 87 diff |= A[i] ^ B[i];
borlanic 0:fbdae7e6d805 88
borlanic 0:fbdae7e6d805 89 return( diff );
borlanic 0:fbdae7e6d805 90 }
borlanic 0:fbdae7e6d805 91
borlanic 0:fbdae7e6d805 92 int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 93 const mbedtls_mpi *N,
borlanic 0:fbdae7e6d805 94 const mbedtls_mpi *P, const mbedtls_mpi *Q,
borlanic 0:fbdae7e6d805 95 const mbedtls_mpi *D, const mbedtls_mpi *E )
borlanic 0:fbdae7e6d805 96 {
borlanic 0:fbdae7e6d805 97 int ret;
borlanic 0:fbdae7e6d805 98
borlanic 0:fbdae7e6d805 99 if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 100 ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 101 ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 102 ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 103 ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
borlanic 0:fbdae7e6d805 104 {
borlanic 0:fbdae7e6d805 105 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 106 }
borlanic 0:fbdae7e6d805 107
borlanic 0:fbdae7e6d805 108 if( N != NULL )
borlanic 0:fbdae7e6d805 109 ctx->len = mbedtls_mpi_size( &ctx->N );
borlanic 0:fbdae7e6d805 110
borlanic 0:fbdae7e6d805 111 return( 0 );
borlanic 0:fbdae7e6d805 112 }
borlanic 0:fbdae7e6d805 113
borlanic 0:fbdae7e6d805 114 int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 115 unsigned char const *N, size_t N_len,
borlanic 0:fbdae7e6d805 116 unsigned char const *P, size_t P_len,
borlanic 0:fbdae7e6d805 117 unsigned char const *Q, size_t Q_len,
borlanic 0:fbdae7e6d805 118 unsigned char const *D, size_t D_len,
borlanic 0:fbdae7e6d805 119 unsigned char const *E, size_t E_len )
borlanic 0:fbdae7e6d805 120 {
borlanic 0:fbdae7e6d805 121 int ret = 0;
borlanic 0:fbdae7e6d805 122
borlanic 0:fbdae7e6d805 123 if( N != NULL )
borlanic 0:fbdae7e6d805 124 {
borlanic 0:fbdae7e6d805 125 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
borlanic 0:fbdae7e6d805 126 ctx->len = mbedtls_mpi_size( &ctx->N );
borlanic 0:fbdae7e6d805 127 }
borlanic 0:fbdae7e6d805 128
borlanic 0:fbdae7e6d805 129 if( P != NULL )
borlanic 0:fbdae7e6d805 130 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
borlanic 0:fbdae7e6d805 131
borlanic 0:fbdae7e6d805 132 if( Q != NULL )
borlanic 0:fbdae7e6d805 133 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
borlanic 0:fbdae7e6d805 134
borlanic 0:fbdae7e6d805 135 if( D != NULL )
borlanic 0:fbdae7e6d805 136 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
borlanic 0:fbdae7e6d805 137
borlanic 0:fbdae7e6d805 138 if( E != NULL )
borlanic 0:fbdae7e6d805 139 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
borlanic 0:fbdae7e6d805 140
borlanic 0:fbdae7e6d805 141 cleanup:
borlanic 0:fbdae7e6d805 142
borlanic 0:fbdae7e6d805 143 if( ret != 0 )
borlanic 0:fbdae7e6d805 144 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 145
borlanic 0:fbdae7e6d805 146 return( 0 );
borlanic 0:fbdae7e6d805 147 }
borlanic 0:fbdae7e6d805 148
borlanic 0:fbdae7e6d805 149 /*
borlanic 0:fbdae7e6d805 150 * Checks whether the context fields are set in such a way
borlanic 0:fbdae7e6d805 151 * that the RSA primitives will be able to execute without error.
borlanic 0:fbdae7e6d805 152 * It does *not* make guarantees for consistency of the parameters.
borlanic 0:fbdae7e6d805 153 */
borlanic 0:fbdae7e6d805 154 static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
borlanic 0:fbdae7e6d805 155 int blinding_needed )
borlanic 0:fbdae7e6d805 156 {
borlanic 0:fbdae7e6d805 157 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 158 /* blinding_needed is only used for NO_CRT to decide whether
borlanic 0:fbdae7e6d805 159 * P,Q need to be present or not. */
borlanic 0:fbdae7e6d805 160 ((void) blinding_needed);
borlanic 0:fbdae7e6d805 161 #endif
borlanic 0:fbdae7e6d805 162
borlanic 0:fbdae7e6d805 163 if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
borlanic 0:fbdae7e6d805 164 ctx->len > MBEDTLS_MPI_MAX_SIZE )
borlanic 0:fbdae7e6d805 165 {
borlanic 0:fbdae7e6d805 166 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 167 }
borlanic 0:fbdae7e6d805 168
borlanic 0:fbdae7e6d805 169 /*
borlanic 0:fbdae7e6d805 170 * 1. Modular exponentiation needs positive, odd moduli.
borlanic 0:fbdae7e6d805 171 */
borlanic 0:fbdae7e6d805 172
borlanic 0:fbdae7e6d805 173 /* Modular exponentiation wrt. N is always used for
borlanic 0:fbdae7e6d805 174 * RSA public key operations. */
borlanic 0:fbdae7e6d805 175 if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
borlanic 0:fbdae7e6d805 176 mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0 )
borlanic 0:fbdae7e6d805 177 {
borlanic 0:fbdae7e6d805 178 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 179 }
borlanic 0:fbdae7e6d805 180
borlanic 0:fbdae7e6d805 181 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 182 /* Modular exponentiation for P and Q is only
borlanic 0:fbdae7e6d805 183 * used for private key operations and if CRT
borlanic 0:fbdae7e6d805 184 * is used. */
borlanic 0:fbdae7e6d805 185 if( is_priv &&
borlanic 0:fbdae7e6d805 186 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
borlanic 0:fbdae7e6d805 187 mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
borlanic 0:fbdae7e6d805 188 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
borlanic 0:fbdae7e6d805 189 mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0 ) )
borlanic 0:fbdae7e6d805 190 {
borlanic 0:fbdae7e6d805 191 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 192 }
borlanic 0:fbdae7e6d805 193 #endif /* !MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 194
borlanic 0:fbdae7e6d805 195 /*
borlanic 0:fbdae7e6d805 196 * 2. Exponents must be positive
borlanic 0:fbdae7e6d805 197 */
borlanic 0:fbdae7e6d805 198
borlanic 0:fbdae7e6d805 199 /* Always need E for public key operations */
borlanic 0:fbdae7e6d805 200 if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
borlanic 0:fbdae7e6d805 201 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 202
borlanic 0:fbdae7e6d805 203 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 204 /* For private key operations, use D or DP & DQ
borlanic 0:fbdae7e6d805 205 * as (unblinded) exponents. */
borlanic 0:fbdae7e6d805 206 if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
borlanic 0:fbdae7e6d805 207 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 208 #else
borlanic 0:fbdae7e6d805 209 if( is_priv &&
borlanic 0:fbdae7e6d805 210 ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
borlanic 0:fbdae7e6d805 211 mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0 ) )
borlanic 0:fbdae7e6d805 212 {
borlanic 0:fbdae7e6d805 213 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 214 }
borlanic 0:fbdae7e6d805 215 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 216
borlanic 0:fbdae7e6d805 217 /* Blinding shouldn't make exponents negative either,
borlanic 0:fbdae7e6d805 218 * so check that P, Q >= 1 if that hasn't yet been
borlanic 0:fbdae7e6d805 219 * done as part of 1. */
borlanic 0:fbdae7e6d805 220 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 221 if( is_priv && blinding_needed &&
borlanic 0:fbdae7e6d805 222 ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
borlanic 0:fbdae7e6d805 223 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
borlanic 0:fbdae7e6d805 224 {
borlanic 0:fbdae7e6d805 225 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 226 }
borlanic 0:fbdae7e6d805 227 #endif
borlanic 0:fbdae7e6d805 228
borlanic 0:fbdae7e6d805 229 /* It wouldn't lead to an error if it wasn't satisfied,
borlanic 0:fbdae7e6d805 230 * but check for QP >= 1 nonetheless. */
borlanic 0:fbdae7e6d805 231 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 232 if( is_priv &&
borlanic 0:fbdae7e6d805 233 mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
borlanic 0:fbdae7e6d805 234 {
borlanic 0:fbdae7e6d805 235 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 236 }
borlanic 0:fbdae7e6d805 237 #endif
borlanic 0:fbdae7e6d805 238
borlanic 0:fbdae7e6d805 239 return( 0 );
borlanic 0:fbdae7e6d805 240 }
borlanic 0:fbdae7e6d805 241
borlanic 0:fbdae7e6d805 242 int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
borlanic 0:fbdae7e6d805 243 {
borlanic 0:fbdae7e6d805 244 int ret = 0;
borlanic 0:fbdae7e6d805 245
borlanic 0:fbdae7e6d805 246 const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
borlanic 0:fbdae7e6d805 247 const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
borlanic 0:fbdae7e6d805 248 const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
borlanic 0:fbdae7e6d805 249 const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
borlanic 0:fbdae7e6d805 250 const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
borlanic 0:fbdae7e6d805 251
borlanic 0:fbdae7e6d805 252 /*
borlanic 0:fbdae7e6d805 253 * Check whether provided parameters are enough
borlanic 0:fbdae7e6d805 254 * to deduce all others. The following incomplete
borlanic 0:fbdae7e6d805 255 * parameter sets for private keys are supported:
borlanic 0:fbdae7e6d805 256 *
borlanic 0:fbdae7e6d805 257 * (1) P, Q missing.
borlanic 0:fbdae7e6d805 258 * (2) D and potentially N missing.
borlanic 0:fbdae7e6d805 259 *
borlanic 0:fbdae7e6d805 260 */
borlanic 0:fbdae7e6d805 261
borlanic 0:fbdae7e6d805 262 const int n_missing = have_P && have_Q && have_D && have_E;
borlanic 0:fbdae7e6d805 263 const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
borlanic 0:fbdae7e6d805 264 const int d_missing = have_P && have_Q && !have_D && have_E;
borlanic 0:fbdae7e6d805 265 const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
borlanic 0:fbdae7e6d805 266
borlanic 0:fbdae7e6d805 267 /* These three alternatives are mutually exclusive */
borlanic 0:fbdae7e6d805 268 const int is_priv = n_missing || pq_missing || d_missing;
borlanic 0:fbdae7e6d805 269
borlanic 0:fbdae7e6d805 270 if( !is_priv && !is_pub )
borlanic 0:fbdae7e6d805 271 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 272
borlanic 0:fbdae7e6d805 273 /*
borlanic 0:fbdae7e6d805 274 * Step 1: Deduce N if P, Q are provided.
borlanic 0:fbdae7e6d805 275 */
borlanic 0:fbdae7e6d805 276
borlanic 0:fbdae7e6d805 277 if( !have_N && have_P && have_Q )
borlanic 0:fbdae7e6d805 278 {
borlanic 0:fbdae7e6d805 279 if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
borlanic 0:fbdae7e6d805 280 &ctx->Q ) ) != 0 )
borlanic 0:fbdae7e6d805 281 {
borlanic 0:fbdae7e6d805 282 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 283 }
borlanic 0:fbdae7e6d805 284
borlanic 0:fbdae7e6d805 285 ctx->len = mbedtls_mpi_size( &ctx->N );
borlanic 0:fbdae7e6d805 286 }
borlanic 0:fbdae7e6d805 287
borlanic 0:fbdae7e6d805 288 /*
borlanic 0:fbdae7e6d805 289 * Step 2: Deduce and verify all remaining core parameters.
borlanic 0:fbdae7e6d805 290 */
borlanic 0:fbdae7e6d805 291
borlanic 0:fbdae7e6d805 292 if( pq_missing )
borlanic 0:fbdae7e6d805 293 {
borlanic 0:fbdae7e6d805 294 ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
borlanic 0:fbdae7e6d805 295 &ctx->P, &ctx->Q );
borlanic 0:fbdae7e6d805 296 if( ret != 0 )
borlanic 0:fbdae7e6d805 297 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 298
borlanic 0:fbdae7e6d805 299 }
borlanic 0:fbdae7e6d805 300 else if( d_missing )
borlanic 0:fbdae7e6d805 301 {
borlanic 0:fbdae7e6d805 302 if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
borlanic 0:fbdae7e6d805 303 &ctx->Q,
borlanic 0:fbdae7e6d805 304 &ctx->E,
borlanic 0:fbdae7e6d805 305 &ctx->D ) ) != 0 )
borlanic 0:fbdae7e6d805 306 {
borlanic 0:fbdae7e6d805 307 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 308 }
borlanic 0:fbdae7e6d805 309 }
borlanic 0:fbdae7e6d805 310
borlanic 0:fbdae7e6d805 311 /*
borlanic 0:fbdae7e6d805 312 * Step 3: Deduce all additional parameters specific
borlanic 0:fbdae7e6d805 313 * to our current RSA implementation.
borlanic 0:fbdae7e6d805 314 */
borlanic 0:fbdae7e6d805 315
borlanic 0:fbdae7e6d805 316 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 317 if( is_priv )
borlanic 0:fbdae7e6d805 318 {
borlanic 0:fbdae7e6d805 319 ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
borlanic 0:fbdae7e6d805 320 &ctx->DP, &ctx->DQ, &ctx->QP );
borlanic 0:fbdae7e6d805 321 if( ret != 0 )
borlanic 0:fbdae7e6d805 322 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 323 }
borlanic 0:fbdae7e6d805 324 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 325
borlanic 0:fbdae7e6d805 326 /*
borlanic 0:fbdae7e6d805 327 * Step 3: Basic sanity checks
borlanic 0:fbdae7e6d805 328 */
borlanic 0:fbdae7e6d805 329
borlanic 0:fbdae7e6d805 330 return( rsa_check_context( ctx, is_priv, 1 ) );
borlanic 0:fbdae7e6d805 331 }
borlanic 0:fbdae7e6d805 332
borlanic 0:fbdae7e6d805 333 int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 334 unsigned char *N, size_t N_len,
borlanic 0:fbdae7e6d805 335 unsigned char *P, size_t P_len,
borlanic 0:fbdae7e6d805 336 unsigned char *Q, size_t Q_len,
borlanic 0:fbdae7e6d805 337 unsigned char *D, size_t D_len,
borlanic 0:fbdae7e6d805 338 unsigned char *E, size_t E_len )
borlanic 0:fbdae7e6d805 339 {
borlanic 0:fbdae7e6d805 340 int ret = 0;
borlanic 0:fbdae7e6d805 341
borlanic 0:fbdae7e6d805 342 /* Check if key is private or public */
borlanic 0:fbdae7e6d805 343 const int is_priv =
borlanic 0:fbdae7e6d805 344 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 345 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 346 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 347 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 348 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
borlanic 0:fbdae7e6d805 349
borlanic 0:fbdae7e6d805 350 if( !is_priv )
borlanic 0:fbdae7e6d805 351 {
borlanic 0:fbdae7e6d805 352 /* If we're trying to export private parameters for a public key,
borlanic 0:fbdae7e6d805 353 * something must be wrong. */
borlanic 0:fbdae7e6d805 354 if( P != NULL || Q != NULL || D != NULL )
borlanic 0:fbdae7e6d805 355 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 356
borlanic 0:fbdae7e6d805 357 }
borlanic 0:fbdae7e6d805 358
borlanic 0:fbdae7e6d805 359 if( N != NULL )
borlanic 0:fbdae7e6d805 360 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
borlanic 0:fbdae7e6d805 361
borlanic 0:fbdae7e6d805 362 if( P != NULL )
borlanic 0:fbdae7e6d805 363 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
borlanic 0:fbdae7e6d805 364
borlanic 0:fbdae7e6d805 365 if( Q != NULL )
borlanic 0:fbdae7e6d805 366 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
borlanic 0:fbdae7e6d805 367
borlanic 0:fbdae7e6d805 368 if( D != NULL )
borlanic 0:fbdae7e6d805 369 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
borlanic 0:fbdae7e6d805 370
borlanic 0:fbdae7e6d805 371 if( E != NULL )
borlanic 0:fbdae7e6d805 372 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
borlanic 0:fbdae7e6d805 373
borlanic 0:fbdae7e6d805 374 cleanup:
borlanic 0:fbdae7e6d805 375
borlanic 0:fbdae7e6d805 376 return( ret );
borlanic 0:fbdae7e6d805 377 }
borlanic 0:fbdae7e6d805 378
borlanic 0:fbdae7e6d805 379 int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 380 mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
borlanic 0:fbdae7e6d805 381 mbedtls_mpi *D, mbedtls_mpi *E )
borlanic 0:fbdae7e6d805 382 {
borlanic 0:fbdae7e6d805 383 int ret;
borlanic 0:fbdae7e6d805 384
borlanic 0:fbdae7e6d805 385 /* Check if key is private or public */
borlanic 0:fbdae7e6d805 386 int is_priv =
borlanic 0:fbdae7e6d805 387 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 388 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 389 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 390 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 391 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
borlanic 0:fbdae7e6d805 392
borlanic 0:fbdae7e6d805 393 if( !is_priv )
borlanic 0:fbdae7e6d805 394 {
borlanic 0:fbdae7e6d805 395 /* If we're trying to export private parameters for a public key,
borlanic 0:fbdae7e6d805 396 * something must be wrong. */
borlanic 0:fbdae7e6d805 397 if( P != NULL || Q != NULL || D != NULL )
borlanic 0:fbdae7e6d805 398 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 399
borlanic 0:fbdae7e6d805 400 }
borlanic 0:fbdae7e6d805 401
borlanic 0:fbdae7e6d805 402 /* Export all requested core parameters. */
borlanic 0:fbdae7e6d805 403
borlanic 0:fbdae7e6d805 404 if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 405 ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 406 ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 407 ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 408 ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
borlanic 0:fbdae7e6d805 409 {
borlanic 0:fbdae7e6d805 410 return( ret );
borlanic 0:fbdae7e6d805 411 }
borlanic 0:fbdae7e6d805 412
borlanic 0:fbdae7e6d805 413 return( 0 );
borlanic 0:fbdae7e6d805 414 }
borlanic 0:fbdae7e6d805 415
borlanic 0:fbdae7e6d805 416 /*
borlanic 0:fbdae7e6d805 417 * Export CRT parameters
borlanic 0:fbdae7e6d805 418 * This must also be implemented if CRT is not used, for being able to
borlanic 0:fbdae7e6d805 419 * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
borlanic 0:fbdae7e6d805 420 * can be used in this case.
borlanic 0:fbdae7e6d805 421 */
borlanic 0:fbdae7e6d805 422 int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 423 mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
borlanic 0:fbdae7e6d805 424 {
borlanic 0:fbdae7e6d805 425 int ret;
borlanic 0:fbdae7e6d805 426
borlanic 0:fbdae7e6d805 427 /* Check if key is private or public */
borlanic 0:fbdae7e6d805 428 int is_priv =
borlanic 0:fbdae7e6d805 429 mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 430 mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 431 mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 432 mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
borlanic 0:fbdae7e6d805 433 mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
borlanic 0:fbdae7e6d805 434
borlanic 0:fbdae7e6d805 435 if( !is_priv )
borlanic 0:fbdae7e6d805 436 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 437
borlanic 0:fbdae7e6d805 438 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 439 /* Export all requested blinding parameters. */
borlanic 0:fbdae7e6d805 440 if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 441 ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
borlanic 0:fbdae7e6d805 442 ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
borlanic 0:fbdae7e6d805 443 {
borlanic 0:fbdae7e6d805 444 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 445 }
borlanic 0:fbdae7e6d805 446 #else
borlanic 0:fbdae7e6d805 447 if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
borlanic 0:fbdae7e6d805 448 DP, DQ, QP ) ) != 0 )
borlanic 0:fbdae7e6d805 449 {
borlanic 0:fbdae7e6d805 450 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
borlanic 0:fbdae7e6d805 451 }
borlanic 0:fbdae7e6d805 452 #endif
borlanic 0:fbdae7e6d805 453
borlanic 0:fbdae7e6d805 454 return( 0 );
borlanic 0:fbdae7e6d805 455 }
borlanic 0:fbdae7e6d805 456
borlanic 0:fbdae7e6d805 457 /*
borlanic 0:fbdae7e6d805 458 * Initialize an RSA context
borlanic 0:fbdae7e6d805 459 */
borlanic 0:fbdae7e6d805 460 void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 461 int padding,
borlanic 0:fbdae7e6d805 462 int hash_id )
borlanic 0:fbdae7e6d805 463 {
borlanic 0:fbdae7e6d805 464 memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
borlanic 0:fbdae7e6d805 465
borlanic 0:fbdae7e6d805 466 mbedtls_rsa_set_padding( ctx, padding, hash_id );
borlanic 0:fbdae7e6d805 467
borlanic 0:fbdae7e6d805 468 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 469 mbedtls_mutex_init( &ctx->mutex );
borlanic 0:fbdae7e6d805 470 #endif
borlanic 0:fbdae7e6d805 471 }
borlanic 0:fbdae7e6d805 472
borlanic 0:fbdae7e6d805 473 /*
borlanic 0:fbdae7e6d805 474 * Set padding for an existing RSA context
borlanic 0:fbdae7e6d805 475 */
borlanic 0:fbdae7e6d805 476 void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
borlanic 0:fbdae7e6d805 477 {
borlanic 0:fbdae7e6d805 478 ctx->padding = padding;
borlanic 0:fbdae7e6d805 479 ctx->hash_id = hash_id;
borlanic 0:fbdae7e6d805 480 }
borlanic 0:fbdae7e6d805 481
borlanic 0:fbdae7e6d805 482 /*
borlanic 0:fbdae7e6d805 483 * Get length in bytes of RSA modulus
borlanic 0:fbdae7e6d805 484 */
borlanic 0:fbdae7e6d805 485
borlanic 0:fbdae7e6d805 486 size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
borlanic 0:fbdae7e6d805 487 {
borlanic 0:fbdae7e6d805 488 return( ctx->len );
borlanic 0:fbdae7e6d805 489 }
borlanic 0:fbdae7e6d805 490
borlanic 0:fbdae7e6d805 491
borlanic 0:fbdae7e6d805 492 #if defined(MBEDTLS_GENPRIME)
borlanic 0:fbdae7e6d805 493
borlanic 0:fbdae7e6d805 494 /*
borlanic 0:fbdae7e6d805 495 * Generate an RSA keypair
borlanic 0:fbdae7e6d805 496 */
borlanic 0:fbdae7e6d805 497 int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 498 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 499 void *p_rng,
borlanic 0:fbdae7e6d805 500 unsigned int nbits, int exponent )
borlanic 0:fbdae7e6d805 501 {
borlanic 0:fbdae7e6d805 502 int ret;
borlanic 0:fbdae7e6d805 503 mbedtls_mpi H, G;
borlanic 0:fbdae7e6d805 504
borlanic 0:fbdae7e6d805 505 if( f_rng == NULL || nbits < 128 || exponent < 3 )
borlanic 0:fbdae7e6d805 506 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 507
borlanic 0:fbdae7e6d805 508 if( nbits % 2 )
borlanic 0:fbdae7e6d805 509 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 510
borlanic 0:fbdae7e6d805 511 mbedtls_mpi_init( &H );
borlanic 0:fbdae7e6d805 512 mbedtls_mpi_init( &G );
borlanic 0:fbdae7e6d805 513
borlanic 0:fbdae7e6d805 514 /*
borlanic 0:fbdae7e6d805 515 * find primes P and Q with Q < P so that:
borlanic 0:fbdae7e6d805 516 * GCD( E, (P-1)*(Q-1) ) == 1
borlanic 0:fbdae7e6d805 517 */
borlanic 0:fbdae7e6d805 518 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
borlanic 0:fbdae7e6d805 519
borlanic 0:fbdae7e6d805 520 do
borlanic 0:fbdae7e6d805 521 {
borlanic 0:fbdae7e6d805 522 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0,
borlanic 0:fbdae7e6d805 523 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 524
borlanic 0:fbdae7e6d805 525 MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0,
borlanic 0:fbdae7e6d805 526 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 527
borlanic 0:fbdae7e6d805 528 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
borlanic 0:fbdae7e6d805 529 continue;
borlanic 0:fbdae7e6d805 530
borlanic 0:fbdae7e6d805 531 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
borlanic 0:fbdae7e6d805 532 if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
borlanic 0:fbdae7e6d805 533 continue;
borlanic 0:fbdae7e6d805 534
borlanic 0:fbdae7e6d805 535 if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
borlanic 0:fbdae7e6d805 536 mbedtls_mpi_swap( &ctx->P, &ctx->Q );
borlanic 0:fbdae7e6d805 537
borlanic 0:fbdae7e6d805 538 /* Temporarily replace P,Q by P-1, Q-1 */
borlanic 0:fbdae7e6d805 539 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
borlanic 0:fbdae7e6d805 540 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
borlanic 0:fbdae7e6d805 541 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
borlanic 0:fbdae7e6d805 542 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) );
borlanic 0:fbdae7e6d805 543 }
borlanic 0:fbdae7e6d805 544 while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 );
borlanic 0:fbdae7e6d805 545
borlanic 0:fbdae7e6d805 546 /* Restore P,Q */
borlanic 0:fbdae7e6d805 547 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P, &ctx->P, 1 ) );
borlanic 0:fbdae7e6d805 548 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q, &ctx->Q, 1 ) );
borlanic 0:fbdae7e6d805 549
borlanic 0:fbdae7e6d805 550 ctx->len = mbedtls_mpi_size( &ctx->N );
borlanic 0:fbdae7e6d805 551
borlanic 0:fbdae7e6d805 552 /*
borlanic 0:fbdae7e6d805 553 * D = E^-1 mod ((P-1)*(Q-1))
borlanic 0:fbdae7e6d805 554 * DP = D mod (P - 1)
borlanic 0:fbdae7e6d805 555 * DQ = D mod (Q - 1)
borlanic 0:fbdae7e6d805 556 * QP = Q^-1 mod P
borlanic 0:fbdae7e6d805 557 */
borlanic 0:fbdae7e6d805 558
borlanic 0:fbdae7e6d805 559 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &H ) );
borlanic 0:fbdae7e6d805 560
borlanic 0:fbdae7e6d805 561 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 562 MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
borlanic 0:fbdae7e6d805 563 &ctx->DP, &ctx->DQ, &ctx->QP ) );
borlanic 0:fbdae7e6d805 564 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 565
borlanic 0:fbdae7e6d805 566 /* Double-check */
borlanic 0:fbdae7e6d805 567 MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
borlanic 0:fbdae7e6d805 568
borlanic 0:fbdae7e6d805 569 cleanup:
borlanic 0:fbdae7e6d805 570
borlanic 0:fbdae7e6d805 571 mbedtls_mpi_free( &H );
borlanic 0:fbdae7e6d805 572 mbedtls_mpi_free( &G );
borlanic 0:fbdae7e6d805 573
borlanic 0:fbdae7e6d805 574 if( ret != 0 )
borlanic 0:fbdae7e6d805 575 {
borlanic 0:fbdae7e6d805 576 mbedtls_rsa_free( ctx );
borlanic 0:fbdae7e6d805 577 return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
borlanic 0:fbdae7e6d805 578 }
borlanic 0:fbdae7e6d805 579
borlanic 0:fbdae7e6d805 580 return( 0 );
borlanic 0:fbdae7e6d805 581 }
borlanic 0:fbdae7e6d805 582
borlanic 0:fbdae7e6d805 583 #endif /* MBEDTLS_GENPRIME */
borlanic 0:fbdae7e6d805 584
borlanic 0:fbdae7e6d805 585 /*
borlanic 0:fbdae7e6d805 586 * Check a public RSA key
borlanic 0:fbdae7e6d805 587 */
borlanic 0:fbdae7e6d805 588 int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
borlanic 0:fbdae7e6d805 589 {
borlanic 0:fbdae7e6d805 590 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
borlanic 0:fbdae7e6d805 591 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 592
borlanic 0:fbdae7e6d805 593 if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
borlanic 0:fbdae7e6d805 594 {
borlanic 0:fbdae7e6d805 595 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 596 }
borlanic 0:fbdae7e6d805 597
borlanic 0:fbdae7e6d805 598 if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
borlanic 0:fbdae7e6d805 599 mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
borlanic 0:fbdae7e6d805 600 mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
borlanic 0:fbdae7e6d805 601 {
borlanic 0:fbdae7e6d805 602 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 603 }
borlanic 0:fbdae7e6d805 604
borlanic 0:fbdae7e6d805 605 return( 0 );
borlanic 0:fbdae7e6d805 606 }
borlanic 0:fbdae7e6d805 607
borlanic 0:fbdae7e6d805 608 /*
borlanic 0:fbdae7e6d805 609 * Check for the consistency of all fields in an RSA private key context
borlanic 0:fbdae7e6d805 610 */
borlanic 0:fbdae7e6d805 611 int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
borlanic 0:fbdae7e6d805 612 {
borlanic 0:fbdae7e6d805 613 if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
borlanic 0:fbdae7e6d805 614 rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
borlanic 0:fbdae7e6d805 615 {
borlanic 0:fbdae7e6d805 616 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 617 }
borlanic 0:fbdae7e6d805 618
borlanic 0:fbdae7e6d805 619 if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
borlanic 0:fbdae7e6d805 620 &ctx->D, &ctx->E, NULL, NULL ) != 0 )
borlanic 0:fbdae7e6d805 621 {
borlanic 0:fbdae7e6d805 622 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 623 }
borlanic 0:fbdae7e6d805 624
borlanic 0:fbdae7e6d805 625 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 626 else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
borlanic 0:fbdae7e6d805 627 &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
borlanic 0:fbdae7e6d805 628 {
borlanic 0:fbdae7e6d805 629 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 630 }
borlanic 0:fbdae7e6d805 631 #endif
borlanic 0:fbdae7e6d805 632
borlanic 0:fbdae7e6d805 633 return( 0 );
borlanic 0:fbdae7e6d805 634 }
borlanic 0:fbdae7e6d805 635
borlanic 0:fbdae7e6d805 636 /*
borlanic 0:fbdae7e6d805 637 * Check if contexts holding a public and private key match
borlanic 0:fbdae7e6d805 638 */
borlanic 0:fbdae7e6d805 639 int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
borlanic 0:fbdae7e6d805 640 const mbedtls_rsa_context *prv )
borlanic 0:fbdae7e6d805 641 {
borlanic 0:fbdae7e6d805 642 if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
borlanic 0:fbdae7e6d805 643 mbedtls_rsa_check_privkey( prv ) != 0 )
borlanic 0:fbdae7e6d805 644 {
borlanic 0:fbdae7e6d805 645 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 646 }
borlanic 0:fbdae7e6d805 647
borlanic 0:fbdae7e6d805 648 if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
borlanic 0:fbdae7e6d805 649 mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
borlanic 0:fbdae7e6d805 650 {
borlanic 0:fbdae7e6d805 651 return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
borlanic 0:fbdae7e6d805 652 }
borlanic 0:fbdae7e6d805 653
borlanic 0:fbdae7e6d805 654 return( 0 );
borlanic 0:fbdae7e6d805 655 }
borlanic 0:fbdae7e6d805 656
borlanic 0:fbdae7e6d805 657 /*
borlanic 0:fbdae7e6d805 658 * Do an RSA public key operation
borlanic 0:fbdae7e6d805 659 */
borlanic 0:fbdae7e6d805 660 int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 661 const unsigned char *input,
borlanic 0:fbdae7e6d805 662 unsigned char *output )
borlanic 0:fbdae7e6d805 663 {
borlanic 0:fbdae7e6d805 664 int ret;
borlanic 0:fbdae7e6d805 665 size_t olen;
borlanic 0:fbdae7e6d805 666 mbedtls_mpi T;
borlanic 0:fbdae7e6d805 667
borlanic 0:fbdae7e6d805 668 if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
borlanic 0:fbdae7e6d805 669 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 670
borlanic 0:fbdae7e6d805 671 mbedtls_mpi_init( &T );
borlanic 0:fbdae7e6d805 672
borlanic 0:fbdae7e6d805 673 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 674 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
borlanic 0:fbdae7e6d805 675 return( ret );
borlanic 0:fbdae7e6d805 676 #endif
borlanic 0:fbdae7e6d805 677
borlanic 0:fbdae7e6d805 678 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
borlanic 0:fbdae7e6d805 679
borlanic 0:fbdae7e6d805 680 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
borlanic 0:fbdae7e6d805 681 {
borlanic 0:fbdae7e6d805 682 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 683 goto cleanup;
borlanic 0:fbdae7e6d805 684 }
borlanic 0:fbdae7e6d805 685
borlanic 0:fbdae7e6d805 686 olen = ctx->len;
borlanic 0:fbdae7e6d805 687 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
borlanic 0:fbdae7e6d805 688 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
borlanic 0:fbdae7e6d805 689
borlanic 0:fbdae7e6d805 690 cleanup:
borlanic 0:fbdae7e6d805 691 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 692 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
borlanic 0:fbdae7e6d805 693 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
borlanic 0:fbdae7e6d805 694 #endif
borlanic 0:fbdae7e6d805 695
borlanic 0:fbdae7e6d805 696 mbedtls_mpi_free( &T );
borlanic 0:fbdae7e6d805 697
borlanic 0:fbdae7e6d805 698 if( ret != 0 )
borlanic 0:fbdae7e6d805 699 return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
borlanic 0:fbdae7e6d805 700
borlanic 0:fbdae7e6d805 701 return( 0 );
borlanic 0:fbdae7e6d805 702 }
borlanic 0:fbdae7e6d805 703
borlanic 0:fbdae7e6d805 704 /*
borlanic 0:fbdae7e6d805 705 * Generate or update blinding values, see section 10 of:
borlanic 0:fbdae7e6d805 706 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
borlanic 0:fbdae7e6d805 707 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
borlanic 0:fbdae7e6d805 708 * Berlin Heidelberg, 1996. p. 104-113.
borlanic 0:fbdae7e6d805 709 */
borlanic 0:fbdae7e6d805 710 static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 711 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
borlanic 0:fbdae7e6d805 712 {
borlanic 0:fbdae7e6d805 713 int ret, count = 0;
borlanic 0:fbdae7e6d805 714
borlanic 0:fbdae7e6d805 715 if( ctx->Vf.p != NULL )
borlanic 0:fbdae7e6d805 716 {
borlanic 0:fbdae7e6d805 717 /* We already have blinding values, just update them by squaring */
borlanic 0:fbdae7e6d805 718 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
borlanic 0:fbdae7e6d805 719 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
borlanic 0:fbdae7e6d805 720 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
borlanic 0:fbdae7e6d805 721 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
borlanic 0:fbdae7e6d805 722
borlanic 0:fbdae7e6d805 723 goto cleanup;
borlanic 0:fbdae7e6d805 724 }
borlanic 0:fbdae7e6d805 725
borlanic 0:fbdae7e6d805 726 /* Unblinding value: Vf = random number, invertible mod N */
borlanic 0:fbdae7e6d805 727 do {
borlanic 0:fbdae7e6d805 728 if( count++ > 10 )
borlanic 0:fbdae7e6d805 729 return( MBEDTLS_ERR_RSA_RNG_FAILED );
borlanic 0:fbdae7e6d805 730
borlanic 0:fbdae7e6d805 731 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 732 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
borlanic 0:fbdae7e6d805 733 } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
borlanic 0:fbdae7e6d805 734
borlanic 0:fbdae7e6d805 735 /* Blinding value: Vi = Vf^(-e) mod N */
borlanic 0:fbdae7e6d805 736 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
borlanic 0:fbdae7e6d805 737 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
borlanic 0:fbdae7e6d805 738
borlanic 0:fbdae7e6d805 739
borlanic 0:fbdae7e6d805 740 cleanup:
borlanic 0:fbdae7e6d805 741 return( ret );
borlanic 0:fbdae7e6d805 742 }
borlanic 0:fbdae7e6d805 743
borlanic 0:fbdae7e6d805 744 /*
borlanic 0:fbdae7e6d805 745 * Exponent blinding supposed to prevent side-channel attacks using multiple
borlanic 0:fbdae7e6d805 746 * traces of measurements to recover the RSA key. The more collisions are there,
borlanic 0:fbdae7e6d805 747 * the more bits of the key can be recovered. See [3].
borlanic 0:fbdae7e6d805 748 *
borlanic 0:fbdae7e6d805 749 * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
borlanic 0:fbdae7e6d805 750 * observations on avarage.
borlanic 0:fbdae7e6d805 751 *
borlanic 0:fbdae7e6d805 752 * For example with 28 byte blinding to achieve 2 collisions the adversary has
borlanic 0:fbdae7e6d805 753 * to make 2^112 observations on avarage.
borlanic 0:fbdae7e6d805 754 *
borlanic 0:fbdae7e6d805 755 * (With the currently (as of 2017 April) known best algorithms breaking 2048
borlanic 0:fbdae7e6d805 756 * bit RSA requires approximately as much time as trying out 2^112 random keys.
borlanic 0:fbdae7e6d805 757 * Thus in this sense with 28 byte blinding the security is not reduced by
borlanic 0:fbdae7e6d805 758 * side-channel attacks like the one in [3])
borlanic 0:fbdae7e6d805 759 *
borlanic 0:fbdae7e6d805 760 * This countermeasure does not help if the key recovery is possible with a
borlanic 0:fbdae7e6d805 761 * single trace.
borlanic 0:fbdae7e6d805 762 */
borlanic 0:fbdae7e6d805 763 #define RSA_EXPONENT_BLINDING 28
borlanic 0:fbdae7e6d805 764
borlanic 0:fbdae7e6d805 765 /*
borlanic 0:fbdae7e6d805 766 * Do an RSA private key operation
borlanic 0:fbdae7e6d805 767 */
borlanic 0:fbdae7e6d805 768 int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 769 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 770 void *p_rng,
borlanic 0:fbdae7e6d805 771 const unsigned char *input,
borlanic 0:fbdae7e6d805 772 unsigned char *output )
borlanic 0:fbdae7e6d805 773 {
borlanic 0:fbdae7e6d805 774 int ret;
borlanic 0:fbdae7e6d805 775 size_t olen;
borlanic 0:fbdae7e6d805 776 mbedtls_mpi T, T1, T2;
borlanic 0:fbdae7e6d805 777 mbedtls_mpi P1, Q1, R;
borlanic 0:fbdae7e6d805 778 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 779 mbedtls_mpi D_blind;
borlanic 0:fbdae7e6d805 780 mbedtls_mpi *D = &ctx->D;
borlanic 0:fbdae7e6d805 781 #else
borlanic 0:fbdae7e6d805 782 mbedtls_mpi DP_blind, DQ_blind;
borlanic 0:fbdae7e6d805 783 mbedtls_mpi *DP = &ctx->DP;
borlanic 0:fbdae7e6d805 784 mbedtls_mpi *DQ = &ctx->DQ;
borlanic 0:fbdae7e6d805 785 #endif
borlanic 0:fbdae7e6d805 786
borlanic 0:fbdae7e6d805 787 if( rsa_check_context( ctx, 1 /* private key checks */,
borlanic 0:fbdae7e6d805 788 f_rng != NULL /* blinding y/n */ ) != 0 )
borlanic 0:fbdae7e6d805 789 {
borlanic 0:fbdae7e6d805 790 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 791 }
borlanic 0:fbdae7e6d805 792
borlanic 0:fbdae7e6d805 793 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
borlanic 0:fbdae7e6d805 794 mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R );
borlanic 0:fbdae7e6d805 795
borlanic 0:fbdae7e6d805 796 if( f_rng != NULL )
borlanic 0:fbdae7e6d805 797 {
borlanic 0:fbdae7e6d805 798 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 799 mbedtls_mpi_init( &D_blind );
borlanic 0:fbdae7e6d805 800 #else
borlanic 0:fbdae7e6d805 801 mbedtls_mpi_init( &DP_blind );
borlanic 0:fbdae7e6d805 802 mbedtls_mpi_init( &DQ_blind );
borlanic 0:fbdae7e6d805 803 #endif
borlanic 0:fbdae7e6d805 804 }
borlanic 0:fbdae7e6d805 805
borlanic 0:fbdae7e6d805 806
borlanic 0:fbdae7e6d805 807 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 808 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
borlanic 0:fbdae7e6d805 809 return( ret );
borlanic 0:fbdae7e6d805 810 #endif
borlanic 0:fbdae7e6d805 811
borlanic 0:fbdae7e6d805 812 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
borlanic 0:fbdae7e6d805 813 if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
borlanic 0:fbdae7e6d805 814 {
borlanic 0:fbdae7e6d805 815 ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
borlanic 0:fbdae7e6d805 816 goto cleanup;
borlanic 0:fbdae7e6d805 817 }
borlanic 0:fbdae7e6d805 818
borlanic 0:fbdae7e6d805 819 if( f_rng != NULL )
borlanic 0:fbdae7e6d805 820 {
borlanic 0:fbdae7e6d805 821 /*
borlanic 0:fbdae7e6d805 822 * Blinding
borlanic 0:fbdae7e6d805 823 * T = T * Vi mod N
borlanic 0:fbdae7e6d805 824 */
borlanic 0:fbdae7e6d805 825 MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 826 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
borlanic 0:fbdae7e6d805 827 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
borlanic 0:fbdae7e6d805 828
borlanic 0:fbdae7e6d805 829 /*
borlanic 0:fbdae7e6d805 830 * Exponent blinding
borlanic 0:fbdae7e6d805 831 */
borlanic 0:fbdae7e6d805 832 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
borlanic 0:fbdae7e6d805 833 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
borlanic 0:fbdae7e6d805 834
borlanic 0:fbdae7e6d805 835 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 836 /*
borlanic 0:fbdae7e6d805 837 * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
borlanic 0:fbdae7e6d805 838 */
borlanic 0:fbdae7e6d805 839 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
borlanic 0:fbdae7e6d805 840 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 841 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
borlanic 0:fbdae7e6d805 842 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
borlanic 0:fbdae7e6d805 843 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
borlanic 0:fbdae7e6d805 844
borlanic 0:fbdae7e6d805 845 D = &D_blind;
borlanic 0:fbdae7e6d805 846 #else
borlanic 0:fbdae7e6d805 847 /*
borlanic 0:fbdae7e6d805 848 * DP_blind = ( P - 1 ) * R + DP
borlanic 0:fbdae7e6d805 849 */
borlanic 0:fbdae7e6d805 850 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
borlanic 0:fbdae7e6d805 851 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 852 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
borlanic 0:fbdae7e6d805 853 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
borlanic 0:fbdae7e6d805 854 &ctx->DP ) );
borlanic 0:fbdae7e6d805 855
borlanic 0:fbdae7e6d805 856 DP = &DP_blind;
borlanic 0:fbdae7e6d805 857
borlanic 0:fbdae7e6d805 858 /*
borlanic 0:fbdae7e6d805 859 * DQ_blind = ( Q - 1 ) * R + DQ
borlanic 0:fbdae7e6d805 860 */
borlanic 0:fbdae7e6d805 861 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
borlanic 0:fbdae7e6d805 862 f_rng, p_rng ) );
borlanic 0:fbdae7e6d805 863 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
borlanic 0:fbdae7e6d805 864 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
borlanic 0:fbdae7e6d805 865 &ctx->DQ ) );
borlanic 0:fbdae7e6d805 866
borlanic 0:fbdae7e6d805 867 DQ = &DQ_blind;
borlanic 0:fbdae7e6d805 868 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 869 }
borlanic 0:fbdae7e6d805 870
borlanic 0:fbdae7e6d805 871 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 872 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
borlanic 0:fbdae7e6d805 873 #else
borlanic 0:fbdae7e6d805 874 /*
borlanic 0:fbdae7e6d805 875 * Faster decryption using the CRT
borlanic 0:fbdae7e6d805 876 *
borlanic 0:fbdae7e6d805 877 * T1 = input ^ dP mod P
borlanic 0:fbdae7e6d805 878 * T2 = input ^ dQ mod Q
borlanic 0:fbdae7e6d805 879 */
borlanic 0:fbdae7e6d805 880 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) );
borlanic 0:fbdae7e6d805 881 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) );
borlanic 0:fbdae7e6d805 882
borlanic 0:fbdae7e6d805 883 /*
borlanic 0:fbdae7e6d805 884 * T = (T1 - T2) * (Q^-1 mod P) mod P
borlanic 0:fbdae7e6d805 885 */
borlanic 0:fbdae7e6d805 886 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) );
borlanic 0:fbdae7e6d805 887 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) );
borlanic 0:fbdae7e6d805 888 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) );
borlanic 0:fbdae7e6d805 889
borlanic 0:fbdae7e6d805 890 /*
borlanic 0:fbdae7e6d805 891 * T = T2 + T * Q
borlanic 0:fbdae7e6d805 892 */
borlanic 0:fbdae7e6d805 893 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) );
borlanic 0:fbdae7e6d805 894 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) );
borlanic 0:fbdae7e6d805 895 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 896
borlanic 0:fbdae7e6d805 897 if( f_rng != NULL )
borlanic 0:fbdae7e6d805 898 {
borlanic 0:fbdae7e6d805 899 /*
borlanic 0:fbdae7e6d805 900 * Unblind
borlanic 0:fbdae7e6d805 901 * T = T * Vf mod N
borlanic 0:fbdae7e6d805 902 */
borlanic 0:fbdae7e6d805 903 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
borlanic 0:fbdae7e6d805 904 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
borlanic 0:fbdae7e6d805 905 }
borlanic 0:fbdae7e6d805 906
borlanic 0:fbdae7e6d805 907 olen = ctx->len;
borlanic 0:fbdae7e6d805 908 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
borlanic 0:fbdae7e6d805 909
borlanic 0:fbdae7e6d805 910 cleanup:
borlanic 0:fbdae7e6d805 911 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 912 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
borlanic 0:fbdae7e6d805 913 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
borlanic 0:fbdae7e6d805 914 #endif
borlanic 0:fbdae7e6d805 915
borlanic 0:fbdae7e6d805 916 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
borlanic 0:fbdae7e6d805 917 mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R );
borlanic 0:fbdae7e6d805 918
borlanic 0:fbdae7e6d805 919 if( f_rng != NULL )
borlanic 0:fbdae7e6d805 920 {
borlanic 0:fbdae7e6d805 921 #if defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 922 mbedtls_mpi_free( &D_blind );
borlanic 0:fbdae7e6d805 923 #else
borlanic 0:fbdae7e6d805 924 mbedtls_mpi_free( &DP_blind );
borlanic 0:fbdae7e6d805 925 mbedtls_mpi_free( &DQ_blind );
borlanic 0:fbdae7e6d805 926 #endif
borlanic 0:fbdae7e6d805 927 }
borlanic 0:fbdae7e6d805 928
borlanic 0:fbdae7e6d805 929 if( ret != 0 )
borlanic 0:fbdae7e6d805 930 return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
borlanic 0:fbdae7e6d805 931
borlanic 0:fbdae7e6d805 932 return( 0 );
borlanic 0:fbdae7e6d805 933 }
borlanic 0:fbdae7e6d805 934
borlanic 0:fbdae7e6d805 935 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 936 /**
borlanic 0:fbdae7e6d805 937 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
borlanic 0:fbdae7e6d805 938 *
borlanic 0:fbdae7e6d805 939 * \param dst buffer to mask
borlanic 0:fbdae7e6d805 940 * \param dlen length of destination buffer
borlanic 0:fbdae7e6d805 941 * \param src source of the mask generation
borlanic 0:fbdae7e6d805 942 * \param slen length of the source buffer
borlanic 0:fbdae7e6d805 943 * \param md_ctx message digest context to use
borlanic 0:fbdae7e6d805 944 */
borlanic 0:fbdae7e6d805 945 static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
borlanic 0:fbdae7e6d805 946 size_t slen, mbedtls_md_context_t *md_ctx )
borlanic 0:fbdae7e6d805 947 {
borlanic 0:fbdae7e6d805 948 unsigned char mask[MBEDTLS_MD_MAX_SIZE];
borlanic 0:fbdae7e6d805 949 unsigned char counter[4];
borlanic 0:fbdae7e6d805 950 unsigned char *p;
borlanic 0:fbdae7e6d805 951 unsigned int hlen;
borlanic 0:fbdae7e6d805 952 size_t i, use_len;
borlanic 0:fbdae7e6d805 953 int ret = 0;
borlanic 0:fbdae7e6d805 954
borlanic 0:fbdae7e6d805 955 memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
borlanic 0:fbdae7e6d805 956 memset( counter, 0, 4 );
borlanic 0:fbdae7e6d805 957
borlanic 0:fbdae7e6d805 958 hlen = mbedtls_md_get_size( md_ctx->md_info );
borlanic 0:fbdae7e6d805 959
borlanic 0:fbdae7e6d805 960 /* Generate and apply dbMask */
borlanic 0:fbdae7e6d805 961 p = dst;
borlanic 0:fbdae7e6d805 962
borlanic 0:fbdae7e6d805 963 while( dlen > 0 )
borlanic 0:fbdae7e6d805 964 {
borlanic 0:fbdae7e6d805 965 use_len = hlen;
borlanic 0:fbdae7e6d805 966 if( dlen < hlen )
borlanic 0:fbdae7e6d805 967 use_len = dlen;
borlanic 0:fbdae7e6d805 968
borlanic 0:fbdae7e6d805 969 if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 970 goto exit;
borlanic 0:fbdae7e6d805 971 if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
borlanic 0:fbdae7e6d805 972 goto exit;
borlanic 0:fbdae7e6d805 973 if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
borlanic 0:fbdae7e6d805 974 goto exit;
borlanic 0:fbdae7e6d805 975 if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
borlanic 0:fbdae7e6d805 976 goto exit;
borlanic 0:fbdae7e6d805 977
borlanic 0:fbdae7e6d805 978 for( i = 0; i < use_len; ++i )
borlanic 0:fbdae7e6d805 979 *p++ ^= mask[i];
borlanic 0:fbdae7e6d805 980
borlanic 0:fbdae7e6d805 981 counter[3]++;
borlanic 0:fbdae7e6d805 982
borlanic 0:fbdae7e6d805 983 dlen -= use_len;
borlanic 0:fbdae7e6d805 984 }
borlanic 0:fbdae7e6d805 985
borlanic 0:fbdae7e6d805 986 exit:
borlanic 0:fbdae7e6d805 987 mbedtls_zeroize( mask, sizeof( mask ) );
borlanic 0:fbdae7e6d805 988
borlanic 0:fbdae7e6d805 989 return( ret );
borlanic 0:fbdae7e6d805 990 }
borlanic 0:fbdae7e6d805 991 #endif /* MBEDTLS_PKCS1_V21 */
borlanic 0:fbdae7e6d805 992
borlanic 0:fbdae7e6d805 993 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 994 /*
borlanic 0:fbdae7e6d805 995 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
borlanic 0:fbdae7e6d805 996 */
borlanic 0:fbdae7e6d805 997 int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 998 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 999 void *p_rng,
borlanic 0:fbdae7e6d805 1000 int mode,
borlanic 0:fbdae7e6d805 1001 const unsigned char *label, size_t label_len,
borlanic 0:fbdae7e6d805 1002 size_t ilen,
borlanic 0:fbdae7e6d805 1003 const unsigned char *input,
borlanic 0:fbdae7e6d805 1004 unsigned char *output )
borlanic 0:fbdae7e6d805 1005 {
borlanic 0:fbdae7e6d805 1006 size_t olen;
borlanic 0:fbdae7e6d805 1007 int ret;
borlanic 0:fbdae7e6d805 1008 unsigned char *p = output;
borlanic 0:fbdae7e6d805 1009 unsigned int hlen;
borlanic 0:fbdae7e6d805 1010 const mbedtls_md_info_t *md_info;
borlanic 0:fbdae7e6d805 1011 mbedtls_md_context_t md_ctx;
borlanic 0:fbdae7e6d805 1012
borlanic 0:fbdae7e6d805 1013 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
borlanic 0:fbdae7e6d805 1014 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1015
borlanic 0:fbdae7e6d805 1016 if( f_rng == NULL )
borlanic 0:fbdae7e6d805 1017 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1018
borlanic 0:fbdae7e6d805 1019 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
borlanic 0:fbdae7e6d805 1020 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1021 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1022
borlanic 0:fbdae7e6d805 1023 olen = ctx->len;
borlanic 0:fbdae7e6d805 1024 hlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1025
borlanic 0:fbdae7e6d805 1026 /* first comparison checks for overflow */
borlanic 0:fbdae7e6d805 1027 if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
borlanic 0:fbdae7e6d805 1028 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1029
borlanic 0:fbdae7e6d805 1030 memset( output, 0, olen );
borlanic 0:fbdae7e6d805 1031
borlanic 0:fbdae7e6d805 1032 *p++ = 0;
borlanic 0:fbdae7e6d805 1033
borlanic 0:fbdae7e6d805 1034 /* Generate a random octet string seed */
borlanic 0:fbdae7e6d805 1035 if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
borlanic 0:fbdae7e6d805 1036 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
borlanic 0:fbdae7e6d805 1037
borlanic 0:fbdae7e6d805 1038 p += hlen;
borlanic 0:fbdae7e6d805 1039
borlanic 0:fbdae7e6d805 1040 /* Construct DB */
borlanic 0:fbdae7e6d805 1041 if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
borlanic 0:fbdae7e6d805 1042 return( ret );
borlanic 0:fbdae7e6d805 1043 p += hlen;
borlanic 0:fbdae7e6d805 1044 p += olen - 2 * hlen - 2 - ilen;
borlanic 0:fbdae7e6d805 1045 *p++ = 1;
borlanic 0:fbdae7e6d805 1046 memcpy( p, input, ilen );
borlanic 0:fbdae7e6d805 1047
borlanic 0:fbdae7e6d805 1048 mbedtls_md_init( &md_ctx );
borlanic 0:fbdae7e6d805 1049 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
borlanic 0:fbdae7e6d805 1050 goto exit;
borlanic 0:fbdae7e6d805 1051
borlanic 0:fbdae7e6d805 1052 /* maskedDB: Apply dbMask to DB */
borlanic 0:fbdae7e6d805 1053 if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
borlanic 0:fbdae7e6d805 1054 &md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 1055 goto exit;
borlanic 0:fbdae7e6d805 1056
borlanic 0:fbdae7e6d805 1057 /* maskedSeed: Apply seedMask to seed */
borlanic 0:fbdae7e6d805 1058 if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
borlanic 0:fbdae7e6d805 1059 &md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 1060 goto exit;
borlanic 0:fbdae7e6d805 1061
borlanic 0:fbdae7e6d805 1062 exit:
borlanic 0:fbdae7e6d805 1063 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1064
borlanic 0:fbdae7e6d805 1065 if( ret != 0 )
borlanic 0:fbdae7e6d805 1066 return( ret );
borlanic 0:fbdae7e6d805 1067
borlanic 0:fbdae7e6d805 1068 return( ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1069 ? mbedtls_rsa_public( ctx, output, output )
borlanic 0:fbdae7e6d805 1070 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
borlanic 0:fbdae7e6d805 1071 }
borlanic 0:fbdae7e6d805 1072 #endif /* MBEDTLS_PKCS1_V21 */
borlanic 0:fbdae7e6d805 1073
borlanic 0:fbdae7e6d805 1074 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1075 /*
borlanic 0:fbdae7e6d805 1076 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
borlanic 0:fbdae7e6d805 1077 */
borlanic 0:fbdae7e6d805 1078 int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1079 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1080 void *p_rng,
borlanic 0:fbdae7e6d805 1081 int mode, size_t ilen,
borlanic 0:fbdae7e6d805 1082 const unsigned char *input,
borlanic 0:fbdae7e6d805 1083 unsigned char *output )
borlanic 0:fbdae7e6d805 1084 {
borlanic 0:fbdae7e6d805 1085 size_t nb_pad, olen;
borlanic 0:fbdae7e6d805 1086 int ret;
borlanic 0:fbdae7e6d805 1087 unsigned char *p = output;
borlanic 0:fbdae7e6d805 1088
borlanic 0:fbdae7e6d805 1089 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
borlanic 0:fbdae7e6d805 1090 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1091
borlanic 0:fbdae7e6d805 1092 // We don't check p_rng because it won't be dereferenced here
borlanic 0:fbdae7e6d805 1093 if( f_rng == NULL || input == NULL || output == NULL )
borlanic 0:fbdae7e6d805 1094 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1095
borlanic 0:fbdae7e6d805 1096 olen = ctx->len;
borlanic 0:fbdae7e6d805 1097
borlanic 0:fbdae7e6d805 1098 /* first comparison checks for overflow */
borlanic 0:fbdae7e6d805 1099 if( ilen + 11 < ilen || olen < ilen + 11 )
borlanic 0:fbdae7e6d805 1100 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1101
borlanic 0:fbdae7e6d805 1102 nb_pad = olen - 3 - ilen;
borlanic 0:fbdae7e6d805 1103
borlanic 0:fbdae7e6d805 1104 *p++ = 0;
borlanic 0:fbdae7e6d805 1105 if( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1106 {
borlanic 0:fbdae7e6d805 1107 *p++ = MBEDTLS_RSA_CRYPT;
borlanic 0:fbdae7e6d805 1108
borlanic 0:fbdae7e6d805 1109 while( nb_pad-- > 0 )
borlanic 0:fbdae7e6d805 1110 {
borlanic 0:fbdae7e6d805 1111 int rng_dl = 100;
borlanic 0:fbdae7e6d805 1112
borlanic 0:fbdae7e6d805 1113 do {
borlanic 0:fbdae7e6d805 1114 ret = f_rng( p_rng, p, 1 );
borlanic 0:fbdae7e6d805 1115 } while( *p == 0 && --rng_dl && ret == 0 );
borlanic 0:fbdae7e6d805 1116
borlanic 0:fbdae7e6d805 1117 /* Check if RNG failed to generate data */
borlanic 0:fbdae7e6d805 1118 if( rng_dl == 0 || ret != 0 )
borlanic 0:fbdae7e6d805 1119 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
borlanic 0:fbdae7e6d805 1120
borlanic 0:fbdae7e6d805 1121 p++;
borlanic 0:fbdae7e6d805 1122 }
borlanic 0:fbdae7e6d805 1123 }
borlanic 0:fbdae7e6d805 1124 else
borlanic 0:fbdae7e6d805 1125 {
borlanic 0:fbdae7e6d805 1126 *p++ = MBEDTLS_RSA_SIGN;
borlanic 0:fbdae7e6d805 1127
borlanic 0:fbdae7e6d805 1128 while( nb_pad-- > 0 )
borlanic 0:fbdae7e6d805 1129 *p++ = 0xFF;
borlanic 0:fbdae7e6d805 1130 }
borlanic 0:fbdae7e6d805 1131
borlanic 0:fbdae7e6d805 1132 *p++ = 0;
borlanic 0:fbdae7e6d805 1133 memcpy( p, input, ilen );
borlanic 0:fbdae7e6d805 1134
borlanic 0:fbdae7e6d805 1135 return( ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1136 ? mbedtls_rsa_public( ctx, output, output )
borlanic 0:fbdae7e6d805 1137 : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
borlanic 0:fbdae7e6d805 1138 }
borlanic 0:fbdae7e6d805 1139 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 1140
borlanic 0:fbdae7e6d805 1141 /*
borlanic 0:fbdae7e6d805 1142 * Add the message padding, then do an RSA operation
borlanic 0:fbdae7e6d805 1143 */
borlanic 0:fbdae7e6d805 1144 int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1145 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1146 void *p_rng,
borlanic 0:fbdae7e6d805 1147 int mode, size_t ilen,
borlanic 0:fbdae7e6d805 1148 const unsigned char *input,
borlanic 0:fbdae7e6d805 1149 unsigned char *output )
borlanic 0:fbdae7e6d805 1150 {
borlanic 0:fbdae7e6d805 1151 switch( ctx->padding )
borlanic 0:fbdae7e6d805 1152 {
borlanic 0:fbdae7e6d805 1153 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1154 case MBEDTLS_RSA_PKCS_V15:
borlanic 0:fbdae7e6d805 1155 return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
borlanic 0:fbdae7e6d805 1156 input, output );
borlanic 0:fbdae7e6d805 1157 #endif
borlanic 0:fbdae7e6d805 1158
borlanic 0:fbdae7e6d805 1159 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1160 case MBEDTLS_RSA_PKCS_V21:
borlanic 0:fbdae7e6d805 1161 return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
borlanic 0:fbdae7e6d805 1162 ilen, input, output );
borlanic 0:fbdae7e6d805 1163 #endif
borlanic 0:fbdae7e6d805 1164
borlanic 0:fbdae7e6d805 1165 default:
borlanic 0:fbdae7e6d805 1166 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
borlanic 0:fbdae7e6d805 1167 }
borlanic 0:fbdae7e6d805 1168 }
borlanic 0:fbdae7e6d805 1169
borlanic 0:fbdae7e6d805 1170 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1171 /*
borlanic 0:fbdae7e6d805 1172 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
borlanic 0:fbdae7e6d805 1173 */
borlanic 0:fbdae7e6d805 1174 int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1175 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1176 void *p_rng,
borlanic 0:fbdae7e6d805 1177 int mode,
borlanic 0:fbdae7e6d805 1178 const unsigned char *label, size_t label_len,
borlanic 0:fbdae7e6d805 1179 size_t *olen,
borlanic 0:fbdae7e6d805 1180 const unsigned char *input,
borlanic 0:fbdae7e6d805 1181 unsigned char *output,
borlanic 0:fbdae7e6d805 1182 size_t output_max_len )
borlanic 0:fbdae7e6d805 1183 {
borlanic 0:fbdae7e6d805 1184 int ret;
borlanic 0:fbdae7e6d805 1185 size_t ilen, i, pad_len;
borlanic 0:fbdae7e6d805 1186 unsigned char *p, bad, pad_done;
borlanic 0:fbdae7e6d805 1187 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
borlanic 0:fbdae7e6d805 1188 unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
borlanic 0:fbdae7e6d805 1189 unsigned int hlen;
borlanic 0:fbdae7e6d805 1190 const mbedtls_md_info_t *md_info;
borlanic 0:fbdae7e6d805 1191 mbedtls_md_context_t md_ctx;
borlanic 0:fbdae7e6d805 1192
borlanic 0:fbdae7e6d805 1193 /*
borlanic 0:fbdae7e6d805 1194 * Parameters sanity checks
borlanic 0:fbdae7e6d805 1195 */
borlanic 0:fbdae7e6d805 1196 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
borlanic 0:fbdae7e6d805 1197 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1198
borlanic 0:fbdae7e6d805 1199 ilen = ctx->len;
borlanic 0:fbdae7e6d805 1200
borlanic 0:fbdae7e6d805 1201 if( ilen < 16 || ilen > sizeof( buf ) )
borlanic 0:fbdae7e6d805 1202 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1203
borlanic 0:fbdae7e6d805 1204 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
borlanic 0:fbdae7e6d805 1205 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1206 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1207
borlanic 0:fbdae7e6d805 1208 hlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1209
borlanic 0:fbdae7e6d805 1210 // checking for integer underflow
borlanic 0:fbdae7e6d805 1211 if( 2 * hlen + 2 > ilen )
borlanic 0:fbdae7e6d805 1212 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1213
borlanic 0:fbdae7e6d805 1214 /*
borlanic 0:fbdae7e6d805 1215 * RSA operation
borlanic 0:fbdae7e6d805 1216 */
borlanic 0:fbdae7e6d805 1217 ret = ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1218 ? mbedtls_rsa_public( ctx, input, buf )
borlanic 0:fbdae7e6d805 1219 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
borlanic 0:fbdae7e6d805 1220
borlanic 0:fbdae7e6d805 1221 if( ret != 0 )
borlanic 0:fbdae7e6d805 1222 goto cleanup;
borlanic 0:fbdae7e6d805 1223
borlanic 0:fbdae7e6d805 1224 /*
borlanic 0:fbdae7e6d805 1225 * Unmask data and generate lHash
borlanic 0:fbdae7e6d805 1226 */
borlanic 0:fbdae7e6d805 1227 mbedtls_md_init( &md_ctx );
borlanic 0:fbdae7e6d805 1228 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
borlanic 0:fbdae7e6d805 1229 {
borlanic 0:fbdae7e6d805 1230 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1231 goto cleanup;
borlanic 0:fbdae7e6d805 1232 }
borlanic 0:fbdae7e6d805 1233
borlanic 0:fbdae7e6d805 1234 /* seed: Apply seedMask to maskedSeed */
borlanic 0:fbdae7e6d805 1235 if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
borlanic 0:fbdae7e6d805 1236 &md_ctx ) ) != 0 ||
borlanic 0:fbdae7e6d805 1237 /* DB: Apply dbMask to maskedDB */
borlanic 0:fbdae7e6d805 1238 ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
borlanic 0:fbdae7e6d805 1239 &md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 1240 {
borlanic 0:fbdae7e6d805 1241 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1242 goto cleanup;
borlanic 0:fbdae7e6d805 1243 }
borlanic 0:fbdae7e6d805 1244
borlanic 0:fbdae7e6d805 1245 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1246
borlanic 0:fbdae7e6d805 1247 /* Generate lHash */
borlanic 0:fbdae7e6d805 1248 if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
borlanic 0:fbdae7e6d805 1249 goto cleanup;
borlanic 0:fbdae7e6d805 1250
borlanic 0:fbdae7e6d805 1251 /*
borlanic 0:fbdae7e6d805 1252 * Check contents, in "constant-time"
borlanic 0:fbdae7e6d805 1253 */
borlanic 0:fbdae7e6d805 1254 p = buf;
borlanic 0:fbdae7e6d805 1255 bad = 0;
borlanic 0:fbdae7e6d805 1256
borlanic 0:fbdae7e6d805 1257 bad |= *p++; /* First byte must be 0 */
borlanic 0:fbdae7e6d805 1258
borlanic 0:fbdae7e6d805 1259 p += hlen; /* Skip seed */
borlanic 0:fbdae7e6d805 1260
borlanic 0:fbdae7e6d805 1261 /* Check lHash */
borlanic 0:fbdae7e6d805 1262 for( i = 0; i < hlen; i++ )
borlanic 0:fbdae7e6d805 1263 bad |= lhash[i] ^ *p++;
borlanic 0:fbdae7e6d805 1264
borlanic 0:fbdae7e6d805 1265 /* Get zero-padding len, but always read till end of buffer
borlanic 0:fbdae7e6d805 1266 * (minus one, for the 01 byte) */
borlanic 0:fbdae7e6d805 1267 pad_len = 0;
borlanic 0:fbdae7e6d805 1268 pad_done = 0;
borlanic 0:fbdae7e6d805 1269 for( i = 0; i < ilen - 2 * hlen - 2; i++ )
borlanic 0:fbdae7e6d805 1270 {
borlanic 0:fbdae7e6d805 1271 pad_done |= p[i];
borlanic 0:fbdae7e6d805 1272 pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
borlanic 0:fbdae7e6d805 1273 }
borlanic 0:fbdae7e6d805 1274
borlanic 0:fbdae7e6d805 1275 p += pad_len;
borlanic 0:fbdae7e6d805 1276 bad |= *p++ ^ 0x01;
borlanic 0:fbdae7e6d805 1277
borlanic 0:fbdae7e6d805 1278 /*
borlanic 0:fbdae7e6d805 1279 * The only information "leaked" is whether the padding was correct or not
borlanic 0:fbdae7e6d805 1280 * (eg, no data is copied if it was not correct). This meets the
borlanic 0:fbdae7e6d805 1281 * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
borlanic 0:fbdae7e6d805 1282 * the different error conditions.
borlanic 0:fbdae7e6d805 1283 */
borlanic 0:fbdae7e6d805 1284 if( bad != 0 )
borlanic 0:fbdae7e6d805 1285 {
borlanic 0:fbdae7e6d805 1286 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
borlanic 0:fbdae7e6d805 1287 goto cleanup;
borlanic 0:fbdae7e6d805 1288 }
borlanic 0:fbdae7e6d805 1289
borlanic 0:fbdae7e6d805 1290 if( ilen - ( p - buf ) > output_max_len )
borlanic 0:fbdae7e6d805 1291 {
borlanic 0:fbdae7e6d805 1292 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
borlanic 0:fbdae7e6d805 1293 goto cleanup;
borlanic 0:fbdae7e6d805 1294 }
borlanic 0:fbdae7e6d805 1295
borlanic 0:fbdae7e6d805 1296 *olen = ilen - (p - buf);
borlanic 0:fbdae7e6d805 1297 memcpy( output, p, *olen );
borlanic 0:fbdae7e6d805 1298 ret = 0;
borlanic 0:fbdae7e6d805 1299
borlanic 0:fbdae7e6d805 1300 cleanup:
borlanic 0:fbdae7e6d805 1301 mbedtls_zeroize( buf, sizeof( buf ) );
borlanic 0:fbdae7e6d805 1302 mbedtls_zeroize( lhash, sizeof( lhash ) );
borlanic 0:fbdae7e6d805 1303
borlanic 0:fbdae7e6d805 1304 return( ret );
borlanic 0:fbdae7e6d805 1305 }
borlanic 0:fbdae7e6d805 1306 #endif /* MBEDTLS_PKCS1_V21 */
borlanic 0:fbdae7e6d805 1307
borlanic 0:fbdae7e6d805 1308 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1309 /*
borlanic 0:fbdae7e6d805 1310 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
borlanic 0:fbdae7e6d805 1311 */
borlanic 0:fbdae7e6d805 1312 int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1313 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1314 void *p_rng,
borlanic 0:fbdae7e6d805 1315 int mode, size_t *olen,
borlanic 0:fbdae7e6d805 1316 const unsigned char *input,
borlanic 0:fbdae7e6d805 1317 unsigned char *output,
borlanic 0:fbdae7e6d805 1318 size_t output_max_len)
borlanic 0:fbdae7e6d805 1319 {
borlanic 0:fbdae7e6d805 1320 int ret;
borlanic 0:fbdae7e6d805 1321 size_t ilen, pad_count = 0, i;
borlanic 0:fbdae7e6d805 1322 unsigned char *p, bad, pad_done = 0;
borlanic 0:fbdae7e6d805 1323 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
borlanic 0:fbdae7e6d805 1324
borlanic 0:fbdae7e6d805 1325 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
borlanic 0:fbdae7e6d805 1326 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1327
borlanic 0:fbdae7e6d805 1328 ilen = ctx->len;
borlanic 0:fbdae7e6d805 1329
borlanic 0:fbdae7e6d805 1330 if( ilen < 16 || ilen > sizeof( buf ) )
borlanic 0:fbdae7e6d805 1331 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1332
borlanic 0:fbdae7e6d805 1333 ret = ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1334 ? mbedtls_rsa_public( ctx, input, buf )
borlanic 0:fbdae7e6d805 1335 : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
borlanic 0:fbdae7e6d805 1336
borlanic 0:fbdae7e6d805 1337 if( ret != 0 )
borlanic 0:fbdae7e6d805 1338 goto cleanup;
borlanic 0:fbdae7e6d805 1339
borlanic 0:fbdae7e6d805 1340 p = buf;
borlanic 0:fbdae7e6d805 1341 bad = 0;
borlanic 0:fbdae7e6d805 1342
borlanic 0:fbdae7e6d805 1343 /*
borlanic 0:fbdae7e6d805 1344 * Check and get padding len in "constant-time"
borlanic 0:fbdae7e6d805 1345 */
borlanic 0:fbdae7e6d805 1346 bad |= *p++; /* First byte must be 0 */
borlanic 0:fbdae7e6d805 1347
borlanic 0:fbdae7e6d805 1348 /* This test does not depend on secret data */
borlanic 0:fbdae7e6d805 1349 if( mode == MBEDTLS_RSA_PRIVATE )
borlanic 0:fbdae7e6d805 1350 {
borlanic 0:fbdae7e6d805 1351 bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
borlanic 0:fbdae7e6d805 1352
borlanic 0:fbdae7e6d805 1353 /* Get padding len, but always read till end of buffer
borlanic 0:fbdae7e6d805 1354 * (minus one, for the 00 byte) */
borlanic 0:fbdae7e6d805 1355 for( i = 0; i < ilen - 3; i++ )
borlanic 0:fbdae7e6d805 1356 {
borlanic 0:fbdae7e6d805 1357 pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
borlanic 0:fbdae7e6d805 1358 pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
borlanic 0:fbdae7e6d805 1359 }
borlanic 0:fbdae7e6d805 1360
borlanic 0:fbdae7e6d805 1361 p += pad_count;
borlanic 0:fbdae7e6d805 1362 bad |= *p++; /* Must be zero */
borlanic 0:fbdae7e6d805 1363 }
borlanic 0:fbdae7e6d805 1364 else
borlanic 0:fbdae7e6d805 1365 {
borlanic 0:fbdae7e6d805 1366 bad |= *p++ ^ MBEDTLS_RSA_SIGN;
borlanic 0:fbdae7e6d805 1367
borlanic 0:fbdae7e6d805 1368 /* Get padding len, but always read till end of buffer
borlanic 0:fbdae7e6d805 1369 * (minus one, for the 00 byte) */
borlanic 0:fbdae7e6d805 1370 for( i = 0; i < ilen - 3; i++ )
borlanic 0:fbdae7e6d805 1371 {
borlanic 0:fbdae7e6d805 1372 pad_done |= ( p[i] != 0xFF );
borlanic 0:fbdae7e6d805 1373 pad_count += ( pad_done == 0 );
borlanic 0:fbdae7e6d805 1374 }
borlanic 0:fbdae7e6d805 1375
borlanic 0:fbdae7e6d805 1376 p += pad_count;
borlanic 0:fbdae7e6d805 1377 bad |= *p++; /* Must be zero */
borlanic 0:fbdae7e6d805 1378 }
borlanic 0:fbdae7e6d805 1379
borlanic 0:fbdae7e6d805 1380 bad |= ( pad_count < 8 );
borlanic 0:fbdae7e6d805 1381
borlanic 0:fbdae7e6d805 1382 if( bad )
borlanic 0:fbdae7e6d805 1383 {
borlanic 0:fbdae7e6d805 1384 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
borlanic 0:fbdae7e6d805 1385 goto cleanup;
borlanic 0:fbdae7e6d805 1386 }
borlanic 0:fbdae7e6d805 1387
borlanic 0:fbdae7e6d805 1388 if( ilen - ( p - buf ) > output_max_len )
borlanic 0:fbdae7e6d805 1389 {
borlanic 0:fbdae7e6d805 1390 ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
borlanic 0:fbdae7e6d805 1391 goto cleanup;
borlanic 0:fbdae7e6d805 1392 }
borlanic 0:fbdae7e6d805 1393
borlanic 0:fbdae7e6d805 1394 *olen = ilen - (p - buf);
borlanic 0:fbdae7e6d805 1395 memcpy( output, p, *olen );
borlanic 0:fbdae7e6d805 1396 ret = 0;
borlanic 0:fbdae7e6d805 1397
borlanic 0:fbdae7e6d805 1398 cleanup:
borlanic 0:fbdae7e6d805 1399 mbedtls_zeroize( buf, sizeof( buf ) );
borlanic 0:fbdae7e6d805 1400
borlanic 0:fbdae7e6d805 1401 return( ret );
borlanic 0:fbdae7e6d805 1402 }
borlanic 0:fbdae7e6d805 1403 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 1404
borlanic 0:fbdae7e6d805 1405 /*
borlanic 0:fbdae7e6d805 1406 * Do an RSA operation, then remove the message padding
borlanic 0:fbdae7e6d805 1407 */
borlanic 0:fbdae7e6d805 1408 int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1409 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1410 void *p_rng,
borlanic 0:fbdae7e6d805 1411 int mode, size_t *olen,
borlanic 0:fbdae7e6d805 1412 const unsigned char *input,
borlanic 0:fbdae7e6d805 1413 unsigned char *output,
borlanic 0:fbdae7e6d805 1414 size_t output_max_len)
borlanic 0:fbdae7e6d805 1415 {
borlanic 0:fbdae7e6d805 1416 switch( ctx->padding )
borlanic 0:fbdae7e6d805 1417 {
borlanic 0:fbdae7e6d805 1418 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1419 case MBEDTLS_RSA_PKCS_V15:
borlanic 0:fbdae7e6d805 1420 return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
borlanic 0:fbdae7e6d805 1421 input, output, output_max_len );
borlanic 0:fbdae7e6d805 1422 #endif
borlanic 0:fbdae7e6d805 1423
borlanic 0:fbdae7e6d805 1424 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1425 case MBEDTLS_RSA_PKCS_V21:
borlanic 0:fbdae7e6d805 1426 return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
borlanic 0:fbdae7e6d805 1427 olen, input, output,
borlanic 0:fbdae7e6d805 1428 output_max_len );
borlanic 0:fbdae7e6d805 1429 #endif
borlanic 0:fbdae7e6d805 1430
borlanic 0:fbdae7e6d805 1431 default:
borlanic 0:fbdae7e6d805 1432 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
borlanic 0:fbdae7e6d805 1433 }
borlanic 0:fbdae7e6d805 1434 }
borlanic 0:fbdae7e6d805 1435
borlanic 0:fbdae7e6d805 1436 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1437 /*
borlanic 0:fbdae7e6d805 1438 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
borlanic 0:fbdae7e6d805 1439 */
borlanic 0:fbdae7e6d805 1440 int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1441 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1442 void *p_rng,
borlanic 0:fbdae7e6d805 1443 int mode,
borlanic 0:fbdae7e6d805 1444 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1445 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1446 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1447 unsigned char *sig )
borlanic 0:fbdae7e6d805 1448 {
borlanic 0:fbdae7e6d805 1449 size_t olen;
borlanic 0:fbdae7e6d805 1450 unsigned char *p = sig;
borlanic 0:fbdae7e6d805 1451 unsigned char salt[MBEDTLS_MD_MAX_SIZE];
borlanic 0:fbdae7e6d805 1452 unsigned int slen, hlen, offset = 0;
borlanic 0:fbdae7e6d805 1453 int ret;
borlanic 0:fbdae7e6d805 1454 size_t msb;
borlanic 0:fbdae7e6d805 1455 const mbedtls_md_info_t *md_info;
borlanic 0:fbdae7e6d805 1456 mbedtls_md_context_t md_ctx;
borlanic 0:fbdae7e6d805 1457
borlanic 0:fbdae7e6d805 1458 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
borlanic 0:fbdae7e6d805 1459 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1460
borlanic 0:fbdae7e6d805 1461 if( f_rng == NULL )
borlanic 0:fbdae7e6d805 1462 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1463
borlanic 0:fbdae7e6d805 1464 olen = ctx->len;
borlanic 0:fbdae7e6d805 1465
borlanic 0:fbdae7e6d805 1466 if( md_alg != MBEDTLS_MD_NONE )
borlanic 0:fbdae7e6d805 1467 {
borlanic 0:fbdae7e6d805 1468 /* Gather length of hash to sign */
borlanic 0:fbdae7e6d805 1469 md_info = mbedtls_md_info_from_type( md_alg );
borlanic 0:fbdae7e6d805 1470 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1471 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1472
borlanic 0:fbdae7e6d805 1473 hashlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1474 }
borlanic 0:fbdae7e6d805 1475
borlanic 0:fbdae7e6d805 1476 md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
borlanic 0:fbdae7e6d805 1477 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1478 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1479
borlanic 0:fbdae7e6d805 1480 hlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1481 slen = hlen;
borlanic 0:fbdae7e6d805 1482
borlanic 0:fbdae7e6d805 1483 if( olen < hlen + slen + 2 )
borlanic 0:fbdae7e6d805 1484 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1485
borlanic 0:fbdae7e6d805 1486 memset( sig, 0, olen );
borlanic 0:fbdae7e6d805 1487
borlanic 0:fbdae7e6d805 1488 /* Generate salt of length slen */
borlanic 0:fbdae7e6d805 1489 if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
borlanic 0:fbdae7e6d805 1490 return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
borlanic 0:fbdae7e6d805 1491
borlanic 0:fbdae7e6d805 1492 /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
borlanic 0:fbdae7e6d805 1493 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
borlanic 0:fbdae7e6d805 1494 p += olen - hlen * 2 - 2;
borlanic 0:fbdae7e6d805 1495 *p++ = 0x01;
borlanic 0:fbdae7e6d805 1496 memcpy( p, salt, slen );
borlanic 0:fbdae7e6d805 1497 p += slen;
borlanic 0:fbdae7e6d805 1498
borlanic 0:fbdae7e6d805 1499 mbedtls_md_init( &md_ctx );
borlanic 0:fbdae7e6d805 1500 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
borlanic 0:fbdae7e6d805 1501 goto exit;
borlanic 0:fbdae7e6d805 1502
borlanic 0:fbdae7e6d805 1503 /* Generate H = Hash( M' ) */
borlanic 0:fbdae7e6d805 1504 if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 1505 goto exit;
borlanic 0:fbdae7e6d805 1506 if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
borlanic 0:fbdae7e6d805 1507 goto exit;
borlanic 0:fbdae7e6d805 1508 if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
borlanic 0:fbdae7e6d805 1509 goto exit;
borlanic 0:fbdae7e6d805 1510 if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
borlanic 0:fbdae7e6d805 1511 goto exit;
borlanic 0:fbdae7e6d805 1512 if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
borlanic 0:fbdae7e6d805 1513 goto exit;
borlanic 0:fbdae7e6d805 1514
borlanic 0:fbdae7e6d805 1515 /* Compensate for boundary condition when applying mask */
borlanic 0:fbdae7e6d805 1516 if( msb % 8 == 0 )
borlanic 0:fbdae7e6d805 1517 offset = 1;
borlanic 0:fbdae7e6d805 1518
borlanic 0:fbdae7e6d805 1519 /* maskedDB: Apply dbMask to DB */
borlanic 0:fbdae7e6d805 1520 if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
borlanic 0:fbdae7e6d805 1521 &md_ctx ) ) != 0 )
borlanic 0:fbdae7e6d805 1522 goto exit;
borlanic 0:fbdae7e6d805 1523
borlanic 0:fbdae7e6d805 1524 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
borlanic 0:fbdae7e6d805 1525 sig[0] &= 0xFF >> ( olen * 8 - msb );
borlanic 0:fbdae7e6d805 1526
borlanic 0:fbdae7e6d805 1527 p += hlen;
borlanic 0:fbdae7e6d805 1528 *p++ = 0xBC;
borlanic 0:fbdae7e6d805 1529
borlanic 0:fbdae7e6d805 1530 mbedtls_zeroize( salt, sizeof( salt ) );
borlanic 0:fbdae7e6d805 1531
borlanic 0:fbdae7e6d805 1532 exit:
borlanic 0:fbdae7e6d805 1533 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1534
borlanic 0:fbdae7e6d805 1535 if( ret != 0 )
borlanic 0:fbdae7e6d805 1536 return( ret );
borlanic 0:fbdae7e6d805 1537
borlanic 0:fbdae7e6d805 1538 return( ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1539 ? mbedtls_rsa_public( ctx, sig, sig )
borlanic 0:fbdae7e6d805 1540 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
borlanic 0:fbdae7e6d805 1541 }
borlanic 0:fbdae7e6d805 1542 #endif /* MBEDTLS_PKCS1_V21 */
borlanic 0:fbdae7e6d805 1543
borlanic 0:fbdae7e6d805 1544 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1545 /*
borlanic 0:fbdae7e6d805 1546 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
borlanic 0:fbdae7e6d805 1547 */
borlanic 0:fbdae7e6d805 1548
borlanic 0:fbdae7e6d805 1549 /* Construct a PKCS v1.5 encoding of a hashed message
borlanic 0:fbdae7e6d805 1550 *
borlanic 0:fbdae7e6d805 1551 * This is used both for signature generation and verification.
borlanic 0:fbdae7e6d805 1552 *
borlanic 0:fbdae7e6d805 1553 * Parameters:
borlanic 0:fbdae7e6d805 1554 * - md_alg: Identifies the hash algorithm used to generate the given hash;
borlanic 0:fbdae7e6d805 1555 * MBEDTLS_MD_NONE if raw data is signed.
borlanic 0:fbdae7e6d805 1556 * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
borlanic 0:fbdae7e6d805 1557 * - hash: Buffer containing the hashed message or the raw data.
borlanic 0:fbdae7e6d805 1558 * - dst_len: Length of the encoded message.
borlanic 0:fbdae7e6d805 1559 * - dst: Buffer to hold the encoded message.
borlanic 0:fbdae7e6d805 1560 *
borlanic 0:fbdae7e6d805 1561 * Assumptions:
borlanic 0:fbdae7e6d805 1562 * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
borlanic 0:fbdae7e6d805 1563 * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
borlanic 0:fbdae7e6d805 1564 * - dst points to a buffer of size at least dst_len.
borlanic 0:fbdae7e6d805 1565 *
borlanic 0:fbdae7e6d805 1566 */
borlanic 0:fbdae7e6d805 1567 static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1568 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1569 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1570 size_t dst_len,
borlanic 0:fbdae7e6d805 1571 unsigned char *dst )
borlanic 0:fbdae7e6d805 1572 {
borlanic 0:fbdae7e6d805 1573 size_t oid_size = 0;
borlanic 0:fbdae7e6d805 1574 size_t nb_pad = dst_len;
borlanic 0:fbdae7e6d805 1575 unsigned char *p = dst;
borlanic 0:fbdae7e6d805 1576 const char *oid = NULL;
borlanic 0:fbdae7e6d805 1577
borlanic 0:fbdae7e6d805 1578 /* Are we signing hashed or raw data? */
borlanic 0:fbdae7e6d805 1579 if( md_alg != MBEDTLS_MD_NONE )
borlanic 0:fbdae7e6d805 1580 {
borlanic 0:fbdae7e6d805 1581 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
borlanic 0:fbdae7e6d805 1582 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1583 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1584
borlanic 0:fbdae7e6d805 1585 if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
borlanic 0:fbdae7e6d805 1586 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1587
borlanic 0:fbdae7e6d805 1588 hashlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1589
borlanic 0:fbdae7e6d805 1590 /* Double-check that 8 + hashlen + oid_size can be used as a
borlanic 0:fbdae7e6d805 1591 * 1-byte ASN.1 length encoding and that there's no overflow. */
borlanic 0:fbdae7e6d805 1592 if( 8 + hashlen + oid_size >= 0x80 ||
borlanic 0:fbdae7e6d805 1593 10 + hashlen < hashlen ||
borlanic 0:fbdae7e6d805 1594 10 + hashlen + oid_size < 10 + hashlen )
borlanic 0:fbdae7e6d805 1595 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1596
borlanic 0:fbdae7e6d805 1597 /*
borlanic 0:fbdae7e6d805 1598 * Static bounds check:
borlanic 0:fbdae7e6d805 1599 * - Need 10 bytes for five tag-length pairs.
borlanic 0:fbdae7e6d805 1600 * (Insist on 1-byte length encodings to protect against variants of
borlanic 0:fbdae7e6d805 1601 * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
borlanic 0:fbdae7e6d805 1602 * - Need hashlen bytes for hash
borlanic 0:fbdae7e6d805 1603 * - Need oid_size bytes for hash alg OID.
borlanic 0:fbdae7e6d805 1604 */
borlanic 0:fbdae7e6d805 1605 if( nb_pad < 10 + hashlen + oid_size )
borlanic 0:fbdae7e6d805 1606 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1607 nb_pad -= 10 + hashlen + oid_size;
borlanic 0:fbdae7e6d805 1608 }
borlanic 0:fbdae7e6d805 1609 else
borlanic 0:fbdae7e6d805 1610 {
borlanic 0:fbdae7e6d805 1611 if( nb_pad < hashlen )
borlanic 0:fbdae7e6d805 1612 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1613
borlanic 0:fbdae7e6d805 1614 nb_pad -= hashlen;
borlanic 0:fbdae7e6d805 1615 }
borlanic 0:fbdae7e6d805 1616
borlanic 0:fbdae7e6d805 1617 /* Need space for signature header and padding delimiter (3 bytes),
borlanic 0:fbdae7e6d805 1618 * and 8 bytes for the minimal padding */
borlanic 0:fbdae7e6d805 1619 if( nb_pad < 3 + 8 )
borlanic 0:fbdae7e6d805 1620 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1621 nb_pad -= 3;
borlanic 0:fbdae7e6d805 1622
borlanic 0:fbdae7e6d805 1623 /* Now nb_pad is the amount of memory to be filled
borlanic 0:fbdae7e6d805 1624 * with padding, and at least 8 bytes long. */
borlanic 0:fbdae7e6d805 1625
borlanic 0:fbdae7e6d805 1626 /* Write signature header and padding */
borlanic 0:fbdae7e6d805 1627 *p++ = 0;
borlanic 0:fbdae7e6d805 1628 *p++ = MBEDTLS_RSA_SIGN;
borlanic 0:fbdae7e6d805 1629 memset( p, 0xFF, nb_pad );
borlanic 0:fbdae7e6d805 1630 p += nb_pad;
borlanic 0:fbdae7e6d805 1631 *p++ = 0;
borlanic 0:fbdae7e6d805 1632
borlanic 0:fbdae7e6d805 1633 /* Are we signing raw data? */
borlanic 0:fbdae7e6d805 1634 if( md_alg == MBEDTLS_MD_NONE )
borlanic 0:fbdae7e6d805 1635 {
borlanic 0:fbdae7e6d805 1636 memcpy( p, hash, hashlen );
borlanic 0:fbdae7e6d805 1637 return( 0 );
borlanic 0:fbdae7e6d805 1638 }
borlanic 0:fbdae7e6d805 1639
borlanic 0:fbdae7e6d805 1640 /* Signing hashed data, add corresponding ASN.1 structure
borlanic 0:fbdae7e6d805 1641 *
borlanic 0:fbdae7e6d805 1642 * DigestInfo ::= SEQUENCE {
borlanic 0:fbdae7e6d805 1643 * digestAlgorithm DigestAlgorithmIdentifier,
borlanic 0:fbdae7e6d805 1644 * digest Digest }
borlanic 0:fbdae7e6d805 1645 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
borlanic 0:fbdae7e6d805 1646 * Digest ::= OCTET STRING
borlanic 0:fbdae7e6d805 1647 *
borlanic 0:fbdae7e6d805 1648 * Schematic:
borlanic 0:fbdae7e6d805 1649 * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ]
borlanic 0:fbdae7e6d805 1650 * TAG-NULL + LEN [ NULL ] ]
borlanic 0:fbdae7e6d805 1651 * TAG-OCTET + LEN [ HASH ] ]
borlanic 0:fbdae7e6d805 1652 */
borlanic 0:fbdae7e6d805 1653 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
borlanic 0:fbdae7e6d805 1654 *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
borlanic 0:fbdae7e6d805 1655 *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
borlanic 0:fbdae7e6d805 1656 *p++ = (unsigned char)( 0x04 + oid_size );
borlanic 0:fbdae7e6d805 1657 *p++ = MBEDTLS_ASN1_OID;
borlanic 0:fbdae7e6d805 1658 *p++ = (unsigned char) oid_size;
borlanic 0:fbdae7e6d805 1659 memcpy( p, oid, oid_size );
borlanic 0:fbdae7e6d805 1660 p += oid_size;
borlanic 0:fbdae7e6d805 1661 *p++ = MBEDTLS_ASN1_NULL;
borlanic 0:fbdae7e6d805 1662 *p++ = 0x00;
borlanic 0:fbdae7e6d805 1663 *p++ = MBEDTLS_ASN1_OCTET_STRING;
borlanic 0:fbdae7e6d805 1664 *p++ = (unsigned char) hashlen;
borlanic 0:fbdae7e6d805 1665 memcpy( p, hash, hashlen );
borlanic 0:fbdae7e6d805 1666 p += hashlen;
borlanic 0:fbdae7e6d805 1667
borlanic 0:fbdae7e6d805 1668 /* Just a sanity-check, should be automatic
borlanic 0:fbdae7e6d805 1669 * after the initial bounds check. */
borlanic 0:fbdae7e6d805 1670 if( p != dst + dst_len )
borlanic 0:fbdae7e6d805 1671 {
borlanic 0:fbdae7e6d805 1672 mbedtls_zeroize( dst, dst_len );
borlanic 0:fbdae7e6d805 1673 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1674 }
borlanic 0:fbdae7e6d805 1675
borlanic 0:fbdae7e6d805 1676 return( 0 );
borlanic 0:fbdae7e6d805 1677 }
borlanic 0:fbdae7e6d805 1678
borlanic 0:fbdae7e6d805 1679 /*
borlanic 0:fbdae7e6d805 1680 * Do an RSA operation to sign the message digest
borlanic 0:fbdae7e6d805 1681 */
borlanic 0:fbdae7e6d805 1682 int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1683 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1684 void *p_rng,
borlanic 0:fbdae7e6d805 1685 int mode,
borlanic 0:fbdae7e6d805 1686 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1687 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1688 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1689 unsigned char *sig )
borlanic 0:fbdae7e6d805 1690 {
borlanic 0:fbdae7e6d805 1691 int ret;
borlanic 0:fbdae7e6d805 1692 unsigned char *sig_try = NULL, *verif = NULL;
borlanic 0:fbdae7e6d805 1693
borlanic 0:fbdae7e6d805 1694 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
borlanic 0:fbdae7e6d805 1695 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1696
borlanic 0:fbdae7e6d805 1697 /*
borlanic 0:fbdae7e6d805 1698 * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
borlanic 0:fbdae7e6d805 1699 */
borlanic 0:fbdae7e6d805 1700
borlanic 0:fbdae7e6d805 1701 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
borlanic 0:fbdae7e6d805 1702 ctx->len, sig ) ) != 0 )
borlanic 0:fbdae7e6d805 1703 return( ret );
borlanic 0:fbdae7e6d805 1704
borlanic 0:fbdae7e6d805 1705 /*
borlanic 0:fbdae7e6d805 1706 * Call respective RSA primitive
borlanic 0:fbdae7e6d805 1707 */
borlanic 0:fbdae7e6d805 1708
borlanic 0:fbdae7e6d805 1709 if( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1710 {
borlanic 0:fbdae7e6d805 1711 /* Skip verification on a public key operation */
borlanic 0:fbdae7e6d805 1712 return( mbedtls_rsa_public( ctx, sig, sig ) );
borlanic 0:fbdae7e6d805 1713 }
borlanic 0:fbdae7e6d805 1714
borlanic 0:fbdae7e6d805 1715 /* Private key operation
borlanic 0:fbdae7e6d805 1716 *
borlanic 0:fbdae7e6d805 1717 * In order to prevent Lenstra's attack, make the signature in a
borlanic 0:fbdae7e6d805 1718 * temporary buffer and check it before returning it.
borlanic 0:fbdae7e6d805 1719 */
borlanic 0:fbdae7e6d805 1720
borlanic 0:fbdae7e6d805 1721 sig_try = mbedtls_calloc( 1, ctx->len );
borlanic 0:fbdae7e6d805 1722 if( sig_try == NULL )
borlanic 0:fbdae7e6d805 1723 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
borlanic 0:fbdae7e6d805 1724
borlanic 0:fbdae7e6d805 1725 verif = mbedtls_calloc( 1, ctx->len );
borlanic 0:fbdae7e6d805 1726 if( verif == NULL )
borlanic 0:fbdae7e6d805 1727 {
borlanic 0:fbdae7e6d805 1728 mbedtls_free( sig_try );
borlanic 0:fbdae7e6d805 1729 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
borlanic 0:fbdae7e6d805 1730 }
borlanic 0:fbdae7e6d805 1731
borlanic 0:fbdae7e6d805 1732 MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
borlanic 0:fbdae7e6d805 1733 MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
borlanic 0:fbdae7e6d805 1734
borlanic 0:fbdae7e6d805 1735 if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
borlanic 0:fbdae7e6d805 1736 {
borlanic 0:fbdae7e6d805 1737 ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
borlanic 0:fbdae7e6d805 1738 goto cleanup;
borlanic 0:fbdae7e6d805 1739 }
borlanic 0:fbdae7e6d805 1740
borlanic 0:fbdae7e6d805 1741 memcpy( sig, sig_try, ctx->len );
borlanic 0:fbdae7e6d805 1742
borlanic 0:fbdae7e6d805 1743 cleanup:
borlanic 0:fbdae7e6d805 1744 mbedtls_free( sig_try );
borlanic 0:fbdae7e6d805 1745 mbedtls_free( verif );
borlanic 0:fbdae7e6d805 1746
borlanic 0:fbdae7e6d805 1747 return( ret );
borlanic 0:fbdae7e6d805 1748 }
borlanic 0:fbdae7e6d805 1749 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 1750
borlanic 0:fbdae7e6d805 1751 /*
borlanic 0:fbdae7e6d805 1752 * Do an RSA operation to sign the message digest
borlanic 0:fbdae7e6d805 1753 */
borlanic 0:fbdae7e6d805 1754 int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1755 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1756 void *p_rng,
borlanic 0:fbdae7e6d805 1757 int mode,
borlanic 0:fbdae7e6d805 1758 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1759 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1760 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1761 unsigned char *sig )
borlanic 0:fbdae7e6d805 1762 {
borlanic 0:fbdae7e6d805 1763 switch( ctx->padding )
borlanic 0:fbdae7e6d805 1764 {
borlanic 0:fbdae7e6d805 1765 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1766 case MBEDTLS_RSA_PKCS_V15:
borlanic 0:fbdae7e6d805 1767 return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
borlanic 0:fbdae7e6d805 1768 hashlen, hash, sig );
borlanic 0:fbdae7e6d805 1769 #endif
borlanic 0:fbdae7e6d805 1770
borlanic 0:fbdae7e6d805 1771 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1772 case MBEDTLS_RSA_PKCS_V21:
borlanic 0:fbdae7e6d805 1773 return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
borlanic 0:fbdae7e6d805 1774 hashlen, hash, sig );
borlanic 0:fbdae7e6d805 1775 #endif
borlanic 0:fbdae7e6d805 1776
borlanic 0:fbdae7e6d805 1777 default:
borlanic 0:fbdae7e6d805 1778 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
borlanic 0:fbdae7e6d805 1779 }
borlanic 0:fbdae7e6d805 1780 }
borlanic 0:fbdae7e6d805 1781
borlanic 0:fbdae7e6d805 1782 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 1783 /*
borlanic 0:fbdae7e6d805 1784 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
borlanic 0:fbdae7e6d805 1785 */
borlanic 0:fbdae7e6d805 1786 int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1787 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1788 void *p_rng,
borlanic 0:fbdae7e6d805 1789 int mode,
borlanic 0:fbdae7e6d805 1790 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1791 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1792 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1793 mbedtls_md_type_t mgf1_hash_id,
borlanic 0:fbdae7e6d805 1794 int expected_salt_len,
borlanic 0:fbdae7e6d805 1795 const unsigned char *sig )
borlanic 0:fbdae7e6d805 1796 {
borlanic 0:fbdae7e6d805 1797 int ret;
borlanic 0:fbdae7e6d805 1798 size_t siglen;
borlanic 0:fbdae7e6d805 1799 unsigned char *p;
borlanic 0:fbdae7e6d805 1800 unsigned char *hash_start;
borlanic 0:fbdae7e6d805 1801 unsigned char result[MBEDTLS_MD_MAX_SIZE];
borlanic 0:fbdae7e6d805 1802 unsigned char zeros[8];
borlanic 0:fbdae7e6d805 1803 unsigned int hlen;
borlanic 0:fbdae7e6d805 1804 size_t observed_salt_len, msb;
borlanic 0:fbdae7e6d805 1805 const mbedtls_md_info_t *md_info;
borlanic 0:fbdae7e6d805 1806 mbedtls_md_context_t md_ctx;
borlanic 0:fbdae7e6d805 1807 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
borlanic 0:fbdae7e6d805 1808
borlanic 0:fbdae7e6d805 1809 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
borlanic 0:fbdae7e6d805 1810 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1811
borlanic 0:fbdae7e6d805 1812 siglen = ctx->len;
borlanic 0:fbdae7e6d805 1813
borlanic 0:fbdae7e6d805 1814 if( siglen < 16 || siglen > sizeof( buf ) )
borlanic 0:fbdae7e6d805 1815 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1816
borlanic 0:fbdae7e6d805 1817 ret = ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1818 ? mbedtls_rsa_public( ctx, sig, buf )
borlanic 0:fbdae7e6d805 1819 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
borlanic 0:fbdae7e6d805 1820
borlanic 0:fbdae7e6d805 1821 if( ret != 0 )
borlanic 0:fbdae7e6d805 1822 return( ret );
borlanic 0:fbdae7e6d805 1823
borlanic 0:fbdae7e6d805 1824 p = buf;
borlanic 0:fbdae7e6d805 1825
borlanic 0:fbdae7e6d805 1826 if( buf[siglen - 1] != 0xBC )
borlanic 0:fbdae7e6d805 1827 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
borlanic 0:fbdae7e6d805 1828
borlanic 0:fbdae7e6d805 1829 if( md_alg != MBEDTLS_MD_NONE )
borlanic 0:fbdae7e6d805 1830 {
borlanic 0:fbdae7e6d805 1831 /* Gather length of hash to sign */
borlanic 0:fbdae7e6d805 1832 md_info = mbedtls_md_info_from_type( md_alg );
borlanic 0:fbdae7e6d805 1833 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1834 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1835
borlanic 0:fbdae7e6d805 1836 hashlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1837 }
borlanic 0:fbdae7e6d805 1838
borlanic 0:fbdae7e6d805 1839 md_info = mbedtls_md_info_from_type( mgf1_hash_id );
borlanic 0:fbdae7e6d805 1840 if( md_info == NULL )
borlanic 0:fbdae7e6d805 1841 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1842
borlanic 0:fbdae7e6d805 1843 hlen = mbedtls_md_get_size( md_info );
borlanic 0:fbdae7e6d805 1844
borlanic 0:fbdae7e6d805 1845 memset( zeros, 0, 8 );
borlanic 0:fbdae7e6d805 1846
borlanic 0:fbdae7e6d805 1847 /*
borlanic 0:fbdae7e6d805 1848 * Note: EMSA-PSS verification is over the length of N - 1 bits
borlanic 0:fbdae7e6d805 1849 */
borlanic 0:fbdae7e6d805 1850 msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
borlanic 0:fbdae7e6d805 1851
borlanic 0:fbdae7e6d805 1852 if( buf[0] >> ( 8 - siglen * 8 + msb ) )
borlanic 0:fbdae7e6d805 1853 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1854
borlanic 0:fbdae7e6d805 1855 /* Compensate for boundary condition when applying mask */
borlanic 0:fbdae7e6d805 1856 if( msb % 8 == 0 )
borlanic 0:fbdae7e6d805 1857 {
borlanic 0:fbdae7e6d805 1858 p++;
borlanic 0:fbdae7e6d805 1859 siglen -= 1;
borlanic 0:fbdae7e6d805 1860 }
borlanic 0:fbdae7e6d805 1861
borlanic 0:fbdae7e6d805 1862 if( siglen < hlen + 2 )
borlanic 0:fbdae7e6d805 1863 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1864 hash_start = p + siglen - hlen - 1;
borlanic 0:fbdae7e6d805 1865
borlanic 0:fbdae7e6d805 1866 mbedtls_md_init( &md_ctx );
borlanic 0:fbdae7e6d805 1867 if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
borlanic 0:fbdae7e6d805 1868 goto exit;
borlanic 0:fbdae7e6d805 1869
borlanic 0:fbdae7e6d805 1870 ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
borlanic 0:fbdae7e6d805 1871 if( ret != 0 )
borlanic 0:fbdae7e6d805 1872 goto exit;
borlanic 0:fbdae7e6d805 1873
borlanic 0:fbdae7e6d805 1874 buf[0] &= 0xFF >> ( siglen * 8 - msb );
borlanic 0:fbdae7e6d805 1875
borlanic 0:fbdae7e6d805 1876 while( p < hash_start - 1 && *p == 0 )
borlanic 0:fbdae7e6d805 1877 p++;
borlanic 0:fbdae7e6d805 1878
borlanic 0:fbdae7e6d805 1879 if( *p++ != 0x01 )
borlanic 0:fbdae7e6d805 1880 {
borlanic 0:fbdae7e6d805 1881 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
borlanic 0:fbdae7e6d805 1882 goto exit;
borlanic 0:fbdae7e6d805 1883 }
borlanic 0:fbdae7e6d805 1884
borlanic 0:fbdae7e6d805 1885 observed_salt_len = hash_start - p;
borlanic 0:fbdae7e6d805 1886
borlanic 0:fbdae7e6d805 1887 if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
borlanic 0:fbdae7e6d805 1888 observed_salt_len != (size_t) expected_salt_len )
borlanic 0:fbdae7e6d805 1889 {
borlanic 0:fbdae7e6d805 1890 ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
borlanic 0:fbdae7e6d805 1891 goto exit;
borlanic 0:fbdae7e6d805 1892 }
borlanic 0:fbdae7e6d805 1893
borlanic 0:fbdae7e6d805 1894 /*
borlanic 0:fbdae7e6d805 1895 * Generate H = Hash( M' )
borlanic 0:fbdae7e6d805 1896 */
borlanic 0:fbdae7e6d805 1897 ret = mbedtls_md_starts( &md_ctx );
borlanic 0:fbdae7e6d805 1898 if ( ret != 0 )
borlanic 0:fbdae7e6d805 1899 goto exit;
borlanic 0:fbdae7e6d805 1900 ret = mbedtls_md_update( &md_ctx, zeros, 8 );
borlanic 0:fbdae7e6d805 1901 if ( ret != 0 )
borlanic 0:fbdae7e6d805 1902 goto exit;
borlanic 0:fbdae7e6d805 1903 ret = mbedtls_md_update( &md_ctx, hash, hashlen );
borlanic 0:fbdae7e6d805 1904 if ( ret != 0 )
borlanic 0:fbdae7e6d805 1905 goto exit;
borlanic 0:fbdae7e6d805 1906 ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );
borlanic 0:fbdae7e6d805 1907 if ( ret != 0 )
borlanic 0:fbdae7e6d805 1908 goto exit;
borlanic 0:fbdae7e6d805 1909 ret = mbedtls_md_finish( &md_ctx, result );
borlanic 0:fbdae7e6d805 1910 if ( ret != 0 )
borlanic 0:fbdae7e6d805 1911 goto exit;
borlanic 0:fbdae7e6d805 1912
borlanic 0:fbdae7e6d805 1913 if( memcmp( hash_start, result, hlen ) != 0 )
borlanic 0:fbdae7e6d805 1914 {
borlanic 0:fbdae7e6d805 1915 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
borlanic 0:fbdae7e6d805 1916 goto exit;
borlanic 0:fbdae7e6d805 1917 }
borlanic 0:fbdae7e6d805 1918
borlanic 0:fbdae7e6d805 1919 exit:
borlanic 0:fbdae7e6d805 1920 mbedtls_md_free( &md_ctx );
borlanic 0:fbdae7e6d805 1921
borlanic 0:fbdae7e6d805 1922 return( ret );
borlanic 0:fbdae7e6d805 1923 }
borlanic 0:fbdae7e6d805 1924
borlanic 0:fbdae7e6d805 1925 /*
borlanic 0:fbdae7e6d805 1926 * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
borlanic 0:fbdae7e6d805 1927 */
borlanic 0:fbdae7e6d805 1928 int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1929 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1930 void *p_rng,
borlanic 0:fbdae7e6d805 1931 int mode,
borlanic 0:fbdae7e6d805 1932 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1933 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1934 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1935 const unsigned char *sig )
borlanic 0:fbdae7e6d805 1936 {
borlanic 0:fbdae7e6d805 1937 mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
borlanic 0:fbdae7e6d805 1938 ? (mbedtls_md_type_t) ctx->hash_id
borlanic 0:fbdae7e6d805 1939 : md_alg;
borlanic 0:fbdae7e6d805 1940
borlanic 0:fbdae7e6d805 1941 return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
borlanic 0:fbdae7e6d805 1942 md_alg, hashlen, hash,
borlanic 0:fbdae7e6d805 1943 mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
borlanic 0:fbdae7e6d805 1944 sig ) );
borlanic 0:fbdae7e6d805 1945
borlanic 0:fbdae7e6d805 1946 }
borlanic 0:fbdae7e6d805 1947 #endif /* MBEDTLS_PKCS1_V21 */
borlanic 0:fbdae7e6d805 1948
borlanic 0:fbdae7e6d805 1949 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 1950 /*
borlanic 0:fbdae7e6d805 1951 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
borlanic 0:fbdae7e6d805 1952 */
borlanic 0:fbdae7e6d805 1953 int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 1954 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 1955 void *p_rng,
borlanic 0:fbdae7e6d805 1956 int mode,
borlanic 0:fbdae7e6d805 1957 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 1958 unsigned int hashlen,
borlanic 0:fbdae7e6d805 1959 const unsigned char *hash,
borlanic 0:fbdae7e6d805 1960 const unsigned char *sig )
borlanic 0:fbdae7e6d805 1961 {
borlanic 0:fbdae7e6d805 1962 int ret = 0;
borlanic 0:fbdae7e6d805 1963 const size_t sig_len = ctx->len;
borlanic 0:fbdae7e6d805 1964 unsigned char *encoded = NULL, *encoded_expected = NULL;
borlanic 0:fbdae7e6d805 1965
borlanic 0:fbdae7e6d805 1966 if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
borlanic 0:fbdae7e6d805 1967 return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
borlanic 0:fbdae7e6d805 1968
borlanic 0:fbdae7e6d805 1969 /*
borlanic 0:fbdae7e6d805 1970 * Prepare expected PKCS1 v1.5 encoding of hash.
borlanic 0:fbdae7e6d805 1971 */
borlanic 0:fbdae7e6d805 1972
borlanic 0:fbdae7e6d805 1973 if( ( encoded = mbedtls_calloc( 1, sig_len ) ) == NULL ||
borlanic 0:fbdae7e6d805 1974 ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
borlanic 0:fbdae7e6d805 1975 {
borlanic 0:fbdae7e6d805 1976 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
borlanic 0:fbdae7e6d805 1977 goto cleanup;
borlanic 0:fbdae7e6d805 1978 }
borlanic 0:fbdae7e6d805 1979
borlanic 0:fbdae7e6d805 1980 if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
borlanic 0:fbdae7e6d805 1981 encoded_expected ) ) != 0 )
borlanic 0:fbdae7e6d805 1982 goto cleanup;
borlanic 0:fbdae7e6d805 1983
borlanic 0:fbdae7e6d805 1984 /*
borlanic 0:fbdae7e6d805 1985 * Apply RSA primitive to get what should be PKCS1 encoded hash.
borlanic 0:fbdae7e6d805 1986 */
borlanic 0:fbdae7e6d805 1987
borlanic 0:fbdae7e6d805 1988 ret = ( mode == MBEDTLS_RSA_PUBLIC )
borlanic 0:fbdae7e6d805 1989 ? mbedtls_rsa_public( ctx, sig, encoded )
borlanic 0:fbdae7e6d805 1990 : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded );
borlanic 0:fbdae7e6d805 1991 if( ret != 0 )
borlanic 0:fbdae7e6d805 1992 goto cleanup;
borlanic 0:fbdae7e6d805 1993
borlanic 0:fbdae7e6d805 1994 /*
borlanic 0:fbdae7e6d805 1995 * Compare
borlanic 0:fbdae7e6d805 1996 */
borlanic 0:fbdae7e6d805 1997
borlanic 0:fbdae7e6d805 1998 if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
borlanic 0:fbdae7e6d805 1999 sig_len ) ) != 0 )
borlanic 0:fbdae7e6d805 2000 {
borlanic 0:fbdae7e6d805 2001 ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
borlanic 0:fbdae7e6d805 2002 goto cleanup;
borlanic 0:fbdae7e6d805 2003 }
borlanic 0:fbdae7e6d805 2004
borlanic 0:fbdae7e6d805 2005 cleanup:
borlanic 0:fbdae7e6d805 2006
borlanic 0:fbdae7e6d805 2007 if( encoded != NULL )
borlanic 0:fbdae7e6d805 2008 {
borlanic 0:fbdae7e6d805 2009 mbedtls_zeroize( encoded, sig_len );
borlanic 0:fbdae7e6d805 2010 mbedtls_free( encoded );
borlanic 0:fbdae7e6d805 2011 }
borlanic 0:fbdae7e6d805 2012
borlanic 0:fbdae7e6d805 2013 if( encoded_expected != NULL )
borlanic 0:fbdae7e6d805 2014 {
borlanic 0:fbdae7e6d805 2015 mbedtls_zeroize( encoded_expected, sig_len );
borlanic 0:fbdae7e6d805 2016 mbedtls_free( encoded_expected );
borlanic 0:fbdae7e6d805 2017 }
borlanic 0:fbdae7e6d805 2018
borlanic 0:fbdae7e6d805 2019 return( ret );
borlanic 0:fbdae7e6d805 2020 }
borlanic 0:fbdae7e6d805 2021 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 2022
borlanic 0:fbdae7e6d805 2023 /*
borlanic 0:fbdae7e6d805 2024 * Do an RSA operation and check the message digest
borlanic 0:fbdae7e6d805 2025 */
borlanic 0:fbdae7e6d805 2026 int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
borlanic 0:fbdae7e6d805 2027 int (*f_rng)(void *, unsigned char *, size_t),
borlanic 0:fbdae7e6d805 2028 void *p_rng,
borlanic 0:fbdae7e6d805 2029 int mode,
borlanic 0:fbdae7e6d805 2030 mbedtls_md_type_t md_alg,
borlanic 0:fbdae7e6d805 2031 unsigned int hashlen,
borlanic 0:fbdae7e6d805 2032 const unsigned char *hash,
borlanic 0:fbdae7e6d805 2033 const unsigned char *sig )
borlanic 0:fbdae7e6d805 2034 {
borlanic 0:fbdae7e6d805 2035 switch( ctx->padding )
borlanic 0:fbdae7e6d805 2036 {
borlanic 0:fbdae7e6d805 2037 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 2038 case MBEDTLS_RSA_PKCS_V15:
borlanic 0:fbdae7e6d805 2039 return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
borlanic 0:fbdae7e6d805 2040 hashlen, hash, sig );
borlanic 0:fbdae7e6d805 2041 #endif
borlanic 0:fbdae7e6d805 2042
borlanic 0:fbdae7e6d805 2043 #if defined(MBEDTLS_PKCS1_V21)
borlanic 0:fbdae7e6d805 2044 case MBEDTLS_RSA_PKCS_V21:
borlanic 0:fbdae7e6d805 2045 return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
borlanic 0:fbdae7e6d805 2046 hashlen, hash, sig );
borlanic 0:fbdae7e6d805 2047 #endif
borlanic 0:fbdae7e6d805 2048
borlanic 0:fbdae7e6d805 2049 default:
borlanic 0:fbdae7e6d805 2050 return( MBEDTLS_ERR_RSA_INVALID_PADDING );
borlanic 0:fbdae7e6d805 2051 }
borlanic 0:fbdae7e6d805 2052 }
borlanic 0:fbdae7e6d805 2053
borlanic 0:fbdae7e6d805 2054 /*
borlanic 0:fbdae7e6d805 2055 * Copy the components of an RSA key
borlanic 0:fbdae7e6d805 2056 */
borlanic 0:fbdae7e6d805 2057 int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
borlanic 0:fbdae7e6d805 2058 {
borlanic 0:fbdae7e6d805 2059 int ret;
borlanic 0:fbdae7e6d805 2060
borlanic 0:fbdae7e6d805 2061 dst->ver = src->ver;
borlanic 0:fbdae7e6d805 2062 dst->len = src->len;
borlanic 0:fbdae7e6d805 2063
borlanic 0:fbdae7e6d805 2064 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
borlanic 0:fbdae7e6d805 2065 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
borlanic 0:fbdae7e6d805 2066
borlanic 0:fbdae7e6d805 2067 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
borlanic 0:fbdae7e6d805 2068 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
borlanic 0:fbdae7e6d805 2069 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
borlanic 0:fbdae7e6d805 2070
borlanic 0:fbdae7e6d805 2071 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 2072 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
borlanic 0:fbdae7e6d805 2073 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
borlanic 0:fbdae7e6d805 2074 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
borlanic 0:fbdae7e6d805 2075 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
borlanic 0:fbdae7e6d805 2076 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
borlanic 0:fbdae7e6d805 2077 #endif
borlanic 0:fbdae7e6d805 2078
borlanic 0:fbdae7e6d805 2079 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
borlanic 0:fbdae7e6d805 2080
borlanic 0:fbdae7e6d805 2081 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
borlanic 0:fbdae7e6d805 2082 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
borlanic 0:fbdae7e6d805 2083
borlanic 0:fbdae7e6d805 2084 dst->padding = src->padding;
borlanic 0:fbdae7e6d805 2085 dst->hash_id = src->hash_id;
borlanic 0:fbdae7e6d805 2086
borlanic 0:fbdae7e6d805 2087 cleanup:
borlanic 0:fbdae7e6d805 2088 if( ret != 0 )
borlanic 0:fbdae7e6d805 2089 mbedtls_rsa_free( dst );
borlanic 0:fbdae7e6d805 2090
borlanic 0:fbdae7e6d805 2091 return( ret );
borlanic 0:fbdae7e6d805 2092 }
borlanic 0:fbdae7e6d805 2093
borlanic 0:fbdae7e6d805 2094 /*
borlanic 0:fbdae7e6d805 2095 * Free the components of an RSA key
borlanic 0:fbdae7e6d805 2096 */
borlanic 0:fbdae7e6d805 2097 void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
borlanic 0:fbdae7e6d805 2098 {
borlanic 0:fbdae7e6d805 2099 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
borlanic 0:fbdae7e6d805 2100 mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
borlanic 0:fbdae7e6d805 2101 mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
borlanic 0:fbdae7e6d805 2102 mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
borlanic 0:fbdae7e6d805 2103
borlanic 0:fbdae7e6d805 2104 #if !defined(MBEDTLS_RSA_NO_CRT)
borlanic 0:fbdae7e6d805 2105 mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
borlanic 0:fbdae7e6d805 2106 mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
borlanic 0:fbdae7e6d805 2107 mbedtls_mpi_free( &ctx->DP );
borlanic 0:fbdae7e6d805 2108 #endif /* MBEDTLS_RSA_NO_CRT */
borlanic 0:fbdae7e6d805 2109
borlanic 0:fbdae7e6d805 2110 #if defined(MBEDTLS_THREADING_C)
borlanic 0:fbdae7e6d805 2111 mbedtls_mutex_free( &ctx->mutex );
borlanic 0:fbdae7e6d805 2112 #endif
borlanic 0:fbdae7e6d805 2113 }
borlanic 0:fbdae7e6d805 2114
borlanic 0:fbdae7e6d805 2115 #endif /* !MBEDTLS_RSA_ALT */
borlanic 0:fbdae7e6d805 2116
borlanic 0:fbdae7e6d805 2117 #if defined(MBEDTLS_SELF_TEST)
borlanic 0:fbdae7e6d805 2118
borlanic 0:fbdae7e6d805 2119 #include "mbedtls/sha1.h"
borlanic 0:fbdae7e6d805 2120
borlanic 0:fbdae7e6d805 2121 /*
borlanic 0:fbdae7e6d805 2122 * Example RSA-1024 keypair, for test purposes
borlanic 0:fbdae7e6d805 2123 */
borlanic 0:fbdae7e6d805 2124 #define KEY_LEN 128
borlanic 0:fbdae7e6d805 2125
borlanic 0:fbdae7e6d805 2126 #define RSA_N "9292758453063D803DD603D5E777D788" \
borlanic 0:fbdae7e6d805 2127 "8ED1D5BF35786190FA2F23EBC0848AEA" \
borlanic 0:fbdae7e6d805 2128 "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
borlanic 0:fbdae7e6d805 2129 "7130B9CED7ACDF54CFC7555AC14EEBAB" \
borlanic 0:fbdae7e6d805 2130 "93A89813FBF3C4F8066D2D800F7C38A8" \
borlanic 0:fbdae7e6d805 2131 "1AE31942917403FF4946B0A83D3D3E05" \
borlanic 0:fbdae7e6d805 2132 "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
borlanic 0:fbdae7e6d805 2133 "5E94BB77B07507233A0BC7BAC8F90F79"
borlanic 0:fbdae7e6d805 2134
borlanic 0:fbdae7e6d805 2135 #define RSA_E "10001"
borlanic 0:fbdae7e6d805 2136
borlanic 0:fbdae7e6d805 2137 #define RSA_D "24BF6185468786FDD303083D25E64EFC" \
borlanic 0:fbdae7e6d805 2138 "66CA472BC44D253102F8B4A9D3BFA750" \
borlanic 0:fbdae7e6d805 2139 "91386C0077937FE33FA3252D28855837" \
borlanic 0:fbdae7e6d805 2140 "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
borlanic 0:fbdae7e6d805 2141 "DF79C5CE07EE72C7F123142198164234" \
borlanic 0:fbdae7e6d805 2142 "CABB724CF78B8173B9F880FC86322407" \
borlanic 0:fbdae7e6d805 2143 "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
borlanic 0:fbdae7e6d805 2144 "071513A1E85B5DFA031F21ECAE91A34D"
borlanic 0:fbdae7e6d805 2145
borlanic 0:fbdae7e6d805 2146 #define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
borlanic 0:fbdae7e6d805 2147 "2C01CAD19EA484A87EA4377637E75500" \
borlanic 0:fbdae7e6d805 2148 "FCB2005C5C7DD6EC4AC023CDA285D796" \
borlanic 0:fbdae7e6d805 2149 "C3D9E75E1EFC42488BB4F1D13AC30A57"
borlanic 0:fbdae7e6d805 2150
borlanic 0:fbdae7e6d805 2151 #define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
borlanic 0:fbdae7e6d805 2152 "E211C2B9E5DB1ED0BF61D0D9899620F4" \
borlanic 0:fbdae7e6d805 2153 "910E4168387E3C30AA1E00C339A79508" \
borlanic 0:fbdae7e6d805 2154 "8452DD96A9A5EA5D9DCA68DA636032AF"
borlanic 0:fbdae7e6d805 2155
borlanic 0:fbdae7e6d805 2156 #define PT_LEN 24
borlanic 0:fbdae7e6d805 2157 #define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
borlanic 0:fbdae7e6d805 2158 "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
borlanic 0:fbdae7e6d805 2159
borlanic 0:fbdae7e6d805 2160 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 2161 static int myrand( void *rng_state, unsigned char *output, size_t len )
borlanic 0:fbdae7e6d805 2162 {
borlanic 0:fbdae7e6d805 2163 #if !defined(__OpenBSD__)
borlanic 0:fbdae7e6d805 2164 size_t i;
borlanic 0:fbdae7e6d805 2165
borlanic 0:fbdae7e6d805 2166 if( rng_state != NULL )
borlanic 0:fbdae7e6d805 2167 rng_state = NULL;
borlanic 0:fbdae7e6d805 2168
borlanic 0:fbdae7e6d805 2169 for( i = 0; i < len; ++i )
borlanic 0:fbdae7e6d805 2170 output[i] = rand();
borlanic 0:fbdae7e6d805 2171 #else
borlanic 0:fbdae7e6d805 2172 if( rng_state != NULL )
borlanic 0:fbdae7e6d805 2173 rng_state = NULL;
borlanic 0:fbdae7e6d805 2174
borlanic 0:fbdae7e6d805 2175 arc4random_buf( output, len );
borlanic 0:fbdae7e6d805 2176 #endif /* !OpenBSD */
borlanic 0:fbdae7e6d805 2177
borlanic 0:fbdae7e6d805 2178 return( 0 );
borlanic 0:fbdae7e6d805 2179 }
borlanic 0:fbdae7e6d805 2180 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 2181
borlanic 0:fbdae7e6d805 2182 /*
borlanic 0:fbdae7e6d805 2183 * Checkup routine
borlanic 0:fbdae7e6d805 2184 */
borlanic 0:fbdae7e6d805 2185 int mbedtls_rsa_self_test( int verbose )
borlanic 0:fbdae7e6d805 2186 {
borlanic 0:fbdae7e6d805 2187 int ret = 0;
borlanic 0:fbdae7e6d805 2188 #if defined(MBEDTLS_PKCS1_V15)
borlanic 0:fbdae7e6d805 2189 size_t len;
borlanic 0:fbdae7e6d805 2190 mbedtls_rsa_context rsa;
borlanic 0:fbdae7e6d805 2191 unsigned char rsa_plaintext[PT_LEN];
borlanic 0:fbdae7e6d805 2192 unsigned char rsa_decrypted[PT_LEN];
borlanic 0:fbdae7e6d805 2193 unsigned char rsa_ciphertext[KEY_LEN];
borlanic 0:fbdae7e6d805 2194 #if defined(MBEDTLS_SHA1_C)
borlanic 0:fbdae7e6d805 2195 unsigned char sha1sum[20];
borlanic 0:fbdae7e6d805 2196 #endif
borlanic 0:fbdae7e6d805 2197
borlanic 0:fbdae7e6d805 2198 mbedtls_mpi K;
borlanic 0:fbdae7e6d805 2199
borlanic 0:fbdae7e6d805 2200 mbedtls_mpi_init( &K );
borlanic 0:fbdae7e6d805 2201 mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
borlanic 0:fbdae7e6d805 2202
borlanic 0:fbdae7e6d805 2203 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N ) );
borlanic 0:fbdae7e6d805 2204 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
borlanic 0:fbdae7e6d805 2205 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P ) );
borlanic 0:fbdae7e6d805 2206 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
borlanic 0:fbdae7e6d805 2207 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q ) );
borlanic 0:fbdae7e6d805 2208 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
borlanic 0:fbdae7e6d805 2209 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D ) );
borlanic 0:fbdae7e6d805 2210 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
borlanic 0:fbdae7e6d805 2211 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E ) );
borlanic 0:fbdae7e6d805 2212 MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
borlanic 0:fbdae7e6d805 2213
borlanic 0:fbdae7e6d805 2214 MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
borlanic 0:fbdae7e6d805 2215
borlanic 0:fbdae7e6d805 2216 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2217 mbedtls_printf( " RSA key validation: " );
borlanic 0:fbdae7e6d805 2218
borlanic 0:fbdae7e6d805 2219 if( mbedtls_rsa_check_pubkey( &rsa ) != 0 ||
borlanic 0:fbdae7e6d805 2220 mbedtls_rsa_check_privkey( &rsa ) != 0 )
borlanic 0:fbdae7e6d805 2221 {
borlanic 0:fbdae7e6d805 2222 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2223 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2224
borlanic 0:fbdae7e6d805 2225 return( 1 );
borlanic 0:fbdae7e6d805 2226 }
borlanic 0:fbdae7e6d805 2227
borlanic 0:fbdae7e6d805 2228 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2229 mbedtls_printf( "passed\n PKCS#1 encryption : " );
borlanic 0:fbdae7e6d805 2230
borlanic 0:fbdae7e6d805 2231 memcpy( rsa_plaintext, RSA_PT, PT_LEN );
borlanic 0:fbdae7e6d805 2232
borlanic 0:fbdae7e6d805 2233 if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
borlanic 0:fbdae7e6d805 2234 PT_LEN, rsa_plaintext,
borlanic 0:fbdae7e6d805 2235 rsa_ciphertext ) != 0 )
borlanic 0:fbdae7e6d805 2236 {
borlanic 0:fbdae7e6d805 2237 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2238 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2239
borlanic 0:fbdae7e6d805 2240 return( 1 );
borlanic 0:fbdae7e6d805 2241 }
borlanic 0:fbdae7e6d805 2242
borlanic 0:fbdae7e6d805 2243 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2244 mbedtls_printf( "passed\n PKCS#1 decryption : " );
borlanic 0:fbdae7e6d805 2245
borlanic 0:fbdae7e6d805 2246 if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
borlanic 0:fbdae7e6d805 2247 &len, rsa_ciphertext, rsa_decrypted,
borlanic 0:fbdae7e6d805 2248 sizeof(rsa_decrypted) ) != 0 )
borlanic 0:fbdae7e6d805 2249 {
borlanic 0:fbdae7e6d805 2250 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2251 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2252
borlanic 0:fbdae7e6d805 2253 return( 1 );
borlanic 0:fbdae7e6d805 2254 }
borlanic 0:fbdae7e6d805 2255
borlanic 0:fbdae7e6d805 2256 if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
borlanic 0:fbdae7e6d805 2257 {
borlanic 0:fbdae7e6d805 2258 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2259 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2260
borlanic 0:fbdae7e6d805 2261 return( 1 );
borlanic 0:fbdae7e6d805 2262 }
borlanic 0:fbdae7e6d805 2263
borlanic 0:fbdae7e6d805 2264 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2265 mbedtls_printf( "passed\n" );
borlanic 0:fbdae7e6d805 2266
borlanic 0:fbdae7e6d805 2267 #if defined(MBEDTLS_SHA1_C)
borlanic 0:fbdae7e6d805 2268 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2269 mbedtls_printf( " PKCS#1 data sign : " );
borlanic 0:fbdae7e6d805 2270
borlanic 0:fbdae7e6d805 2271 if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
borlanic 0:fbdae7e6d805 2272 {
borlanic 0:fbdae7e6d805 2273 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2274 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2275
borlanic 0:fbdae7e6d805 2276 return( 1 );
borlanic 0:fbdae7e6d805 2277 }
borlanic 0:fbdae7e6d805 2278
borlanic 0:fbdae7e6d805 2279 if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
borlanic 0:fbdae7e6d805 2280 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
borlanic 0:fbdae7e6d805 2281 sha1sum, rsa_ciphertext ) != 0 )
borlanic 0:fbdae7e6d805 2282 {
borlanic 0:fbdae7e6d805 2283 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2284 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2285
borlanic 0:fbdae7e6d805 2286 return( 1 );
borlanic 0:fbdae7e6d805 2287 }
borlanic 0:fbdae7e6d805 2288
borlanic 0:fbdae7e6d805 2289 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2290 mbedtls_printf( "passed\n PKCS#1 sig. verify: " );
borlanic 0:fbdae7e6d805 2291
borlanic 0:fbdae7e6d805 2292 if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
borlanic 0:fbdae7e6d805 2293 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
borlanic 0:fbdae7e6d805 2294 sha1sum, rsa_ciphertext ) != 0 )
borlanic 0:fbdae7e6d805 2295 {
borlanic 0:fbdae7e6d805 2296 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2297 mbedtls_printf( "failed\n" );
borlanic 0:fbdae7e6d805 2298
borlanic 0:fbdae7e6d805 2299 return( 1 );
borlanic 0:fbdae7e6d805 2300 }
borlanic 0:fbdae7e6d805 2301
borlanic 0:fbdae7e6d805 2302 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2303 mbedtls_printf( "passed\n" );
borlanic 0:fbdae7e6d805 2304 #endif /* MBEDTLS_SHA1_C */
borlanic 0:fbdae7e6d805 2305
borlanic 0:fbdae7e6d805 2306 if( verbose != 0 )
borlanic 0:fbdae7e6d805 2307 mbedtls_printf( "\n" );
borlanic 0:fbdae7e6d805 2308
borlanic 0:fbdae7e6d805 2309 cleanup:
borlanic 0:fbdae7e6d805 2310 mbedtls_mpi_free( &K );
borlanic 0:fbdae7e6d805 2311 mbedtls_rsa_free( &rsa );
borlanic 0:fbdae7e6d805 2312 #else /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 2313 ((void) verbose);
borlanic 0:fbdae7e6d805 2314 #endif /* MBEDTLS_PKCS1_V15 */
borlanic 0:fbdae7e6d805 2315 return( ret );
borlanic 0:fbdae7e6d805 2316 }
borlanic 0:fbdae7e6d805 2317
borlanic 0:fbdae7e6d805 2318 #endif /* MBEDTLS_SELF_TEST */
borlanic 0:fbdae7e6d805 2319
borlanic 0:fbdae7e6d805 2320 #endif /* MBEDTLS_RSA_C */