PolarSSL v1.3.4
ecdsa.c
Go to the documentation of this file.
1 /*
2  * Elliptic curve DSA
3  *
4  * Copyright (C) 2006-2013, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 /*
27  * References:
28  *
29  * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
30  */
31 
32 #include "polarssl/config.h"
33 
34 #if defined(POLARSSL_ECDSA_C)
35 
36 #include "polarssl/ecdsa.h"
37 #include "polarssl/asn1write.h"
38 
39 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
40 /*
41  * Simplified HMAC_DRBG context.
42  * No reseed counter, no prediction resistance flag.
43  */
44 typedef struct
45 {
46  md_context_t md_ctx;
47  unsigned char V[POLARSSL_MD_MAX_SIZE];
48  unsigned char K[POLARSSL_MD_MAX_SIZE];
49 } hmac_drbg_context;
50 
51 /*
52  * Simplified HMAC_DRBG update, using optional additional data
53  */
54 static void hmac_drbg_update( hmac_drbg_context *ctx,
55  const unsigned char *data, size_t data_len )
56 {
57  size_t md_len = ctx->md_ctx.md_info->size;
58  unsigned char rounds = ( data != NULL && data_len != 0 ) ? 2 : 1;
59  unsigned char sep[1];
60 
61  for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
62  {
63  md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
64  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
65  md_hmac_update( &ctx->md_ctx, sep, 1 );
66  if( rounds == 2 )
67  md_hmac_update( &ctx->md_ctx, data, data_len );
68  md_hmac_finish( &ctx->md_ctx, ctx->K );
69 
70  md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
71  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
72  md_hmac_finish( &ctx->md_ctx, ctx->V );
73  }
74 }
75 
76 /*
77  * Simplified HMAC_DRBG initialisation.
78  *
79  * Uses an entropy buffer rather than callback,
80  * assume personalisation string is included in entropy buffer,
81  * assumes md_info is not NULL and valid.
82  */
83 static void hmac_drbg_init( hmac_drbg_context *ctx,
84  const md_info_t * md_info,
85  const unsigned char *data, size_t data_len )
86 {
87  memset( ctx, 0, sizeof( hmac_drbg_context ) );
88  md_init_ctx( &ctx->md_ctx, md_info );
89 
90  memset( ctx->V, 0x01, md_info->size );
91  /* ctx->K is already 0 */
92 
93  hmac_drbg_update( ctx, data, data_len );
94 }
95 
96 /*
97  * Simplified HMAC_DRBG random function
98  */
99 static int hmac_drbg_random( void *state,
100  unsigned char *output, size_t out_len )
101 {
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;
106 
107  while( left != 0 )
108  {
109  size_t use_len = left > md_len ? md_len : left;
110 
111  md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
112  md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
113  md_hmac_finish( &ctx->md_ctx, ctx->V );
114 
115  memcpy( out, ctx->V, use_len );
116  out += use_len;
117  left -= use_len;
118  }
119 
120  hmac_drbg_update( ctx, NULL, 0 );
121 
122  return( 0 );
123 }
124 
125 static void hmac_drbg_free( hmac_drbg_context *ctx )
126 {
127  if( ctx == NULL )
128  return;
129 
130  md_free_ctx( &ctx->md_ctx );
131 
132  memset( ctx, 0, sizeof( hmac_drbg_context ) );
133 }
134 
135 /*
136  * This a hopefully temporary compatibility function.
137  *
138  * Since we can't ensure the caller will pass a valid md_alg before the next
139  * interface change, try to pick up a decent md by size.
140  *
141  * Argument is the minimum size in bytes of the MD output.
142  */
143 static const md_info_t *md_info_by_size( int min_size )
144 {
145  const md_info_t *md_cur, *md_picked = NULL;
146  const int *md_alg;
147 
148  for( md_alg = md_list(); *md_alg != 0; md_alg++ )
149  {
150  if( ( md_cur = md_info_from_type( *md_alg ) ) == NULL ||
151  md_cur->size < min_size ||
152  ( md_picked != NULL && md_cur->size > md_picked->size ) )
153  continue;
154 
155  md_picked = md_cur;
156  }
157 
158  return( md_picked );
159 }
160 #endif
161 
162 /*
163  * Derive a suitable integer for group grp from a buffer of length len
164  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
165  */
166 static int derive_mpi( const ecp_group *grp, mpi *x,
167  const unsigned char *buf, size_t blen )
168 {
169  int ret;
170  size_t n_size = (grp->nbits + 7) / 8;
171  size_t use_size = blen > n_size ? n_size : blen;
172 
173  MPI_CHK( mpi_read_binary( x, buf, use_size ) );
174  if( use_size * 8 > grp->nbits )
175  MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) );
176 
177  /* While at it, reduce modulo N */
178  if( mpi_cmp_mpi( x, &grp->N ) >= 0 )
179  MPI_CHK( mpi_sub_mpi( x, x, &grp->N ) );
180 
181 cleanup:
182  return( ret );
183 }
184 
185 /*
186  * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
187  * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
188  */
189 int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
190  const mpi *d, const unsigned char *buf, size_t blen,
191  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
192 {
193  int ret, key_tries, sign_tries;
194  ecp_point R;
195  mpi k, e;
196 
197  /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
198  if( grp->N.p == NULL )
200 
201  ecp_point_init( &R );
202  mpi_init( &k );
203  mpi_init( &e );
204 
205  sign_tries = 0;
206  do
207  {
208  /*
209  * Steps 1-3: generate a suitable ephemeral keypair
210  * and set r = xR mod n
211  */
212  key_tries = 0;
213  do
214  {
215  MPI_CHK( ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) );
216  MPI_CHK( mpi_mod_mpi( r, &R.X, &grp->N ) );
217 
218  if( key_tries++ > 10 )
219  {
221  goto cleanup;
222  }
223  }
224  while( mpi_cmp_int( r, 0 ) == 0 );
225 
226  /*
227  * Step 5: derive MPI from hashed message
228  */
229  MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
230 
231  /*
232  * Step 6: compute s = (e + r * d) / k mod n
233  */
234  MPI_CHK( mpi_mul_mpi( s, r, d ) );
235  MPI_CHK( mpi_add_mpi( &e, &e, s ) );
236  MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) );
237  MPI_CHK( mpi_mul_mpi( s, s, &e ) );
238  MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) );
239 
240  if( sign_tries++ > 10 )
241  {
243  goto cleanup;
244  }
245  }
246  while( mpi_cmp_int( s, 0 ) == 0 );
247 
248 cleanup:
249  ecp_point_free( &R );
250  mpi_free( &k );
251  mpi_free( &e );
252 
253  return( ret );
254 }
255 
256 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
257 /*
258  * Deterministic signature wrapper
259  */
260 int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s,
261  const mpi *d, const unsigned char *buf, size_t blen,
262  md_type_t md_alg )
263 {
264  int ret;
265  hmac_drbg_context rng_ctx;
266  unsigned char data[2 * POLARSSL_ECP_MAX_BYTES];
267  size_t grp_len = ( grp->nbits + 7 ) / 8;
268  const md_info_t *md_info;
269  mpi h;
270 
271  /* Temporary fallback */
272  if( md_alg == POLARSSL_MD_NONE )
273  md_info = md_info_by_size( blen );
274  else
275  md_info = md_info_from_type( md_alg );
276 
277  if( md_info == NULL )
279 
280  mpi_init( &h );
281  memset( &rng_ctx, 0, sizeof( hmac_drbg_context ) );
282 
283  /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
284  MPI_CHK( mpi_write_binary( d, data, grp_len ) );
285  MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
286  MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) );
287  hmac_drbg_init( &rng_ctx, md_info, data, 2 * grp_len );
288 
289  ret = ecdsa_sign( grp, r, s, d, buf, blen,
290  hmac_drbg_random, &rng_ctx );
291 
292 cleanup:
293  hmac_drbg_free( &rng_ctx );
294  mpi_free( &h );
295 
296  return( ret );
297 }
298 #endif /* POLARSSL_ECDSA_DETERMINISTIC */
299 
300 /*
301  * Verify ECDSA signature of hashed message (SEC1 4.1.4)
302  * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
303  */
304 int ecdsa_verify( ecp_group *grp,
305  const unsigned char *buf, size_t blen,
306  const ecp_point *Q, const mpi *r, const mpi *s)
307 {
308  int ret;
309  mpi e, s_inv, u1, u2;
310  ecp_point R, P;
311 
312  ecp_point_init( &R ); ecp_point_init( &P );
313  mpi_init( &e ); mpi_init( &s_inv ); mpi_init( &u1 ); mpi_init( &u2 );
314 
315  /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
316  if( grp->N.p == NULL )
318 
319  /*
320  * Step 1: make sure r and s are in range 1..n-1
321  */
322  if( mpi_cmp_int( r, 1 ) < 0 || mpi_cmp_mpi( r, &grp->N ) >= 0 ||
323  mpi_cmp_int( s, 1 ) < 0 || mpi_cmp_mpi( s, &grp->N ) >= 0 )
324  {
326  goto cleanup;
327  }
328 
329  /*
330  * Additional precaution: make sure Q is valid
331  */
332  MPI_CHK( ecp_check_pubkey( grp, Q ) );
333 
334  /*
335  * Step 3: derive MPI from hashed message
336  */
337  MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
338 
339  /*
340  * Step 4: u1 = e / s mod n, u2 = r / s mod n
341  */
342  MPI_CHK( mpi_inv_mod( &s_inv, s, &grp->N ) );
343 
344  MPI_CHK( mpi_mul_mpi( &u1, &e, &s_inv ) );
345  MPI_CHK( mpi_mod_mpi( &u1, &u1, &grp->N ) );
346 
347  MPI_CHK( mpi_mul_mpi( &u2, r, &s_inv ) );
348  MPI_CHK( mpi_mod_mpi( &u2, &u2, &grp->N ) );
349 
350  /*
351  * Step 5: R = u1 G + u2 Q
352  *
353  * Since we're not using any secret data, no need to pass a RNG to
354  * ecp_mul() for countermesures.
355  */
356  MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) );
357  MPI_CHK( ecp_mul( grp, &P, &u2, Q, NULL, NULL ) );
358  MPI_CHK( ecp_add( grp, &R, &R, &P ) );
359 
360  if( ecp_is_zero( &R ) )
361  {
363  goto cleanup;
364  }
365 
366  /*
367  * Step 6: convert xR to an integer (no-op)
368  * Step 7: reduce xR mod n (gives v)
369  */
370  MPI_CHK( mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
371 
372  /*
373  * Step 8: check if v (that is, R.X) is equal to r
374  */
375  if( mpi_cmp_mpi( &R.X, r ) != 0 )
376  {
378  goto cleanup;
379  }
380 
381 cleanup:
382  ecp_point_free( &R ); ecp_point_free( &P );
383  mpi_free( &e ); mpi_free( &s_inv ); mpi_free( &u1 ); mpi_free( &u2 );
384 
385  return( ret );
386 }
387 
388 /*
389  * RFC 4492 page 20:
390  *
391  * Ecdsa-Sig-Value ::= SEQUENCE {
392  * r INTEGER,
393  * s INTEGER
394  * }
395  *
396  * Size is at most
397  * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
398  * twice that + 1 (tag) + 2 (len) for the sequence
399  * (assuming ECP_MAX_BYTES is less than 126 for r and s,
400  * and less than 124 (total len <= 255) for the sequence)
401  */
402 #if POLARSSL_ECP_MAX_BYTES > 124
403 #error "POLARSSL_ECP_MAX_BYTES bigger than expected, please fix MAX_SIG_LEN"
404 #endif
405 #define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) )
406 
407 /*
408  * Convert a signature (given by context) to ASN.1
409  */
410 static int ecdsa_signature_to_asn1( ecdsa_context *ctx,
411  unsigned char *sig, size_t *slen )
412 {
413  int ret;
414  unsigned char buf[MAX_SIG_LEN];
415  unsigned char *p = buf + sizeof( buf );
416  size_t len = 0;
417 
418  ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) );
419  ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) );
420 
421  ASN1_CHK_ADD( len, asn1_write_len( &p, buf, len ) );
422  ASN1_CHK_ADD( len, asn1_write_tag( &p, buf,
424 
425  memcpy( sig, p, len );
426  *slen = len;
427 
428  return( 0 );
429 }
430 
431 /*
432  * Compute and write signature
433  */
435  const unsigned char *hash, size_t hlen,
436  unsigned char *sig, size_t *slen,
437  int (*f_rng)(void *, unsigned char *, size_t),
438  void *p_rng )
439 {
440  int ret;
441 
442  if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
443  hash, hlen, f_rng, p_rng ) ) != 0 )
444  {
445  return( ret );
446  }
447 
448  return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
449 }
450 
451 #if defined(POLARSSL_ECDSA_DETERMINISTIC)
452 /*
453  * Compute and write signature deterministically
454  */
456  const unsigned char *hash, size_t hlen,
457  unsigned char *sig, size_t *slen,
458  md_type_t md_alg )
459 {
460  int ret;
461 
462  if( ( ret = ecdsa_sign_det( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
463  hash, hlen, md_alg ) ) != 0 )
464  {
465  return( ret );
466  }
467 
468  return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
469 }
470 #endif /* POLARSSL_ECDSA_DETERMINISTIC */
471 
472 /*
473  * Read and check signature
474  */
476  const unsigned char *hash, size_t hlen,
477  const unsigned char *sig, size_t slen )
478 {
479  int ret;
480  unsigned char *p = (unsigned char *) sig;
481  const unsigned char *end = sig + slen;
482  size_t len;
483 
484  if( ( ret = asn1_get_tag( &p, end, &len,
485  ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
486  {
487  return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret );
488  }
489 
490  if( p + len != end )
493 
494  if( ( ret = asn1_get_mpi( &p, end, &ctx->r ) ) != 0 ||
495  ( ret = asn1_get_mpi( &p, end, &ctx->s ) ) != 0 )
496  return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret );
497 
498  if( p != end )
501 
502  return( ecdsa_verify( &ctx->grp, hash, hlen, &ctx->Q, &ctx->r, &ctx->s ) );
503 }
504 
505 /*
506  * Generate key pair
507  */
509  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
510 {
511  return( ecp_use_known_dp( &ctx->grp, gid ) ||
512  ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
513 }
514 
515 /*
516  * Set context from an ecp_keypair
517  */
518 int ecdsa_from_keypair( ecdsa_context *ctx, const ecp_keypair *key )
519 {
520  int ret;
521 
522  if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
523  ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 ||
524  ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
525  {
526  ecdsa_free( ctx );
527  }
528 
529  return( ret );
530 }
531 
532 /*
533  * Initialize context
534  */
535 void ecdsa_init( ecdsa_context *ctx )
536 {
537  ecp_group_init( &ctx->grp );
538  mpi_init( &ctx->d );
539  ecp_point_init( &ctx->Q );
540  mpi_init( &ctx->r );
541  mpi_init( &ctx->s );
542 }
543 
544 /*
545  * Free context
546  */
547 void ecdsa_free( ecdsa_context *ctx )
548 {
549  ecp_group_free( &ctx->grp );
550  mpi_free( &ctx->d );
551  ecp_point_free( &ctx->Q );
552  mpi_free( &ctx->r );
553  mpi_free( &ctx->s );
554 }
555 
556 #if defined(POLARSSL_SELF_TEST)
557 
558 /*
559  * Checkup routine
560  */
561 int ecdsa_self_test( int verbose )
562 {
563  ((void) verbose );
564  return( 0 );
565 }
566 
567 #endif
568 
569 #endif /* defined(POLARSSL_ECDSA_C) */
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.
Definition: ecp.h:35
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.
Definition: asn1.h:53
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...
Elliptic curve DSA.
ecp_group grp
Definition: ecp.h:161
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.
#define ASN1_SEQUENCE
Definition: asn1.h:78
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.
ECP group structure.
Definition: ecp.h:132
Configuration options (set of defines)
int ecdsa_self_test(int verbose)
Checkup routine.
ecp_group grp
Definition: ecdsa.h:43
#define ASN1_CONSTRUCTED
Definition: asn1.h:88
ECP key pair structure.
Definition: ecp.h:159
mpi d
Definition: ecp.h:162
MPI structure.
Definition: bignum.h:177
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.
mpi X
Definition: ecp.h:105
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 &gt;&gt;= count.
md_type_t
Definition: md.h:51
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.
Definition: ecp.h:38
ecp_point G
Definition: ecp.h:138
ECP point structure (jacobian coordinates)
Definition: ecp.h:103
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)
mpi N
Definition: ecp.h:139
int mpi_inv_mod(mpi *X, const mpi *A, const mpi *N)
Modular inverse: X = A^-1 mod N.
ECDSA context structure.
Definition: ecdsa.h:41
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.
ecp_point Q
Definition: ecdsa.h:45
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
Definition: ecp.h:174
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.
Definition: md.h:135
int ecp_copy(ecp_point *P, const ecp_point *Q)
Copy the contents of point Q into P.
t_uint * p
Definition: bignum.h:181
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.
Definition: ecp.h:56
#define ASN1_CHK_ADD(g, f)
Definition: asn1write.h:32
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.
size_t nbits
Definition: ecp.h:141
#define POLARSSL_MD_MAX_SIZE
Definition: md.h:67
#define POLARSSL_ERR_ECP_RANDOM_FAILED
Generation of random value, such as (ephemeral) key, failed.
Definition: ecp.h:40
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.
ecp_point Q
Definition: ecp.h:163
int size
Output length of the digest function.
Definition: md.h:82
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.
Definition: md.h:74
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.
Definition: md.h:130
#define MPI_CHK(f)
Definition: bignum.h:61
void ecp_point_free(ecp_point *pt)
Free the components of a point.