mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-30 12:04:16 +01:00
e5a0b366f8
* baremetal: (78 commits) Review corrections 6 Review corrections 5 Minor changes to tinycrypt README Typos in the tinycrypt README Addition of copyright statements to tinycrypt files Add LICENSE and README for tinycrypt Add SPDX lines to each imported TinyCrypt file Review corrections 4 Review corrections 3 Review corrections 2 Review corrections Update signature of BE conversion functions Use function for 16/24/32-bit BE conversion x509.c: Minor readability improvement x509_crt.c: Indicate guarding condition in #else branch X.509: Don't remove verify callback by default Fix Doxygen warnings regarding removed verify cb+ctx parameters ECC restart: Use optional verification mode in bad signature test Re-implement verify chain if vrfy cbs are disabled Add zero-cost abstraction layer for CRT verification chain ...
562 lines
25 KiB
Plaintext
562 lines
25 KiB
Plaintext
/* BEGIN_HEADER */
|
|
#include "mbedtls/ecdsa.h"
|
|
/* END_HEADER */
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
* depends_on:MBEDTLS_ECDSA_C
|
|
* END_DEPENDENCIES
|
|
*/
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
|
|
void ecdsa_invalid_param( )
|
|
{
|
|
mbedtls_ecdsa_context ctx;
|
|
mbedtls_ecp_keypair key;
|
|
mbedtls_ecp_group grp;
|
|
mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
|
|
mbedtls_ecp_point P;
|
|
mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
|
|
mbedtls_mpi m;
|
|
size_t slen;
|
|
unsigned char buf[42] = { 0 };
|
|
|
|
TEST_INVALID_PARAM( mbedtls_ecdsa_init( NULL ) );
|
|
TEST_VALID_PARAM( mbedtls_ecdsa_free( NULL ) );
|
|
|
|
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
|
TEST_INVALID_PARAM( mbedtls_ecdsa_restart_init( NULL ) );
|
|
TEST_VALID_PARAM( mbedtls_ecdsa_restart_free( NULL ) );
|
|
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( NULL, &m, &m, &m,
|
|
buf, sizeof( buf ),
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( &grp, NULL, &m, &m,
|
|
buf, sizeof( buf ),
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( &grp, &m, NULL, &m,
|
|
buf, sizeof( buf ),
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( &grp, &m, &m, NULL,
|
|
buf, sizeof( buf ),
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( &grp, &m, &m, &m,
|
|
NULL, sizeof( buf ),
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign( &grp, &m, &m, &m,
|
|
buf, sizeof( buf ),
|
|
NULL, NULL ) );
|
|
|
|
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det( NULL, &m, &m, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det( &grp, NULL, &m, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det( &grp, &m, NULL, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det( &grp, &m, &m, NULL,
|
|
buf, sizeof( buf ),
|
|
valid_md ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det( &grp, &m, &m, &m,
|
|
NULL, sizeof( buf ),
|
|
valid_md ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det_ext( NULL, &m, &m, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md,
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det_ext( &grp, NULL, &m, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md,
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det_ext( &grp, &m, NULL, &m,
|
|
buf, sizeof( buf ),
|
|
valid_md,
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, NULL,
|
|
buf, sizeof( buf ),
|
|
valid_md,
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_sign_det_ext( &grp, &m, &m, &m,
|
|
NULL, sizeof( buf ),
|
|
valid_md,
|
|
rnd_std_rand, NULL ) );
|
|
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_verify( NULL,
|
|
buf, sizeof( buf ),
|
|
&P, &m, &m ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_verify( &grp,
|
|
NULL, sizeof( buf ),
|
|
&P, &m, &m ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_verify( &grp,
|
|
buf, sizeof( buf ),
|
|
NULL, &m, &m ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_verify( &grp,
|
|
buf, sizeof( buf ),
|
|
&P, NULL, &m ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_verify( &grp,
|
|
buf, sizeof( buf ),
|
|
&P, &m, NULL ) );
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature( NULL,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
buf, &slen,
|
|
rnd_std_rand,
|
|
NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature( &ctx,
|
|
valid_md,
|
|
NULL, sizeof( buf ),
|
|
buf, &slen,
|
|
rnd_std_rand,
|
|
NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature( &ctx,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
NULL, &slen,
|
|
rnd_std_rand,
|
|
NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature( &ctx,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
buf, NULL,
|
|
rnd_std_rand,
|
|
NULL ) );
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature_restartable( NULL,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
buf, &slen,
|
|
rnd_std_rand,
|
|
NULL, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature_restartable( &ctx,
|
|
valid_md,
|
|
NULL, sizeof( buf ),
|
|
buf, &slen,
|
|
rnd_std_rand,
|
|
NULL, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature_restartable( &ctx,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
NULL, &slen,
|
|
rnd_std_rand,
|
|
NULL, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_write_signature_restartable( &ctx,
|
|
valid_md,
|
|
buf, sizeof( buf ),
|
|
buf, NULL,
|
|
rnd_std_rand,
|
|
NULL, NULL ) );
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature( NULL,
|
|
buf, sizeof( buf ),
|
|
buf, sizeof( buf ) ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature( &ctx,
|
|
NULL, sizeof( buf ),
|
|
buf, sizeof( buf ) ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature( &ctx,
|
|
buf, sizeof( buf ),
|
|
NULL, sizeof( buf ) ) );
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature_restartable( NULL,
|
|
buf, sizeof( buf ),
|
|
buf, sizeof( buf ),
|
|
NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
NULL, sizeof( buf ),
|
|
buf, sizeof( buf ),
|
|
NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
buf, sizeof( buf ),
|
|
NULL, sizeof( buf ),
|
|
NULL ) );
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_genkey( NULL, valid_group,
|
|
rnd_std_rand, NULL ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_genkey( &ctx, valid_group,
|
|
NULL, NULL ) );
|
|
|
|
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_from_keypair( NULL, &key ) );
|
|
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
|
|
mbedtls_ecdsa_from_keypair( &ctx, NULL ) );
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void ecdsa_prim_random( int id )
|
|
{
|
|
mbedtls_ecp_group grp;
|
|
mbedtls_ecp_point Q;
|
|
mbedtls_mpi d, r, s;
|
|
rnd_pseudo_info rnd_info;
|
|
unsigned char buf[MBEDTLS_MD_MAX_SIZE];
|
|
|
|
mbedtls_ecp_group_init( &grp );
|
|
mbedtls_ecp_point_init( &Q );
|
|
mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
|
|
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
|
memset( buf, 0, sizeof( buf ) );
|
|
|
|
/* prepare material for signature */
|
|
TEST_ASSERT( rnd_pseudo_rand( &rnd_info, buf, sizeof( buf ) ) == 0 );
|
|
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_ecdsa_sign( &grp, &r, &s, &d, buf, sizeof( buf ),
|
|
&rnd_pseudo_rand, &rnd_info ) == 0 );
|
|
TEST_ASSERT( mbedtls_ecdsa_verify( &grp, buf, sizeof( buf ), &Q, &r, &s ) == 0 );
|
|
|
|
exit:
|
|
mbedtls_ecp_group_free( &grp );
|
|
mbedtls_ecp_point_free( &Q );
|
|
mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void ecdsa_prim_test_vectors( int id, char * d_str, char * xQ_str,
|
|
char * yQ_str, data_t * rnd_buf,
|
|
data_t * hash, char * r_str, char * s_str,
|
|
int result )
|
|
{
|
|
mbedtls_ecp_group grp;
|
|
mbedtls_ecp_point Q;
|
|
mbedtls_mpi d, r, s, r_check, s_check;
|
|
rnd_buf_info rnd_info;
|
|
|
|
mbedtls_ecp_group_init( &grp );
|
|
mbedtls_ecp_point_init( &Q );
|
|
mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
|
|
mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
|
|
|
|
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
|
|
TEST_ASSERT( mbedtls_ecp_point_read_string( &Q, 16, xQ_str, yQ_str ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
|
|
rnd_info.buf = rnd_buf->x;
|
|
rnd_info.length = rnd_buf->len;
|
|
|
|
/* Fix rnd_buf->x by shifting it left if necessary */
|
|
if( grp.nbits % 8 != 0 )
|
|
{
|
|
unsigned char shift = 8 - ( grp.nbits % 8 );
|
|
size_t i;
|
|
|
|
for( i = 0; i < rnd_info.length - 1; i++ )
|
|
rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> ( 8 - shift );
|
|
|
|
rnd_buf->x[rnd_info.length-1] <<= shift;
|
|
}
|
|
|
|
TEST_ASSERT( mbedtls_ecdsa_sign( &grp, &r, &s, &d, hash->x, hash->len,
|
|
rnd_buffer_rand, &rnd_info ) == result );
|
|
|
|
if ( result == 0)
|
|
{
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len, &Q, &r_check, &s_check ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_mpi_sub_int( &r, &r, 1 ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_add_int( &s, &s, 1 ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
|
|
&Q, &r, &s_check ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
|
|
&Q, &r_check, &s ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
TEST_ASSERT( mbedtls_ecdsa_verify( &grp, hash->x, hash->len,
|
|
&grp.G, &r_check, &s_check ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_ecp_group_free( &grp );
|
|
mbedtls_ecp_point_free( &Q );
|
|
mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
|
|
mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
|
|
void ecdsa_det_test_vectors( int id, char * d_str, int md_alg, char * msg,
|
|
char * r_str, char * s_str )
|
|
{
|
|
mbedtls_ecp_group grp;
|
|
mbedtls_mpi d, r, s, r_check, s_check;
|
|
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
|
size_t hlen;
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
mbedtls_ecp_group_init( &grp );
|
|
mbedtls_mpi_init( &d ); mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
|
|
mbedtls_mpi_init( &r_check ); mbedtls_mpi_init( &s_check );
|
|
memset( hash, 0, sizeof( hash ) );
|
|
|
|
TEST_ASSERT( mbedtls_ecp_group_load( &grp, id ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &d, 16, d_str ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &r_check, 16, r_str ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &s_check, 16, s_str ) == 0 );
|
|
|
|
md_info = mbedtls_md_info_from_type( md_alg );
|
|
TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE );
|
|
hlen = mbedtls_md_get_size( md_info );
|
|
TEST_ASSERT( mbedtls_md( md_info, (const unsigned char *) msg,
|
|
strlen( msg ), hash ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_ecdsa_sign_det( &grp, &r, &s, &d, hash, hlen, md_alg ) == 0 );
|
|
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
|
|
|
|
mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
|
|
mbedtls_mpi_init( &r ); mbedtls_mpi_init( &s );
|
|
|
|
TEST_ASSERT(
|
|
mbedtls_ecdsa_sign_det_ext( &grp, &r, &s, &d, hash, hlen,
|
|
md_alg, rnd_std_rand, NULL )
|
|
== 0 );
|
|
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &r, &r_check ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &s, &s_check ) == 0 );
|
|
exit:
|
|
mbedtls_ecp_group_free( &grp );
|
|
mbedtls_mpi_free( &d ); mbedtls_mpi_free( &r ); mbedtls_mpi_free( &s );
|
|
mbedtls_mpi_free( &r_check ); mbedtls_mpi_free( &s_check );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
|
|
void ecdsa_write_read_random( int id )
|
|
{
|
|
mbedtls_ecdsa_context ctx;
|
|
rnd_pseudo_info rnd_info;
|
|
unsigned char hash[32];
|
|
unsigned char sig[200];
|
|
size_t sig_len, i;
|
|
|
|
mbedtls_ecdsa_init( &ctx );
|
|
memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
|
|
memset( hash, 0, sizeof( hash ) );
|
|
memset( sig, 0x2a, sizeof( sig ) );
|
|
|
|
/* prepare material for signature */
|
|
TEST_ASSERT( rnd_pseudo_rand( &rnd_info, hash, sizeof( hash ) ) == 0 );
|
|
|
|
/* generate signing key */
|
|
TEST_ASSERT( mbedtls_ecdsa_genkey( &ctx, id, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
|
|
|
/* generate and write signature, then read and verify it */
|
|
TEST_ASSERT( mbedtls_ecdsa_write_signature( &ctx, MBEDTLS_MD_SHA256,
|
|
hash, sizeof( hash ),
|
|
sig, &sig_len, &rnd_pseudo_rand, &rnd_info ) == 0 );
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len ) == 0 );
|
|
|
|
/* check we didn't write past the announced length */
|
|
for( i = sig_len; i < sizeof( sig ); i++ )
|
|
TEST_ASSERT( sig[i] == 0x2a );
|
|
|
|
/* try verification with invalid length */
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len - 1 ) != 0 );
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len + 1 ) != 0 );
|
|
|
|
/* try invalid sequence tag */
|
|
sig[0]++;
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len ) != 0 );
|
|
sig[0]--;
|
|
|
|
/* try modifying r */
|
|
sig[10]++;
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
sig[10]--;
|
|
|
|
/* try modifying s */
|
|
sig[sig_len - 1]++;
|
|
TEST_ASSERT( mbedtls_ecdsa_read_signature( &ctx, hash, sizeof( hash ),
|
|
sig, sig_len ) == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
sig[sig_len - 1]--;
|
|
|
|
exit:
|
|
mbedtls_ecdsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
|
|
void ecdsa_read_restart( int id, char *k_str, char *h_str, char *s_str,
|
|
int max_ops, int min_restart, int max_restart )
|
|
{
|
|
mbedtls_ecdsa_context ctx;
|
|
mbedtls_ecdsa_restart_ctx rs_ctx;
|
|
unsigned char hash[64];
|
|
unsigned char sig[200];
|
|
unsigned char pk[65];
|
|
size_t sig_len, hash_len, pk_len;
|
|
int ret, cnt_restart;
|
|
|
|
mbedtls_ecdsa_init( &ctx );
|
|
mbedtls_ecdsa_restart_init( &rs_ctx );
|
|
|
|
hash_len = unhexify(hash, h_str);
|
|
sig_len = unhexify(sig, s_str);
|
|
pk_len = unhexify(pk, k_str);
|
|
|
|
TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
|
|
TEST_ASSERT( mbedtls_ecp_point_read_binary( &ctx.grp, &ctx.Q, pk, pk_len ) == 0 );
|
|
|
|
mbedtls_ecp_set_max_ops( max_ops );
|
|
|
|
cnt_restart = 0;
|
|
do {
|
|
ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
hash, hash_len, sig, sig_len, &rs_ctx );
|
|
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
|
|
|
|
TEST_ASSERT( ret == 0 );
|
|
TEST_ASSERT( cnt_restart >= min_restart );
|
|
TEST_ASSERT( cnt_restart <= max_restart );
|
|
|
|
/* try modifying r */
|
|
sig[10]++;
|
|
do {
|
|
ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
hash, hash_len, sig, sig_len, &rs_ctx );
|
|
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
|
|
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
sig[10]--;
|
|
|
|
/* try modifying s */
|
|
sig[sig_len - 1]++;
|
|
do {
|
|
ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
hash, hash_len, sig, sig_len, &rs_ctx );
|
|
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
|
|
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_VERIFY_FAILED );
|
|
sig[sig_len - 1]--;
|
|
|
|
/* Do we leak memory when aborting an operation?
|
|
* This test only makes sense when we actually restart */
|
|
if( min_restart > 0 )
|
|
{
|
|
ret = mbedtls_ecdsa_read_signature_restartable( &ctx,
|
|
hash, hash_len, sig, sig_len, &rs_ctx );
|
|
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_ecdsa_free( &ctx );
|
|
mbedtls_ecdsa_restart_free( &rs_ctx );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
|
|
void ecdsa_write_restart( int id, char *d_str, int md_alg,
|
|
char *msg, char *sig_str,
|
|
int max_ops, int min_restart, int max_restart )
|
|
{
|
|
int ret, cnt_restart;
|
|
mbedtls_ecdsa_restart_ctx rs_ctx;
|
|
mbedtls_ecdsa_context ctx;
|
|
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
|
unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
|
|
unsigned char sig_check[MBEDTLS_ECDSA_MAX_LEN];
|
|
size_t hlen, slen, slen_check;
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
mbedtls_ecdsa_restart_init( &rs_ctx );
|
|
mbedtls_ecdsa_init( &ctx );
|
|
memset( hash, 0, sizeof( hash ) );
|
|
memset( sig, 0, sizeof( sig ) );
|
|
memset( sig_check, 0, sizeof( sig_check ) );
|
|
|
|
TEST_ASSERT( mbedtls_ecp_group_load( &ctx.grp, id ) == 0 );
|
|
TEST_ASSERT( mbedtls_mpi_read_string( &ctx.d, 16, d_str ) == 0 );
|
|
slen_check = unhexify( sig_check, sig_str );
|
|
|
|
md_info = mbedtls_md_info_from_type( md_alg );
|
|
TEST_ASSERT( md_info != MBEDTLS_MD_INVALID_HANDLE );
|
|
|
|
hlen = mbedtls_md_get_size( md_info );
|
|
mbedtls_md( md_info, (const unsigned char *) msg, strlen( msg ), hash );
|
|
|
|
mbedtls_ecp_set_max_ops( max_ops );
|
|
|
|
slen = sizeof( sig );
|
|
cnt_restart = 0;
|
|
do {
|
|
ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
|
|
md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
|
|
} while( ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart );
|
|
|
|
TEST_ASSERT( ret == 0 );
|
|
TEST_ASSERT( slen == slen_check );
|
|
TEST_ASSERT( memcmp( sig, sig_check, slen ) == 0 );
|
|
|
|
TEST_ASSERT( cnt_restart >= min_restart );
|
|
TEST_ASSERT( cnt_restart <= max_restart );
|
|
|
|
/* Do we leak memory when aborting an operation?
|
|
* This test only makes sense when we actually restart */
|
|
if( min_restart > 0 )
|
|
{
|
|
ret = mbedtls_ecdsa_write_signature_restartable( &ctx,
|
|
md_alg, hash, hlen, sig, &slen, NULL, NULL, &rs_ctx );
|
|
TEST_ASSERT( ret == MBEDTLS_ERR_ECP_IN_PROGRESS );
|
|
}
|
|
|
|
exit:
|
|
mbedtls_ecdsa_restart_free( &rs_ctx );
|
|
mbedtls_ecdsa_free( &ctx );
|
|
}
|
|
/* END_CASE */
|