mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-29 03:14:16 +01:00
Implement use of internal DRBG for ecp_mul()
The case of MBEDTLS_ECP_RESTARTABLE isn't handled correctly yet: in that case the DRBG instance should persist when resuming the operation. This will be addressed in the next commit. When both CTR_DRBG and HMAC_DRBG are available, CTR_DRBG is preferred since both are suitable but CTR_DRBG tends to be faster and I needed a tie-breaker. There are currently three possible cases to test: - NO_INTERNAL_RNG is set -> tested in test_ecp_no_internal_rng - it's unset and CTR_DRBG is available -> tested in the default config - it's unset and CTR_DRBG is disabled -> tested in test_ecp_internal_rng_no_ctr_drbg Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
23983f30de
commit
fb11d252b2
@ -98,6 +98,8 @@ typedef struct mbedtls_md_context_t
|
|||||||
* \brief This function returns the list of digests supported by the
|
* \brief This function returns the list of digests supported by the
|
||||||
* generic digest module.
|
* generic digest module.
|
||||||
*
|
*
|
||||||
|
* \note The list starts with the strongest available hashes.
|
||||||
|
*
|
||||||
* \return A statically allocated array of digests. Each element
|
* \return A statically allocated array of digests. Each element
|
||||||
* in the returned list is an integer belonging to the
|
* in the returned list is an integer belonging to the
|
||||||
* message-digest enumeration #mbedtls_md_type_t.
|
* message-digest enumeration #mbedtls_md_type_t.
|
||||||
|
137
library/ecp.c
137
library/ecp.c
@ -104,6 +104,16 @@
|
|||||||
|
|
||||||
#include "mbedtls/ecp_internal.h"
|
#include "mbedtls/ecp_internal.h"
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||||
|
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||||
|
#include "mbedtls/ctr_drbg.h"
|
||||||
|
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||||
|
#include "mbedtls/hmac_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) ) && \
|
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
|
||||||
!defined(inline) && !defined(__cplusplus)
|
!defined(inline) && !defined(__cplusplus)
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
@ -117,6 +127,113 @@
|
|||||||
static unsigned long add_count, dbl_count, mul_count;
|
static unsigned long add_count, dbl_count, mul_count;
|
||||||
#endif
|
#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 reasonning 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
|
||||||
|
* CTR_DRBG or HMAC_DRBG.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 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 )
|
||||||
|
{
|
||||||
|
const unsigned char *secret_p = (const unsigned char *) secret->p;
|
||||||
|
const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint );
|
||||||
|
|
||||||
|
return( mbedtls_ctr_drbg_seed( ctx, ecp_ctr_drbg_null_entropy, NULL,
|
||||||
|
secret_p, secret_size ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif 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 )
|
||||||
|
{
|
||||||
|
const unsigned char *secret_p = (const unsigned char *) secret->p;
|
||||||
|
const size_t secret_size = secret->n * sizeof( mbedtls_mpi_uint );
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
|
||||||
|
return( mbedtls_hmac_drbg_seed_buf( ctx, md_info, secret_p, secret_size ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
/*
|
/*
|
||||||
* Maximum number of "basic operations" to be done in a row.
|
* Maximum number of "basic operations" to be done in a row.
|
||||||
@ -2363,12 +2480,19 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||||||
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
|
||||||
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
|
||||||
char is_grp_capable = 0;
|
char is_grp_capable = 0;
|
||||||
|
#endif
|
||||||
|
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||||
|
ecp_drbg_context drbg_ctx;
|
||||||
#endif
|
#endif
|
||||||
ECP_VALIDATE_RET( grp != NULL );
|
ECP_VALIDATE_RET( grp != NULL );
|
||||||
ECP_VALIDATE_RET( R != NULL );
|
ECP_VALIDATE_RET( R != NULL );
|
||||||
ECP_VALIDATE_RET( m != NULL );
|
ECP_VALIDATE_RET( m != NULL );
|
||||||
ECP_VALIDATE_RET( P != NULL );
|
ECP_VALIDATE_RET( P != NULL );
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||||
|
ecp_drbg_init( &drbg_ctx );
|
||||||
|
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
/* reset ops count for this call if top-level */
|
/* reset ops count for this call if top-level */
|
||||||
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
|
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
|
||||||
@ -2380,6 +2504,15 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
|
|||||||
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
|
MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
|
||||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||||
|
if( f_rng == NULL )
|
||||||
|
{
|
||||||
|
MBEDTLS_MPI_CHK( ecp_drbg_seed( &drbg_ctx, m ) );
|
||||||
|
f_rng = &ecp_drbg_random;
|
||||||
|
p_rng = &drbg_ctx;
|
||||||
|
}
|
||||||
|
#endif /* !MBEDTLS_ECP_NO_INTERNAL_RNG */
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
/* skip argument check when restarting */
|
/* skip argument check when restarting */
|
||||||
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
if( rs_ctx == NULL || rs_ctx->rsm == NULL )
|
||||||
@ -2410,6 +2543,10 @@ cleanup:
|
|||||||
mbedtls_internal_ecp_free( grp );
|
mbedtls_internal_ecp_free( grp );
|
||||||
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_ECP_NO_INTERNAL_RNG)
|
||||||
|
ecp_drbg_free( &drbg_ctx );
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||||
if( rs_ctx != NULL )
|
if( rs_ctx != NULL )
|
||||||
rs_ctx->depth--;
|
rs_ctx->depth--;
|
||||||
|
Loading…
Reference in New Issue
Block a user