iPXE
ecdsa.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 /** @file
28  *
29  * Elliptic curve digital signature algorithm (ECDSA)
30  *
31  * The elliptic curve public key format is documented in RFC 5480.
32  * The original private key format is documented in RFC 5915, and the
33  * generic container PKCS#8 format documented in RFC 5208.
34  *
35  */
36 
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <string.h>
40 #include <ipxe/crypto.h>
41 #include <ipxe/bigint.h>
42 #include <ipxe/hmac_drbg.h>
43 #include <ipxe/ecdsa.h>
44 
45 /* Disambiguate the various error causes */
46 #define EINVAL_POINTSIZE \
47  __einfo_error ( EINFO_EINVAL_POINTSIZE )
48 #define EINFO_EINVAL_POINTSIZE \
49  __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid point size" )
50 #define EINVAL_KEYSIZE \
51  __einfo_error ( EINFO_EINVAL_KEYSIZE )
52 #define EINFO_EINVAL_KEYSIZE \
53  __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid key size" )
54 #define EINVAL_COMPRESSION \
55  __einfo_error ( EINFO_EINVAL_COMPRESSION )
56 #define EINFO_EINVAL_COMPRESSION \
57  __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid compression")
58 #define EINVAL_INFINITY \
59  __einfo_error ( EINFO_EINVAL_INFINITY )
60 #define EINFO_EINVAL_INFINITY \
61  __einfo_uniqify ( EINFO_EINVAL, 0x04, "Point is infinity" )
62 #define EINVAL_SIGNATURE \
63  __einfo_error ( EINFO_EINVAL_SIGNATURE )
64 #define EINFO_EINVAL_SIGNATURE \
65  __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid signature" )
66 
67 /** "ecPublicKey" object identifier */
69 
70 /** Generic elliptic curve container algorithm
71  *
72  * The actual curve to be used is identified via the algorithm
73  * parameters, rather than the top-level OID.
74  */
75 struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm = {
76  .name = "ecPublicKey",
77  .oid = ASN1_CURSOR ( oid_ecpublickey ),
78  .pubkey = &ecdsa_algorithm,
79 };
80 
81 /** An ECDSA key */
82 struct ecdsa_key {
83  /** Elliptic curve */
85  /** Public curve point */
86  const void *public;
87  /** Private multiple of base curve point (if applicable) */
88  const void *private;
89 };
90 
91 /** ECDSA context */
92 struct ecdsa_context {
93  /** Key */
94  struct ecdsa_key key;
95  /** Big integer size */
96  unsigned int size;
97  /** Digest algorithm */
99  /** Digest length */
100  size_t zlen;
101 
102  /** Dynamically allocated storage */
103  void *dynamic;
104  /** Element 0 of modulus N (i.e. curve group order */
106  /** Element 0 of constant N-2 (for Fermat's little theorem) */
108  /** Element 0 of Montgomery constant R^2 mod N */
110  /** Element 0 of constant 1 (in Montgomery form) */
112  /** Element 0 of digest value "z" */
114  /** Element 0 of random key "k" */
116  /** Element 0 of signature value "r" */
118  /** Element 0 of signature value "s" */
120  /** Element 0 of temporary value */
122  /** Element 0 of product buffer */
124  /** Curve point 1 */
125  void *point1;
126  /** Curve point 2 */
127  void *point2;
128  /** Scalar value */
129  void *scalar;
130  /** HMAC_DRBG state for random value generation */
132 };
133 
134 /**
135  * Parse ECDSA key
136  *
137  * @v key ECDSA key
138  * @v raw ASN.1 cursor
139  * @ret rc Return status code
140  */
141 static int ecdsa_parse_key ( struct ecdsa_key *key,
142  const struct asn1_cursor *raw ) {
143  struct asn1_algorithm *algorithm;
144  struct asn1_cursor cursor;
145  struct asn1_cursor curve;
146  struct asn1_cursor private;
147  const uint8_t *compression;
148  int is_private;
149  int rc;
150 
151  /* Enter subjectPublicKeyInfo/ECPrivateKey */
152  memcpy ( &cursor, raw, sizeof ( cursor ) );
153  asn1_enter ( &cursor, ASN1_SEQUENCE );
154  asn1_invalidate_cursor ( &curve );
155  asn1_invalidate_cursor ( &private );
156 
157  /* Determine key format */
158  if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
159 
160  /* Private key */
161  is_private = 1;
162 
163  /* Skip version */
164  asn1_skip_any ( &cursor );
165 
166  /* Parse privateKeyAlgorithm, if present */
167  if ( asn1_type ( &cursor ) == ASN1_SEQUENCE ) {
168 
169  /* PKCS#8 format */
170  DBGC ( key, "ECDSA %p is in PKCS#8 format\n", key );
171 
172  /* Parse privateKeyAlgorithm */
173  memcpy ( &curve, &cursor, sizeof ( curve ) );
174  asn1_skip_any ( &cursor );
175 
176  /* Enter privateKey */
177  asn1_enter ( &cursor, ASN1_OCTET_STRING );
178 
179  /* Enter ECPrivateKey */
180  asn1_enter ( &cursor, ASN1_SEQUENCE );
181 
182  /* Skip version */
183  asn1_skip ( &cursor, ASN1_INTEGER );
184  }
185 
186  /* Parse privateKey */
187  memcpy ( &private, &cursor, sizeof ( private ) );
188  asn1_enter ( &private, ASN1_OCTET_STRING );
189  asn1_skip_any ( &cursor );
190 
191  /* Parse parameters, if present */
192  if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
193  memcpy ( &curve, &cursor, sizeof ( curve ) );
194  asn1_enter_any ( &curve );
195  asn1_skip_any ( &cursor );
196  }
197 
198  /* Enter publicKey */
199  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
200 
201  } else {
202 
203  /* Public key */
204  is_private = 0;
205 
206  /* Parse algorithm */
207  memcpy ( &curve, &cursor, sizeof ( curve ) );
208  asn1_skip_any ( &cursor );
209  }
210 
211  /* Enter publicKey */
212  asn1_enter_bits ( &cursor, NULL );
213 
214  /* Identify curve */
215  if ( ( rc = asn1_curve_algorithm ( &curve, &ecpubkey_algorithm,
216  &algorithm ) ) != 0 ) {
217  DBGC ( key, "ECDSA %p unknown curve: %s\n",
218  key, strerror ( rc ) );
219  DBGC_HDA ( key, 0, raw->data, raw->len );
220  return rc;
221  }
222  key->curve = algorithm->curve;
223  DBGC ( key, "ECDSA %p is a %s (%s) %s key\n", key, algorithm->name,
224  key->curve->name, ( is_private ? "private" : "public" ) );
225 
226  /* Check public key length */
227  if ( cursor.len != ( sizeof ( *compression ) +
228  key->curve->pointsize ) ) {
229  DBGC ( key, "ECDSA %p invalid public key length %zd\n",
230  key, cursor.len );
231  DBGC_HDA ( key, 0, raw->data, raw->len );
232  return -EINVAL_POINTSIZE;
233  }
234 
235  /* Check that key is uncompressed */
236  compression = cursor.data;
237  if ( *compression != ECDSA_UNCOMPRESSED ) {
238  DBGC ( key, "ECDSA %p invalid compression %#02x\n",
239  key, *compression );
240  DBGC_HDA ( key, 0, raw->data, raw->len );
241  return -EINVAL_COMPRESSION;
242  }
243 
244  /* Extract public curve point */
245  key->public = ( cursor.data + sizeof ( *compression ) );
246  DBGC ( key, "ECDSA %p public curve point:\n", key );
247  DBGC_HDA ( key, 0, key->public, key->curve->pointsize );
248 
249  /* Check that public key is not the point at infinity */
250  if ( elliptic_is_infinity ( key->curve, key->public ) ) {
251  DBGC ( key, "ECDSA %p public curve point is infinity\n", key );
252  return -EINVAL_INFINITY;
253  }
254 
255  /* Extract private key, if applicable */
256  if ( is_private ) {
257 
258  /* Check private key length */
259  if ( private.len != key->curve->keysize ) {
260  DBGC ( key, "ECDSA %p invalid private key length "
261  "%zd\n", key, private.len );
262  DBGC_HDA ( key, 0, raw->data, raw->len );
263  return -EINVAL_KEYSIZE;
264  }
265 
266  /* Extract private key */
267  key->private = private.data;
268  DBGC ( key, "ECDSA %p private multiplier:\n", key );
269  DBGC_HDA ( key, 0, key->private, key->curve->keysize );
270 
271  } else {
272 
273  /* No private key */
274  key->private = NULL;
275  }
276 
277  return 0;
278 }
279 
280 /**
281  * Parse ECDSA signature value
282  *
283  * @v ctx ECDSA context
284  * @v rs0 Element 0 of signature "r" or "s" value
285  * @v raw ASN.1 cursor
286  * @ret rc Return status code
287  */
289  bigint_element_t *rs0,
290  const struct asn1_cursor *raw ) {
291  size_t keysize = ctx->key.curve->keysize;
292  unsigned int size = ctx->size;
293  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
294  ( ( void * ) ctx->modulus0 );
295  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
296  ( ( void * ) rs0 );
297  struct asn1_cursor cursor;
298  int rc;
299 
300  /* Enter integer */
301  memcpy ( &cursor, raw, sizeof ( cursor ) );
302  if ( ( rc = asn1_enter_unsigned ( &cursor ) ) != 0 ) {
303  DBGC ( ctx, "ECDSA %p invalid integer:\n", ctx );
304  DBGC_HDA ( ctx, 0, raw->data, raw->len );
305  return rc;
306  }
307 
308  /* Extract value */
309  if ( cursor.len > keysize ) {
310  DBGC ( ctx, "ECDSA %p invalid signature value:\n", ctx );
311  DBGC_HDA ( ctx, 0, raw->data, raw->len );
312  return -EINVAL_KEYSIZE;
313  }
314  bigint_init ( rs, cursor.data, cursor.len );
315 
316  /* Check that value is within the required range */
317  if ( bigint_is_zero ( rs ) || bigint_is_geq ( rs, modulus ) ) {
318  DBGC ( ctx, "ECDSA %p out-of-range signature value:\n", ctx );
319  DBGC_HDA ( ctx, 0, raw->data, raw->len );
320  return -ERANGE;
321  }
322 
323  return 0;
324 }
325 
326 /**
327  * Prepend ECDSA signature value
328  *
329  * @v ctx ECDSA context
330  * @v rs0 Element 0 of signature "r" or "s" value
331  * @v builder ASN.1 builder
332  * @ret rc Return status code
333  */
335  bigint_element_t *rs0,
336  struct asn1_builder *builder ) {
337  size_t keysize = ctx->key.curve->keysize;
338  unsigned int size = ctx->size;
339  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
340  ( ( void * ) rs0 );
341  uint8_t buf[ 1 /* potential sign byte */ + keysize ];
342  uint8_t *data;
343  size_t len;
344  int rc;
345 
346  /* Construct value */
347  buf[0] = 0;
348  bigint_done ( rs, &buf[1], keysize );
349 
350  /* Strip leading zeros */
351  data = buf;
352  len = sizeof ( buf );
353  while ( ( len > 1 ) && ( data[0] == 0 ) && ( data[1] < 0x80 ) ) {
354  data++;
355  len--;
356  }
357 
358  /* Prepend integer */
359  if ( ( rc = asn1_prepend ( builder, ASN1_INTEGER, data, len ) ) != 0 )
360  return rc;
361 
362  return 0;
363 }
364 
365 /**
366  * Allocate ECDSA context dynamic storage
367  *
368  * @v ctx ECDSA context
369  * @ret rc Return status code
370  */
371 static int ecdsa_alloc ( struct ecdsa_context *ctx ) {
372  struct elliptic_curve *curve = ctx->key.curve;
373  size_t pointsize = curve->pointsize;
374  size_t keysize = curve->keysize;
375  unsigned int size =
376  bigint_required_size ( keysize + 1 /* for addition */ );
377  struct {
378  bigint_t ( size ) modulus;
379  bigint_t ( size ) fermat;
380  bigint_t ( size ) square;
381  bigint_t ( size ) one;
382  bigint_t ( size ) z;
383  bigint_t ( size ) k;
384  bigint_t ( size ) r;
385  bigint_t ( size ) s;
386  bigint_t ( size ) temp;
387  bigint_t ( size * 2 ) product;
388  uint8_t point1[pointsize];
389  uint8_t point2[pointsize];
390  uint8_t scalar[keysize];
391  struct hmac_drbg_state drbg;
392  } *dynamic;
393 
394  /* Allocate dynamic storage */
395  dynamic = malloc ( sizeof ( *dynamic ) );
396  if ( ! dynamic )
397  return -ENOMEM;
398 
399  /* Populate context */
400  ctx->size = size;
401  ctx->dynamic = dynamic;
402  ctx->modulus0 = dynamic->modulus.element;
403  ctx->fermat0 = dynamic->fermat.element;
404  ctx->square0 = dynamic->square.element;
405  ctx->one0 = dynamic->one.element;
406  ctx->z0 = dynamic->z.element;
407  ctx->k0 = dynamic->k.element;
408  ctx->r0 = dynamic->r.element;
409  ctx->s0 = dynamic->s.element;
410  ctx->temp0 = dynamic->temp.element;
411  ctx->product0 = dynamic->product.element;
412  ctx->point1 = dynamic->point1;
413  ctx->point2 = dynamic->point2;
414  ctx->scalar = dynamic->scalar;
415  ctx->drbg = &dynamic->drbg;
416 
417  return 0;
418 }
419 
420 /**
421  * Free ECDSA context dynamic storage
422  *
423  * @v ctx ECDSA context
424  */
425 static void ecdsa_free ( struct ecdsa_context *ctx ) {
426 
427  /* Free dynamic storage */
428  free ( ctx->dynamic );
429 }
430 
431 /**
432  * Initialise ECDSA values
433  *
434  * @v ctx ECDSA context
435  * @v digest Digest algorithm
436  * @v value Digest value
437  */
438 static void ecdsa_init_values ( struct ecdsa_context *ctx,
439  struct digest_algorithm *digest,
440  const void *value ) {
441  struct elliptic_curve *curve = ctx->key.curve;
442  unsigned int size = ctx->size;
443  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
444  ( ( void * ) ctx->modulus0 );
445  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
446  ( ( void * ) ctx->fermat0 );
447  bigint_t ( size ) __attribute__ (( may_alias )) *square =
448  ( ( void * ) ctx->square0 );
449  bigint_t ( size ) __attribute__ (( may_alias )) *one =
450  ( ( void * ) ctx->one0 );
451  bigint_t ( size ) __attribute__ (( may_alias )) *z =
452  ( ( void * ) ctx->z0 );
453  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
454  ( ( void * ) ctx->product0 );
455  static const uint8_t two_raw[] = { 2 };
456  size_t zlen;
457 
458  /* Initialise modulus N */
459  bigint_init ( modulus, curve->order, curve->keysize );
460  DBGC2 ( ctx, "ECDSA %p N = %s\n", ctx, bigint_ntoa ( modulus ) );
461 
462  /* Calculate N-2 (using Montgomery constant as temporary buffer) */
463  bigint_copy ( modulus, fermat );
464  bigint_init ( square, two_raw, sizeof ( two_raw ) );
465  bigint_subtract ( square, fermat );
466 
467  /* Calculate Montgomery constant */
468  bigint_reduce ( modulus, square );
469  DBGC2 ( ctx, "ECDSA %p R^2 = %s mod N\n",
470  ctx, bigint_ntoa ( square ) );
471 
472  /* Construct one in Montgomery form */
473  bigint_grow ( square, product );
474  bigint_montgomery ( modulus, product, one );
475  DBGC2 ( ctx, "ECDSA %p R = %s mod N\n",
476  ctx, bigint_ntoa ( one ) );
477 
478  /* Initialise digest */
479  ctx->digest = digest;
480  zlen = ctx->key.curve->keysize;
481  if ( zlen > digest->digestsize )
482  zlen = digest->digestsize;
483  ctx->zlen = zlen;
484  bigint_init ( z, value, zlen );
485  DBGC2 ( ctx, "ECDSA %p z = %s (%s)\n",
486  ctx, bigint_ntoa ( z ), digest->name );
487 }
488 
489 /**
490  * Initialise ECDSA context
491  *
492  * @v ctx ECDSA context
493  * @v key Key
494  * @v digest Digest algorithm
495  * @v value Digest value
496  * @ret rc Return status code
497  */
498 static int ecdsa_init ( struct ecdsa_context *ctx,
499  const struct asn1_cursor *key,
500  struct digest_algorithm *digest,
501  const void *value ) {
502  int rc;
503 
504  /* Parse key */
505  if ( ( rc = ecdsa_parse_key ( &ctx->key, key ) ) != 0 )
506  goto err_parse;
507 
508  /* Allocate dynamic storage */
509  if ( ( rc = ecdsa_alloc ( ctx ) ) != 0 )
510  goto err_alloc;
511 
512  /* Initialise values */
513  ecdsa_init_values ( ctx, digest, value );
514 
515  return 0;
516 
517  ecdsa_free ( ctx );
518  err_alloc:
519  err_parse:
520  return rc;
521 }
522 
523 /**
524  * Invert ECDSA value
525  *
526  * @v ctx ECDSA context
527  * @v val0 Element 0 of value to invert
528  */
529 static void ecdsa_invert ( struct ecdsa_context *ctx,
530  bigint_element_t *val0 ) {
531  unsigned int size = ctx->size;
532  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
533  ( ( void * ) ctx->modulus0 );
534  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
535  ( ( void * ) ctx->fermat0 );
536  bigint_t ( size ) __attribute__ (( may_alias )) *square =
537  ( ( void * ) ctx->square0 );
538  bigint_t ( size ) __attribute__ (( may_alias )) *one =
539  ( ( void * ) ctx->one0 );
540  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
541  ( ( void * ) ctx->temp0 );
542  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
543  ( ( void * ) ctx->product0 );
544  bigint_t ( size ) __attribute__ (( may_alias )) *val =
545  ( ( void * ) val0 );
546 
547  /* Convert value to Montgomery form */
548  bigint_multiply ( val, square, product );
549  bigint_montgomery ( modulus, product, temp );
550 
551  /* Invert value via Fermat's little theorem */
552  bigint_copy ( one, val );
553  bigint_ladder ( val, temp, fermat, bigint_mod_exp_ladder, modulus,
554  product );
555 }
556 
557 /**
558  * Generate ECDSA "r" and "s" values
559  *
560  * @v ctx ECDSA context
561  * @v sig Signature
562  * @ret rc Return status code
563  */
564 static int ecdsa_sign_rs ( struct ecdsa_context *ctx ) {
565  struct digest_algorithm *digest = ctx->digest;
566  struct elliptic_curve *curve = ctx->key.curve;
567  size_t pointsize = curve->pointsize;
568  size_t keysize = curve->keysize;
569  unsigned int size = ctx->size;
570  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
571  ( ( void * ) ctx->modulus0 );
572  bigint_t ( size ) __attribute__ (( may_alias )) *square =
573  ( ( void * ) ctx->square0 );
574  bigint_t ( size ) __attribute__ (( may_alias )) *one =
575  ( ( void * ) ctx->one0 );
576  bigint_t ( size ) __attribute__ (( may_alias )) *z =
577  ( ( void * ) ctx->z0 );
578  bigint_t ( size ) __attribute__ (( may_alias )) *k =
579  ( ( void * ) ctx->k0 );
580  bigint_t ( size ) __attribute__ (( may_alias )) *r =
581  ( ( void * ) ctx->r0 );
582  bigint_t ( size ) __attribute__ (( may_alias )) *s =
583  ( ( void * ) ctx->s0 );
584  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
585  ( ( void * ) ctx->temp0 );
586  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
587  ( ( void * ) ctx->product0 );
588  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
589  ( ( void * ) temp );
590  void *point1 = ctx->point1;
591  void *scalar = ctx->scalar;
592  int rc;
593 
594  /* Loop until a suitable signature is generated */
595  while ( 1 ) {
596 
597  /* Generate pseudo-random data */
598  if ( ( rc = hmac_drbg_generate ( digest, ctx->drbg, NULL, 0,
599  scalar, keysize ) ) != 0 ) {
600  DBGC ( ctx, "ECDSA %p could not generate: %s\n",
601  ctx, strerror ( rc ) );
602  return rc;
603  }
604 
605  /* Check suitability of pseudo-random data */
606  bigint_init ( k, scalar, keysize );
607  DBGC2 ( ctx, "ECDSA %p k = %s\n",
608  ctx, bigint_ntoa ( k ) );
609  if ( bigint_is_zero ( k ) )
610  continue;
611  if ( bigint_is_geq ( k, modulus ) )
612  continue;
613 
614  /* Calculate (x1,y1) = k*G */
615  elliptic_multiply ( curve, curve->base, scalar, point1 );
616  bigint_init ( x1, point1, ( pointsize / 2 ) );
617  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n",
618  ctx, bigint_ntoa ( x1 ) );
619 
620  /* Calculate r = x1 mod N */
621  bigint_multiply ( x1, one, product );
622  bigint_montgomery ( modulus, product, r );
623  DBGC2 ( ctx, "ECDSA %p r = %s\n",
624  ctx, bigint_ntoa ( r ) );
625 
626  /* Check suitability of r */
627  if ( bigint_is_zero ( r ) )
628  continue;
629 
630  /* Calculate k^-1 mod N (in Montgomery form) */
631  ecdsa_invert ( ctx, k->element );
632  DBGC2 ( ctx, "ECDSA %p (k^-1)R = %s mod N\n",
633  ctx, bigint_ntoa ( k ) );
634 
635  /* Calculate r * dA */
636  bigint_init ( temp, ctx->key.private, keysize );
637  DBGC2 ( ctx, "ECDSA %p dA = %s\n",
638  ctx, bigint_ntoa ( temp ) );
639  bigint_multiply ( r, temp, product );
640  bigint_montgomery ( modulus, product, temp );
641  bigint_multiply ( temp, square, product );
642  bigint_montgomery ( modulus, product, temp );
643  DBGC2 ( ctx, "ECDSA %p r*dA = %s mod N\n",
644  ctx, bigint_ntoa ( temp ) );
645 
646  /* Calculate k^-1 * (z + r*dA) */
647  bigint_add ( z, temp );
648  DBGC2 ( ctx, "ECDSA %p z+r*dA = %s mod N\n",
649  ctx, bigint_ntoa ( temp ) );
650  bigint_multiply ( k, temp, product );
651  bigint_montgomery ( modulus, product, s );
652  DBGC2 ( ctx, "ECDSA %p s = %s\n",
653  ctx, bigint_ntoa ( s ) );
654 
655  /* Check suitability of s */
656  if ( bigint_is_zero ( s ) )
657  continue;
658 
659  return 0;
660  }
661 }
662 
663 /**
664  * Verify ECDSA "r" and "s" values
665  *
666  * @v ctx ECDSA context
667  * @v sig Signature
668  * @ret rc Return status code
669  */
670 static int ecdsa_verify_rs ( struct ecdsa_context *ctx ) {
671  struct elliptic_curve *curve = ctx->key.curve;
672  size_t pointsize = curve->pointsize;
673  size_t keysize = curve->keysize;
674  const void *public = ctx->key.public;
675  unsigned int size = ctx->size;
676  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
677  ( ( void * ) ctx->modulus0 );
678  bigint_t ( size ) __attribute__ (( may_alias )) *one =
679  ( ( void * ) ctx->one0 );
680  bigint_t ( size ) __attribute__ (( may_alias )) *z =
681  ( ( void * ) ctx->z0 );
682  bigint_t ( size ) __attribute__ (( may_alias )) *r =
683  ( ( void * ) ctx->r0 );
684  bigint_t ( size ) __attribute__ (( may_alias )) *s =
685  ( ( void * ) ctx->s0 );
686  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
687  ( ( void * ) ctx->temp0 );
688  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
689  ( ( void * ) ctx->product0 );
690  bigint_t ( size ) __attribute__ (( may_alias )) *u1 =
691  ( ( void * ) temp );
692  bigint_t ( size ) __attribute__ (( may_alias )) *u2 =
693  ( ( void * ) temp );
694  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
695  ( ( void * ) temp );
696  void *point1 = ctx->point1;
697  void *point2 = ctx->point2;
698  void *scalar = ctx->scalar;
699  int valid;
700  int rc;
701 
702  DBGC2 ( ctx, "ECDSA %p r = %s\n", ctx, bigint_ntoa ( r ) );
703  DBGC2 ( ctx, "ECDSA %p s = %s\n", ctx, bigint_ntoa ( s ) );
704 
705  /* Calculate s^-1 mod N (in Montgomery form) */
706  ecdsa_invert ( ctx, s->element );
707  DBGC2 ( ctx, "ECDSA %p (s^-1)R = %s mod N\n", ctx, bigint_ntoa ( s ) );
708 
709  /* Calculate u1 = (z * s^-1) mod N */
710  bigint_multiply ( z, s, product );
711  bigint_montgomery ( modulus, product, u1 );
712  DBGC2 ( ctx, "ECDSA %p u1 = %s mod N\n",
713  ctx, bigint_ntoa ( u1 ) );
714  bigint_done ( u1, scalar, keysize );
715 
716  /* Calculate u1 * G */
717  if ( ( rc = elliptic_multiply ( curve, curve->base, scalar,
718  point1 ) ) != 0 ) {
719  DBGC ( ctx, "ECDSA %p could not calculate u1*G: %s\n",
720  ctx, strerror ( rc ) );
721  return rc;
722  }
723 
724  /* Calculate u2 = (r * s^-1) mod N */
725  bigint_multiply ( r, s, product );
726  bigint_montgomery ( modulus, product, u2 );
727  bigint_done ( u2, scalar, keysize );
728  DBGC2 ( ctx, "ECDSA %p u2 = %s mod N\n",
729  ctx, bigint_ntoa ( u2 ) );
730 
731  /* Calculate u2 * Qa */
732  if ( ( rc = elliptic_multiply ( curve, public, scalar,
733  point2 ) ) != 0 ) {
734  DBGC ( ctx, "ECDSA %p could not calculate u2*Qa: %s\n",
735  ctx, strerror ( rc ) );
736  return rc;
737  }
738 
739  /* Calculate u1 * G + u2 * Qa */
740  if ( ( rc = elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
741  DBGC ( ctx, "ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
742  ctx, strerror ( rc ) );
743  return rc;
744  }
745 
746  /* Check that result is not the point at infinity */
747  if ( elliptic_is_infinity ( curve, point1 ) ) {
748  DBGC ( ctx, "ECDSA %p result is point at infinity\n", ctx );
749  return -EINVAL;
750  }
751 
752  /* Calculate x1 mod N */
753  bigint_init ( x1, point1, ( pointsize / 2 ) );
754  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n", ctx, bigint_ntoa ( x1 ) );
755  bigint_multiply ( x1, one, product );
756  bigint_montgomery ( modulus, product, x1 );
757  DBGC2 ( ctx, "ECDSA %p x1 = %s\n", ctx, bigint_ntoa ( x1 ) );
758 
759  /* Check signature */
760  bigint_subtract ( x1, r );
761  valid = bigint_is_zero ( r );
762  DBGC2 ( ctx, "ECDSA %p signature is%s valid\n",
763  ctx, ( valid ? "" : " not" ) );
764 
765  return ( valid ? 0 : -EINVAL_SIGNATURE );
766 }
767 
768 /**
769  * Encrypt using ECDSA
770  *
771  * @v key Key
772  * @v plaintext Plaintext
773  * @v ciphertext Ciphertext
774  * @ret rc Return status code
775  */
776 static int ecdsa_encrypt ( const struct asn1_cursor *key __unused,
777  const struct asn1_cursor *plaintext __unused,
778  struct asn1_builder *ciphertext __unused ) {
779 
780  /* Not a defined operation for ECDSA */
781  return -ENOTTY;
782 }
783 
784 /**
785  * Decrypt using ECDSA
786  *
787  * @v key Key
788  * @v ciphertext Ciphertext
789  * @v plaintext Plaintext
790  * @ret rc Return status code
791  */
792 static int ecdsa_decrypt ( const struct asn1_cursor *key __unused,
793  const struct asn1_cursor *ciphertext __unused,
794  struct asn1_builder *plaintext __unused ) {
795 
796  /* Not a defined operation for ECDSA */
797  return -ENOTTY;
798 }
799 
800 /**
801  * Sign digest value using ECDSA
802  *
803  * @v key Key
804  * @v digest Digest algorithm
805  * @v value Digest value
806  * @v signature Signature
807  * @ret rc Return status code
808  */
809 static int ecdsa_sign ( const struct asn1_cursor *key,
810  struct digest_algorithm *digest, const void *value,
811  struct asn1_builder *signature ) {
812  struct ecdsa_context ctx;
813  int rc;
814 
815  /* Initialise context */
816  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
817  goto err_init;
818 
819  /* Fail unless we have a private key */
820  if ( ! ctx.key.private ) {
821  rc = -ENOTTY;
822  goto err_no_key;
823  }
824 
825  /* Instantiate DRBG */
826  hmac_drbg_instantiate ( digest, ctx.drbg, ctx.key.private,
827  ctx.key.curve->keysize, value, ctx.zlen );
828 
829  /* Create signature */
830  if ( ( rc = ecdsa_sign_rs ( &ctx ) ) != 0 )
831  goto err_signature;
832 
833  /* Construct "r" and "s" values */
834  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.s0, signature ) ) != 0)
835  goto err_s;
836  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.r0, signature ) ) != 0)
837  goto err_r;
838  if ( ( rc = asn1_wrap ( signature, ASN1_SEQUENCE ) ) != 0 )
839  goto err_wrap;
840 
841  /* Free context */
842  ecdsa_free ( &ctx );
843 
844  return 0;
845 
846  err_wrap:
847  err_r:
848  err_s:
849  err_signature:
850  err_no_key:
851  ecdsa_free ( &ctx );
852  err_init:
853  return rc;
854 }
855 
856 /**
857  * Verify signed digest using ECDSA
858  *
859  * @v key Key
860  * @v digest Digest algorithm
861  * @v value Digest value
862  * @v signature Signature
863  * @ret rc Return status code
864  */
865 static int ecdsa_verify ( const struct asn1_cursor *key,
866  struct digest_algorithm *digest, const void *value,
867  const struct asn1_cursor *signature ) {
868  struct ecdsa_context ctx;
869  struct asn1_cursor cursor;
870  int rc;
871 
872  /* Initialise context */
873  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
874  goto err_init;
875 
876  /* Enter sequence */
877  memcpy ( &cursor, signature, sizeof ( cursor ) );
878  asn1_enter ( &cursor, ASN1_SEQUENCE );
879 
880  /* Extract "r" and "s" values */
881  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.r0, &cursor ) ) != 0 )
882  goto err_r;
883  asn1_skip_any ( &cursor );
884  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.s0, &cursor ) ) != 0 )
885  goto err_s;
886 
887  /* Verify signature */
888  if ( ( rc = ecdsa_verify_rs ( &ctx ) ) != 0 )
889  goto err_verify;
890 
891  /* Free context */
892  ecdsa_free ( &ctx );
893 
894  return 0;
895 
896  err_verify:
897  err_s:
898  err_r:
899  ecdsa_free ( &ctx );
900  err_init:
901  return rc;
902 }
903 
904 /**
905  * Check for matching ECDSA public/private key pair
906  *
907  * @v private_key Private key
908  * @v public_key Public key
909  * @ret rc Return status code
910  */
911 static int ecdsa_match ( const struct asn1_cursor *private_key,
912  const struct asn1_cursor *public_key ) {
913  struct elliptic_curve *curve;
914  struct ecdsa_key privkey;
915  struct ecdsa_key pubkey;
916  int rc;
917 
918  /* Parse keys */
919  if ( ( rc = ecdsa_parse_key ( &privkey, private_key ) ) != 0 )
920  return rc;
921  if ( ( rc = ecdsa_parse_key ( &pubkey, public_key ) ) != 0 )
922  return rc;
923 
924  /* Compare curves */
925  if ( privkey.curve != pubkey.curve )
926  return -ENOTTY;
927  curve = privkey.curve;
928 
929  /* Compare public curve points */
930  if ( memcmp ( privkey.public, pubkey.public, curve->pointsize ) != 0 )
931  return -ENOTTY;
932 
933  return 0;
934 }
935 
936 /** ECDSA public-key algorithm */
938  .name = "ecdsa",
939  .encrypt = ecdsa_encrypt,
940  .decrypt = ecdsa_decrypt,
941  .sign = ecdsa_sign,
942  .verify = ecdsa_verify,
943  .match = ecdsa_match,
944 };
int hmac_drbg_generate(struct digest_algorithm *hash, struct hmac_drbg_state *state, const void *additional, size_t additional_len, void *data, size_t len)
Generate pseudorandom bits using HMAC_DRBG.
Definition: hmac_drbg.c:307
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:425
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition: ecdsa.c:141
#define __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:429
bigint_element_t * temp0
Element 0 of temporary value.
Definition: ecdsa.c:121
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition: asn1.c:369
An ASN.1 OID-identified algorithm.
Definition: asn1.h:408
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * public
Public curve point.
Definition: ecdsa.c:86
bigint_element_t * one0
Element 0 of constant 1 (in Montgomery form)
Definition: ecdsa.c:111
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Definition: crypto.h:327
bigint_element_t * product0
Element 0 of product buffer.
Definition: ecdsa.c:123
#define EINVAL_POINTSIZE
Definition: ecdsa.c:46
FILE_SECBOOT(PERMITTED)
const void * order
Order of the generator (if prime)
Definition: crypto.h:188
void __asmcall int val
Definition: setjmp.h:12
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:169
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition: crypto.h:322
Error codes.
void hmac_drbg_instantiate(struct digest_algorithm *hash, struct hmac_drbg_state *state, const void *entropy, size_t entropy_len, const void *personal, size_t personal_len)
Instantiate HMAC_DRBG.
Definition: hmac_drbg.c:207
static int ecdsa_sign(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Sign digest value using ECDSA.
Definition: ecdsa.c:809
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition: asn1.c:311
uint16_t size
Buffer size.
Definition: dwmac.h:14
Elliptic curve digital signature algorithm (ECDSA)
struct elliptic_curve * curve
Elliptic curve.
Definition: ecdsa.c:84
const void * data
Start of data.
Definition: asn1.h:23
#define DBGC(...)
Definition: compiler.h:505
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
Definition: ecdsa.c:529
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:209
static int ecdsa_parse_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, const struct asn1_cursor *raw)
Parse ECDSA signature value.
Definition: ecdsa.c:288
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
static int ecdsa_verify(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Verify signed digest using ECDSA.
Definition: ecdsa.c:865
Cryptographic API.
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:479
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:134
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:290
Big integer support.
bigint_element_t * z0
Element 0 of digest value "z".
Definition: ecdsa.c:113
size_t zlen
Digest length.
Definition: ecdsa.c:100
size_t len
Length of data.
Definition: asn1.h:25
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:145
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct hmac_drbg_state * drbg
HMAC_DRBG state for random value generation.
Definition: ecdsa.c:131
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:402
bigint_element_t * r0
Element 0 of signature value "r".
Definition: ecdsa.c:117
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define DBGC_HDA(...)
Definition: compiler.h:506
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
uint32_t bigint_element_t
Element of a big integer.
Definition: bigint.h:16
ring len
Length.
Definition: dwmac.h:231
struct ecdsa_key key
Key.
Definition: ecdsa.c:94
static int ecdsa_alloc(struct ecdsa_context *ctx)
Allocate ECDSA context dynamic storage.
Definition: ecdsa.c:371
#define EINVAL_COMPRESSION
Definition: ecdsa.c:54
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:75
bigint_element_t * k0
Element 0 of random key "k".
Definition: ecdsa.c:115
static int ecdsa_prepend_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, struct asn1_builder *builder)
Prepend ECDSA signature value.
Definition: ecdsa.c:334
ECDSA context.
Definition: ecdsa.c:92
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
#define ERANGE
Result too large.
Definition: errno.h:640
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:468
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:31
static int ecdsa_decrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused)
Decrypt using ECDSA.
Definition: ecdsa.c:792
An ASN.1 object builder.
Definition: asn1.h:29
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition: asn1.c:280
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
Definition: ecdsa.c:68
unsigned char uint8_t
Definition: stdint.h:10
#define ECDSA_UNCOMPRESSED
Uncompressed curve point.
Definition: ecdsa.h:16
#define EINVAL_SIGNATURE
Definition: ecdsa.c:62
#define EINVAL_INFINITY
Definition: ecdsa.c:58
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
struct pubkey_algorithm ecdsa_algorithm
ECDSA public-key algorithm.
Definition: ecdsa.c:937
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:999
static const uint32_t k[64]
MD5 constants.
Definition: md5.c:54
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:90
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
bigint_element_t * modulus0
Element 0 of modulus N (i.e.
Definition: ecdsa.c:105
void * point2
Curve point 2.
Definition: ecdsa.c:127
bigint_element_t * square0
Element 0 of Montgomery constant R^2 mod N.
Definition: ecdsa.c:109
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:63
void * scalar
Scalar value.
Definition: ecdsa.c:129
static int elliptic_add(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
Definition: crypto.h:333
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
const char * name
Name.
Definition: asn1.h:410
static int ecdsa_encrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused)
Encrypt using ECDSA.
Definition: ecdsa.c:776
An ECDSA key.
Definition: ecdsa.c:82
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
HMAC_DRBG internal state.
Definition: hmac_drbg.h:219
An elliptic curve.
Definition: crypto.h:178
#define DBGC2(...)
Definition: compiler.h:522
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
bigint_element_t * s0
Element 0 of signature value "s".
Definition: ecdsa.c:119
#define ASN1_OID_ECPUBLICKEY
ASN.1 OID for ecPublicKey (1.2.840.10045.2.1)
Definition: asn1.h:132
size_t digestsize
Digest size.
Definition: crypto.h:27
#define EINVAL_KEYSIZE
Definition: ecdsa.c:50
const char * name
Algorithm name.
Definition: crypto.h:21
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:231
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
Definition: asn1.c:972
static int ecdsa_init(struct ecdsa_context *ctx, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value)
Initialise ECDSA context.
Definition: ecdsa.c:498
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
A message digest algorithm.
Definition: crypto.h:19
uint8_t data[48]
Additional event data.
Definition: ena.h:22
A private key.
Definition: privkey.h:17
const void * base
Generator base point.
Definition: crypto.h:186
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition: bigint.h:274
uint8_t product
Product string.
Definition: smbios.h:17
__be32 raw[7]
Definition: CIB_PRM.h:28
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
Generic elliptic curve container algorithm.
Definition: ecdsa.c:75
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:330
void * point1
Curve point 1.
Definition: ecdsa.c:125
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:99
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
size_t pointsize
Point (and public key) size.
Definition: crypto.h:182
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:69
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:87
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static int ecdsa_sign_rs(struct ecdsa_context *ctx)
Generate ECDSA "r" and "s" values.
Definition: ecdsa.c:564
String functions.
unsigned int size
Big integer size.
Definition: ecdsa.c:96
An ASN.1 object cursor.
Definition: asn1.h:21
struct digest_algorithm * digest
Digest algorithm.
Definition: ecdsa.c:98
A public key algorithm.
Definition: crypto.h:122
union @391 key
Sense key.
Definition: scsi.h:18
int asn1_curve_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm *wrapper, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified elliptic curve algorithm.
Definition: asn1.c:659
const char * name
Algorithm name.
Definition: crypto.h:124
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
Definition: ecdsa.c:438
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void * dynamic
Dynamically allocated storage.
Definition: ecdsa.c:103
void bigint_mod_exp_ladder(const bigint_element_t *multiplier0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
Perform modular multiplication as part of a Montgomery ladder.
Definition: bigint.c:720
static const uint8_t r[3][4]
MD4 shift amounts.
Definition: md4.c:54
HMAC_DRBG algorithm.
static int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
Definition: ecdsa.c:670
static int ecdsa_match(const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching ECDSA public/private key pair.
Definition: ecdsa.c:911
bigint_element_t * fermat0
Element 0 of constant N-2 (for Fermat's little theorem)
Definition: ecdsa.c:107