mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-23 02:45:41 +01:00
Merged blinding additions for EC, RSA and DHM into development
This commit is contained in:
commit
c0dcf0ceb1
@ -147,6 +147,9 @@ typedef struct
|
|||||||
mpi GY; /*!< peer = G^Y mod P */
|
mpi GY; /*!< peer = G^Y mod P */
|
||||||
mpi K; /*!< key = GY^X mod P */
|
mpi K; /*!< key = GY^X mod P */
|
||||||
mpi RP; /*!< cached R^2 mod P */
|
mpi RP; /*!< cached R^2 mod P */
|
||||||
|
mpi Vi; /*!< blinding value */
|
||||||
|
mpi Vf; /*!< un-blinding value */
|
||||||
|
mpi _X; /*!< previous X */
|
||||||
}
|
}
|
||||||
dhm_context;
|
dhm_context;
|
||||||
|
|
||||||
@ -219,11 +222,23 @@ int dhm_make_public( dhm_context *ctx, int x_size,
|
|||||||
* \param ctx DHM context
|
* \param ctx DHM context
|
||||||
* \param output destination buffer
|
* \param output destination buffer
|
||||||
* \param olen number of chars written
|
* \param olen number of chars written
|
||||||
|
* \param f_rng RNG function, for blinding purposes
|
||||||
|
* \param p_rng RNG parameter
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
|
||||||
|
*
|
||||||
|
* \note If f_rng is not NULL, it is used to blind the input as
|
||||||
|
* countermeasure against timing attacks. This is only useful
|
||||||
|
* when this function is called repeatedly with the same
|
||||||
|
* secret value (X field), eg when using DH key exchange as
|
||||||
|
* opposed to DHE. It is recommended to use a non-NULL f_rng
|
||||||
|
* only when needed, since otherwise this countermeasure has
|
||||||
|
* high overhead.
|
||||||
*/
|
*/
|
||||||
int dhm_calc_secret( dhm_context *ctx,
|
int dhm_calc_secret( dhm_context *ctx,
|
||||||
unsigned char *output, size_t *olen );
|
unsigned char *output, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free the components of a DHM key
|
* \brief Free the components of a DHM key
|
||||||
|
@ -70,12 +70,20 @@ int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q,
|
|||||||
* \param z Destination MPI (shared secret)
|
* \param z Destination MPI (shared secret)
|
||||||
* \param Q Public key from other party
|
* \param Q Public key from other party
|
||||||
* \param d Our secret exponent
|
* \param d Our secret exponent
|
||||||
|
* \param f_rng RNG function (see notes)
|
||||||
|
* \param p_rng RNG parameter
|
||||||
*
|
*
|
||||||
* \return 0 if successful,
|
* \return 0 if successful,
|
||||||
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
* or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
|
||||||
|
*
|
||||||
|
* \note If f_rng is not NULL, it is used to implement
|
||||||
|
* countermeasures against potential elaborate timing
|
||||||
|
* attacks, see \c ecp_mul() for details.
|
||||||
*/
|
*/
|
||||||
int ecdh_compute_shared( const ecp_group *grp, mpi *z,
|
int ecdh_compute_shared( const ecp_group *grp, mpi *z,
|
||||||
const ecp_point *Q, const mpi *d );
|
const ecp_point *Q, const mpi *d,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize context
|
* \brief Initialize context
|
||||||
@ -156,11 +164,15 @@ int ecdh_read_public( ecdh_context *ctx,
|
|||||||
* \param olen number of bytes written
|
* \param olen number of bytes written
|
||||||
* \param buf destination buffer
|
* \param buf destination buffer
|
||||||
* \param blen buffer length
|
* \param blen buffer length
|
||||||
|
* \param f_rng RNG function, see notes for \c ecdh_compute_shared()
|
||||||
|
* \param p_rng RNG parameter
|
||||||
*
|
*
|
||||||
* \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code
|
* \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code
|
||||||
*/
|
*/
|
||||||
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
|
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
|
||||||
unsigned char *buf, size_t blen );
|
unsigned char *buf, size_t blen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checkup routine
|
* \brief Checkup routine
|
||||||
|
@ -411,17 +411,31 @@ int ecp_sub( const ecp_group *grp, ecp_point *R,
|
|||||||
* \param R Destination point
|
* \param R Destination point
|
||||||
* \param m Integer by which to multiply
|
* \param m Integer by which to multiply
|
||||||
* \param P Point to multiply
|
* \param P Point to multiply
|
||||||
|
* \param f_rng RNG function (see notes)
|
||||||
|
* \param p_rng RNG parameter
|
||||||
*
|
*
|
||||||
* \return 0 if successful,
|
* \return 0 if successful,
|
||||||
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
|
||||||
* POLARSSL_ERR_ECP_GENERIC if m < 0 of m has greater bit
|
* POLARSSL_ERR_ECP_BAD_INPUT_DATA if m < 0 of m has greater
|
||||||
* length than N, the number of points in the group.
|
* bit length than N, the number of points in the group.
|
||||||
*
|
*
|
||||||
* \note This function executes a constant number of operations
|
* \note In order to prevent simple timing attacks, this function
|
||||||
* for random m in the allowed range.
|
* executes a constant number of operations (that is, point
|
||||||
|
* doubling and addition of distinct points) for random m in
|
||||||
|
* the allowed range.
|
||||||
|
*
|
||||||
|
* \note If f_rng is not NULL, it is used to randomize projective
|
||||||
|
* coordinates of indermediate results, in order to prevent
|
||||||
|
* more elaborate timing attacks relying on intermediate
|
||||||
|
* operations. (This is a prophylactic measure since no such
|
||||||
|
* attack has been published yet.) Since this contermeasure
|
||||||
|
* has very low overhead, it is recommended to always provide
|
||||||
|
* a non-NULL f_rng parameter when using secret inputs.
|
||||||
*/
|
*/
|
||||||
int ecp_mul( const ecp_group *grp, ecp_point *R,
|
int ecp_mul( const ecp_group *grp, ecp_point *R,
|
||||||
const mpi *m, const ecp_point *P );
|
const mpi *m, const ecp_point *P,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check that a point is a valid public key on this curve
|
* \brief Check that a point is a valid public key on this curve
|
||||||
|
@ -89,6 +89,11 @@ typedef struct
|
|||||||
mpi RP; /*!< cached R^2 mod P */
|
mpi RP; /*!< cached R^2 mod P */
|
||||||
mpi RQ; /*!< cached R^2 mod Q */
|
mpi RQ; /*!< cached R^2 mod Q */
|
||||||
|
|
||||||
|
#if !defined(POLARSSL_RSA_NO_CRT)
|
||||||
|
mpi Vi; /*!< cached blinding value */
|
||||||
|
mpi Vf; /*!< cached un-blinding value */
|
||||||
|
#endif
|
||||||
|
|
||||||
int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
|
int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
|
||||||
RSA_PKCS_v21 for OAEP/PSS */
|
RSA_PKCS_v21 for OAEP/PSS */
|
||||||
int hash_id; /*!< Hash identifier of md_type_t as
|
int hash_id; /*!< Hash identifier of md_type_t as
|
||||||
|
@ -245,28 +245,113 @@ cleanup:
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the blinding method and optimisation suggested in section 10 of:
|
||||||
|
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
||||||
|
* DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer
|
||||||
|
* Berlin Heidelberg, 1996. p. 104-113.
|
||||||
|
*/
|
||||||
|
static int dhm_update_blinding( dhm_context *ctx,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret, count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If Vi is initialized, update it by squaring it
|
||||||
|
*/
|
||||||
|
if( ctx->Vi.p != NULL )
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Vi = random( 2, P-1 ) */
|
||||||
|
count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng );
|
||||||
|
|
||||||
|
while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
|
||||||
|
mpi_shift_r( &ctx->Vi, 1 );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If X did not change, update Vf by squaring it too
|
||||||
|
*/
|
||||||
|
if( mpi_cmp_mpi( &ctx->X, &ctx->_X ) == 0 )
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise, compute Vf from scratch
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Vf = Vi^-X mod P */
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
|
||||||
|
MPI_CHK( mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
|
/* Remember secret associated with Vi and Vf */
|
||||||
|
MPI_CHK( mpi_copy( &ctx->_X, &ctx->X ) );;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Derive and export the shared secret (G^Y)^X mod P
|
* Derive and export the shared secret (G^Y)^X mod P
|
||||||
*/
|
*/
|
||||||
int dhm_calc_secret( dhm_context *ctx,
|
int dhm_calc_secret( dhm_context *ctx,
|
||||||
unsigned char *output, size_t *olen )
|
unsigned char *output, size_t *olen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
mpi GYb;
|
||||||
|
|
||||||
if( ctx == NULL || *olen < ctx->len )
|
if( ctx == NULL || *olen < ctx->len )
|
||||||
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
|
||||||
|
|
||||||
MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
|
|
||||||
&ctx->P, &ctx->RP ) );
|
|
||||||
|
|
||||||
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
|
||||||
return( ret );
|
return( ret );
|
||||||
|
|
||||||
|
mpi_init( &GYb );
|
||||||
|
|
||||||
|
/* Blind peer's value */
|
||||||
|
if( f_rng != NULL )
|
||||||
|
{
|
||||||
|
MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MPI_CHK( mpi_copy( &GYb, &ctx->GY ) );
|
||||||
|
|
||||||
|
/* Do modular exponentiation */
|
||||||
|
MPI_CHK( mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
|
||||||
|
&ctx->P, &ctx->RP ) );
|
||||||
|
|
||||||
|
/* Unblind secret value */
|
||||||
|
if( f_rng != NULL )
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
|
||||||
|
}
|
||||||
|
|
||||||
*olen = mpi_size( &ctx->K );
|
*olen = mpi_size( &ctx->K );
|
||||||
|
|
||||||
MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );
|
MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
mpi_free( &GYb );
|
||||||
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret );
|
return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret );
|
||||||
@ -279,6 +364,7 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
void dhm_free( dhm_context *ctx )
|
void dhm_free( dhm_context *ctx )
|
||||||
{
|
{
|
||||||
|
mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf );
|
||||||
mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY );
|
mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY );
|
||||||
mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G );
|
mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G );
|
||||||
mpi_free( &ctx->P );
|
mpi_free( &ctx->P );
|
||||||
|
@ -50,7 +50,9 @@ int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q,
|
|||||||
* Compute shared secret (SEC1 3.3.1)
|
* Compute shared secret (SEC1 3.3.1)
|
||||||
*/
|
*/
|
||||||
int ecdh_compute_shared( const ecp_group *grp, mpi *z,
|
int ecdh_compute_shared( const ecp_group *grp, mpi *z,
|
||||||
const ecp_point *Q, const mpi *d )
|
const ecp_point *Q, const mpi *d,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ecp_point P;
|
ecp_point P;
|
||||||
@ -62,7 +64,7 @@ int ecdh_compute_shared( const ecp_group *grp, mpi *z,
|
|||||||
*/
|
*/
|
||||||
MPI_CHK( ecp_check_pubkey( grp, Q ) );
|
MPI_CHK( ecp_check_pubkey( grp, Q ) );
|
||||||
|
|
||||||
MPI_CHK( ecp_mul( grp, &P, d, Q ) );
|
MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
|
||||||
|
|
||||||
if( ecp_is_zero( &P ) )
|
if( ecp_is_zero( &P ) )
|
||||||
{
|
{
|
||||||
@ -202,16 +204,20 @@ int ecdh_read_public( ecdh_context *ctx,
|
|||||||
* Derive and export the shared secret
|
* Derive and export the shared secret
|
||||||
*/
|
*/
|
||||||
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
|
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
|
||||||
unsigned char *buf, size_t blen )
|
unsigned char *buf, size_t blen,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
|
void *p_rng )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if( ctx == NULL )
|
if( ctx == NULL )
|
||||||
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d ) )
|
if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
|
||||||
!= 0 )
|
f_rng, p_rng ) ) != 0 )
|
||||||
|
{
|
||||||
return( ret );
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
if( mpi_size( &ctx->z ) > blen )
|
if( mpi_size( &ctx->z ) > blen )
|
||||||
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
@ -161,9 +161,12 @@ int ecdsa_verify( const ecp_group *grp,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 5: R = u1 G + u2 Q
|
* Step 5: R = u1 G + u2 Q
|
||||||
|
*
|
||||||
|
* Since we're not using any secret data, no need to pass a RNG to
|
||||||
|
* ecp_mul() for countermesures.
|
||||||
*/
|
*/
|
||||||
MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G ) );
|
MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) );
|
||||||
MPI_CHK( ecp_mul( grp, &P, &u2, Q ) );
|
MPI_CHK( ecp_mul( grp, &P, &u2, Q, NULL, NULL ) );
|
||||||
MPI_CHK( ecp_add( grp, &R, &R, &P ) );
|
MPI_CHK( ecp_add( grp, &R, &R, &P ) );
|
||||||
|
|
||||||
if( ecp_is_zero( &R ) )
|
if( ecp_is_zero( &R ) )
|
||||||
@ -217,8 +220,8 @@ int ecdsa_write_signature( ecdsa_context *ctx,
|
|||||||
void *p_rng )
|
void *p_rng )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buf[MAX_SIG_LEN];
|
unsigned char buf[MAX_SIG_LEN + 3];
|
||||||
unsigned char *p = buf + MAX_SIG_LEN - 1;
|
unsigned char *p = buf + MAX_SIG_LEN;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
|
if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
|
||||||
|
@ -30,6 +30,17 @@
|
|||||||
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
|
* GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
|
||||||
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
|
* FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
|
||||||
* RFC 4492 for the related TLS structures and constants
|
* RFC 4492 for the related TLS structures and constants
|
||||||
|
*
|
||||||
|
* [1] OKEYA, Katsuyuki and TAKAGI, Tsuyoshi. The width-w NAF method provides
|
||||||
|
* small memory and fast elliptic scalar multiplications secure against
|
||||||
|
* side channel attacks. In : Topics in Cryptology—CT-RSA 2003. Springer
|
||||||
|
* Berlin Heidelberg, 2003. p. 328-343.
|
||||||
|
* <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
|
||||||
|
*
|
||||||
|
* [2] CORON, Jean-Sébastien. Resistance against differential power analysis
|
||||||
|
* for elliptic curve cryptosystems. In : Cryptographic Hardware and
|
||||||
|
* Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
|
||||||
|
* <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "polarssl/config.h"
|
#include "polarssl/config.h"
|
||||||
@ -51,7 +62,7 @@
|
|||||||
#if defined(POLARSSL_SELF_TEST)
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
/*
|
/*
|
||||||
* Counts of point addition and doubling operations.
|
* Counts of point addition and doubling operations.
|
||||||
* Used to test resistance of point multiplication to SPA/timing attacks.
|
* Used to test resistance of point multiplication to simple timing attacks.
|
||||||
*/
|
*/
|
||||||
unsigned long add_count, dbl_count;
|
unsigned long add_count, dbl_count;
|
||||||
#endif
|
#endif
|
||||||
@ -777,7 +788,7 @@ cleanup:
|
|||||||
* (See for example Cohen's "A Course in Computational Algebraic Number
|
* (See for example Cohen's "A Course in Computational Algebraic Number
|
||||||
* Theory", Algorithm 10.3.4.)
|
* Theory", Algorithm 10.3.4.)
|
||||||
*
|
*
|
||||||
* Warning: fails if one of the points is zero!
|
* Warning: fails (returning an error) if one of the points is zero!
|
||||||
* This should never happen, see choice of w in ecp_mul().
|
* This should never happen, see choice of w in ecp_mul().
|
||||||
*/
|
*/
|
||||||
static int ecp_normalize_many( const ecp_group *grp,
|
static int ecp_normalize_many( const ecp_group *grp,
|
||||||
@ -1049,11 +1060,10 @@ cleanup:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute a modified width-w non-adjacent form (NAF) of a number,
|
* Compute a modified width-w non-adjacent form (NAF) of a number,
|
||||||
* with a fixed pattern for resistance to SPA/timing attacks,
|
* with a fixed pattern for resistance to simple timing attacks (even SPA),
|
||||||
* see <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
|
* see [1]. (The resulting multiplication algorithm can also been seen as a
|
||||||
* (The resulting multiplication algorithm can also been seen as a
|
* modification of 2^w-ary multiplication, with signed coefficients, all of
|
||||||
* modification of 2^w-ary multiplication, with signed coefficients,
|
* them odd.)
|
||||||
* all of them odd.)
|
|
||||||
*
|
*
|
||||||
* Input:
|
* Input:
|
||||||
* m must be an odd positive mpi less than w * k bits long
|
* m must be an odd positive mpi less than w * k bits long
|
||||||
@ -1144,6 +1154,51 @@ cleanup:
|
|||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Randomize jacobian coordinates:
|
||||||
|
* (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
|
||||||
|
* This is sort of the reverse operation of ecp_normalize().
|
||||||
|
*/
|
||||||
|
static int ecp_randomize_coordinates( const ecp_group *grp, ecp_point *pt,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi l, ll;
|
||||||
|
size_t p_size = (grp->pbits + 7) / 8;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
mpi_init( &l ); mpi_init( &ll );
|
||||||
|
|
||||||
|
/* Generate l such that 1 < l < p */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mpi_fill_random( &l, p_size, f_rng, p_rng );
|
||||||
|
|
||||||
|
while( mpi_cmp_mpi( &l, &grp->P ) >= 0 )
|
||||||
|
mpi_shift_r( &l, 1 );
|
||||||
|
|
||||||
|
if( count++ > 10 )
|
||||||
|
return( POLARSSL_ERR_ECP_GENERIC );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &l, 1 ) <= 0 );
|
||||||
|
|
||||||
|
/* Z = l * Z */
|
||||||
|
MPI_CHK( mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
|
||||||
|
|
||||||
|
/* X = l^2 * X */
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
|
||||||
|
|
||||||
|
/* Y = l^3 * Y */
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mpi_free( &l ); mpi_free( &ll );
|
||||||
|
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum length of the precomputed table
|
* Maximum length of the precomputed table
|
||||||
*/
|
*/
|
||||||
@ -1159,14 +1214,19 @@ cleanup:
|
|||||||
/*
|
/*
|
||||||
* Integer multiplication: R = m * P
|
* Integer multiplication: R = m * P
|
||||||
*
|
*
|
||||||
* Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed()
|
* Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed().
|
||||||
* and <http://rd.springer.com/chapter/10.1007/3-540-36563-X_23>.
|
|
||||||
*
|
*
|
||||||
* This function executes a fixed number of operations for
|
* This function executes a fixed number of operations for
|
||||||
* random m in the range 0 .. 2^nbits - 1.
|
* random m in the range 0 .. 2^nbits - 1.
|
||||||
|
*
|
||||||
|
* As an additional countermeasure against potential elaborate timing attacks,
|
||||||
|
* we randomize coordinates after each addition. This was suggested as a
|
||||||
|
* countermeasure against DPA in 5.3 of [2] (with the obvious adaptation that
|
||||||
|
* we use jacobian coordinates, not standard projective coordinates).
|
||||||
*/
|
*/
|
||||||
int ecp_mul( const ecp_group *grp, ecp_point *R,
|
int ecp_mul( const ecp_group *grp, ecp_point *R,
|
||||||
const mpi *m, const ecp_point *P )
|
const mpi *m, const ecp_point *P,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char w, m_is_odd;
|
unsigned char w, m_is_odd;
|
||||||
@ -1176,7 +1236,7 @@ int ecp_mul( const ecp_group *grp, ecp_point *R,
|
|||||||
mpi M;
|
mpi M;
|
||||||
|
|
||||||
if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits )
|
if( mpi_cmp_int( m, 0 ) < 0 || mpi_msb( m ) > grp->nbits )
|
||||||
return( POLARSSL_ERR_ECP_GENERIC );
|
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
|
||||||
|
|
||||||
w = grp->nbits >= 521 ? 6 :
|
w = grp->nbits >= 521 ? 6 :
|
||||||
grp->nbits >= 224 ? 5 :
|
grp->nbits >= 224 ? 5 :
|
||||||
@ -1186,7 +1246,7 @@ int ecp_mul( const ecp_group *grp, ecp_point *R,
|
|||||||
* Make sure w is within the limits.
|
* Make sure w is within the limits.
|
||||||
* The last test ensures that none of the precomputed points is zero,
|
* The last test ensures that none of the precomputed points is zero,
|
||||||
* which wouldn't be handled correctly by ecp_normalize_many().
|
* which wouldn't be handled correctly by ecp_normalize_many().
|
||||||
* It is only useful for small curves, as used in the test suite.
|
* It is only useful for very small curves, as used in the test suite.
|
||||||
*/
|
*/
|
||||||
if( w > POLARSSL_ECP_WINDOW_SIZE )
|
if( w > POLARSSL_ECP_WINDOW_SIZE )
|
||||||
w = POLARSSL_ECP_WINDOW_SIZE;
|
w = POLARSSL_ECP_WINDOW_SIZE;
|
||||||
@ -1237,6 +1297,10 @@ int ecp_mul( const ecp_group *grp, ecp_point *R,
|
|||||||
MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) );
|
MPI_CHK( ecp_add_mixed( grp, &Q, &Q, &T[ naf[i] ], +1 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Countermeasure (see comments above) */
|
||||||
|
if( f_rng != NULL )
|
||||||
|
ecp_randomize_coordinates( grp, &Q, f_rng, p_rng );
|
||||||
|
|
||||||
if( i == 0 )
|
if( i == 0 )
|
||||||
break;
|
break;
|
||||||
i--;
|
i--;
|
||||||
@ -1348,7 +1412,7 @@ int ecp_gen_keypair( const ecp_group *grp, mpi *d, ecp_point *Q,
|
|||||||
}
|
}
|
||||||
while( mpi_cmp_int( d, 1 ) < 0 );
|
while( mpi_cmp_int( d, 1 ) < 0 );
|
||||||
|
|
||||||
return( ecp_mul( grp, Q, d, &grp->G ) );
|
return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(POLARSSL_SELF_TEST)
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
@ -1402,12 +1466,12 @@ int ecp_self_test( int verbose )
|
|||||||
#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
|
#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */
|
||||||
|
|
||||||
if( verbose != 0 )
|
if( verbose != 0 )
|
||||||
printf( " ECP test #1 (SPA resistance): " );
|
printf( " ECP test #1 (resistance to simple timing attacks): " );
|
||||||
|
|
||||||
add_count = 0;
|
add_count = 0;
|
||||||
dbl_count = 0;
|
dbl_count = 0;
|
||||||
MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
|
MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) );
|
||||||
MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G ) );
|
MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
|
||||||
|
|
||||||
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
|
for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
|
||||||
{
|
{
|
||||||
@ -1417,7 +1481,7 @@ int ecp_self_test( int verbose )
|
|||||||
dbl_count = 0;
|
dbl_count = 0;
|
||||||
|
|
||||||
MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
|
MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) );
|
||||||
MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G ) );
|
MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
|
||||||
|
|
||||||
if( add_count != add_c_prev || dbl_count != dbl_c_prev )
|
if( add_count != add_c_prev || dbl_count != dbl_c_prev )
|
||||||
{
|
{
|
||||||
|
@ -253,6 +253,41 @@ cleanup:
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(POLARSSL_RSA_NO_CRT)
|
||||||
|
/*
|
||||||
|
* Generate or update blinding values, see section 10 of:
|
||||||
|
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
|
||||||
|
* DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer
|
||||||
|
* Berlin Heidelberg, 1996. p. 104-113.
|
||||||
|
*/
|
||||||
|
static int rsa_prepare_blinding( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if( ctx->Vf.p != NULL )
|
||||||
|
{
|
||||||
|
/* We already have blinding values, just update them by squaring */
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unblinding value: Vf = random number */
|
||||||
|
MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
|
||||||
|
|
||||||
|
/* Blinding value: Vi = Vf^(-e) mod N */
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
|
||||||
|
MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do an RSA private key operation
|
* Do an RSA private key operation
|
||||||
*/
|
*/
|
||||||
@ -265,11 +300,8 @@ int rsa_private( rsa_context *ctx,
|
|||||||
int ret;
|
int ret;
|
||||||
size_t olen;
|
size_t olen;
|
||||||
mpi T, T1, T2;
|
mpi T, T1, T2;
|
||||||
mpi A, X;
|
|
||||||
|
|
||||||
|
|
||||||
mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
|
mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
|
||||||
mpi_init( &A ); mpi_init( &X );
|
|
||||||
|
|
||||||
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||||
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||||
@ -284,14 +316,12 @@ int rsa_private( rsa_context *ctx,
|
|||||||
if( f_rng != NULL )
|
if( f_rng != NULL )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* RSA Blinding
|
* Blinding
|
||||||
* A = rnd MPI
|
* T = T * Vi mod N
|
||||||
* T = A^E * T mod N
|
|
||||||
*/
|
*/
|
||||||
MPI_CHK( mpi_fill_random( &A, ctx->len - 1, f_rng, p_rng ) );
|
MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
|
||||||
MPI_CHK( mpi_exp_mod( &X, &A, &ctx->E, &ctx->N, NULL ) );
|
MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vi ) );
|
||||||
MPI_CHK( mpi_mul_mpi( &X, &X, &T ) );
|
MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||||
MPI_CHK( mpi_mod_mpi( &T, &X, &ctx->N ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -320,10 +350,9 @@ int rsa_private( rsa_context *ctx,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Unblind
|
* Unblind
|
||||||
* T = T / A mod N
|
* T = T * Vf mod N
|
||||||
*/
|
*/
|
||||||
MPI_CHK( mpi_inv_mod( &A, &A, &ctx->N ) );
|
MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vf ) );
|
||||||
MPI_CHK( mpi_mul_mpi( &T, &T, &A ) );
|
|
||||||
MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
|
MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -334,7 +363,6 @@ int rsa_private( rsa_context *ctx,
|
|||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
|
mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
|
||||||
mpi_free( &A ); mpi_free( &X );
|
|
||||||
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret );
|
return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret );
|
||||||
@ -1280,6 +1308,9 @@ int rsa_copy( rsa_context *dst, const rsa_context *src )
|
|||||||
MPI_CHK( mpi_copy( &dst->RP, &src->RP ) );
|
MPI_CHK( mpi_copy( &dst->RP, &src->RP ) );
|
||||||
MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) );
|
MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) );
|
||||||
|
MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) );
|
||||||
|
|
||||||
dst->padding = src->padding;
|
dst->padding = src->padding;
|
||||||
dst->hash_id = src->padding;
|
dst->hash_id = src->padding;
|
||||||
|
|
||||||
@ -1295,6 +1326,7 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
void rsa_free( rsa_context *ctx )
|
void rsa_free( rsa_context *ctx )
|
||||||
{
|
{
|
||||||
|
mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf );
|
||||||
mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
|
mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
|
||||||
mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
|
mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
|
||||||
mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D );
|
mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D );
|
||||||
|
@ -1711,9 +1711,11 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
||||||
|
|
||||||
|
/* No blinding needed for DHE, but will be needed for fixed DH! */
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
&ssl->handshake->pmslen ) ) != 0 )
|
&ssl->handshake->pmslen,
|
||||||
|
NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
@ -1748,7 +1750,8 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||||||
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
|
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
|
||||||
&ssl->handshake->pmslen,
|
&ssl->handshake->pmslen,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
POLARSSL_MPI_MAX_SIZE ) ) != 0 )
|
POLARSSL_MPI_MAX_SIZE,
|
||||||
|
ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
@ -1840,8 +1843,9 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 );
|
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len >> 8 );
|
||||||
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len );
|
*(p++) = (unsigned char)( ssl->handshake->dhm_ctx.len );
|
||||||
|
/* No blinding needed since this is ephemeral DHM */
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
p, &n ) ) != 0 )
|
p, &n, NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
|
@ -2384,9 +2384,11 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
ssl->handshake->pmslen = ssl->handshake->dhm_ctx.len;
|
||||||
|
|
||||||
|
/* No blinding needed for DHE, but will be needed for fixed DH! */
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
&ssl->handshake->pmslen ) ) != 0 )
|
&ssl->handshake->pmslen,
|
||||||
|
NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||||
@ -2410,7 +2412,8 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
|
|||||||
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
|
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
|
||||||
&ssl->handshake->pmslen,
|
&ssl->handshake->pmslen,
|
||||||
ssl->handshake->premaster,
|
ssl->handshake->premaster,
|
||||||
POLARSSL_MPI_MAX_SIZE ) ) != 0 )
|
POLARSSL_MPI_MAX_SIZE,
|
||||||
|
ssl->f_rng, ssl->p_rng ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||||
@ -2470,8 +2473,9 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
|
|||||||
|
|
||||||
n = ssl->handshake->dhm_ctx.len;
|
n = ssl->handshake->dhm_ctx.len;
|
||||||
|
|
||||||
|
/* No blinding needed since this is ephemeral DHM */
|
||||||
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx,
|
||||||
p, &n ) ) != 0 )
|
p, &n, NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
|
||||||
|
@ -239,7 +239,7 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
n = dhm.len;
|
n = dhm.len;
|
||||||
if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
|
if( ( ret = dhm_calc_secret( &dhm, buf, &n, NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -242,7 +242,7 @@ int main( int argc, char *argv[] )
|
|||||||
printf( "\n . Shared secret: " );
|
printf( "\n . Shared secret: " );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
|
if( ( ret = dhm_calc_secret( &dhm, buf, &n, NULL, NULL ) ) != 0 )
|
||||||
{
|
{
|
||||||
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
printf( " failed\n ! dhm_calc_secret returned %d\n\n", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -92,7 +92,7 @@ int main( int argc, char *argv[] )
|
|||||||
#else
|
#else
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
int keysize;
|
int ret, keysize;
|
||||||
unsigned long i, j, tsc;
|
unsigned long i, j, tsc;
|
||||||
unsigned char tmp[64];
|
unsigned char tmp[64];
|
||||||
#if defined(POLARSSL_ARC4_C)
|
#if defined(POLARSSL_ARC4_C)
|
||||||
@ -431,24 +431,32 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_public( &rsa, buf, buf );
|
ret = rsa_public( &rsa, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu public/s\n", i / 3 );
|
printf( "%9lu public/s\n", i / 3 );
|
||||||
|
|
||||||
printf( HEADER_FORMAT, "RSA-1024" );
|
printf( HEADER_FORMAT, "RSA-1024" );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_private( &rsa, buf, buf );
|
ret = rsa_private( &rsa, myrand, NULL, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu private/s\n", i / 3 );
|
printf( "%9lu private/s\n", i / 3 );
|
||||||
|
|
||||||
rsa_free( &rsa );
|
rsa_free( &rsa );
|
||||||
@ -460,24 +468,32 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_public( &rsa, buf, buf );
|
ret = rsa_public( &rsa, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu public/s\n", i / 3 );
|
printf( "%9lu public/s\n", i / 3 );
|
||||||
|
|
||||||
printf( HEADER_FORMAT, "RSA-2048" );
|
printf( HEADER_FORMAT, "RSA-2048" );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_private( &rsa, buf, buf );
|
ret = rsa_private( &rsa, myrand, NULL, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu private/s\n", i / 3 );
|
printf( "%9lu private/s\n", i / 3 );
|
||||||
|
|
||||||
rsa_free( &rsa );
|
rsa_free( &rsa );
|
||||||
@ -489,24 +505,32 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_public( &rsa, buf, buf );
|
ret = rsa_public( &rsa, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu public/s\n", i / 3 );
|
printf( "%9lu public/s\n", i / 3 );
|
||||||
|
|
||||||
printf( HEADER_FORMAT, "RSA-4096" );
|
printf( HEADER_FORMAT, "RSA-4096" );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
rsa_private( &rsa, buf, buf );
|
ret = rsa_private( &rsa, myrand, NULL, buf, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu private/s\n", i / 3 );
|
printf( "%9lu private/s\n", i / 3 );
|
||||||
|
|
||||||
rsa_free( &rsa );
|
rsa_free( &rsa );
|
||||||
@ -525,12 +549,33 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
olen = sizeof( buf );
|
||||||
dhm_calc_secret( &dhm, buf, &olen );
|
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
|
printf( HEADER_FORMAT, "fixed-DHM-1024" );
|
||||||
|
fflush( stdout );
|
||||||
|
set_alarm( 3 );
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
|
{
|
||||||
|
olen = sizeof( buf );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu handshake/s\n", i / 3 );
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
dhm_free( &dhm );
|
dhm_free( &dhm );
|
||||||
@ -547,16 +592,36 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
olen = sizeof( buf );
|
||||||
dhm_calc_secret( &dhm, buf, &olen );
|
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
|
printf( HEADER_FORMAT, "fixed-DHM-2048" );
|
||||||
|
fflush( stdout );
|
||||||
|
set_alarm( 3 );
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
|
{
|
||||||
|
olen = sizeof( buf );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu handshake/s\n", i / 3 );
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
dhm_free( &dhm );
|
dhm_free( &dhm );
|
||||||
|
|
||||||
memset( &dhm, 0, sizeof( dhm_context ) );
|
memset( &dhm, 0, sizeof( dhm_context ) );
|
||||||
|
|
||||||
mpi_read_string( &dhm.P, 16, POLARSSL_DHM_RFC3526_MODP_3072_P );
|
mpi_read_string( &dhm.P, 16, POLARSSL_DHM_RFC3526_MODP_3072_P );
|
||||||
@ -569,12 +634,33 @@ int main( int argc, char *argv[] )
|
|||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
{
|
{
|
||||||
dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
olen = sizeof( buf );
|
||||||
dhm_calc_secret( &dhm, buf, &olen );
|
ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
|
printf( HEADER_FORMAT, "fixed-DHM-3072" );
|
||||||
|
fflush( stdout );
|
||||||
|
set_alarm( 3 );
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
for( i = 1; ! alarmed && ! ret ; i++ )
|
||||||
|
{
|
||||||
|
olen = sizeof( buf );
|
||||||
|
ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
printf( "FAILED\n" );
|
||||||
|
else
|
||||||
printf( "%9lu handshake/s\n", i / 3 );
|
printf( "%9lu handshake/s\n", i / 3 );
|
||||||
|
|
||||||
dhm_free( &dhm );
|
dhm_free( &dhm );
|
||||||
|
@ -28,6 +28,29 @@ int main( int argc, char *argv[] )
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
static int myrand( void *rng_state, unsigned char *output, size_t len )
|
||||||
|
{
|
||||||
|
size_t use_len;
|
||||||
|
int rnd;
|
||||||
|
|
||||||
|
if( rng_state != NULL )
|
||||||
|
rng_state = NULL;
|
||||||
|
|
||||||
|
while( len > 0 )
|
||||||
|
{
|
||||||
|
use_len = len;
|
||||||
|
if( use_len > sizeof(int) )
|
||||||
|
use_len = sizeof(int);
|
||||||
|
|
||||||
|
rnd = rand();
|
||||||
|
memcpy( output, &rnd, use_len );
|
||||||
|
output += use_len;
|
||||||
|
len -= use_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
static void dhm_bench_case( const char *s, const char *p,
|
static void dhm_bench_case( const char *s, const char *p,
|
||||||
const char *g, const char *x )
|
const char *g, const char *x )
|
||||||
{
|
{
|
||||||
@ -161,7 +184,7 @@ static void ecp_bench_case( size_t dp, const char *s, const char *m )
|
|||||||
set_alarm( 3 );
|
set_alarm( 3 );
|
||||||
|
|
||||||
for( i = 1; ! alarmed; i++ )
|
for( i = 1; ! alarmed; i++ )
|
||||||
ecp_mul( &grp, &R, &M, &grp.G );
|
ecp_mul( &grp, &R, &M, &grp.G, myrand, NULL );
|
||||||
|
|
||||||
printf( "%9lu mul/s\n", i / 3 );
|
printf( "%9lu mul/s\n", i / 3 );
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Diffie-Hellman full exchange #1
|
Diffie-Hellman full exchange #1
|
||||||
dhm_do_dhm:1024:10:"23":10:"5"
|
dhm_do_dhm:10:"23":10:"5"
|
||||||
|
|
||||||
Diffie-Hellman full exchange #2
|
Diffie-Hellman full exchange #2
|
||||||
dhm_do_dhm:1024:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
|
dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
|
||||||
|
|
||||||
Diffie-Hellman full exchange #2
|
Diffie-Hellman full exchange #3
|
||||||
dhm_do_dhm:1024:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271"
|
dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* BEGIN_CASE */
|
/* BEGIN_CASE */
|
||||||
void dhm_do_dhm( int NOTUSED, int radix_P, char *input_P,
|
void dhm_do_dhm( int radix_P, char *input_P,
|
||||||
int radix_G, char *input_G )
|
int radix_G, char *input_G )
|
||||||
{
|
{
|
||||||
dhm_context ctx_srv;
|
dhm_context ctx_srv;
|
||||||
@ -25,8 +25,6 @@ void dhm_do_dhm( int NOTUSED, int radix_P, char *input_P,
|
|||||||
int x_size;
|
int x_size;
|
||||||
rnd_pseudo_info rnd_info;
|
rnd_pseudo_info rnd_info;
|
||||||
|
|
||||||
((void)NOTUSED);
|
|
||||||
|
|
||||||
memset( &ctx_srv, 0x00, sizeof( dhm_context ) );
|
memset( &ctx_srv, 0x00, sizeof( dhm_context ) );
|
||||||
memset( &ctx_cli, 0x00, sizeof( dhm_context ) );
|
memset( &ctx_cli, 0x00, sizeof( dhm_context ) );
|
||||||
memset( ske, 0x00, 1000 );
|
memset( ske, 0x00, 1000 );
|
||||||
@ -35,22 +33,57 @@ void dhm_do_dhm( int NOTUSED, int radix_P, char *input_P,
|
|||||||
memset( sec_cli, 0x00, 1000 );
|
memset( sec_cli, 0x00, 1000 );
|
||||||
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set params
|
||||||
|
*/
|
||||||
TEST_ASSERT( mpi_read_string( &ctx_srv.P, radix_P, input_P ) == 0 );
|
TEST_ASSERT( mpi_read_string( &ctx_srv.P, radix_P, input_P ) == 0 );
|
||||||
TEST_ASSERT( mpi_read_string( &ctx_srv.G, radix_G, input_G ) == 0 );
|
TEST_ASSERT( mpi_read_string( &ctx_srv.G, radix_G, input_G ) == 0 );
|
||||||
x_size = mpi_size( &ctx_srv.P );
|
x_size = mpi_size( &ctx_srv.P );
|
||||||
|
pub_cli_len = x_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First key exchange
|
||||||
|
*/
|
||||||
|
TEST_ASSERT( dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
ske[ske_len++] = 0;
|
||||||
|
ske[ske_len++] = 0;
|
||||||
|
TEST_ASSERT( dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
|
||||||
|
|
||||||
|
TEST_ASSERT( dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
TEST_ASSERT( dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
|
||||||
|
|
||||||
|
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
TEST_ASSERT( dhm_calc_secret( &ctx_cli, sec_cli, &sec_cli_len, NULL, NULL ) == 0 );
|
||||||
|
|
||||||
|
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
||||||
|
TEST_ASSERT( sec_srv_len != 0 );
|
||||||
|
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
||||||
|
|
||||||
|
/* Re-do calc_secret on server to test update of blinding values */
|
||||||
|
sec_srv_len = 1000;
|
||||||
|
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
|
||||||
|
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
||||||
|
TEST_ASSERT( sec_srv_len != 0 );
|
||||||
|
TEST_ASSERT( memcmp( sec_srv, sec_cli, sec_srv_len ) == 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Second key exchange to test change of blinding values on server
|
||||||
|
*/
|
||||||
|
sec_cli_len = 1000;
|
||||||
|
sec_srv_len = 1000;
|
||||||
|
p = ske;
|
||||||
|
|
||||||
TEST_ASSERT( dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
TEST_ASSERT( dhm_make_params( &ctx_srv, x_size, ske, &ske_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
ske[ske_len++] = 0;
|
ske[ske_len++] = 0;
|
||||||
ske[ske_len++] = 0;
|
ske[ske_len++] = 0;
|
||||||
TEST_ASSERT( dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
|
TEST_ASSERT( dhm_read_params( &ctx_cli, &p, ske + ske_len ) == 0 );
|
||||||
|
|
||||||
pub_cli_len = x_size;
|
|
||||||
TEST_ASSERT( dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
TEST_ASSERT( dhm_make_public( &ctx_cli, x_size, pub_cli, pub_cli_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
|
TEST_ASSERT( dhm_read_public( &ctx_srv, pub_cli, pub_cli_len ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len ) == 0 );
|
TEST_ASSERT( dhm_calc_secret( &ctx_srv, sec_srv, &sec_srv_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
TEST_ASSERT( dhm_calc_secret( &ctx_cli, sec_cli, &sec_cli_len ) == 0 );
|
TEST_ASSERT( dhm_calc_secret( &ctx_cli, sec_cli, &sec_cli_len, NULL, NULL ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
TEST_ASSERT( sec_srv_len == sec_cli_len );
|
||||||
TEST_ASSERT( sec_srv_len != 0 );
|
TEST_ASSERT( sec_srv_len != 0 );
|
||||||
|
@ -27,8 +27,10 @@ void ecdh_primitive_random( int id )
|
|||||||
== 0 );
|
== 0 );
|
||||||
TEST_ASSERT( ecdh_gen_public( &grp, &dB, &qB, &rnd_pseudo_rand, &rnd_info )
|
TEST_ASSERT( ecdh_gen_public( &grp, &dB, &qB, &rnd_pseudo_rand, &rnd_info )
|
||||||
== 0 );
|
== 0 );
|
||||||
TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA ) == 0 );
|
TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA,
|
||||||
TEST_ASSERT( ecdh_compute_shared( &grp, &zB, &qA, &dB ) == 0 );
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
TEST_ASSERT( ecdh_compute_shared( &grp, &zB, &qA, &dB,
|
||||||
|
NULL, NULL ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &zA, &zB ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &zA, &zB ) == 0 );
|
||||||
|
|
||||||
@ -70,9 +72,9 @@ void ecdh_primitive_testvec( int id, char *dA_str, char *xA_str, char *yA_str,
|
|||||||
TEST_ASSERT( mpi_cmp_mpi( &qB.Y, &check ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &qB.Y, &check ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( mpi_read_string( &check, 16, z_str ) == 0 );
|
TEST_ASSERT( mpi_read_string( &check, 16, z_str ) == 0 );
|
||||||
TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA ) == 0 );
|
TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA, NULL, NULL ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &zA, &check ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &zA, &check ) == 0 );
|
||||||
TEST_ASSERT( ecdh_compute_shared( &grp, &zB, &qA, &dB ) == 0 );
|
TEST_ASSERT( ecdh_compute_shared( &grp, &zB, &qA, &dB, NULL, NULL ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &zB, &check ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &zB, &check ) == 0 );
|
||||||
|
|
||||||
ecp_group_free( &grp );
|
ecp_group_free( &grp );
|
||||||
@ -107,8 +109,9 @@ void ecdh_exchange( int id )
|
|||||||
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
TEST_ASSERT( ecdh_read_public( &srv, buf, len ) == 0 );
|
TEST_ASSERT( ecdh_read_public( &srv, buf, len ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( ecdh_calc_secret( &srv, &len, buf, 1000 ) == 0 );
|
TEST_ASSERT( ecdh_calc_secret( &srv, &len, buf, 1000,
|
||||||
TEST_ASSERT( ecdh_calc_secret( &cli, &len, buf, 1000 ) == 0 );
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
|
TEST_ASSERT( ecdh_calc_secret( &cli, &len, buf, 1000, NULL, NULL ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &srv.z, &cli.z ) == 0 );
|
||||||
|
|
||||||
ecdh_free( &srv );
|
ecdh_free( &srv );
|
||||||
|
@ -50,7 +50,7 @@ ECP small subtraction #9
|
|||||||
ecp_small_sub:0:"14":"11":0:"14":"36":0:27:30
|
ecp_small_sub:0:"14":"11":0:"14":"36":0:27:30
|
||||||
|
|
||||||
ECP small multiplication negative
|
ECP small multiplication negative
|
||||||
ecp_small_mul:-1:0:0:0:POLARSSL_ERR_ECP_GENERIC
|
ecp_small_mul:-1:0:0:0:POLARSSL_ERR_ECP_BAD_INPUT_DATA
|
||||||
|
|
||||||
ECP small multiplication #0
|
ECP small multiplication #0
|
||||||
ecp_small_mul:0:1:0:0:0
|
ecp_small_mul:0:1:0:0:0
|
||||||
@ -101,7 +101,7 @@ ECP small multiplication #15
|
|||||||
ecp_small_mul:2:0:20:01:0
|
ecp_small_mul:2:0:20:01:0
|
||||||
|
|
||||||
ECP small multiplication too big
|
ECP small multiplication too big
|
||||||
ecp_small_mul:-1:0:0:0:POLARSSL_ERR_ECP_GENERIC
|
ecp_small_mul:-1:0:0:0:POLARSSL_ERR_ECP_BAD_INPUT_DATA
|
||||||
|
|
||||||
ECP small check pubkey #1
|
ECP small check pubkey #1
|
||||||
ecp_small_check_pub:1:1:0:POLARSSL_ERR_ECP_GENERIC
|
ecp_small_check_pub:1:1:0:POLARSSL_ERR_ECP_GENERIC
|
||||||
|
@ -101,17 +101,33 @@ void ecp_small_mul( int m_str, int r_zero, int x_r, int y_r, int ret )
|
|||||||
ecp_group grp;
|
ecp_group grp;
|
||||||
ecp_point R;
|
ecp_point R;
|
||||||
mpi m;
|
mpi m;
|
||||||
|
rnd_pseudo_info rnd_info;
|
||||||
|
|
||||||
ecp_group_init( &grp );
|
ecp_group_init( &grp );
|
||||||
ecp_point_init( &R );
|
ecp_point_init( &R );
|
||||||
mpi_init( &m );
|
mpi_init( &m );
|
||||||
|
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
||||||
|
|
||||||
TEST_ASSERT( ecp_group_read_string( &grp, 10,
|
TEST_ASSERT( ecp_group_read_string( &grp, 10,
|
||||||
"47", "4", "17", "42", "13" ) == 0 );
|
"47", "4", "17", "42", "13" ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( mpi_lset( &m, m_str ) == 0 );
|
TEST_ASSERT( mpi_lset( &m, m_str ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( ecp_mul( &grp, &R, &m, &grp.G ) == ret );
|
TEST_ASSERT( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) == ret );
|
||||||
|
|
||||||
|
if( r_zero )
|
||||||
|
TEST_ASSERT( mpi_cmp_int( &R.Z, 0 ) == 0 );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TEST_ASSERT( mpi_cmp_int( &R.X, x_r ) == 0 );
|
||||||
|
TEST_ASSERT( mpi_cmp_int( &R.Y, y_r ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try again with randomization */
|
||||||
|
ecp_point_free( &R );
|
||||||
|
|
||||||
|
TEST_ASSERT( ecp_mul( &grp, &R, &m, &grp.G,
|
||||||
|
&rnd_pseudo_rand, &rnd_info ) == ret );
|
||||||
|
|
||||||
if( r_zero )
|
if( r_zero )
|
||||||
TEST_ASSERT( mpi_cmp_int( &R.Z, 0 ) == 0 );
|
TEST_ASSERT( mpi_cmp_int( &R.Z, 0 ) == 0 );
|
||||||
@ -158,10 +174,12 @@ void ecp_test_vect( int id, char *dA_str, char *xA_str, char *yA_str,
|
|||||||
ecp_group grp;
|
ecp_group grp;
|
||||||
ecp_point R;
|
ecp_point R;
|
||||||
mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
|
mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
|
||||||
|
rnd_pseudo_info rnd_info;
|
||||||
|
|
||||||
ecp_group_init( &grp ); ecp_point_init( &R );
|
ecp_group_init( &grp ); ecp_point_init( &R );
|
||||||
mpi_init( &dA ); mpi_init( &xA ); mpi_init( &yA ); mpi_init( &dB );
|
mpi_init( &dA ); mpi_init( &xA ); mpi_init( &yA ); mpi_init( &dB );
|
||||||
mpi_init( &xB ); mpi_init( &yB ); mpi_init( &xZ ); mpi_init( &yZ );
|
mpi_init( &xB ); mpi_init( &yB ); mpi_init( &xZ ); mpi_init( &yZ );
|
||||||
|
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
||||||
|
|
||||||
TEST_ASSERT( ecp_use_known_dp( &grp, id ) == 0 );
|
TEST_ASSERT( ecp_use_known_dp( &grp, id ) == 0 );
|
||||||
|
|
||||||
@ -176,20 +194,22 @@ void ecp_test_vect( int id, char *dA_str, char *xA_str, char *yA_str,
|
|||||||
TEST_ASSERT( mpi_read_string( &xZ, 16, xZ_str ) == 0 );
|
TEST_ASSERT( mpi_read_string( &xZ, 16, xZ_str ) == 0 );
|
||||||
TEST_ASSERT( mpi_read_string( &yZ, 16, yZ_str ) == 0 );
|
TEST_ASSERT( mpi_read_string( &yZ, 16, yZ_str ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &grp.G ) == 0 );
|
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &grp.G,
|
||||||
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xA ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xA ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yA ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yA ) == 0 );
|
||||||
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
||||||
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &R ) == 0 );
|
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &R, NULL, NULL ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xZ ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xZ ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
|
||||||
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
||||||
|
|
||||||
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &grp.G ) == 0 );
|
TEST_ASSERT( ecp_mul( &grp, &R, &dB, &grp.G, NULL, NULL ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xB ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xB ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yB ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yB ) == 0 );
|
||||||
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
||||||
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &R ) == 0 );
|
TEST_ASSERT( ecp_mul( &grp, &R, &dA, &R,
|
||||||
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xZ ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.X, &xZ ) == 0 );
|
||||||
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
|
TEST_ASSERT( mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
|
||||||
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );
|
||||||
|
Loading…
Reference in New Issue
Block a user