static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { ((void) md_alg); return( ecdsa_read_signature( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len ) ); }
static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ) { int ret; ((void) md_alg); ret = ecdsa_read_signature( (ecdsa_context *) ctx, hash, hash_len, sig, sig_len ); if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ) return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); return( ret ); }
int main( int argc, char *argv[] ) { int ret; ecdsa_context ctx_sign, ctx_verify; entropy_context entropy; ctr_drbg_context ctr_drbg; unsigned char hash[] = "This should be the hash of a message."; unsigned char sig[512]; size_t sig_len; const char *pers = "ecdsa"; ((void) argv); ecdsa_init( &ctx_sign ); ecdsa_init( &ctx_verify ); memset(sig, 0, sizeof( sig ) ); ret = 1; if( argc != 1 ) { polarssl_printf( "usage: ecdsa\n" ); #if defined(_WIN32) polarssl_printf( "\n" ); #endif goto exit; } /* * Generate a key pair for signing */ polarssl_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { polarssl_printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n . Generating key pair..." ); fflush( stdout ); if( ( ret = ecdsa_genkey( &ctx_sign, ECPARAMS, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (key size: %d bits)\n", (int) ctx_sign.grp.pbits ); dump_pubkey( " + Public key: ", &ctx_sign ); /* * Sign some message hash */ polarssl_printf( " . Signing message..." ); fflush( stdout ); if( ( ret = ecdsa_write_signature( &ctx_sign, hash, sizeof( hash ), sig, &sig_len, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_genkey returned %d\n", ret ); goto exit; } polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len ); dump_buf( " + Hash: ", hash, sizeof hash ); dump_buf( " + Signature: ", sig, sig_len ); /* * Signature is serialized as defined by RFC 4492 p. 20, * but one can also access 'r' and 's' directly from the context */ #ifdef POLARSSL_FS_IO mpi_write_file( " r = ", &ctx_sign.r, 16, NULL ); mpi_write_file( " s = ", &ctx_sign.s, 16, NULL ); #endif /* * Transfer public information to verifying context * * We could use the same context for verification and signatures, but we * chose to use a new one in order to make it clear that the verifying * context only needs the public key (Q), and not the private key (d). */ polarssl_printf( " . Preparing verification context..." ); fflush( stdout ); if( ( ret = ecp_group_copy( &ctx_verify.grp, &ctx_sign.grp ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_group_copy returned %d\n", ret ); goto exit; } if( ( ret = ecp_copy( &ctx_verify.Q, &ctx_sign.Q ) ) != 0 ) { polarssl_printf( " failed\n ! ecp_copy returned %d\n", ret ); goto exit; } ret = 0; /* * Verify signature */ polarssl_printf( " ok\n . Verifying signature..." ); fflush( stdout ); if( ( ret = ecdsa_read_signature( &ctx_verify, hash, sizeof( hash ), sig, sig_len ) ) != 0 ) { polarssl_printf( " failed\n ! ecdsa_read_signature returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n" ); exit: #if defined(_WIN32) polarssl_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif ecdsa_free( &ctx_verify ); ecdsa_free( &ctx_sign ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); return( ret ); }