1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +03:00

Merge development commit 8e76332 into development-psa

Additional changes to temporarily enable running tests:
ssl_srv.c and test_suite_ecdh use mbedtls_ecp_group_load instead of
mbedtls_ecdh_setup
test_suite_ctr_drbg uses mbedtls_ctr_drbg_update instead of 
mbedtls_ctr_drbg_update_ret
This commit is contained in:
Andrzej Kurek
2019-01-31 08:20:20 -05:00
parent 7b9575c654
commit c470b6b021
208 changed files with 11024 additions and 2553 deletions

View File

@ -71,6 +71,12 @@
#if !defined(MBEDTLS_RSA_ALT)
/* Parameter validation macros */
#define RSA_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
#define RSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_PKCS1_V15)
/* constant-time buffer comparison */
static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
@ -93,6 +99,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
const mbedtls_mpi *D, const mbedtls_mpi *E )
{
int ret;
RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
@ -117,6 +124,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
unsigned char const *E, size_t E_len )
{
int ret = 0;
RSA_VALIDATE_RET( ctx != NULL );
if( N != NULL )
{
@ -240,12 +248,16 @@ static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
{
int ret = 0;
int have_N, have_P, have_Q, have_D, have_E;
int n_missing, pq_missing, d_missing, is_pub, is_priv;
const int have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
const int have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
const int have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
const int have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
const int have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
RSA_VALIDATE_RET( ctx != NULL );
have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
/*
* Check whether provided parameters are enough
@ -257,13 +269,13 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
*
*/
const int n_missing = have_P && have_Q && have_D && have_E;
const int pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
const int d_missing = have_P && have_Q && !have_D && have_E;
const int is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
n_missing = have_P && have_Q && have_D && have_E;
pq_missing = have_N && !have_P && !have_Q && have_D && have_E;
d_missing = have_P && have_Q && !have_D && have_E;
is_pub = have_N && !have_P && !have_Q && !have_D && have_E;
/* These three alternatives are mutually exclusive */
const int is_priv = n_missing || pq_missing || d_missing;
is_priv = n_missing || pq_missing || d_missing;
if( !is_priv && !is_pub )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -336,9 +348,11 @@ int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
unsigned char *E, size_t E_len )
{
int ret = 0;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
const int is_priv =
is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@ -379,9 +393,11 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
mbedtls_mpi *D, mbedtls_mpi *E )
{
int ret;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
int is_priv =
is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@ -421,9 +437,11 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
int ret;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
/* Check if key is private or public */
int is_priv =
is_priv =
mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
@ -459,6 +477,10 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
int padding,
int hash_id )
{
RSA_VALIDATE( ctx != NULL );
RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
padding == MBEDTLS_RSA_PKCS_V21 );
memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
mbedtls_rsa_set_padding( ctx, padding, hash_id );
@ -471,8 +493,13 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
/*
* Set padding for an existing RSA context
*/
void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
int hash_id )
{
RSA_VALIDATE( ctx != NULL );
RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
padding == MBEDTLS_RSA_PKCS_V21 );
ctx->padding = padding;
ctx->hash_id = hash_id;
}
@ -503,11 +530,10 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
int ret;
mbedtls_mpi H, G, L;
int prime_quality = 0;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( f_rng != NULL );
if( f_rng == NULL || nbits < 128 || exponent < 3 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
if( nbits % 2 )
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
/*
@ -612,6 +638,8 @@ cleanup:
*/
int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
{
RSA_VALIDATE_RET( ctx != NULL );
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
@ -635,6 +663,8 @@ int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
*/
int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
{
RSA_VALIDATE_RET( ctx != NULL );
if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
{
@ -664,6 +694,9 @@ int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
const mbedtls_rsa_context *prv )
{
RSA_VALIDATE_RET( pub != NULL );
RSA_VALIDATE_RET( prv != NULL );
if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
mbedtls_rsa_check_privkey( prv ) != 0 )
{
@ -689,6 +722,9 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
int ret;
size_t olen;
mbedtls_mpi T;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( output != NULL );
if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -831,6 +867,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
* checked result; should be the same in the end. */
mbedtls_mpi I, C;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( output != NULL );
if( rsa_check_context( ctx, 1 /* private key checks */,
f_rng != NULL /* blinding y/n */ ) != 0 )
{
@ -1091,6 +1131,13 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1167,11 +1214,13 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
int ret;
unsigned char *p = output;
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
RSA_VALIDATE_RET( input != NULL );
// We don't check p_rng because it won't be dereferenced here
if( f_rng == NULL || input == NULL || output == NULL )
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len;
@ -1185,6 +1234,9 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
*p++ = 0;
if( mode == MBEDTLS_RSA_PUBLIC )
{
if( f_rng == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
*p++ = MBEDTLS_RSA_CRYPT;
while( nb_pad-- > 0 )
@ -1229,6 +1281,12 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
RSA_VALIDATE_RET( input != NULL );
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@ -1271,6 +1329,14 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( olen != NULL );
/*
* Parameters sanity checks
*/
@ -1387,6 +1453,97 @@ cleanup:
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
*
* \param value The value to analyze.
* \return Zero if \p value is zero, otherwise all-bits-one.
*/
static unsigned all_or_nothing_int( unsigned value )
{
/* MSVC has a warning about unary minus on unsigned, but this is
* well-defined and precisely what we want to do here */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
}
/** Check whether a size is out of bounds, without branches.
*
* This is equivalent to `size > max`, but is likely to be compiled to
* to code using bitwise operation rather than a branch.
*
* \param size Size to check.
* \param max Maximum desired value for \p size.
* \return \c 0 if `size <= max`.
* \return \c 1 if `size > max`.
*/
static unsigned size_greater_than( size_t size, size_t max )
{
/* Return the sign bit (1 for negative) of (max - size). */
return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
}
/** Choose between two integer values, without branches.
*
* This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
* to code using bitwise operation rather than a branch.
*
* \param cond Condition to test.
* \param if1 Value to use if \p cond is nonzero.
* \param if0 Value to use if \p cond is zero.
* \return \c if1 if \p cond is nonzero, otherwise \c if0.
*/
static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
{
unsigned mask = all_or_nothing_int( cond );
return( ( mask & if1 ) | (~mask & if0 ) );
}
/** Shift some data towards the left inside a buffer without leaking
* the length of the data through side channels.
*
* `mem_move_to_left(start, total, offset)` is functionally equivalent to
* ```
* memmove(start, start + offset, total - offset);
* memset(start + offset, 0, total - offset);
* ```
* but it strives to use a memory access pattern (and thus total timing)
* that does not depend on \p offset. This timing independence comes at
* the expense of performance.
*
* \param start Pointer to the start of the buffer.
* \param total Total size of the buffer.
* \param offset Offset from which to copy \p total - \p offset bytes.
*/
static void mem_move_to_left( void *start,
size_t total,
size_t offset )
{
volatile unsigned char *buf = start;
size_t i, n;
if( total == 0 )
return;
for( i = 0; i < total; i++ )
{
unsigned no_op = size_greater_than( total - offset, i );
/* The first `total - offset` passes are a no-op. The last
* `offset` passes shift the data one byte to the left and
* zero out the last byte. */
for( n = 0; n < total - 1; n++ )
{
unsigned char current = buf[n];
unsigned char next = buf[n+1];
buf[n] = if_int( no_op, current, next );
}
buf[total-1] = if_int( no_op, buf[total-1], 0 );
}
}
/*
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
*/
@ -1396,18 +1553,42 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
int mode, size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len)
size_t output_max_len )
{
int ret;
size_t ilen, pad_count = 0, i;
unsigned char *p, bad, pad_done = 0;
size_t ilen, i, plaintext_max_size;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
/* The following variables take sensitive values: their value must
* not leak into the observable behavior of the function other than
* the designated outputs (output, olen, return value). Otherwise
* this would open the execution of the function to
* side-channel-based variants of the Bleichenbacher padding oracle
* attack. Potential side channels include overall timing, memory
* access patterns (especially visible to an adversary who has access
* to a shared memory cache), and branches (especially visible to
* an adversary who has access to a shared code cache or to a shared
* branch predictor). */
size_t pad_count = 0;
unsigned bad = 0;
unsigned char pad_done = 0;
size_t plaintext_size = 0;
unsigned output_too_large;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( olen != NULL );
ilen = ctx->len;
plaintext_max_size = ( output_max_len > ilen - 11 ?
ilen - 11 :
output_max_len );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
ilen = ctx->len;
if( ilen < 16 || ilen > sizeof( buf ) )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1418,63 +1599,109 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
if( ret != 0 )
goto cleanup;
p = buf;
bad = 0;
/* Check and get padding length in constant time and constant
* memory trace. The first byte must be 0. */
bad |= buf[0];
/*
* Check and get padding len in "constant-time"
*/
bad |= *p++; /* First byte must be 0 */
/* This test does not depend on secret data */
if( mode == MBEDTLS_RSA_PRIVATE )
{
bad |= *p++ ^ MBEDTLS_RSA_CRYPT;
/* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
* where PS must be at least 8 nonzero bytes. */
bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
/* Get padding len, but always read till end of buffer
* (minus one, for the 00 byte) */
for( i = 0; i < ilen - 3; i++ )
/* Read the whole buffer. Set pad_done to nonzero if we find
* the 0x00 byte and remember the padding length in pad_count. */
for( i = 2; i < ilen; i++ )
{
pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
}
p += pad_count;
bad |= *p++; /* Must be zero */
}
else
{
bad |= *p++ ^ MBEDTLS_RSA_SIGN;
/* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
* where PS must be at least 8 bytes with the value 0xFF. */
bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
/* Get padding len, but always read till end of buffer
* (minus one, for the 00 byte) */
for( i = 0; i < ilen - 3; i++ )
/* Read the whole buffer. Set pad_done to nonzero if we find
* the 0x00 byte and remember the padding length in pad_count.
* If there's a non-0xff byte in the padding, the padding is bad. */
for( i = 2; i < ilen; i++ )
{
pad_done |= ( p[i] != 0xFF );
pad_count += ( pad_done == 0 );
pad_done |= if_int( buf[i], 0, 1 );
pad_count += if_int( pad_done, 0, 1 );
bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
}
p += pad_count;
bad |= *p++; /* Must be zero */
}
bad |= ( pad_count < 8 );
/* If pad_done is still zero, there's no data, only unfinished padding. */
bad |= if_int( pad_done, 0, 1 );
if( bad )
{
ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
goto cleanup;
}
/* There must be at least 8 bytes of padding. */
bad |= size_greater_than( 8, pad_count );
if( ilen - ( p - buf ) > output_max_len )
{
ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
goto cleanup;
}
/* If the padding is valid, set plaintext_size to the number of
* remaining bytes after stripping the padding. If the padding
* is invalid, avoid leaking this fact through the size of the
* output: use the maximum message size that fits in the output
* buffer. Do it without branches to avoid leaking the padding
* validity through timing. RSA keys are small enough that all the
* size_t values involved fit in unsigned int. */
plaintext_size = if_int( bad,
(unsigned) plaintext_max_size,
(unsigned) ( ilen - pad_count - 3 ) );
*olen = ilen - (p - buf);
memcpy( output, p, *olen );
ret = 0;
/* Set output_too_large to 0 if the plaintext fits in the output
* buffer and to 1 otherwise. */
output_too_large = size_greater_than( plaintext_size,
plaintext_max_size );
/* Set ret without branches to avoid timing attacks. Return:
* - INVALID_PADDING if the padding is bad (bad != 0).
* - OUTPUT_TOO_LARGE if the padding is good but the decrypted
* plaintext does not fit in the output buffer.
* - 0 if the padding is correct. */
ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
0 ) );
/* If the padding is bad or the plaintext is too large, zero the
* data that we're about to copy to the output buffer.
* We need to copy the same amount of data
* from the same buffer whether the padding is good or not to
* avoid leaking the padding validity through overall timing or
* through memory or cache access patterns. */
bad = all_or_nothing_int( bad | output_too_large );
for( i = 11; i < ilen; i++ )
buf[i] &= ~bad;
/* If the plaintext is too large, truncate it to the buffer size.
* Copy anyway to avoid revealing the length through timing, because
* revealing the length is as bad as revealing the padding validity
* for a Bleichenbacher attack. */
plaintext_size = if_int( output_too_large,
(unsigned) plaintext_max_size,
(unsigned) plaintext_size );
/* Move the plaintext to the leftmost position where it can start in
* the working buffer, i.e. make it start plaintext_max_size from
* the end of the buffer. Do this with a memory access trace that
* does not depend on the plaintext size. After this move, the
* starting location of the plaintext is no longer sensitive
* information. */
mem_move_to_left( buf + ilen - plaintext_max_size,
plaintext_max_size,
plaintext_max_size - plaintext_size );
/* Finally copy the decrypted plaintext plus trailing zeros
* into the output buffer. */
memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
/* Report the amount of data we copied to the output buffer. In case
* of errors (bad padding or output too large), the value of *olen
* when this function returns is not specified. Making it equivalent
* to the good case limits the risks of leaking the padding validity. */
*olen = plaintext_size;
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@ -1494,6 +1721,13 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
unsigned char *output,
size_t output_max_len)
{
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
RSA_VALIDATE_RET( input != NULL );
RSA_VALIDATE_RET( olen != NULL );
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@ -1535,6 +1769,13 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
size_t msb;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
RSA_VALIDATE_RET( sig != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1782,6 +2023,14 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
int ret;
unsigned char *sig_try = NULL, *verif = NULL;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
RSA_VALIDATE_RET( sig != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1851,6 +2100,14 @@ int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
const unsigned char *hash,
unsigned char *sig )
{
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
RSA_VALIDATE_RET( sig != NULL );
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@ -1897,6 +2154,14 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
mbedtls_md_context_t md_ctx;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( sig != NULL );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -2025,7 +2290,16 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
const unsigned char *hash,
const unsigned char *sig )
{
mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
mbedtls_md_type_t mgf1_hash_id;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( sig != NULL );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
? (mbedtls_md_type_t) ctx->hash_id
: md_alg;
@ -2051,9 +2325,19 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
const unsigned char *sig )
{
int ret = 0;
const size_t sig_len = ctx->len;
size_t sig_len;
unsigned char *encoded = NULL, *encoded_expected = NULL;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( sig != NULL );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
sig_len = ctx->len;
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -2123,6 +2407,14 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
const unsigned char *hash,
const unsigned char *sig )
{
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( sig != NULL );
RSA_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE &&
hashlen == 0 ) ||
hash != NULL );
switch( ctx->padding )
{
#if defined(MBEDTLS_PKCS1_V15)
@ -2148,6 +2440,8 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{
int ret;
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );
dst->ver = src->ver;
dst->len = src->len;
@ -2187,14 +2481,23 @@ cleanup:
*/
void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
{
mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->RN ); mbedtls_mpi_free( &ctx->D );
mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P );
mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N );
if( ctx == NULL )
return;
mbedtls_mpi_free( &ctx->Vi );
mbedtls_mpi_free( &ctx->Vf );
mbedtls_mpi_free( &ctx->RN );
mbedtls_mpi_free( &ctx->D );
mbedtls_mpi_free( &ctx->Q );
mbedtls_mpi_free( &ctx->P );
mbedtls_mpi_free( &ctx->E );
mbedtls_mpi_free( &ctx->N );
#if !defined(MBEDTLS_RSA_NO_CRT)
mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ );
mbedtls_mpi_free( &ctx->RQ );
mbedtls_mpi_free( &ctx->RP );
mbedtls_mpi_free( &ctx->QP );
mbedtls_mpi_free( &ctx->DQ );
mbedtls_mpi_free( &ctx->DP );
#endif /* MBEDTLS_RSA_NO_CRT */