mbedtls/tests/suites/test_suite_ecp.function
Janos Follath 171a7efd02 Add mbedtls_ecp_read_key
The private keys used in ECDH differ in the case of Weierstrass and
Montgomery curves. They have different constraints, the former is based
on big endian, the latter little endian byte order. The fundamental
approach is different too:
- Weierstrass keys have to be in the right interval, otherwise they are
  rejected.
- Any byte array of the right size is a valid Montgomery key and it
  needs to be masked before interpreting it as a number.

Historically it was sufficient to use mbedtls_mpi_read_binary() to read
private keys, but as a preparation to improve support for Montgomery
curves we add mbedtls_ecp_read_key() to enable uniform treatment of EC
keys.

For the masking the `mbedtls_mpi_set_bit()` function is used. This is
suboptimal but seems to provide the best trade-off at this time.
Alternatives considered:
- Making a copy of the input buffer (less efficient)
- removing the `const` constraint from the input buffer (breaks the api
and makes it less user friendly)
- applying the mask directly to the limbs (violates the api between the
modules and creates and unwanted dependency)
2019-02-22 15:39:03 +00:00

1052 lines
42 KiB
Plaintext

/* BEGIN_HEADER */
#include "mbedtls/ecp.h"
#define ECP_PF_UNKNOWN -1
#define ECP_PT_RESET( x ) \
mbedtls_ecp_point_free( x ); \
mbedtls_ecp_point_init( x );
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_ECP_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE */
void ecp_valid_param( )
{
TEST_VALID_PARAM( mbedtls_ecp_group_free( NULL ) );
TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) );
TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) );
#if defined(MBEDTLS_ECP_RESTARTABLE)
TEST_VALID_PARAM( mbedtls_ecp_restart_free( NULL ) );
#endif /* MBEDTLS_ECP_RESTARTABLE */
exit:
return;
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
void ecp_invalid_param( )
{
mbedtls_ecp_group grp;
mbedtls_ecp_keypair kp;
mbedtls_ecp_point P;
mbedtls_mpi m;
const char *x = "deadbeef";
int valid_fmt = MBEDTLS_ECP_PF_UNCOMPRESSED;
int invalid_fmt = 42;
size_t olen;
unsigned char buf[42] = { 0 };
const unsigned char *null_buf = NULL;
mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
mbedtls_ecp_restart_ctx restart_ctx;
TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) );
TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) );
TEST_INVALID_PARAM( mbedtls_ecp_group_init( NULL ) );
#if defined(MBEDTLS_ECP_RESTARTABLE)
TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) );
TEST_INVALID_PARAM( mbedtls_ecp_check_budget( NULL, &restart_ctx, 42 ) );
#endif /* MBEDTLS_ECP_RESTARTABLE */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_copy( NULL, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_copy( &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_group_copy( NULL, &grp ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_group_copy( &grp, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_privkey( NULL,
&m,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_privkey( &grp,
NULL,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_privkey( &grp,
&m,
NULL,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_set_zero( NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_is_zero( NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_cmp( NULL, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_cmp( &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_string( NULL, 2,
x, x ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_string( &P, 2,
NULL, x ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_string( &P, 2,
x, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_write_binary( NULL, &P,
valid_fmt,
&olen,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_write_binary( &grp, NULL,
valid_fmt,
&olen,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_write_binary( &grp, &P,
invalid_fmt,
&olen,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_write_binary( &grp, &P,
valid_fmt,
NULL,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_write_binary( &grp, &P,
valid_fmt,
&olen,
NULL, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_binary( NULL, &P, buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_binary( &grp, NULL, buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_point_read_binary( &grp, &P, NULL,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_point( NULL, &P,
(const unsigned char **) &buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_point( &grp, NULL,
(const unsigned char **) &buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_point( &grp, &P, &null_buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_point( &grp, &P, NULL,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_point( NULL, &P,
valid_fmt,
&olen,
buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_point( &grp, NULL,
valid_fmt,
&olen,
buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_point( &grp, &P,
invalid_fmt,
&olen,
buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_point( &grp, &P,
valid_fmt,
NULL,
buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_point( &grp, &P,
valid_fmt,
&olen,
NULL,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_group_load( NULL, valid_group ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group( NULL,
(const unsigned char **) &buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group( &grp, NULL,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group( &grp, &null_buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group_id( NULL,
(const unsigned char **) &buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group_id( &valid_group, NULL,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_read_group_id( &valid_group,
&null_buf,
sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_group( NULL, &olen,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_group( &grp, NULL,
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_tls_write_group( &grp, &olen,
NULL, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul( NULL, &P, &m, &P,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul( &grp, NULL, &m, &P,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul( &grp, &P, NULL, &P,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul( &grp, &P, &m, NULL,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul_restartable( NULL, &P, &m, &P,
rnd_std_rand, NULL , NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul_restartable( &grp, NULL, &m, &P,
rnd_std_rand, NULL , NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul_restartable( &grp, &P, NULL, &P,
rnd_std_rand, NULL , NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_mul_restartable( &grp, &P, &m, NULL,
rnd_std_rand, NULL , NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( NULL, &P, &m, &P,
&m, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( &grp, NULL, &m, &P,
&m, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( &grp, &P, NULL, &P,
&m, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( &grp, &P, &m, NULL,
&m, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( &grp, &P, &m, &P,
NULL, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd( &grp, &P, &m, &P,
&m, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( NULL, &P, &m, &P,
&m, &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( &grp, NULL, &m, &P,
&m, &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( &grp, &P, NULL, &P,
&m, &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( &grp, &P, &m, NULL,
&m, &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P,
NULL, &P, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P,
&m, NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_pubkey( NULL, &P ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_pubkey( &grp, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_pub_priv( NULL, &kp ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_pub_priv( &kp, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_privkey( NULL, &m ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_check_privkey( &grp, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair_base( NULL, &P,
&m, &P,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair_base( &grp, NULL,
&m, &P,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair_base( &grp, &P,
NULL, &P,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair_base( &grp, &P,
&m, NULL,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair_base( &grp, &P,
&m, &P,
NULL,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair( NULL,
&m, &P,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair( &grp,
NULL, &P,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair( &grp,
&m, NULL,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_keypair( &grp,
&m, &P,
NULL,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_key( valid_group, NULL,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecp_gen_key( valid_group, &kp,
NULL, NULL ) );
exit:
return;
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_curve_info( int id, int tls_id, int size, char * name )
{
const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
by_id = mbedtls_ecp_curve_info_from_grp_id( id );
by_tls = mbedtls_ecp_curve_info_from_tls_id( tls_id );
by_name = mbedtls_ecp_curve_info_from_name( name );
TEST_ASSERT( by_id != NULL );
TEST_ASSERT( by_tls != NULL );
TEST_ASSERT( by_name != NULL );
TEST_ASSERT( by_id == by_tls );
TEST_ASSERT( by_id == by_name );
TEST_ASSERT( by_id->bit_size == size );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_check_pub( int grp_id, char * x_hex, char * y_hex, char * z_hex,
int ret )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &P );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, grp_id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z_hex ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &P ) == ret );
exit:
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &P );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
void ecp_test_vect_restart( int id,
char *dA_str, char *xA_str, char *yA_str,
char *dB_str, char *xZ_str, char *yZ_str,
int max_ops, int min_restarts, int max_restarts )
{
/*
* Test for early restart. Based on test vectors like ecp_test_vect(),
* but for the sake of simplicity only does half of each side. It's
* important to test both base point and random point, though, as memory
* management is different in each case.
*
* Don't try using too precise bounds for restarts as the exact number
* will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
* MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
* change in the future. A factor 2 is a minimum safety margin.
*
* For reference, with mbed TLS 2.4 and default settings, for P-256:
* - Random point mult: ~3250M
* - Cold base point mult: ~3300M
* - Hot base point mult: ~1100M
* With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
* - Random point mult: ~3850M
*/
mbedtls_ecp_restart_ctx ctx;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, P;
mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
int cnt_restarts;
int ret;
mbedtls_ecp_restart_init( &ctx );
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &R ); mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &xA ); mbedtls_mpi_init( &yA );
mbedtls_mpi_init( &dB ); mbedtls_mpi_init( &xZ ); mbedtls_mpi_init( &yZ );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
mbedtls_ecp_set_max_ops( (unsigned) max_ops );
/* Base point case */
cnt_restarts = 0;
do {
ECP_PT_RESET( &R );
ret = mbedtls_ecp_mul_restartable( &grp, &R, &dA, &grp.G, NULL, NULL, &ctx );
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts );
TEST_ASSERT( ret == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xA ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yA ) == 0 );
TEST_ASSERT( cnt_restarts >= min_restarts );
TEST_ASSERT( cnt_restarts <= max_restarts );
/* Non-base point case */
mbedtls_ecp_copy( &P, &R );
cnt_restarts = 0;
do {
ECP_PT_RESET( &R );
ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P, NULL, NULL, &ctx );
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts );
TEST_ASSERT( ret == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xZ ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
TEST_ASSERT( cnt_restarts >= min_restarts );
TEST_ASSERT( cnt_restarts <= max_restarts );
/* Do we leak memory when aborting an operation?
* This test only makes sense when we actually restart */
if( min_restarts > 0 )
{
ret = mbedtls_ecp_mul_restartable( &grp, &R, &dB, &P, NULL, NULL, &ctx );
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
}
exit:
mbedtls_ecp_restart_free( &ctx );
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &R ); mbedtls_ecp_point_free( &P );
mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &xA ); mbedtls_mpi_free( &yA );
mbedtls_mpi_free( &dB ); mbedtls_mpi_free( &xZ ); mbedtls_mpi_free( &yZ );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
void ecp_muladd_restart( int id, char *xR_str, char *yR_str,
char *u1_str, char *u2_str,
char *xQ_str, char *yQ_str,
int max_ops, int min_restarts, int max_restarts )
{
/*
* Compute R = u1 * G + u2 * Q
* (test vectors mostly taken from ECDSA intermediate results)
*
* See comments at the top of ecp_test_vect_restart()
*/
mbedtls_ecp_restart_ctx ctx;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, Q;
mbedtls_mpi u1, u2, xR, yR;
int cnt_restarts;
int ret;
mbedtls_ecp_restart_init( &ctx );
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &R );
mbedtls_ecp_point_init( &Q );
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
mbedtls_mpi_init( &xR ); mbedtls_mpi_init( &yR );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &u1, 16, u1_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &u2, 16, u2_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xR, 16, xR_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yR, 16, yR_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q.X, 16, xQ_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Q.Y, 16, yQ_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_lset( &Q.Z, 1 ) == 0 );
mbedtls_ecp_set_max_ops( (unsigned) max_ops );
cnt_restarts = 0;
do {
ECP_PT_RESET( &R );
ret = mbedtls_ecp_muladd_restartable( &grp, &R,
&u1, &grp.G, &u2, &Q, &ctx );
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts );
TEST_ASSERT( ret == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xR ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yR ) == 0 );
TEST_ASSERT( cnt_restarts >= min_restarts );
TEST_ASSERT( cnt_restarts <= max_restarts );
/* Do we leak memory when aborting an operation?
* This test only makes sense when we actually restart */
if( min_restarts > 0 )
{
ret = mbedtls_ecp_muladd_restartable( &grp, &R,
&u1, &grp.G, &u2, &Q, &ctx );
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
}
exit:
mbedtls_ecp_restart_free( &ctx );
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &R );
mbedtls_ecp_point_free( &Q );
mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
mbedtls_mpi_free( &xR ); mbedtls_mpi_free( &yR );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_test_vect( int id, char * dA_str, char * xA_str, char * yA_str,
char * dB_str, char * xB_str, char * yB_str,
char * xZ_str, char * yZ_str )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point R;
mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
rnd_pseudo_info rnd_info;
mbedtls_ecp_group_init( &grp ); mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &xA ); mbedtls_mpi_init( &yA ); mbedtls_mpi_init( &dB );
mbedtls_mpi_init( &xB ); mbedtls_mpi_init( &yB ); mbedtls_mpi_init( &xZ ); mbedtls_mpi_init( &yZ );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yA, 16, yA_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yB, 16, yB_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xZ, 16, xZ_str ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &yZ, 16, yZ_str ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xA ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yA ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &R, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xZ ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xB ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yB ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &R,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xZ ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.Y, &yZ ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
exit:
mbedtls_ecp_group_free( &grp ); mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &xA ); mbedtls_mpi_free( &yA ); mbedtls_mpi_free( &dB );
mbedtls_mpi_free( &xB ); mbedtls_mpi_free( &yB ); mbedtls_mpi_free( &xZ ); mbedtls_mpi_free( &yZ );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_test_vec_x( int id, char * dA_hex, char * xA_hex, char * dB_hex,
char * xB_hex, char * xS_hex )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point R;
mbedtls_mpi dA, xA, dB, xB, xS;
rnd_pseudo_info rnd_info;
mbedtls_ecp_group_init( &grp ); mbedtls_ecp_point_init( &R );
mbedtls_mpi_init( &dA ); mbedtls_mpi_init( &xA );
mbedtls_mpi_init( &dB ); mbedtls_mpi_init( &xB );
mbedtls_mpi_init( &xS );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &grp.G ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dA, 16, dA_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &dB, 16, dB_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xA, 16, xA_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xB, 16, xB_hex ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &xS, 16, xS_hex ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &grp.G,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xA ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &R,
&rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xS ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dB, &grp.G, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xB ) == 0 );
TEST_ASSERT( mbedtls_ecp_mul( &grp, &R, &dA, &R, NULL, NULL ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &R ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R.X, &xS ) == 0 );
exit:
mbedtls_ecp_group_free( &grp ); mbedtls_ecp_point_free( &R );
mbedtls_mpi_free( &dA ); mbedtls_mpi_free( &xA );
mbedtls_mpi_free( &dB ); mbedtls_mpi_free( &xB );
mbedtls_mpi_free( &xS );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_fast_mod( int id, char * N_str )
{
mbedtls_ecp_group grp;
mbedtls_mpi N, R;
mbedtls_mpi_init( &N ); mbedtls_mpi_init( &R );
mbedtls_ecp_group_init( &grp );
TEST_ASSERT( mbedtls_mpi_read_string( &N, 16, N_str ) == 0 );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( grp.modp != NULL );
/*
* Store correct result before we touch N
*/
TEST_ASSERT( mbedtls_mpi_mod_mpi( &R, &N, &grp.P ) == 0 );
TEST_ASSERT( grp.modp( &N ) == 0 );
TEST_ASSERT( mbedtls_mpi_bitlen( &N ) <= grp.pbits + 3 );
/*
* Use mod rather than addition/subtraction in case previous test fails
*/
TEST_ASSERT( mbedtls_mpi_mod_mpi( &N, &N, &grp.P ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &N, &R ) == 0 );
exit:
mbedtls_mpi_free( &N ); mbedtls_mpi_free( &R );
mbedtls_ecp_group_free( &grp );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_write_binary( int id, char * x, char * y, char * z, int format,
data_t * out, int blen, int ret )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
unsigned char buf[256];
size_t olen;
memset( buf, 0, sizeof( buf ) );
mbedtls_ecp_group_init( &grp ); mbedtls_ecp_point_init( &P );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.X, 16, x ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.Y, 16, y ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &P.Z, 16, z ) == 0 );
TEST_ASSERT( mbedtls_ecp_point_write_binary( &grp, &P, format,
&olen, buf, blen ) == ret );
if( ret == 0 )
{
TEST_ASSERT( hexcmp( buf, out->x, olen, out->len ) == 0 );
}
exit:
mbedtls_ecp_group_free( &grp ); mbedtls_ecp_point_free( &P );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_read_binary( int id, data_t * buf, char * x, char * y, char * z,
int ret )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
mbedtls_mpi X, Y, Z;
mbedtls_ecp_group_init( &grp ); mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
TEST_ASSERT( mbedtls_ecp_point_read_binary( &grp, &P, buf->x, buf->len ) == ret );
if( ret == 0 )
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.X, &X ) == 0 );
/*
* At the time of writing, the following condition is equivalent with
* if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
* but has the advantage of not using internal symbols.
*/
if( grp.G.Y.p == NULL )
{
TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, 0 ) == 0 );
TEST_ASSERT( P.Y.p == NULL );
TEST_ASSERT( mbedtls_mpi_cmp_int( &Z, 1 ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_int( &P.Z, 1 ) == 0 );
}
else
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 );
}
}
exit:
mbedtls_ecp_group_free( &grp ); mbedtls_ecp_point_free( &P );
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_tls_read_point( int id, data_t * buf, char * x, char * y,
char * z, int ret )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point P;
mbedtls_mpi X, Y, Z;
const unsigned char *vbuf = buf->x;
mbedtls_ecp_group_init( &grp ); mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &X, 16, x ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Y, 16, y ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &Z, 16, z ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &P, &vbuf, buf->len ) == ret );
if( ret == 0 )
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.X, &X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 );
TEST_ASSERT( (uint32_t)( vbuf - buf->x ) == buf->len );
}
exit:
mbedtls_ecp_group_free( &grp ); mbedtls_ecp_point_free( &P );
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_tls_write_read_point( int id )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point pt;
unsigned char buf[256];
const unsigned char *vbuf;
size_t olen;
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &pt );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
TEST_ASSERT( mbedtls_ecp_tls_write_point( &grp, &grp.G,
MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256 ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &pt, &vbuf, olen )
== MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
TEST_ASSERT( vbuf == buf + olen );
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
TEST_ASSERT( mbedtls_ecp_tls_write_point( &grp, &grp.G,
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256 ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &pt, &vbuf, olen ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &grp.G.X, &pt.X ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &grp.G.Y, &pt.Y ) == 0 );
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &grp.G.Z, &pt.Z ) == 0 );
TEST_ASSERT( vbuf == buf + olen );
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
TEST_ASSERT( mbedtls_ecp_set_zero( &pt ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_write_point( &grp, &pt,
MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256 ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &pt, &vbuf, olen ) == 0 );
TEST_ASSERT( mbedtls_ecp_is_zero( &pt ) );
TEST_ASSERT( vbuf == buf + olen );
memset( buf, 0x00, sizeof( buf ) ); vbuf = buf;
TEST_ASSERT( mbedtls_ecp_set_zero( &pt ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_write_point( &grp, &pt,
MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256 ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_read_point( &grp, &pt, &vbuf, olen ) == 0 );
TEST_ASSERT( mbedtls_ecp_is_zero( &pt ) );
TEST_ASSERT( vbuf == buf + olen );
exit:
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &pt );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_tls_read_group( data_t * buf, int result, int bits,
int record_len )
{
mbedtls_ecp_group grp;
const unsigned char *vbuf = buf->x;
int ret;
mbedtls_ecp_group_init( &grp );
ret = mbedtls_ecp_tls_read_group( &grp, &vbuf, buf->len );
TEST_ASSERT( ret == result );
if( ret == 0)
{
TEST_ASSERT( mbedtls_mpi_bitlen( &grp.P ) == (size_t) bits );
TEST_ASSERT( vbuf - buf->x == record_len);
}
exit:
mbedtls_ecp_group_free( &grp );
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_tls_write_read_group( int id )
{
mbedtls_ecp_group grp1, grp2;
unsigned char buf[10];
const unsigned char *vbuf = buf;
size_t len;
int ret;
mbedtls_ecp_group_init( &grp1 );
mbedtls_ecp_group_init( &grp2 );
memset( buf, 0x00, sizeof( buf ) );
TEST_ASSERT( mbedtls_ecp_group_load( &grp1, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_tls_write_group( &grp1, &len, buf, 10 ) == 0 );
ret = mbedtls_ecp_tls_read_group( &grp2, &vbuf, len );
TEST_ASSERT( ret == 0 );
if( ret == 0 )
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &grp1.N, &grp2.N ) == 0 );
TEST_ASSERT( grp1.id == grp2.id );
}
exit:
mbedtls_ecp_group_free( &grp1 );
mbedtls_ecp_group_free( &grp2 );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_check_privkey( int id, char * key_hex, int ret )
{
mbedtls_ecp_group grp;
mbedtls_mpi d;
mbedtls_ecp_group_init( &grp );
mbedtls_mpi_init( &d );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, key_hex ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_privkey( &grp, &d ) == ret );
exit:
mbedtls_ecp_group_free( &grp );
mbedtls_mpi_free( &d );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_check_pub_priv( int id_pub, char * Qx_pub, char * Qy_pub,
int id, char * d, char * Qx, char * Qy,
int ret )
{
mbedtls_ecp_keypair pub, prv;
mbedtls_ecp_keypair_init( &pub );
mbedtls_ecp_keypair_init( &prv );
if( id_pub != MBEDTLS_ECP_DP_NONE )
TEST_ASSERT( mbedtls_ecp_group_load( &pub.grp, id_pub ) == 0 );
TEST_ASSERT( mbedtls_ecp_point_read_string( &pub.Q, 16, Qx_pub, Qy_pub ) == 0 );
if( id != MBEDTLS_ECP_DP_NONE )
TEST_ASSERT( mbedtls_ecp_group_load( &prv.grp, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_point_read_string( &prv.Q, 16, Qx, Qy ) == 0 );
TEST_ASSERT( mbedtls_mpi_read_string( &prv.d, 16, d ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pub_priv( &pub, &prv ) == ret );
exit:
mbedtls_ecp_keypair_free( &pub );
mbedtls_ecp_keypair_free( &prv );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_gen_keypair( int id )
{
mbedtls_ecp_group grp;
mbedtls_ecp_point Q;
mbedtls_mpi d;
rnd_pseudo_info rnd_info;
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &Q );
mbedtls_mpi_init( &d );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
TEST_ASSERT( mbedtls_ecp_gen_keypair( &grp, &d, &Q, &rnd_pseudo_rand, &rnd_info )
== 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &grp, &Q ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_privkey( &grp, &d ) == 0 );
exit:
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &Q );
mbedtls_mpi_free( &d );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_gen_key( int id )
{
mbedtls_ecp_keypair key;
rnd_pseudo_info rnd_info;
mbedtls_ecp_keypair_init( &key );
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
TEST_ASSERT( mbedtls_ecp_gen_key( id, &key, &rnd_pseudo_rand, &rnd_info ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_pubkey( &key.grp, &key.Q ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_privkey( &key.grp, &key.d ) == 0 );
exit:
mbedtls_ecp_keypair_free( &key );
}
/* END_CASE */
/* BEGIN_CASE */
void mbedtls_ecp_read_key( int grp_id, data_t* in_key, int expected )
{
int ret = 0;
mbedtls_ecp_keypair key;
mbedtls_ecp_keypair_init( &key );
ret = mbedtls_ecp_read_key( grp_id, &key, in_key->x, in_key->len );
TEST_ASSERT( ret == expected );
if( expected == 0 )
{
ret = mbedtls_ecp_check_privkey( &key.grp, &key.d );
TEST_ASSERT( ret == 0 );
}
exit:
mbedtls_ecp_keypair_free( &key );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void ecp_selftest( )
{
TEST_ASSERT( mbedtls_ecp_self_test( 1 ) == 0 );
}
/* END_CASE */