takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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