Merge pull request #4661 from mpg/make-blinding-mandatory
Make blinding mandatory
This commit is contained in:
commit
ae35830295
57 changed files with 572 additions and 618 deletions
|
@ -444,6 +444,9 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
|
|||
DHM_VALIDATE_RET( output != NULL );
|
||||
DHM_VALIDATE_RET( olen != NULL );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
if( output_size < mbedtls_dhm_get_len( ctx ) )
|
||||
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
|
||||
|
||||
|
@ -453,25 +456,17 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
|
|||
mbedtls_mpi_init( &GYb );
|
||||
|
||||
/* Blind peer's value */
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
|
||||
}
|
||||
else
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
|
||||
MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
|
||||
|
||||
/* Do modular exponentiation */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
|
||||
&ctx->P, &ctx->RP ) );
|
||||
|
||||
/* Unblind secret value */
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
|
||||
}
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
|
||||
|
||||
/* Output the secret without any leading zero byte. This is mandatory
|
||||
* for TLS per RFC 5246 §8.1.2. */
|
||||
|
|
|
@ -962,6 +962,28 @@ static const unsigned char ecjpake_test_pms[] = {
|
|||
0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
|
||||
};
|
||||
|
||||
/*
|
||||
* PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
|
||||
*
|
||||
* This is the linear congruential generator from numerical recipes,
|
||||
* except we only use the low byte as the output. See
|
||||
* https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
|
||||
*/
|
||||
static int self_test_rng( void *ctx, unsigned char *out, size_t len )
|
||||
{
|
||||
static uint32_t state = 42;
|
||||
|
||||
(void) ctx;
|
||||
|
||||
for( size_t i = 0; i < len; i++ )
|
||||
{
|
||||
state = state * 1664525u + 1013904223u;
|
||||
out[i] = (unsigned char) state;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Load my private keys and generate the corresponding public keys */
|
||||
static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
|
||||
const unsigned char *xm1, size_t len1,
|
||||
|
@ -972,9 +994,9 @@ static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
|
|||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
|
||||
&ctx->grp.G, NULL, NULL ) );
|
||||
&ctx->grp.G, self_test_rng, NULL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
|
||||
&ctx->grp.G, NULL, NULL ) );
|
||||
&ctx->grp.G, self_test_rng, NULL ) );
|
||||
|
||||
cleanup:
|
||||
return( ret );
|
||||
|
|
296
library/ecp.c
296
library/ecp.c
|
@ -101,16 +101,6 @@
|
|||
|
||||
#include "ecp_internal_alt.h"
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
#if defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#elif defined(MBEDTLS_CTR_DRBG_C)
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#else
|
||||
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
|
||||
#endif
|
||||
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||
!defined(inline) && !defined(__cplusplus)
|
||||
#define inline __inline
|
||||
|
@ -124,144 +114,6 @@
|
|||
static unsigned long add_count, dbl_count, mul_count;
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
/*
|
||||
* Currently ecp_mul() takes a RNG function as an argument, used for
|
||||
* side-channel protection, but it can be NULL. The initial reasoning was
|
||||
* that people will pass non-NULL RNG when they care about side-channels, but
|
||||
* unfortunately we have some APIs that call ecp_mul() with a NULL RNG, with
|
||||
* no opportunity for the user to do anything about it.
|
||||
*
|
||||
* The obvious strategies for addressing that include:
|
||||
* - change those APIs so that they take RNG arguments;
|
||||
* - require a global RNG to be available to all crypto modules.
|
||||
*
|
||||
* Unfortunately those would break compatibility. So what we do instead is
|
||||
* have our own internal DRBG instance, seeded from the secret scalar.
|
||||
*
|
||||
* The following is a light-weight abstraction layer for doing that with
|
||||
* HMAC_DRBG (first choice) or CTR_DRBG.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_HMAC_DRBG_C)
|
||||
|
||||
/* DRBG context type */
|
||||
typedef mbedtls_hmac_drbg_context ecp_drbg_context;
|
||||
|
||||
/* DRBG context init */
|
||||
static inline void ecp_drbg_init( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_hmac_drbg_init( ctx );
|
||||
}
|
||||
|
||||
/* DRBG context free */
|
||||
static inline void ecp_drbg_free( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_hmac_drbg_free( ctx );
|
||||
}
|
||||
|
||||
/* DRBG function */
|
||||
static inline int ecp_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len )
|
||||
{
|
||||
return( mbedtls_hmac_drbg_random( p_rng, output, output_len ) );
|
||||
}
|
||||
|
||||
/* DRBG context seeding */
|
||||
static int ecp_drbg_seed( ecp_drbg_context *ctx,
|
||||
const mbedtls_mpi *secret, size_t secret_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
|
||||
/* The list starts with strong hashes */
|
||||
const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
|
||||
|
||||
if( secret_len > MBEDTLS_ECP_MAX_BYTES )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
|
||||
secret_bytes, secret_len ) );
|
||||
|
||||
ret = mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_bytes, secret_len );
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize( secret_bytes, secret_len );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#elif defined(MBEDTLS_CTR_DRBG_C)
|
||||
|
||||
/* DRBG context type */
|
||||
typedef mbedtls_ctr_drbg_context ecp_drbg_context;
|
||||
|
||||
/* DRBG context init */
|
||||
static inline void ecp_drbg_init( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_ctr_drbg_init( ctx );
|
||||
}
|
||||
|
||||
/* DRBG context free */
|
||||
static inline void ecp_drbg_free( ecp_drbg_context *ctx )
|
||||
{
|
||||
mbedtls_ctr_drbg_free( ctx );
|
||||
}
|
||||
|
||||
/* DRBG function */
|
||||
static inline int ecp_drbg_random( void *p_rng,
|
||||
unsigned char *output, size_t output_len )
|
||||
{
|
||||
return( mbedtls_ctr_drbg_random( p_rng, output, output_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Since CTR_DRBG doesn't have a seed_buf() function the way HMAC_DRBG does,
|
||||
* we need to pass an entropy function when seeding. So we use a dummy
|
||||
* function for that, and pass the actual entropy as customisation string.
|
||||
* (During seeding of CTR_DRBG the entropy input and customisation string are
|
||||
* concatenated before being used to update the secret state.)
|
||||
*/
|
||||
static int ecp_ctr_drbg_null_entropy(void *ctx, unsigned char *out, size_t len)
|
||||
{
|
||||
(void) ctx;
|
||||
memset( out, 0, len );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* DRBG context seeding */
|
||||
static int ecp_drbg_seed( ecp_drbg_context *ctx,
|
||||
const mbedtls_mpi *secret, size_t secret_len )
|
||||
{
|
||||
int ret;
|
||||
unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
|
||||
|
||||
if( secret_len > MBEDTLS_ECP_MAX_BYTES )
|
||||
{
|
||||
ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
|
||||
secret_bytes, secret_len ) );
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL,
|
||||
secret_bytes, secret_len );
|
||||
|
||||
cleanup:
|
||||
mbedtls_platform_zeroize( secret_bytes, secret_len );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
|
||||
#endif /* DRBG modules */
|
||||
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/*
|
||||
* Maximum number of "basic operations" to be done in a row.
|
||||
|
@ -309,10 +161,6 @@ struct mbedtls_ecp_restart_mul
|
|||
ecp_rsm_comb_core, /* ecp_mul_comb_core() */
|
||||
ecp_rsm_final_norm, /* do the final normalization */
|
||||
} state;
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_context drbg_ctx;
|
||||
unsigned char drbg_seeded;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -325,10 +173,6 @@ static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx )
|
|||
ctx->T = NULL;
|
||||
ctx->T_size = 0;
|
||||
ctx->state = ecp_rsm_init;
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_init( &ctx->drbg_ctx );
|
||||
ctx->drbg_seeded = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -350,10 +194,6 @@ static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx )
|
|||
mbedtls_free( ctx->T );
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_free( &ctx->drbg_ctx );
|
||||
#endif
|
||||
|
||||
ecp_restart_rsm_init( ctx );
|
||||
}
|
||||
|
||||
|
@ -2068,9 +1908,7 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R
|
|||
i = d;
|
||||
MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
|
||||
#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng != 0 )
|
||||
#endif
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
|
||||
}
|
||||
|
||||
|
@ -2204,9 +2042,7 @@ final_norm:
|
|||
*
|
||||
* Avoid the leak by randomizing coordinates before we normalize them.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng != 0 )
|
||||
#endif
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
|
||||
|
@ -2286,42 +2122,9 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
size_t d;
|
||||
unsigned char T_size = 0, T_ok = 0;
|
||||
mbedtls_ecp_point *T = NULL;
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_context drbg_ctx;
|
||||
|
||||
ecp_drbg_init( &drbg_ctx );
|
||||
#endif
|
||||
|
||||
ECP_RS_ENTER( rsm );
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng == NULL )
|
||||
{
|
||||
/* Adjust pointers */
|
||||
f_rng = &ecp_drbg_random;
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( rs_ctx != NULL && rs_ctx->rsm != NULL )
|
||||
p_rng = &rs_ctx->rsm->drbg_ctx;
|
||||
else
|
||||
#endif
|
||||
p_rng = &drbg_ctx;
|
||||
|
||||
/* Initialize internal DRBG if necessary */
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( rs_ctx == NULL || rs_ctx->rsm == NULL ||
|
||||
rs_ctx->rsm->drbg_seeded == 0 )
|
||||
#endif
|
||||
{
|
||||
const size_t m_len = ( grp->nbits + 7 ) / 8;
|
||||
MBEDTLS_MPI_CHK( ecp_drbg_seed( p_rng, m, m_len ) );
|
||||
}
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
if( rs_ctx != NULL && rs_ctx->rsm != NULL )
|
||||
rs_ctx->rsm->drbg_seeded = 1;
|
||||
#endif
|
||||
}
|
||||
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
|
||||
/* Is P the base point ? */
|
||||
#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
|
||||
p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
|
||||
|
@ -2393,10 +2196,6 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
|
||||
cleanup:
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_free( &drbg_ctx );
|
||||
#endif
|
||||
|
||||
/* does T belong to the group? */
|
||||
if( T == grp->T )
|
||||
T = NULL;
|
||||
|
@ -2583,22 +2382,10 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
unsigned char b;
|
||||
mbedtls_ecp_point RP;
|
||||
mbedtls_mpi PX;
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_context drbg_ctx;
|
||||
|
||||
ecp_drbg_init( &drbg_ctx );
|
||||
#endif
|
||||
mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
|
||||
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng == NULL )
|
||||
{
|
||||
const size_t m_len = ( grp->nbits + 7 ) / 8;
|
||||
MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m, m_len ) );
|
||||
f_rng = &ecp_drbg_random;
|
||||
p_rng = &drbg_ctx;
|
||||
}
|
||||
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
/* Save PX and read from P before writing to R, in case P == R */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
|
||||
|
@ -2613,10 +2400,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
MOD_ADD( RP.X );
|
||||
|
||||
/* Randomize coordinates of the starting point */
|
||||
#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng != NULL )
|
||||
#endif
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
|
||||
|
||||
/* Loop invariant: R = result so far, RP = R + P */
|
||||
i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
|
||||
|
@ -2648,18 +2432,10 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
*
|
||||
* Avoid the leak by randomizing coordinates before we normalize them.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
if( f_rng != NULL )
|
||||
#endif
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
|
||||
|
||||
MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
|
||||
|
||||
cleanup:
|
||||
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||
ecp_drbg_free( &drbg_ctx );
|
||||
#endif
|
||||
|
||||
mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
|
||||
|
||||
return( ret );
|
||||
|
@ -2669,8 +2445,11 @@ cleanup:
|
|||
|
||||
/*
|
||||
* Restartable multiplication R = m * P
|
||||
*
|
||||
* This internal function can be called without an RNG in case where we know
|
||||
* the inputs are not sensitive.
|
||||
*/
|
||||
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
static int ecp_mul_restartable_internal( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_ecp_restart_ctx *rs_ctx )
|
||||
|
@ -2679,10 +2458,6 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||
char is_grp_capable = 0;
|
||||
#endif
|
||||
ECP_VALIDATE_RET( grp != NULL );
|
||||
ECP_VALIDATE_RET( R != NULL );
|
||||
ECP_VALIDATE_RET( m != NULL );
|
||||
ECP_VALIDATE_RET( P != NULL );
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/* reset ops count for this call if top-level */
|
||||
|
@ -2735,6 +2510,25 @@ cleanup:
|
|||
return( ret );
|
||||
}
|
||||
|
||||
/*
|
||||
* Restartable multiplication R = m * P
|
||||
*/
|
||||
int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
||||
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
|
||||
mbedtls_ecp_restart_ctx *rs_ctx )
|
||||
{
|
||||
ECP_VALIDATE_RET( grp != NULL );
|
||||
ECP_VALIDATE_RET( R != NULL );
|
||||
ECP_VALIDATE_RET( m != NULL );
|
||||
ECP_VALIDATE_RET( P != NULL );
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
return( ecp_mul_restartable_internal( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiplication R = m * P
|
||||
*/
|
||||
|
@ -2828,8 +2622,8 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
|
|||
}
|
||||
else
|
||||
{
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
|
||||
NULL, NULL, rs_ctx ) );
|
||||
MBEDTLS_MPI_CHK( ecp_mul_restartable_internal( grp, R, m, P,
|
||||
NULL, NULL, rs_ctx ) );
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -3272,7 +3066,9 @@ cleanup:
|
|||
/*
|
||||
* Check a public-private key pair
|
||||
*/
|
||||
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
|
||||
int mbedtls_ecp_check_pub_priv(
|
||||
const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_ecp_point Q;
|
||||
|
@ -3296,7 +3092,7 @@ int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ec
|
|||
mbedtls_ecp_group_copy( &grp, &prv->grp );
|
||||
|
||||
/* Also checks d is valid */
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng ) );
|
||||
|
||||
if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
|
||||
mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
|
||||
|
@ -3315,6 +3111,28 @@ cleanup:
|
|||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/*
|
||||
* PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
|
||||
*
|
||||
* This is the linear congruential generator from numerical recipes,
|
||||
* except we only use the low byte as the output. See
|
||||
* https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
|
||||
*/
|
||||
static int self_test_rng( void *ctx, unsigned char *out, size_t len )
|
||||
{
|
||||
static uint32_t state = 42;
|
||||
|
||||
(void) ctx;
|
||||
|
||||
for( size_t i = 0; i < len; i++ )
|
||||
{
|
||||
state = state * 1664525u + 1013904223u;
|
||||
out[i] = (unsigned char) state;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Adjust the exponent to be a valid private point for the specified curve.
|
||||
* This is sometimes necessary because we use a single set of exponents
|
||||
* for all curves but the validity of values depends on the curve. */
|
||||
|
@ -3370,7 +3188,7 @@ static int self_test_point( int verbose,
|
|||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
|
||||
MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
|
||||
|
||||
for( i = 1; i < n_exponents; i++ )
|
||||
{
|
||||
|
@ -3383,7 +3201,7 @@ static int self_test_point( int verbose,
|
|||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
|
||||
MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, self_test_rng, NULL ) );
|
||||
|
||||
if( add_count != add_c_prev ||
|
||||
dbl_count != dbl_c_prev ||
|
||||
|
@ -3461,7 +3279,7 @@ int mbedtls_ecp_self_test( int verbose )
|
|||
mbedtls_printf( " ECP SW test #1 (constant op_count, base point G): " );
|
||||
/* Do a dummy multiplication first to trigger precomputation */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, self_test_rng, NULL ) );
|
||||
ret = self_test_point( verbose,
|
||||
&grp, &R, &m, &grp.G,
|
||||
sw_exponents,
|
||||
|
|
10
library/pk.c
10
library/pk.c
|
@ -500,7 +500,10 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
|
|||
/*
|
||||
* Check public-private key pair
|
||||
*/
|
||||
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
|
||||
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub,
|
||||
const mbedtls_pk_context *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
PK_VALIDATE_RET( pub != NULL );
|
||||
PK_VALIDATE_RET( prv != NULL );
|
||||
|
@ -511,6 +514,9 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
|
|||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
if( prv->pk_info->check_pair_func == NULL )
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
|
||||
|
@ -525,7 +531,7 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
|
|||
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||
}
|
||||
|
||||
return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
|
||||
return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx, f_rng, p_rng ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -154,8 +154,12 @@ static int rsa_encrypt_wrap( void *ctx,
|
|||
ilen, input, output ) );
|
||||
}
|
||||
|
||||
static int rsa_check_pair_wrap( const void *pub, const void *prv )
|
||||
static int rsa_check_pair_wrap( const void *pub, const void *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
|
||||
(const mbedtls_rsa_context *) prv ) );
|
||||
}
|
||||
|
@ -388,10 +392,13 @@ cleanup:
|
|||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#endif /* MBEDTLS_ECDSA_C */
|
||||
|
||||
static int eckey_check_pair( const void *pub, const void *prv )
|
||||
static int eckey_check_pair( const void *pub, const void *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
|
||||
(const mbedtls_ecp_keypair *) prv ) );
|
||||
(const mbedtls_ecp_keypair *) prv,
|
||||
f_rng, p_rng ) );
|
||||
}
|
||||
|
||||
static void *eckey_alloc_wrap( void )
|
||||
|
@ -799,7 +806,9 @@ static int rsa_alt_decrypt_wrap( void *ctx,
|
|||
}
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
static int rsa_alt_check_pair( const void *pub, const void *prv )
|
||||
static int rsa_alt_check_pair( const void *pub, const void *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
|
||||
unsigned char hash[32];
|
||||
|
@ -813,7 +822,7 @@ static int rsa_alt_check_pair( const void *pub, const void *prv )
|
|||
|
||||
if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
|
||||
hash, sizeof( hash ),
|
||||
sig, &sig_len, NULL, NULL ) ) != 0 )
|
||||
sig, &sig_len, f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
|
|
@ -85,7 +85,9 @@ struct mbedtls_pk_info_t
|
|||
void *p_rng );
|
||||
|
||||
/** Check public-private key pair */
|
||||
int (*check_pair_func)( const void *pub, const void *prv );
|
||||
int (*check_pair_func)( const void *pub, const void *prv,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng );
|
||||
|
||||
/** Allocate a new context */
|
||||
void * (*ctx_alloc_func)( void );
|
||||
|
|
|
@ -123,7 +123,8 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
|
|||
* Load and parse a private key
|
||||
*/
|
||||
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
||||
const char *path, const char *pwd )
|
||||
const char *path, const char *pwd,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t n;
|
||||
|
@ -136,10 +137,10 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
|
|||
return( ret );
|
||||
|
||||
if( pwd == NULL )
|
||||
ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
|
||||
ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0, f_rng, p_rng );
|
||||
else
|
||||
ret = mbedtls_pk_parse_key( ctx, buf, n,
|
||||
(const unsigned char *) pwd, strlen( pwd ) );
|
||||
(const unsigned char *) pwd, strlen( pwd ), f_rng, p_rng );
|
||||
|
||||
mbedtls_platform_zeroize( buf, n );
|
||||
mbedtls_free( buf );
|
||||
|
@ -859,8 +860,8 @@ cleanup:
|
|||
* Parse a SEC1 encoded private EC key
|
||||
*/
|
||||
static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
||||
const unsigned char *key,
|
||||
size_t keylen )
|
||||
const unsigned char *key, size_t keylen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
int version, pubkey_done;
|
||||
|
@ -967,7 +968,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
|||
|
||||
if( ! pubkey_done &&
|
||||
( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
|
||||
NULL, NULL ) ) != 0 )
|
||||
f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
mbedtls_ecp_keypair_free( eck );
|
||||
return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
|
||||
|
@ -997,9 +998,9 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
|
|||
*
|
||||
*/
|
||||
static int pk_parse_key_pkcs8_unencrypted_der(
|
||||
mbedtls_pk_context *pk,
|
||||
const unsigned char* key,
|
||||
size_t keylen )
|
||||
mbedtls_pk_context *pk,
|
||||
const unsigned char* key, size_t keylen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret, version;
|
||||
size_t len;
|
||||
|
@ -1009,6 +1010,11 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
||||
#if !defined(MBEDTLS_ECP_C)
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
|
||||
*
|
||||
|
@ -1071,7 +1077,7 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
|
||||
{
|
||||
if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
|
||||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 )
|
||||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len, f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_free( pk );
|
||||
return( ret );
|
||||
|
@ -1094,9 +1100,10 @@ static int pk_parse_key_pkcs8_unencrypted_der(
|
|||
*/
|
||||
#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
|
||||
static int pk_parse_key_pkcs8_encrypted_der(
|
||||
mbedtls_pk_context *pk,
|
||||
unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
mbedtls_pk_context *pk,
|
||||
unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret, decrypted = 0;
|
||||
size_t len;
|
||||
|
@ -1206,7 +1213,7 @@ static int pk_parse_key_pkcs8_encrypted_der(
|
|||
if( decrypted == 0 )
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
|
||||
return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
|
||||
return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len, f_rng, p_rng ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
|
||||
|
||||
|
@ -1215,7 +1222,8 @@ static int pk_parse_key_pkcs8_encrypted_der(
|
|||
*/
|
||||
int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
||||
const unsigned char *key, size_t keylen,
|
||||
const unsigned char *pwd, size_t pwdlen )
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
const mbedtls_pk_info_t *pk_info;
|
||||
|
@ -1278,7 +1286,8 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
|
||||
if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
|
||||
( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
|
||||
pem.buf, pem.buflen ) ) != 0 )
|
||||
pem.buf, pem.buflen,
|
||||
f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_free( pk );
|
||||
}
|
||||
|
@ -1305,7 +1314,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
if( ret == 0 )
|
||||
{
|
||||
if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
|
||||
pem.buf, pem.buflen ) ) != 0 )
|
||||
pem.buf, pem.buflen, f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_free( pk );
|
||||
}
|
||||
|
@ -1327,9 +1336,8 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
key, NULL, 0, &len );
|
||||
if( ret == 0 )
|
||||
{
|
||||
if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
|
||||
pem.buf, pem.buflen,
|
||||
pwd, pwdlen ) ) != 0 )
|
||||
if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, pem.buf, pem.buflen,
|
||||
pwd, pwdlen, f_rng, p_rng ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_free( pk );
|
||||
}
|
||||
|
@ -1362,7 +1370,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
memcpy( key_copy, key, keylen );
|
||||
|
||||
ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
|
||||
pwd, pwdlen );
|
||||
pwd, pwdlen, f_rng, p_rng );
|
||||
|
||||
mbedtls_platform_zeroize( key_copy, keylen );
|
||||
mbedtls_free( key_copy );
|
||||
|
@ -1380,8 +1388,11 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
}
|
||||
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
|
||||
|
||||
if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
|
||||
if( ( ret = pk_parse_key_pkcs8_unencrypted_der(
|
||||
pk, key, keylen, f_rng, p_rng ) ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
|
@ -1403,7 +1414,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
|
|||
pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
|
||||
if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
|
||||
pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
|
||||
key, keylen ) == 0 )
|
||||
key, keylen, f_rng, p_rng ) == 0 )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
|
|
@ -108,7 +108,8 @@ psa_status_t mbedtls_psa_rsa_load_representation(
|
|||
/* Parse the data. */
|
||||
if( PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0 ) );
|
||||
mbedtls_pk_parse_key( &ctx, data, data_length, NULL, 0,
|
||||
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
|
||||
else
|
||||
status = mbedtls_to_psa_error(
|
||||
mbedtls_pk_parse_public_key( &ctx, data, data_length ) );
|
||||
|
|
121
library/rsa.c
121
library/rsa.c
|
@ -929,8 +929,11 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
|||
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 )
|
||||
if( f_rng == NULL )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
if( rsa_check_context( ctx, 1 /* private key checks */,
|
||||
1 /* blinding on */ ) != 0 )
|
||||
{
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
@ -947,15 +950,12 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
|||
mbedtls_mpi_init( &Q1 );
|
||||
mbedtls_mpi_init( &R );
|
||||
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
#if defined(MBEDTLS_RSA_NO_CRT)
|
||||
mbedtls_mpi_init( &D_blind );
|
||||
mbedtls_mpi_init( &D_blind );
|
||||
#else
|
||||
mbedtls_mpi_init( &DP_blind );
|
||||
mbedtls_mpi_init( &DQ_blind );
|
||||
mbedtls_mpi_init( &DP_blind );
|
||||
mbedtls_mpi_init( &DQ_blind );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
|
||||
|
@ -975,57 +975,54 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
|||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
|
||||
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
/*
|
||||
* Blinding
|
||||
* T = T * Vi mod N
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||
/*
|
||||
* Blinding
|
||||
* T = T * Vi mod N
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||
|
||||
/*
|
||||
* Exponent blinding
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||
/*
|
||||
* Exponent blinding
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||
|
||||
#if defined(MBEDTLS_RSA_NO_CRT)
|
||||
/*
|
||||
* D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
|
||||
/*
|
||||
* D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
|
||||
|
||||
D = &D_blind;
|
||||
D = &D_blind;
|
||||
#else
|
||||
/*
|
||||
* DP_blind = ( P - 1 ) * R + DP
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
|
||||
&ctx->DP ) );
|
||||
/*
|
||||
* DP_blind = ( P - 1 ) * R + DP
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
|
||||
&ctx->DP ) );
|
||||
|
||||
DP = &DP_blind;
|
||||
DP = &DP_blind;
|
||||
|
||||
/*
|
||||
* DQ_blind = ( Q - 1 ) * R + DQ
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
|
||||
&ctx->DQ ) );
|
||||
/*
|
||||
* DQ_blind = ( Q - 1 ) * R + DQ
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
|
||||
f_rng, p_rng ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
|
||||
&ctx->DQ ) );
|
||||
|
||||
DQ = &DQ_blind;
|
||||
DQ = &DQ_blind;
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_RSA_NO_CRT)
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
|
||||
|
@ -1054,15 +1051,12 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
|
|||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
/*
|
||||
* Unblind
|
||||
* T = T * Vf mod N
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||
}
|
||||
/*
|
||||
* Unblind
|
||||
* T = T * Vf mod N
|
||||
*/
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||
|
||||
/* Verify the result to prevent glitching attacks. */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
|
||||
|
@ -1086,15 +1080,12 @@ cleanup:
|
|||
mbedtls_mpi_free( &Q1 );
|
||||
mbedtls_mpi_free( &R );
|
||||
|
||||
if( f_rng != NULL )
|
||||
{
|
||||
#if defined(MBEDTLS_RSA_NO_CRT)
|
||||
mbedtls_mpi_free( &D_blind );
|
||||
mbedtls_mpi_free( &D_blind );
|
||||
#else
|
||||
mbedtls_mpi_free( &DP_blind );
|
||||
mbedtls_mpi_free( &DQ_blind );
|
||||
mbedtls_mpi_free( &DP_blind );
|
||||
mbedtls_mpi_free( &DQ_blind );
|
||||
#endif
|
||||
}
|
||||
|
||||
mbedtls_mpi_free( &T );
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue