mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Externals: Update mbedtls to 2.28.0
This commit is contained in:
495
Externals/mbedtls/library/rsa.c
vendored
495
Externals/mbedtls/library/rsa.c
vendored
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The RSA public-key cryptosystem
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@ -15,8 +15,6 @@
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -37,11 +35,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
|
||||
@ -49,6 +43,9 @@
|
||||
#include "mbedtls/rsa_internal.h"
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "constant_time_internal.h"
|
||||
#include "mbedtls/constant_time.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -56,7 +53,7 @@
|
||||
#include "mbedtls/md.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
|
||||
#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
@ -77,28 +74,12 @@
|
||||
#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 )
|
||||
{
|
||||
size_t i;
|
||||
const unsigned char *A = (const unsigned char *) a;
|
||||
const unsigned char *B = (const unsigned char *) b;
|
||||
unsigned char diff = 0;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
diff |= A[i] ^ B[i];
|
||||
|
||||
return( diff );
|
||||
}
|
||||
#endif /* MBEDTLS_PKCS1_V15 */
|
||||
|
||||
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
|
||||
const mbedtls_mpi *N,
|
||||
const mbedtls_mpi *P, const mbedtls_mpi *Q,
|
||||
const mbedtls_mpi *D, const mbedtls_mpi *E )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
|
||||
@ -107,7 +88,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
|
||||
( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
|
||||
( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
|
||||
if( N != NULL )
|
||||
@ -147,7 +128,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
|
||||
cleanup:
|
||||
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -249,6 +230,9 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
{
|
||||
int ret = 0;
|
||||
int have_N, have_P, have_Q, have_D, have_E;
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
int have_DP, have_DQ, have_QP;
|
||||
#endif
|
||||
int n_missing, pq_missing, d_missing, is_pub, is_priv;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
@ -259,6 +243,12 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
|
||||
have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
have_DP = ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0 );
|
||||
have_DQ = ( mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0 );
|
||||
have_QP = ( mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0 );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check whether provided parameters are enough
|
||||
* to deduce all others. The following incomplete
|
||||
@ -289,7 +279,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
|
||||
&ctx->Q ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
|
||||
ctx->len = mbedtls_mpi_size( &ctx->N );
|
||||
@ -304,7 +294,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
|
||||
&ctx->P, &ctx->Q );
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
|
||||
}
|
||||
else if( d_missing )
|
||||
@ -314,7 +304,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
&ctx->E,
|
||||
&ctx->D ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,12 +314,12 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
if( is_priv )
|
||||
if( is_priv && ! ( have_DP && have_DQ && have_QP ) )
|
||||
{
|
||||
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
|
||||
&ctx->DP, &ctx->DQ, &ctx->QP );
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
|
||||
@ -392,7 +382,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
|
||||
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
|
||||
mbedtls_mpi *D, mbedtls_mpi *E )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int is_priv;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
@ -436,7 +426,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
|
||||
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
|
||||
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int is_priv;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
|
||||
@ -457,13 +447,13 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
|
||||
( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
|
||||
( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
#else
|
||||
if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
|
||||
DP, DQ, QP ) ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -486,6 +476,9 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
|
||||
mbedtls_rsa_set_padding( ctx, padding, hash_id );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Set ctx->ver to nonzero to indicate that the mutex has been
|
||||
* initialized and will need to be freed. */
|
||||
ctx->ver = 1;
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
@ -527,15 +520,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
||||
void *p_rng,
|
||||
unsigned int nbits, int exponent )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_mpi H, G, L;
|
||||
int prime_quality = 0;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
/*
|
||||
* If the modulus is 1024 bit long or shorter, then the security strength of
|
||||
* the RSA algorithm is less than or equal to 80 bits and therefore an error
|
||||
@ -548,6 +538,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
||||
mbedtls_mpi_init( &G );
|
||||
mbedtls_mpi_init( &L );
|
||||
|
||||
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* find primes P and Q with Q < P so that:
|
||||
* 1. |P-Q| > 2^( nbits / 2 - 100 )
|
||||
@ -625,7 +621,10 @@ cleanup:
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_rsa_free( ctx );
|
||||
return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
|
||||
|
||||
if( ( -ret & ~0x7f ) == 0 )
|
||||
ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
@ -719,7 +718,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen;
|
||||
mbedtls_mpi T;
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
@ -757,7 +756,7 @@ cleanup:
|
||||
mbedtls_mpi_free( &T );
|
||||
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -772,6 +771,9 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret, count = 0;
|
||||
mbedtls_mpi R;
|
||||
|
||||
mbedtls_mpi_init( &R );
|
||||
|
||||
if( ctx->Vf.p != NULL )
|
||||
{
|
||||
@ -787,18 +789,40 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
|
||||
/* Unblinding value: Vf = random number, invertible mod N */
|
||||
do {
|
||||
if( count++ > 10 )
|
||||
return( MBEDTLS_ERR_RSA_RNG_FAILED );
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_RNG_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
|
||||
} while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
|
||||
|
||||
/* Blinding value: Vi = Vf^(-e) mod N */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
|
||||
/* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
|
||||
|
||||
/* At this point, Vi is invertible mod N if and only if both Vf and R
|
||||
* are invertible mod N. If one of them isn't, we don't need to know
|
||||
* which one, we just loop and choose new values for both of them.
|
||||
* (Each iteration succeeds with overwhelming probability.) */
|
||||
ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
|
||||
if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
|
||||
goto cleanup;
|
||||
|
||||
} while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
|
||||
|
||||
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
|
||||
|
||||
/* Blinding value: Vi = Vf^(-e) mod N
|
||||
* (Vi already contains Vf^-1 at this point) */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free( &R );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
@ -832,7 +856,7 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t olen;
|
||||
|
||||
/* Temporary holding the result */
|
||||
@ -1047,10 +1071,10 @@ cleanup:
|
||||
mbedtls_mpi_free( &C );
|
||||
mbedtls_mpi_free( &I );
|
||||
|
||||
if( ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
|
||||
if( ret != 0 && ret >= -0x007f )
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret ) );
|
||||
|
||||
return( 0 );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
@ -1125,7 +1149,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
|
||||
unsigned char *output )
|
||||
{
|
||||
size_t olen;
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = output;
|
||||
unsigned int hlen;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
@ -1135,7 +1159,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
|
||||
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
|
||||
mode == MBEDTLS_RSA_PUBLIC );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
|
||||
|
||||
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
|
||||
@ -1161,7 +1185,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
|
||||
|
||||
/* Generate a random octet string seed */
|
||||
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
|
||||
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
|
||||
|
||||
p += hlen;
|
||||
|
||||
@ -1171,7 +1195,8 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
|
||||
p += hlen;
|
||||
p += olen - 2 * hlen - 2 - ilen;
|
||||
*p++ = 1;
|
||||
memcpy( p, input, ilen );
|
||||
if( ilen != 0 )
|
||||
memcpy( p, input, ilen );
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
|
||||
@ -1211,14 +1236,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
|
||||
unsigned char *output )
|
||||
{
|
||||
size_t nb_pad, olen;
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *p = 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 );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
@ -1249,7 +1274,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
|
||||
|
||||
/* Check if RNG failed to generate data */
|
||||
if( rng_dl == 0 || ret != 0 )
|
||||
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
|
||||
|
||||
p++;
|
||||
}
|
||||
@ -1263,7 +1288,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
memcpy( p, input, ilen );
|
||||
if( ilen != 0 )
|
||||
memcpy( p, input, ilen );
|
||||
|
||||
return( ( mode == MBEDTLS_RSA_PUBLIC )
|
||||
? mbedtls_rsa_public( ctx, output, output )
|
||||
@ -1285,7 +1311,7 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
|
||||
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
|
||||
mode == MBEDTLS_RSA_PUBLIC );
|
||||
RSA_VALIDATE_RET( output != NULL );
|
||||
RSA_VALIDATE_RET( input != NULL );
|
||||
RSA_VALIDATE_RET( ilen == 0 || input != NULL );
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
@ -1320,7 +1346,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
|
||||
unsigned char *output,
|
||||
size_t output_max_len )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t ilen, i, pad_len;
|
||||
unsigned char *p, bad, pad_done;
|
||||
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
|
||||
@ -1441,7 +1467,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
|
||||
}
|
||||
|
||||
*olen = ilen - (p - buf);
|
||||
memcpy( output, p, *olen );
|
||||
if( *olen != 0 )
|
||||
memcpy( output, p, *olen );
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -1453,126 +1480,21 @@ 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
|
||||
*/
|
||||
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t *olen,
|
||||
int mode,
|
||||
size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len )
|
||||
{
|
||||
int ret;
|
||||
size_t ilen, i, plaintext_max_size;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t ilen;
|
||||
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 ||
|
||||
@ -1582,9 +1504,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
||||
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 );
|
||||
@ -1599,109 +1518,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
|
||||
if( ret != 0 )
|
||||
goto cleanup;
|
||||
|
||||
/* Check and get padding length in constant time and constant
|
||||
* memory trace. The first byte must be 0. */
|
||||
bad |= buf[0];
|
||||
|
||||
if( mode == MBEDTLS_RSA_PRIVATE )
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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 |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
|
||||
pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
|
||||
/* 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 |= if_int( buf[i], 0, 1 );
|
||||
pad_count += if_int( pad_done, 0, 1 );
|
||||
bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
|
||||
}
|
||||
}
|
||||
|
||||
/* If pad_done is still zero, there's no data, only unfinished padding. */
|
||||
bad |= if_int( pad_done, 0, 1 );
|
||||
|
||||
/* There must be at least 8 bytes of padding. */
|
||||
bad |= size_greater_than( 8, pad_count );
|
||||
|
||||
/* 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 ) );
|
||||
|
||||
/* 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;
|
||||
ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( mode, buf, ilen,
|
||||
output, output_max_len, olen );
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
||||
@ -1749,23 +1567,21 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V21)
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
|
||||
*/
|
||||
int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
||||
static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
int saltlen,
|
||||
unsigned char *sig )
|
||||
{
|
||||
size_t olen;
|
||||
unsigned char *p = sig;
|
||||
unsigned char salt[MBEDTLS_MD_MAX_SIZE];
|
||||
unsigned char *salt = NULL;
|
||||
size_t slen, min_slen, hlen, offset = 0;
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t msb;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
@ -1801,31 +1617,44 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
||||
|
||||
hlen = mbedtls_md_get_size( md_info );
|
||||
|
||||
/* Calculate the largest possible salt length. Normally this is the hash
|
||||
* length, which is the maximum length the salt can have. If there is not
|
||||
* enough room, use the maximum salt length that fits. The constraint is
|
||||
* that the hash length plus the salt length plus 2 bytes must be at most
|
||||
* the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
|
||||
* (PKCS#1 v2.2) §9.1.1 step 3. */
|
||||
min_slen = hlen - 2;
|
||||
if( olen < hlen + min_slen + 2 )
|
||||
if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY)
|
||||
{
|
||||
/* Calculate the largest possible salt length, up to the hash size.
|
||||
* Normally this is the hash length, which is the maximum salt length
|
||||
* according to FIPS 185-4 §5.5 (e) and common practice. If there is not
|
||||
* enough room, use the maximum salt length that fits. The constraint is
|
||||
* that the hash length plus the salt length plus 2 bytes must be at most
|
||||
* the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
|
||||
* (PKCS#1 v2.2) §9.1.1 step 3. */
|
||||
min_slen = hlen - 2;
|
||||
if( olen < hlen + min_slen + 2 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
else if( olen >= hlen + hlen + 2 )
|
||||
slen = hlen;
|
||||
else
|
||||
slen = olen - hlen - 2;
|
||||
}
|
||||
else if ( (saltlen < 0) || (saltlen + hlen + 2 > olen) )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
else if( olen >= hlen + hlen + 2 )
|
||||
slen = hlen;
|
||||
}
|
||||
else
|
||||
slen = olen - hlen - 2;
|
||||
{
|
||||
slen = (size_t) saltlen;
|
||||
}
|
||||
|
||||
memset( sig, 0, olen );
|
||||
|
||||
/* Generate salt of length slen */
|
||||
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
|
||||
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
|
||||
|
||||
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */
|
||||
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
|
||||
p += olen - hlen - slen - 2;
|
||||
*p++ = 0x01;
|
||||
memcpy( p, salt, slen );
|
||||
|
||||
/* Generate salt of length slen in place in the encoded message */
|
||||
salt = p;
|
||||
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
|
||||
|
||||
p += slen;
|
||||
|
||||
mbedtls_md_init( &md_ctx );
|
||||
@ -1859,8 +1688,6 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
||||
p += hlen;
|
||||
*p++ = 0xBC;
|
||||
|
||||
mbedtls_platform_zeroize( salt, sizeof( salt ) );
|
||||
|
||||
exit:
|
||||
mbedtls_md_free( &md_ctx );
|
||||
|
||||
@ -1871,6 +1698,40 @@ exit:
|
||||
? mbedtls_rsa_public( ctx, sig, sig )
|
||||
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
|
||||
* the option to pass in the salt length.
|
||||
*/
|
||||
int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
int saltlen,
|
||||
unsigned char *sig )
|
||||
{
|
||||
return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, md_alg,
|
||||
hashlen, hash, saltlen, sig );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
|
||||
*/
|
||||
int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
|
||||
hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig );
|
||||
}
|
||||
#endif /* MBEDTLS_PKCS1_V21 */
|
||||
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
@ -2020,7 +1881,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char *sig_try = NULL, *verif = NULL;
|
||||
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
@ -2072,7 +1933,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
|
||||
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
|
||||
|
||||
if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
|
||||
if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
|
||||
goto cleanup;
|
||||
@ -2081,9 +1942,13 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
|
||||
memcpy( sig, sig_try, ctx->len );
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize( sig_try, ctx->len );
|
||||
mbedtls_platform_zeroize( verif, ctx->len );
|
||||
mbedtls_free( sig_try );
|
||||
mbedtls_free( verif );
|
||||
|
||||
if( ret != 0 )
|
||||
memset( sig, '!', ctx->len );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_PKCS1_V15 */
|
||||
@ -2142,7 +2007,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
|
||||
int expected_salt_len,
|
||||
const unsigned char *sig )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t siglen;
|
||||
unsigned char *p;
|
||||
unsigned char *hash_start;
|
||||
@ -2370,8 +2235,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
|
||||
* Compare
|
||||
*/
|
||||
|
||||
if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
|
||||
sig_len ) ) != 0 )
|
||||
if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
|
||||
sig_len ) ) != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
|
||||
goto cleanup;
|
||||
@ -2439,11 +2304,10 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
|
||||
*/
|
||||
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
|
||||
{
|
||||
int ret;
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
RSA_VALIDATE_RET( dst != NULL );
|
||||
RSA_VALIDATE_RET( src != NULL );
|
||||
|
||||
dst->ver = src->ver;
|
||||
dst->len = src->len;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
|
||||
@ -2502,7 +2366,12 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
/* Free the mutex, but only if it hasn't been freed already. */
|
||||
if( ctx->ver != 0 )
|
||||
{
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
ctx->ver = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2554,7 +2423,7 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
|
||||
#if defined(MBEDTLS_PKCS1_V15)
|
||||
static int myrand( void *rng_state, unsigned char *output, size_t len )
|
||||
{
|
||||
#if !defined(__OpenBSD__)
|
||||
#if !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
size_t i;
|
||||
|
||||
if( rng_state != NULL )
|
||||
@ -2567,7 +2436,7 @@ static int myrand( void *rng_state, unsigned char *output, size_t len )
|
||||
rng_state = NULL;
|
||||
|
||||
arc4random_buf( output, len );
|
||||
#endif /* !OpenBSD */
|
||||
#endif /* !OpenBSD && !NetBSD */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
Reference in New Issue
Block a user