34 #if defined(POLARSSL_ECDSA_C)
39 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
54 static void hmac_drbg_update( hmac_drbg_context *ctx,
55 const unsigned char *data,
size_t data_len )
57 size_t md_len = ctx->
md_ctx.md_info->size;
58 unsigned char rounds = ( data != NULL && data_len != 0 ) ? 2 : 1;
61 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
83 static void hmac_drbg_init( hmac_drbg_context *ctx,
85 const unsigned char *data,
size_t data_len )
87 memset( ctx, 0,
sizeof( hmac_drbg_context ) );
90 memset( ctx->V, 0x01, md_info->
size );
93 hmac_drbg_update( ctx, data, data_len );
99 static int hmac_drbg_random(
void *state,
100 unsigned char *output,
size_t out_len )
102 hmac_drbg_context *ctx = (hmac_drbg_context *) state;
103 size_t md_len = ctx->md_ctx.md_info->size;
104 size_t left = out_len;
105 unsigned char *out = output;
109 size_t use_len = left > md_len ? md_len : left;
115 memcpy( out, ctx->V, use_len );
120 hmac_drbg_update( ctx, NULL, 0 );
125 static void hmac_drbg_free( hmac_drbg_context *ctx )
132 memset( ctx, 0,
sizeof( hmac_drbg_context ) );
143 static const md_info_t *md_info_by_size(
int min_size )
145 const md_info_t *md_cur, *md_picked = NULL;
148 for( md_alg =
md_list(); *md_alg != 0; md_alg++ )
151 md_cur->
size < min_size ||
152 ( md_picked != NULL && md_cur->
size > md_picked->
size ) )
167 const unsigned char *buf,
size_t blen )
170 size_t n_size = (grp->
nbits + 7) / 8;
171 size_t use_size = blen > n_size ? n_size : blen;
174 if( use_size * 8 > grp->
nbits )
190 const mpi *d,
const unsigned char *buf,
size_t blen,
191 int (*f_rng)(
void *,
unsigned char *,
size_t),
void *p_rng )
193 int ret, key_tries, sign_tries;
198 if( grp->
N.
p == NULL )
218 if( key_tries++ > 10 )
229 MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
240 if( sign_tries++ > 10 )
256 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
261 const mpi *d,
const unsigned char *buf,
size_t blen,
265 hmac_drbg_context rng_ctx;
267 size_t grp_len = ( grp->
nbits + 7 ) / 8;
273 md_info = md_info_by_size( blen );
277 if( md_info == NULL )
281 memset( &rng_ctx, 0,
sizeof( hmac_drbg_context ) );
285 MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
287 hmac_drbg_init( &rng_ctx, md_info, data, 2 * grp_len );
290 hmac_drbg_random, &rng_ctx );
293 hmac_drbg_free( &rng_ctx );
305 const unsigned char *buf,
size_t blen,
309 mpi e, s_inv, u1, u2;
316 if( grp->
N.
p == NULL )
337 MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
402 #if POLARSSL_ECP_MAX_BYTES > 124
403 #error "POLARSSL_ECP_MAX_BYTES bigger than expected, please fix MAX_SIG_LEN"
405 #define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) )
411 unsigned char *sig,
size_t *slen )
414 unsigned char buf[MAX_SIG_LEN];
415 unsigned char *p = buf +
sizeof( buf );
425 memcpy( sig, p, len );
435 const unsigned char *hash,
size_t hlen,
436 unsigned char *sig,
size_t *slen,
437 int (*f_rng)(
void *,
unsigned char *,
size_t),
443 hash, hlen, f_rng, p_rng ) ) != 0 )
448 return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
451 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
456 const unsigned char *hash,
size_t hlen,
457 unsigned char *sig,
size_t *slen,
463 hash, hlen, md_alg ) ) != 0 )
468 return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
476 const unsigned char *hash,
size_t hlen,
477 const unsigned char *sig,
size_t slen )
480 unsigned char *p = (
unsigned char *) sig;
481 const unsigned char *end = sig + slen;
509 int (*f_rng)(
void *,
unsigned char *,
size_t),
void *p_rng )
523 ( ret =
mpi_copy( &ctx->
d, &key->
d ) ) != 0 ||
556 #if defined(POLARSSL_SELF_TEST)
int mpi_cmp_int(const mpi *X, t_sint z)
Compare signed values.
int ecdsa_from_keypair(ecdsa_context *ctx, const ecp_keypair *key)
Set an ECDSA context from an EC key pair.
int ecdsa_verify(ecp_group *grp, const unsigned char *buf, size_t blen, const ecp_point *Q, const mpi *r, const mpi *s)
Verify ECDSA signature of a previously hashed message.
#define POLARSSL_ERR_ECP_BAD_INPUT_DATA
Bad input parameters to function.
int ecp_group_copy(ecp_group *dst, const ecp_group *src)
Copy the contents of a group object.
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
int ecdsa_write_signature(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Compute ECDSA signature and write it to buffer, serialized as defined in RFC 4492 page 20...
int md_init_ctx(md_context_t *ctx, const md_info_t *md_info)
Initialises and fills the message digest context structure with the appropriate values.
int ecdsa_sign(ecp_group *grp, mpi *r, mpi *s, const mpi *d, const unsigned char *buf, size_t blen, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Compute ECDSA signature of a previously hashed message.
Configuration options (set of defines)
int ecdsa_self_test(int verbose)
Checkup routine.
int ecp_mul(ecp_group *grp, ecp_point *R, const mpi *m, const ecp_point *P, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Multiplication by an integer: R = m * P (Not thread-safe to use same group in multiple threads) ...
void mpi_init(mpi *X)
Initialize one MPI.
int mpi_cmp_mpi(const mpi *X, const mpi *Y)
Compare signed values.
int mpi_shift_r(mpi *X, size_t count)
Right-shift: X >>= count.
int asn1_write_len(unsigned char **p, unsigned char *start, size_t len)
Write a length field in ASN.1 format Note: function works backwards in data buffer.
int mpi_add_mpi(mpi *X, const mpi *A, const mpi *B)
Signed addition: X = A + B.
const md_info_t * md_info_from_type(md_type_t md_type)
Returns the message digest information associated with the given digest type.
#define POLARSSL_ERR_ECP_VERIFY_FAILED
The signature is not valid.
ECP point structure (jacobian coordinates)
int ecp_is_zero(ecp_point *pt)
Tell if a point is zero.
void ecp_point_init(ecp_point *pt)
Initialize a point (as zero)
int mpi_inv_mod(mpi *X, const mpi *A, const mpi *N)
Modular inverse: X = A^-1 mod N.
void mpi_free(mpi *X)
Unallocate one MPI.
void ecp_group_free(ecp_group *grp)
Free the components of an ECP group.
int ecdsa_read_signature(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen)
Read and verify an ECDSA signature.
void ecdsa_init(ecdsa_context *ctx)
Initialize context.
int ecp_gen_keypair(ecp_group *grp, mpi *d, ecp_point *Q, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Generate a keypair.
const int * md_list(void)
Returns the list of digests supported by the generic digest module.
#define POLARSSL_ECP_MAX_BYTES
int asn1_write_mpi(unsigned char **p, unsigned char *start, mpi *X)
Write a big number (ASN1_INTEGER) in ASN.1 format Note: function works backwards in data buffer...
int ecp_use_known_dp(ecp_group *grp, ecp_group_id index)
Set a group using well-known domain parameters.
int md_hmac_starts(md_context_t *ctx, const unsigned char *key, size_t keylen)
Generic HMAC context setup.
void * md_ctx
Digest-specific context.
int ecp_copy(ecp_point *P, const ecp_point *Q)
Copy the contents of point Q into P.
int mpi_read_binary(mpi *X, const unsigned char *buf, size_t buflen)
Import X from unsigned binary data, big endian.
ecp_group_id
Domain parameters (curve, subgroup and generator) identifiers.
#define ASN1_CHK_ADD(g, f)
int ecdsa_genkey(ecdsa_context *ctx, ecp_group_id gid, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Generate an ECDSA keypair on the given curve.
void ecp_group_init(ecp_group *grp)
Initialize a group (to something meaningless)
int md_hmac_update(md_context_t *ctx, const unsigned char *input, size_t ilen)
Generic HMAC process buffer.
#define POLARSSL_MD_MAX_SIZE
#define POLARSSL_ERR_ECP_RANDOM_FAILED
Generation of random value, such as (ephemeral) key, failed.
int mpi_copy(mpi *X, const mpi *Y)
Copy the contents of Y into X.
int mpi_mod_mpi(mpi *R, const mpi *A, const mpi *B)
Modulo: R = A mod B.
int ecdsa_sign_det(ecp_group *grp, mpi *r, mpi *s, const mpi *d, const unsigned char *buf, size_t blen, md_type_t md_alg)
Compute ECDSA signature of a previously hashed message (deterministic version)
int asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag.
int mpi_write_binary(const mpi *X, unsigned char *buf, size_t buflen)
Export X into unsigned binary data, big endian.
void ecdsa_free(ecdsa_context *ctx)
Free context.
ASN.1 buffer writing functionality.
int size
Output length of the digest function.
int ecp_check_pubkey(const ecp_group *grp, const ecp_point *pt)
Check that a point is a valid public key on this curve.
int ecp_add(const ecp_group *grp, ecp_point *R, const ecp_point *P, const ecp_point *Q)
Addition: R = P + Q.
int asn1_write_tag(unsigned char **p, unsigned char *start, unsigned char tag)
Write a ASN.1 tag in ASN.1 format Note: function works backwards in data buffer.
int mpi_mul_mpi(mpi *X, const mpi *A, const mpi *B)
Baseline multiplication: X = A * B.
int mpi_sub_mpi(mpi *X, const mpi *A, const mpi *B)
Signed subtraction: X = A - B.
int md_free_ctx(md_context_t *ctx)
Free the message-specific context of ctx.
int asn1_get_mpi(unsigned char **p, const unsigned char *end, mpi *X)
Retrieve a MPI value from an integer ASN.1 tag.
Message digest information.
int ecdsa_write_signature_det(ecdsa_context *ctx, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, md_type_t md_alg)
Compute ECDSA signature and write it to buffer, serialized as defined in RFC 4492 page 20...
int md_hmac_finish(md_context_t *ctx, unsigned char *output)
Generic HMAC final digest.
Generic message digest context.
void ecp_point_free(ecp_point *pt)
Free the components of a point.