diff --git a/include/polarssl/dhm.h b/include/polarssl/dhm.h index da787c346..09de70b0e 100644 --- a/include/polarssl/dhm.h +++ b/include/polarssl/dhm.h @@ -147,6 +147,9 @@ typedef struct mpi GY; /*!< peer = G^Y mod P */ mpi K; /*!< key = GY^X mod P */ mpi RP; /*!< cached R^2 mod P */ + mpi Vi; /*!< blinding value */ + mpi Vf; /*!< un-blinding value */ + mpi _X; /*!< previous X */ } dhm_context; @@ -219,11 +222,23 @@ int dhm_make_public( dhm_context *ctx, int x_size, * \param ctx DHM context * \param output destination buffer * \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 + * + * \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, - 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 diff --git a/include/polarssl/ecdh.h b/include/polarssl/ecdh.h index 2184ab95f..d91aea58d 100644 --- a/include/polarssl/ecdh.h +++ b/include/polarssl/ecdh.h @@ -70,12 +70,20 @@ int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q, * \param z Destination MPI (shared secret) * \param Q Public key from other party * \param d Our secret exponent + * \param f_rng RNG function (see notes) + * \param p_rng RNG parameter * * \return 0 if successful, * 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, - 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 @@ -156,11 +164,15 @@ int ecdh_read_public( ecdh_context *ctx, * \param olen number of bytes written * \param buf destination buffer * \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 */ 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 diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index ad31bff66..31f9e6ddb 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -411,17 +411,31 @@ int ecp_sub( const ecp_group *grp, ecp_point *R, * \param R Destination point * \param m Integer by which to multiply * \param P Point to multiply + * \param f_rng RNG function (see notes) + * \param p_rng RNG parameter * * \return 0 if successful, * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed - * POLARSSL_ERR_ECP_GENERIC if m < 0 of m has greater bit - * length than N, the number of points in the group. + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if m < 0 of m has greater + * bit length than N, the number of points in the group. * - * \note This function executes a constant number of operations - * for random m in the allowed range. + * \note In order to prevent simple timing attacks, this function + * 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, - 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 diff --git a/include/polarssl/rsa.h b/include/polarssl/rsa.h index 4e85ca6cc..71fbff2d8 100644 --- a/include/polarssl/rsa.h +++ b/include/polarssl/rsa.h @@ -89,6 +89,11 @@ typedef struct mpi RP; /*!< cached R^2 mod P */ 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 RSA_PKCS_v21 for OAEP/PSS */ int hash_id; /*!< Hash identifier of md_type_t as diff --git a/library/dhm.c b/library/dhm.c index 0c65dfec3..b95f89958 100644 --- a/library/dhm.c +++ b/library/dhm.c @@ -245,28 +245,113 @@ cleanup: 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 */ 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; + mpi GYb; if( ctx == NULL || *olen < ctx->len ) 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 ) 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 ); MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) ); cleanup: + mpi_free( &GYb ); if( ret != 0 ) return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret ); @@ -279,6 +364,7 @@ cleanup: */ 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->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G ); mpi_free( &ctx->P ); diff --git a/library/ecdh.c b/library/ecdh.c index d76596eb2..8ef02f54b 100644 --- a/library/ecdh.c +++ b/library/ecdh.c @@ -50,7 +50,9 @@ int ecdh_gen_public( const ecp_group *grp, mpi *d, ecp_point *Q, * Compute shared secret (SEC1 3.3.1) */ 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; 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_mul( grp, &P, d, Q ) ); + MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); if( ecp_is_zero( &P ) ) { @@ -202,16 +204,20 @@ int ecdh_read_public( ecdh_context *ctx, * Derive and export the shared secret */ 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; if( ctx == NULL ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); - if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d ) ) - != 0 ) + if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, + f_rng, p_rng ) ) != 0 ) + { return( ret ); + } if( mpi_size( &ctx->z ) > blen ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); diff --git a/library/ecdsa.c b/library/ecdsa.c index 67774c9d0..dc169cefc 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -161,9 +161,12 @@ int ecdsa_verify( const ecp_group *grp, /* * 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, &P, &u2, Q ) ); + MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) ); + MPI_CHK( ecp_mul( grp, &P, &u2, Q, NULL, NULL ) ); MPI_CHK( ecp_add( grp, &R, &R, &P ) ); if( ecp_is_zero( &R ) ) @@ -217,8 +220,8 @@ int ecdsa_write_signature( ecdsa_context *ctx, void *p_rng ) { int ret; - unsigned char buf[MAX_SIG_LEN]; - unsigned char *p = buf + MAX_SIG_LEN - 1; + unsigned char buf[MAX_SIG_LEN + 3]; + unsigned char *p = buf + MAX_SIG_LEN; size_t len = 0; if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, diff --git a/library/ecp.c b/library/ecp.c index 09a021bf8..a80ddac63 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -30,6 +30,17 @@ * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf * 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. + * . + * + * [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. + * */ #include "polarssl/config.h" @@ -51,7 +62,7 @@ #if defined(POLARSSL_SELF_TEST) /* * 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; #endif @@ -777,7 +788,7 @@ cleanup: * (See for example Cohen's "A Course in Computational Algebraic Number * 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(). */ 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, - * with a fixed pattern for resistance to SPA/timing attacks, - * see . - * (The resulting multiplication algorithm can also been seen as a - * modification of 2^w-ary multiplication, with signed coefficients, - * all of them odd.) + * with a fixed pattern for resistance to simple timing attacks (even SPA), + * see [1]. (The resulting multiplication algorithm can also been seen as a + * modification of 2^w-ary multiplication, with signed coefficients, all of + * them odd.) * * Input: * m must be an odd positive mpi less than w * k bits long @@ -1144,6 +1154,51 @@ cleanup: 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 */ @@ -1159,14 +1214,19 @@ cleanup: /* * Integer multiplication: R = m * P * - * Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed() - * and . + * Based on fixed-pattern width-w NAF, see comments of ecp_w_naf_fixed(). * * This function executes a fixed number of operations for * 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, - 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; unsigned char w, m_is_odd; @@ -1176,17 +1236,17 @@ int ecp_mul( const ecp_group *grp, ecp_point *R, mpi M; 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 : grp->nbits >= 224 ? 5 : - 4; + 4; /* * Make sure w is within the limits. * The last test ensures that none of the precomputed points is zero, * 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 ) 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 ) ); } + /* Countermeasure (see comments above) */ + if( f_rng != NULL ) + ecp_randomize_coordinates( grp, &Q, f_rng, p_rng ); + if( i == 0 ) break; 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 ); - 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) @@ -1402,12 +1466,12 @@ int ecp_self_test( int verbose ) #endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ if( verbose != 0 ) - printf( " ECP test #1 (SPA resistance): " ); + printf( " ECP test #1 (resistance to simple timing attacks): " ); add_count = 0; dbl_count = 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++ ) { @@ -1417,7 +1481,7 @@ int ecp_self_test( int verbose ) dbl_count = 0; 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 ) { diff --git a/library/rsa.c b/library/rsa.c index c39a338a3..c82ffaa8a 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -253,6 +253,41 @@ cleanup: 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 */ @@ -265,11 +300,8 @@ int rsa_private( rsa_context *ctx, int ret; size_t olen; mpi T, T1, T2; - mpi A, X; - mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 ); - mpi_init( &A ); mpi_init( &X ); MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) @@ -284,14 +316,12 @@ int rsa_private( rsa_context *ctx, if( f_rng != NULL ) { /* - * RSA Blinding - * A = rnd MPI - * T = A^E * T mod N + * Blinding + * T = T * Vi mod N */ - MPI_CHK( mpi_fill_random( &A, ctx->len - 1, f_rng, p_rng ) ); - MPI_CHK( mpi_exp_mod( &X, &A, &ctx->E, &ctx->N, NULL ) ); - MPI_CHK( mpi_mul_mpi( &X, &X, &T ) ); - MPI_CHK( mpi_mod_mpi( &T, &X, &ctx->N ) ); + MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); } /* @@ -320,10 +350,9 @@ int rsa_private( rsa_context *ctx, { /* * 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, &A ) ); + MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vf ) ); MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); } #endif @@ -334,7 +363,6 @@ int rsa_private( rsa_context *ctx, cleanup: mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 ); - mpi_free( &A ); mpi_free( &X ); if( ret != 0 ) 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->RQ, &src->RQ ) ); + MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) ); + MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) ); + dst->padding = src->padding; dst->hash_id = src->padding; @@ -1295,6 +1326,7 @@ cleanup: */ 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->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP ); mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D ); diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 0fccf3443..19f0cb683 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1711,9 +1711,11 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) 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, ssl->handshake->premaster, - &ssl->handshake->pmslen ) ) != 0 ) + &ssl->handshake->pmslen, + NULL, NULL ) ) != 0 ) { SSL_DEBUG_RET( 1, "dhm_calc_secret", 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, &ssl->handshake->pmslen, 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 ); 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 ); + /* No blinding needed since this is ephemeral DHM */ 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 ); return( ret ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 7608d789e..8edc57f0d 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2384,9 +2384,11 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl ) 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, ssl->handshake->premaster, - &ssl->handshake->pmslen ) ) != 0 ) + &ssl->handshake->pmslen, + NULL, NULL ) ) != 0 ) { SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); 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, &ssl->handshake->pmslen, 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 ); 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; + /* No blinding needed since this is ephemeral DHM */ 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 ); return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index f06b9069b..c5c6f7584 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -239,7 +239,7 @@ int main( int argc, char *argv[] ) fflush( stdout ); 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 ); goto exit; diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index 1eba8061e..33823077d 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -242,7 +242,7 @@ int main( int argc, char *argv[] ) printf( "\n . Shared secret: " ); 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 ); goto exit; diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index c33f5b5bc..e0d65d33d 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -92,7 +92,7 @@ int main( int argc, char *argv[] ) #else int main( int argc, char *argv[] ) { - int keysize; + int ret, keysize; unsigned long i, j, tsc; unsigned char tmp[64]; #if defined(POLARSSL_ARC4_C) @@ -431,25 +431,33 @@ int main( int argc, char *argv[] ) fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_public( &rsa, buf, buf ); + ret = rsa_public( &rsa, buf, buf ); } - printf( "%9lu public/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu public/s\n", i / 3 ); printf( HEADER_FORMAT, "RSA-1024" ); fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_private( &rsa, buf, buf ); + ret = rsa_private( &rsa, myrand, NULL, buf, buf ); } - printf( "%9lu private/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu private/s\n", i / 3 ); rsa_free( &rsa ); @@ -460,25 +468,33 @@ int main( int argc, char *argv[] ) fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_public( &rsa, buf, buf ); + ret = rsa_public( &rsa, buf, buf ); } - printf( "%9lu public/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu public/s\n", i / 3 ); printf( HEADER_FORMAT, "RSA-2048" ); fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_private( &rsa, buf, buf ); + ret = rsa_private( &rsa, myrand, NULL, buf, buf ); } - printf( "%9lu private/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu private/s\n", i / 3 ); rsa_free( &rsa ); @@ -489,25 +505,33 @@ int main( int argc, char *argv[] ) fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_public( &rsa, buf, buf ); + ret = rsa_public( &rsa, buf, buf ); } - printf( "%9lu public/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu public/s\n", i / 3 ); printf( HEADER_FORMAT, "RSA-4096" ); fflush( stdout ); set_alarm( 3 ); - for( i = 1; ! alarmed; i++ ) + ret = 0; + for( i = 1; ! alarmed && ! ret ; i++ ) { buf[0] = 0; - rsa_private( &rsa, buf, buf ); + ret = rsa_private( &rsa, myrand, NULL, buf, buf ); } - printf( "%9lu private/s\n", i / 3 ); + if( ret != 0 ) + printf( "FAILED\n" ); + else + printf( "%9lu private/s\n", i / 3 ); rsa_free( &rsa ); #endif @@ -525,13 +549,34 @@ int main( int argc, char *argv[] ) fflush( stdout ); 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 ); - dhm_calc_secret( &dhm, buf, &olen ); + olen = sizeof( buf ); + ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL ); + ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL ); } - printf( "%9lu handshake/s\n", i / 3 ); + 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 ); dhm_free( &dhm ); @@ -547,16 +592,36 @@ int main( int argc, char *argv[] ) fflush( stdout ); 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 ); - dhm_calc_secret( &dhm, buf, &olen ); + olen = sizeof( buf ); + ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL ); + ret |= dhm_calc_secret( &dhm, buf, &olen, myrand, NULL ); } - printf( "%9lu handshake/s\n", i / 3 ); + 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 ); dhm_free( &dhm ); - memset( &dhm, 0, sizeof( dhm_context ) ); mpi_read_string( &dhm.P, 16, POLARSSL_DHM_RFC3526_MODP_3072_P ); @@ -569,13 +634,34 @@ int main( int argc, char *argv[] ) fflush( stdout ); 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 ); - dhm_calc_secret( &dhm, buf, &olen ); + olen = sizeof( buf ); + ret |= dhm_make_public( &dhm, dhm.len, buf, dhm.len, myrand, NULL ); + ret |= dhm_calc_secret( &dhm, buf, &olen, NULL, NULL ); } - printf( "%9lu handshake/s\n", i / 3 ); + 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 ); dhm_free( &dhm ); #endif diff --git a/programs/test/ecp-bench.c b/programs/test/ecp-bench.c index 0a0e015b4..923111876 100644 --- a/programs/test/ecp-bench.c +++ b/programs/test/ecp-bench.c @@ -28,6 +28,29 @@ int main( int argc, char *argv[] ) #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, 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 ); 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 ); diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data index 99f44826d..168c77c1b 100644 --- a/tests/suites/test_suite_dhm.data +++ b/tests/suites/test_suite_dhm.data @@ -1,8 +1,8 @@ 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 -dhm_do_dhm:1024:10:"93450983094850938450983409623":10:"9345098304850938450983409622" +dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622" -Diffie-Hellman full exchange #2 -dhm_do_dhm:1024:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271" +Diffie-Hellman full exchange #3 +dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271" diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function index e6524cc14..e8d9cea84 100644 --- a/tests/suites/test_suite_dhm.function +++ b/tests/suites/test_suite_dhm.function @@ -8,7 +8,7 @@ */ /* 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 ) { dhm_context ctx_srv; @@ -25,8 +25,6 @@ void dhm_do_dhm( int NOTUSED, int radix_P, char *input_P, int x_size; rnd_pseudo_info rnd_info; - ((void)NOTUSED); - memset( &ctx_srv, 0x00, sizeof( dhm_context ) ); memset( &ctx_cli, 0x00, sizeof( dhm_context ) ); 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( &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.G, radix_G, input_G ) == 0 ); 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 ); ske[ske_len++] = 0; 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_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_cli, sec_cli, &sec_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 ); diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index 5bfd63db7..ba35c76a7 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -27,8 +27,10 @@ void ecdh_primitive_random( int id ) == 0 ); TEST_ASSERT( ecdh_gen_public( &grp, &dB, &qB, &rnd_pseudo_rand, &rnd_info ) == 0 ); - TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA ) == 0 ); - TEST_ASSERT( ecdh_compute_shared( &grp, &zB, &qA, &dB ) == 0 ); + TEST_ASSERT( ecdh_compute_shared( &grp, &zA, &qB, &dA, + &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 ); @@ -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_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( 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 ); ecp_group_free( &grp ); @@ -107,8 +109,9 @@ void ecdh_exchange( int id ) &rnd_pseudo_rand, &rnd_info ) == 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( &cli, &len, buf, 1000 ) == 0 ); + TEST_ASSERT( ecdh_calc_secret( &srv, &len, buf, 1000, + &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 ); ecdh_free( &srv ); diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index ce9263364..55a34539f 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -50,7 +50,7 @@ ECP small subtraction #9 ecp_small_sub:0:"14":"11":0:"14":"36":0:27:30 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_mul:0:1:0:0:0 @@ -101,7 +101,7 @@ ECP small multiplication #15 ecp_small_mul:2:0:20:01:0 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_pub:1:1:0:POLARSSL_ERR_ECP_GENERIC diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 62c5de2d4..5b1ab601d 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -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_point R; mpi m; + rnd_pseudo_info rnd_info; ecp_group_init( &grp ); ecp_point_init( &R ); mpi_init( &m ); + memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) ); TEST_ASSERT( ecp_group_read_string( &grp, 10, "47", "4", "17", "42", "13" ) == 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 ) 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_point R; mpi dA, xA, yA, dB, xB, yB, xZ, yZ; + rnd_pseudo_info rnd_info; ecp_group_init( &grp ); ecp_point_init( &R ); mpi_init( &dA ); mpi_init( &xA ); mpi_init( &yA ); mpi_init( &dB ); 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 ); @@ -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( &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.Y, &yA ) == 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.Y, &yZ ) == 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.Y, &yB ) == 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.Y, &yZ ) == 0 ); TEST_ASSERT( ecp_check_pubkey( &grp, &R ) == 0 );