mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 17 23:23:45 2019 +0000
Revision:
0:5b88d5760320
mbed-os5 only for TYBLE16

Who changed what in which revision?

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