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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_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 */
75struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm = {
76 .name = "ecPublicKey",
78 .pubkey = &ecdsa_algorithm,
79};
80
81/** An ECDSA key */
82struct 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 */
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 */
141static int ecdsa_parse_key ( struct ecdsa_key *key,
142 const struct asn1_cursor *raw ) {
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 len Canonical length of "r"/"s", or negative error
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 uint8_t msb;
299 size_t len;
300 int rc;
301
302 /* Enter integer */
303 memcpy ( &cursor, raw, sizeof ( cursor ) );
304 if ( ( rc = asn1_enter_unsigned ( &cursor ) ) != 0 ) {
305 DBGC ( ctx, "ECDSA %p invalid integer:\n", ctx );
306 DBGC_HDA ( ctx, 0, raw->data, raw->len );
307 return rc;
308 }
309
310 /* Extract value */
311 if ( cursor.len > keysize ) {
312 DBGC ( ctx, "ECDSA %p invalid signature value:\n", ctx );
313 DBGC_HDA ( ctx, 0, raw->data, raw->len );
314 return -EINVAL_KEYSIZE;
315 }
316 bigint_init ( rs, cursor.data, cursor.len );
317
318 /* Check that value is within the required range */
319 if ( bigint_is_zero ( rs ) || bigint_is_geq ( rs, modulus ) ) {
320 DBGC ( ctx, "ECDSA %p out-of-range signature value:\n", ctx );
321 DBGC_HDA ( ctx, 0, raw->data, raw->len );
322 return -ERANGE;
323 }
324
325 /* Calculate canonical length */
326 msb = *( ( const uint8_t * ) cursor.data );
327 len = ( cursor.len + ( ( msb & 0x80 ) ? 1 : 0 ) );
328 len += asn1_header_len ( len );
329
330 return len;
331}
332
333/**
334 * Prepend ECDSA signature value
335 *
336 * @v ctx ECDSA context
337 * @v rs0 Element 0 of signature "r" or "s" value
338 * @v builder ASN.1 builder
339 * @ret rc Return status code
340 */
342 bigint_element_t *rs0,
343 struct asn1_builder *builder ) {
344 size_t keysize = ctx->key.curve->keysize;
345 unsigned int size = ctx->size;
346 bigint_t ( size ) __attribute__ (( may_alias )) *rs =
347 ( ( void * ) rs0 );
348 uint8_t buf[ 1 /* potential sign byte */ + keysize ];
349 uint8_t *data;
350 size_t len;
351 int rc;
352
353 /* Construct value */
354 buf[0] = 0;
355 bigint_done ( rs, &buf[1], keysize );
356
357 /* Strip leading zeros */
358 data = buf;
359 len = sizeof ( buf );
360 while ( ( len > 1 ) && ( data[0] == 0 ) && ( data[1] < 0x80 ) ) {
361 data++;
362 len--;
363 }
364
365 /* Prepend integer */
366 if ( ( rc = asn1_prepend ( builder, ASN1_INTEGER, data, len ) ) != 0 )
367 return rc;
368
369 return 0;
370}
371
372/**
373 * Allocate ECDSA context dynamic storage
374 *
375 * @v ctx ECDSA context
376 * @ret rc Return status code
377 */
378static int ecdsa_alloc ( struct ecdsa_context *ctx ) {
379 struct elliptic_curve *curve = ctx->key.curve;
380 size_t pointsize = curve->pointsize;
381 size_t keysize = curve->keysize;
382 unsigned int size =
383 bigint_required_size ( keysize + 1 /* for addition */ );
384 struct {
385 bigint_t ( size ) modulus;
386 bigint_t ( size ) fermat;
387 bigint_t ( size ) square;
388 bigint_t ( size ) one;
389 bigint_t ( size ) z;
390 bigint_t ( size ) k;
391 bigint_t ( size ) r;
392 bigint_t ( size ) s;
393 bigint_t ( size ) temp;
394 bigint_t ( size * 2 ) product;
395 uint8_t point1[pointsize];
396 uint8_t point2[pointsize];
397 uint8_t scalar[keysize];
398 struct hmac_drbg_state drbg;
399 } *dynamic;
400
401 /* Allocate dynamic storage */
402 dynamic = malloc ( sizeof ( *dynamic ) );
403 if ( ! dynamic )
404 return -ENOMEM;
405
406 /* Populate context */
407 ctx->size = size;
408 ctx->dynamic = dynamic;
409 ctx->modulus0 = dynamic->modulus.element;
410 ctx->fermat0 = dynamic->fermat.element;
411 ctx->square0 = dynamic->square.element;
412 ctx->one0 = dynamic->one.element;
413 ctx->z0 = dynamic->z.element;
414 ctx->k0 = dynamic->k.element;
415 ctx->r0 = dynamic->r.element;
416 ctx->s0 = dynamic->s.element;
417 ctx->temp0 = dynamic->temp.element;
418 ctx->product0 = dynamic->product.element;
419 ctx->point1 = dynamic->point1;
420 ctx->point2 = dynamic->point2;
421 ctx->scalar = dynamic->scalar;
422 ctx->drbg = &dynamic->drbg;
423
424 return 0;
425}
426
427/**
428 * Free ECDSA context dynamic storage
429 *
430 * @v ctx ECDSA context
431 */
432static void ecdsa_free ( struct ecdsa_context *ctx ) {
433
434 /* Free dynamic storage */
435 zfree ( ctx->dynamic );
436}
437
438/**
439 * Initialise ECDSA values
440 *
441 * @v ctx ECDSA context
442 * @v digest Digest algorithm
443 * @v value Digest value
444 */
445static void ecdsa_init_values ( struct ecdsa_context *ctx,
446 struct digest_algorithm *digest,
447 const void *value ) {
448 struct elliptic_curve *curve = ctx->key.curve;
449 unsigned int size = ctx->size;
450 bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
451 ( ( void * ) ctx->modulus0 );
452 bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
453 ( ( void * ) ctx->fermat0 );
454 bigint_t ( size ) __attribute__ (( may_alias )) *square =
455 ( ( void * ) ctx->square0 );
456 bigint_t ( size ) __attribute__ (( may_alias )) *one =
457 ( ( void * ) ctx->one0 );
458 bigint_t ( size ) __attribute__ (( may_alias )) *z =
459 ( ( void * ) ctx->z0 );
460 bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
461 ( ( void * ) ctx->product0 );
462 static const uint8_t two_raw[] = { 2 };
463 size_t zlen;
464
465 /* Initialise modulus N */
466 bigint_init ( modulus, curve->order, curve->keysize );
467 DBGC2 ( ctx, "ECDSA %p N = %s\n", ctx, bigint_ntoa ( modulus ) );
468
469 /* Calculate N-2 (using Montgomery constant as temporary buffer) */
470 bigint_copy ( modulus, fermat );
471 bigint_init ( square, two_raw, sizeof ( two_raw ) );
472 bigint_subtract ( square, fermat );
473
474 /* Calculate Montgomery constant */
475 bigint_reduce ( modulus, square );
476 DBGC2 ( ctx, "ECDSA %p R^2 = %s mod N\n",
477 ctx, bigint_ntoa ( square ) );
478
479 /* Construct one in Montgomery form */
480 bigint_grow ( square, product );
481 bigint_montgomery ( modulus, product, one );
482 DBGC2 ( ctx, "ECDSA %p R = %s mod N\n",
483 ctx, bigint_ntoa ( one ) );
484
485 /* Initialise digest */
486 ctx->digest = digest;
487 zlen = ctx->key.curve->keysize;
488 if ( zlen > digest->digestsize )
489 zlen = digest->digestsize;
490 ctx->zlen = zlen;
491 bigint_init ( z, value, zlen );
492 DBGC2 ( ctx, "ECDSA %p z = %s (%s)\n",
493 ctx, bigint_ntoa ( z ), digest->name );
494}
495
496/**
497 * Initialise ECDSA context
498 *
499 * @v ctx ECDSA context
500 * @v key Key
501 * @v digest Digest algorithm
502 * @v value Digest value
503 * @ret rc Return status code
504 */
505static int ecdsa_init ( struct ecdsa_context *ctx,
506 const struct asn1_cursor *key,
507 struct digest_algorithm *digest,
508 const void *value ) {
509 int rc;
510
511 /* Parse key */
512 if ( ( rc = ecdsa_parse_key ( &ctx->key, key ) ) != 0 )
513 goto err_parse;
514
515 /* Allocate dynamic storage */
516 if ( ( rc = ecdsa_alloc ( ctx ) ) != 0 )
517 goto err_alloc;
518
519 /* Initialise values */
520 ecdsa_init_values ( ctx, digest, value );
521
522 return 0;
523
524 ecdsa_free ( ctx );
525 err_alloc:
526 err_parse:
527 return rc;
528}
529
530/**
531 * Invert ECDSA value
532 *
533 * @v ctx ECDSA context
534 * @v val0 Element 0 of value to invert
535 */
536static void ecdsa_invert ( struct ecdsa_context *ctx,
537 bigint_element_t *val0 ) {
538 unsigned int size = ctx->size;
539 bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
540 ( ( void * ) ctx->modulus0 );
541 bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
542 ( ( void * ) ctx->fermat0 );
543 bigint_t ( size ) __attribute__ (( may_alias )) *square =
544 ( ( void * ) ctx->square0 );
545 bigint_t ( size ) __attribute__ (( may_alias )) *one =
546 ( ( void * ) ctx->one0 );
547 bigint_t ( size ) __attribute__ (( may_alias )) *temp =
548 ( ( void * ) ctx->temp0 );
549 bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
550 ( ( void * ) ctx->product0 );
551 bigint_t ( size ) __attribute__ (( may_alias )) *val =
552 ( ( void * ) val0 );
553
554 /* Convert value to Montgomery form */
555 bigint_multiply ( val, square, product );
556 bigint_montgomery ( modulus, product, temp );
557
558 /* Invert value via Fermat's little theorem */
559 bigint_copy ( one, val );
560 bigint_ladder ( val, temp, fermat, bigint_mod_exp_ladder, modulus,
561 product );
562}
563
564/**
565 * Generate ECDSA "r" and "s" values
566 *
567 * @v ctx ECDSA context
568 * @v sig Signature
569 * @ret rc Return status code
570 */
571static int ecdsa_sign_rs ( struct ecdsa_context *ctx ) {
572 struct digest_algorithm *digest = ctx->digest;
573 struct elliptic_curve *curve = ctx->key.curve;
574 size_t pointsize = curve->pointsize;
575 size_t keysize = curve->keysize;
576 unsigned int size = ctx->size;
577 bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
578 ( ( void * ) ctx->modulus0 );
579 bigint_t ( size ) __attribute__ (( may_alias )) *square =
580 ( ( void * ) ctx->square0 );
581 bigint_t ( size ) __attribute__ (( may_alias )) *one =
582 ( ( void * ) ctx->one0 );
583 bigint_t ( size ) __attribute__ (( may_alias )) *z =
584 ( ( void * ) ctx->z0 );
585 bigint_t ( size ) __attribute__ (( may_alias )) *k =
586 ( ( void * ) ctx->k0 );
587 bigint_t ( size ) __attribute__ (( may_alias )) *r =
588 ( ( void * ) ctx->r0 );
589 bigint_t ( size ) __attribute__ (( may_alias )) *s =
590 ( ( void * ) ctx->s0 );
591 bigint_t ( size ) __attribute__ (( may_alias )) *temp =
592 ( ( void * ) ctx->temp0 );
593 bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
594 ( ( void * ) ctx->product0 );
595 bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
596 ( ( void * ) temp );
597 void *point1 = ctx->point1;
598 void *scalar = ctx->scalar;
599 int rc;
600
601 /* Loop until a suitable signature is generated */
602 while ( 1 ) {
603
604 /* Generate pseudo-random data */
605 if ( ( rc = hmac_drbg_generate ( digest, ctx->drbg, NULL, 0,
606 scalar, keysize ) ) != 0 ) {
607 DBGC ( ctx, "ECDSA %p could not generate: %s\n",
608 ctx, strerror ( rc ) );
609 return rc;
610 }
611
612 /* Check suitability of pseudo-random data */
613 bigint_init ( k, scalar, keysize );
614 DBGC2 ( ctx, "ECDSA %p k = %s\n",
615 ctx, bigint_ntoa ( k ) );
616 if ( bigint_is_zero ( k ) )
617 continue;
618 if ( bigint_is_geq ( k, modulus ) )
619 continue;
620
621 /* Calculate (x1,y1) = k*G */
622 elliptic_multiply ( curve, curve->base, scalar, point1 );
623 bigint_init ( x1, point1, ( pointsize / 2 ) );
624 DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n",
625 ctx, bigint_ntoa ( x1 ) );
626
627 /* Calculate r = x1 mod N */
628 bigint_multiply ( x1, one, product );
629 bigint_montgomery ( modulus, product, r );
630 DBGC2 ( ctx, "ECDSA %p r = %s\n",
631 ctx, bigint_ntoa ( r ) );
632
633 /* Check suitability of r */
634 if ( bigint_is_zero ( r ) )
635 continue;
636
637 /* Calculate k^-1 mod N (in Montgomery form) */
638 ecdsa_invert ( ctx, k->element );
639 DBGC2 ( ctx, "ECDSA %p (k^-1)R = %s mod N\n",
640 ctx, bigint_ntoa ( k ) );
641
642 /* Calculate r * dA */
643 bigint_init ( temp, ctx->key.private, keysize );
644 DBGC2 ( ctx, "ECDSA %p dA = %s\n",
645 ctx, bigint_ntoa ( temp ) );
646 bigint_multiply ( r, temp, product );
647 bigint_montgomery ( modulus, product, temp );
648 bigint_multiply ( temp, square, product );
649 bigint_montgomery ( modulus, product, temp );
650 DBGC2 ( ctx, "ECDSA %p r*dA = %s mod N\n",
651 ctx, bigint_ntoa ( temp ) );
652
653 /* Calculate k^-1 * (z + r*dA) */
654 bigint_add ( z, temp );
655 DBGC2 ( ctx, "ECDSA %p z+r*dA = %s mod N\n",
656 ctx, bigint_ntoa ( temp ) );
657 bigint_multiply ( k, temp, product );
658 bigint_montgomery ( modulus, product, s );
659 DBGC2 ( ctx, "ECDSA %p s = %s\n",
660 ctx, bigint_ntoa ( s ) );
661
662 /* Check suitability of s */
663 if ( bigint_is_zero ( s ) )
664 continue;
665
666 return 0;
667 }
668}
669
670/**
671 * Verify ECDSA "r" and "s" values
672 *
673 * @v ctx ECDSA context
674 * @v sig Signature
675 * @ret rc Return status code
676 */
677static int ecdsa_verify_rs ( struct ecdsa_context *ctx ) {
678 struct elliptic_curve *curve = ctx->key.curve;
679 size_t pointsize = curve->pointsize;
680 size_t keysize = curve->keysize;
681 const void *public = ctx->key.public;
682 unsigned int size = ctx->size;
683 bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
684 ( ( void * ) ctx->modulus0 );
685 bigint_t ( size ) __attribute__ (( may_alias )) *one =
686 ( ( void * ) ctx->one0 );
687 bigint_t ( size ) __attribute__ (( may_alias )) *z =
688 ( ( void * ) ctx->z0 );
689 bigint_t ( size ) __attribute__ (( may_alias )) *r =
690 ( ( void * ) ctx->r0 );
691 bigint_t ( size ) __attribute__ (( may_alias )) *s =
692 ( ( void * ) ctx->s0 );
693 bigint_t ( size ) __attribute__ (( may_alias )) *temp =
694 ( ( void * ) ctx->temp0 );
695 bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
696 ( ( void * ) ctx->product0 );
697 bigint_t ( size ) __attribute__ (( may_alias )) *u1 =
698 ( ( void * ) temp );
699 bigint_t ( size ) __attribute__ (( may_alias )) *u2 =
700 ( ( void * ) temp );
701 bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
702 ( ( void * ) temp );
703 void *point1 = ctx->point1;
704 void *point2 = ctx->point2;
705 void *scalar = ctx->scalar;
706 int valid;
707 int rc;
708
709 DBGC2 ( ctx, "ECDSA %p r = %s\n", ctx, bigint_ntoa ( r ) );
710 DBGC2 ( ctx, "ECDSA %p s = %s\n", ctx, bigint_ntoa ( s ) );
711
712 /* Calculate s^-1 mod N (in Montgomery form) */
713 ecdsa_invert ( ctx, s->element );
714 DBGC2 ( ctx, "ECDSA %p (s^-1)R = %s mod N\n", ctx, bigint_ntoa ( s ) );
715
716 /* Calculate u1 = (z * s^-1) mod N */
717 bigint_multiply ( z, s, product );
718 bigint_montgomery ( modulus, product, u1 );
719 DBGC2 ( ctx, "ECDSA %p u1 = %s mod N\n",
720 ctx, bigint_ntoa ( u1 ) );
721 bigint_done ( u1, scalar, keysize );
722
723 /* Calculate u1 * G */
724 if ( ( rc = elliptic_multiply ( curve, curve->base, scalar,
725 point1 ) ) != 0 ) {
726 DBGC ( ctx, "ECDSA %p could not calculate u1*G: %s\n",
727 ctx, strerror ( rc ) );
728 return rc;
729 }
730
731 /* Calculate u2 = (r * s^-1) mod N */
732 bigint_multiply ( r, s, product );
733 bigint_montgomery ( modulus, product, u2 );
734 bigint_done ( u2, scalar, keysize );
735 DBGC2 ( ctx, "ECDSA %p u2 = %s mod N\n",
736 ctx, bigint_ntoa ( u2 ) );
737
738 /* Calculate u2 * Qa */
739 if ( ( rc = elliptic_multiply ( curve, public, scalar,
740 point2 ) ) != 0 ) {
741 DBGC ( ctx, "ECDSA %p could not calculate u2*Qa: %s\n",
742 ctx, strerror ( rc ) );
743 return rc;
744 }
745
746 /* Calculate u1 * G + u2 * Qa */
747 if ( ( rc = elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
748 DBGC ( ctx, "ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
749 ctx, strerror ( rc ) );
750 return rc;
751 }
752
753 /* Check that result is not the point at infinity */
754 if ( elliptic_is_infinity ( curve, point1 ) ) {
755 DBGC ( ctx, "ECDSA %p result is point at infinity\n", ctx );
756 return -EINVAL;
757 }
758
759 /* Calculate x1 mod N */
760 bigint_init ( x1, point1, ( pointsize / 2 ) );
761 DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n", ctx, bigint_ntoa ( x1 ) );
762 bigint_multiply ( x1, one, product );
763 bigint_montgomery ( modulus, product, x1 );
764 DBGC2 ( ctx, "ECDSA %p x1 = %s\n", ctx, bigint_ntoa ( x1 ) );
765
766 /* Check signature */
767 bigint_subtract ( x1, r );
768 valid = bigint_is_zero ( r );
769 DBGC2 ( ctx, "ECDSA %p signature is%s valid\n",
770 ctx, ( valid ? "" : " not" ) );
771
772 return ( valid ? 0 : -EINVAL_SIGNATURE );
773}
774
775/**
776 * Sign digest value using ECDSA
777 *
778 * @v pubkey Public-key algorithm
779 * @v key Key
780 * @v digest Digest algorithm
781 * @v value Digest value
782 * @v signature Signature
783 * @ret rc Return status code
784 */
785static int ecdsa_sign ( struct pubkey_algorithm *pubkey __unused,
786 const struct asn1_cursor *key,
787 struct digest_algorithm *digest, const void *value,
788 struct asn1_builder *signature ) {
789 struct ecdsa_context ctx;
790 int rc;
791
792 /* Initialise context */
793 if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
794 goto err_init;
795
796 /* Fail unless we have a private key */
797 if ( ! ctx.key.private ) {
798 rc = -ENOTTY;
799 goto err_no_key;
800 }
801
802 /* Instantiate DRBG */
803 hmac_drbg_instantiate ( digest, ctx.drbg, ctx.key.private,
804 ctx.key.curve->keysize, value, ctx.zlen );
805
806 /* Create signature */
807 if ( ( rc = ecdsa_sign_rs ( &ctx ) ) != 0 )
808 goto err_signature;
809
810 /* Construct "r" and "s" values */
811 if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.s0, signature ) ) != 0)
812 goto err_s;
813 if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.r0, signature ) ) != 0)
814 goto err_r;
815 if ( ( rc = asn1_wrap ( signature, ASN1_SEQUENCE ) ) != 0 )
816 goto err_wrap;
817
818 /* Free context */
819 ecdsa_free ( &ctx );
820
821 return 0;
822
823 err_wrap:
824 err_r:
825 err_s:
826 err_signature:
827 err_no_key:
828 ecdsa_free ( &ctx );
829 err_init:
830 return rc;
831}
832
833/**
834 * Verify signed digest using ECDSA
835 *
836 * @v pubkey Public-key algorithm
837 * @v key Key
838 * @v digest Digest algorithm
839 * @v value Digest value
840 * @v signature Signature
841 * @ret rc Return status code
842 */
843static int ecdsa_verify ( struct pubkey_algorithm *pubkey __unused,
844 const struct asn1_cursor *key,
845 struct digest_algorithm *digest, const void *value,
846 const struct asn1_cursor *signature ) {
847 struct ecdsa_context ctx;
848 struct asn1_cursor cursor;
849 int rlen;
850 int slen;
851 size_t len;
852 int rc;
853
854 /* Initialise context */
855 if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
856 goto err_init;
857
858 /* Enter sequence */
859 memcpy ( &cursor, signature, sizeof ( cursor ) );
860 asn1_enter ( &cursor, ASN1_SEQUENCE );
861
862 /* Extract "r" and "s" values */
863 if ( ( rlen = ecdsa_parse_signature ( &ctx, ctx.r0, &cursor ) ) < 0 ) {
864 rc = rlen;
865 goto err_parse;
866 }
867 asn1_skip_any ( &cursor );
868 if ( ( slen = ecdsa_parse_signature ( &ctx, ctx.s0, &cursor ) ) < 0 ) {
869 rc = slen;
870 goto err_parse;
871 }
872
873 /* Check for any extraneous content in signature */
874 len = ( rlen + slen );
875 len += asn1_header_len ( len );
876 if ( len != signature->len ) {
877 DBGC ( &ctx, "ECDSA %p non-canonical signature:\n", &ctx );
878 DBGC_HDA ( &ctx, 0, signature->data, signature->len );
880 goto err_parse;
881 }
882
883 /* Verify signature */
884 if ( ( rc = ecdsa_verify_rs ( &ctx ) ) != 0 )
885 goto err_verify;
886
887 /* Free context */
888 ecdsa_free ( &ctx );
889
890 return 0;
891
892 err_verify:
893 err_parse:
894 ecdsa_free ( &ctx );
895 err_init:
896 return rc;
897}
898
899/**
900 * Check for matching ECDSA public/private key pair
901 *
902 * @v pubkey Public-key algorithm
903 * @v private_key Private key
904 * @v public_key Public key
905 * @ret rc Return status code
906 */
907static int ecdsa_match ( struct pubkey_algorithm *pubkey __unused,
908 const struct asn1_cursor *private_key,
909 const struct asn1_cursor *public_key ) {
910 struct elliptic_curve *curve;
911 struct ecdsa_key private;
912 struct ecdsa_key public;
913 int rc;
914
915 /* Parse keys */
916 if ( ( rc = ecdsa_parse_key ( &private, private_key ) ) != 0 )
917 return rc;
918 if ( ( rc = ecdsa_parse_key ( &public, public_key ) ) != 0 )
919 return rc;
920
921 /* Compare curves */
922 if ( private.curve != public.curve )
923 return -ENOTTY;
924 curve = private.curve;
925
926 /* Compare public curve points */
927 if ( memcmp ( private.public, public.public, curve->pointsize ) != 0 )
928 return -ENOTTY;
929
930 return 0;
931}
932
933/** ECDSA public-key algorithm */
935 .name = "ecdsa",
936 .encrypt = pubkey_null_encrypt,
937 .decrypt = pubkey_null_decrypt,
938 .sign = ecdsa_sign,
939 .verify = ecdsa_verify,
940 .match = ecdsa_match,
941};
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct golan_eq_context ctx
Definition CIB_PRM.h:0
__be32 raw[7]
Definition CIB_PRM.h:0
u8 signature
CPU signature.
Definition CIB_PRM.h:7
union @162305117151260234136356364136041353210355154177 key
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned char uint8_t
Definition stdint.h:10
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:15
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:1092
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition asn1.c:459
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:382
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:767
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:261
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition asn1.c:372
size_t asn1_header_len(size_t len)
Calculate ASN.1 header length.
Definition asn1.c:1023
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition asn1.c:323
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition asn1.c:403
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition asn1.c:1119
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition asn1.h:102
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition asn1.h:494
#define __asn1_algorithm
Declare an ASN.1 OID-identified algorithm.
Definition asn1.h:457
#define ASN1_OID_ECPUBLICKEY
ASN.1 OID for ecPublicKey (1.2.840.10045.2.1).
Definition asn1.h:135
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition asn1.h:423
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:93
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:505
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:854
int pubkey_null_decrypt(struct pubkey_algorithm *pubkey __unused, const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused)
int pubkey_null_encrypt(struct pubkey_algorithm *pubkey __unused, const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused)
ring len
Length.
Definition dwmac.h:226
#define EINVAL_INFINITY
Definition ecdsa.c:58
static int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
Definition ecdsa.c:677
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition ecdsa.c:141
#define EINVAL_POINTSIZE
Definition ecdsa.c:46
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
Definition ecdsa.c:445
#define EINVAL_COMPRESSION
Definition ecdsa.c:54
static int ecdsa_match(struct pubkey_algorithm *pubkey __unused, const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching ECDSA public/private key pair.
Definition ecdsa.c:907
static int ecdsa_alloc(struct ecdsa_context *ctx)
Allocate ECDSA context dynamic storage.
Definition ecdsa.c:378
#define EINVAL_SIGNATURE
Definition ecdsa.c:62
struct pubkey_algorithm ecdsa_algorithm
ECDSA public-key algorithm.
Definition ecdsa.c:934
#define EINVAL_KEYSIZE
Definition ecdsa.c:50
static int ecdsa_sign_rs(struct ecdsa_context *ctx)
Generate ECDSA "r" and "s" values.
Definition ecdsa.c:571
static int ecdsa_sign(struct pubkey_algorithm *pubkey __unused, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Sign digest value using ECDSA.
Definition ecdsa.c:785
static int ecdsa_prepend_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, struct asn1_builder *builder)
Prepend ECDSA signature value.
Definition ecdsa.c:341
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:505
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
Definition ecdsa.c:68
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition ecdsa.c:432
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
Definition ecdsa.c:536
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
static int ecdsa_verify(struct pubkey_algorithm *pubkey __unused, 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:843
Elliptic curve digital signature algorithm (ECDSA).
#define ECDSA_UNCOMPRESSED
Uncompressed curve point.
Definition ecdsa.h:16
uint8_t data[48]
Additional event data.
Definition ena.h:11
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define EINVAL
Invalid argument.
Definition errno.h:472
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ERANGE
Result too large.
Definition errno.h:683
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
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
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
HMAC_DRBG algorithm.
u16 algorithm
Authentication algorithm (Open System or Shared Key).
Definition ieee80211.h:1
#define __attribute__(x)
Definition compiler.h:10
Big integer support.
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:210
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition bigint.h:331
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition bigint.h:275
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:100
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition bigint.h:315
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:236
#define bigint_is_geq(value, reference)
Compare big integers.
Definition bigint.h:146
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition bigint.h:135
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:21
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:32
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition bigint.h:261
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:76
#define bigint_add(addend, value)
Add big integers.
Definition bigint.h:88
#define bigint_ntoa(value)
Transcribe big integer (for debugging).
Definition bigint.h:51
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:63
Cryptographic API.
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Definition crypto.h:419
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition crypto.h:414
static int elliptic_add(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
Definition crypto.h:425
uint8_t product
Product string.
Definition smbios.h:5
void __asmcall int val
Definition setjmp.h:12
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
void zfree(void *ptr)
Clear and free memory.
Definition malloc.c:738
static const uint8_t r[3][4]
MD4 shift amounts.
Definition md4.c:50
static const uint32_t k[64]
MD5 constants.
Definition md5.c:50
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
An ASN.1 OID-identified algorithm.
Definition asn1.h:429
An ASN.1 object builder.
Definition asn1.h:29
An ASN.1 object cursor.
Definition asn1.h:21
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
const char * name
Algorithm name.
Definition crypto.h:21
ECDSA context.
Definition ecdsa.c:92
void * dynamic
Dynamically allocated storage.
Definition ecdsa.c:103
bigint_element_t * s0
Element 0 of signature value "s".
Definition ecdsa.c:119
size_t zlen
Digest length.
Definition ecdsa.c:100
struct digest_algorithm * digest
Digest algorithm.
Definition ecdsa.c:98
bigint_element_t * z0
Element 0 of digest value "z".
Definition ecdsa.c:113
void * point1
Curve point 1.
Definition ecdsa.c:125
bigint_element_t * modulus0
Element 0 of modulus N (i.e.
Definition ecdsa.c:105
unsigned int size
Big integer size.
Definition ecdsa.c:96
bigint_element_t * product0
Element 0 of product buffer.
Definition ecdsa.c:123
bigint_element_t * temp0
Element 0 of temporary value.
Definition ecdsa.c:121
bigint_element_t * fermat0
Element 0 of constant N-2 (for Fermat's little theorem).
Definition ecdsa.c:107
struct ecdsa_key key
Key.
Definition ecdsa.c:94
bigint_element_t * r0
Element 0 of signature value "r".
Definition ecdsa.c:117
bigint_element_t * k0
Element 0 of random key "k".
Definition ecdsa.c:115
bigint_element_t * square0
Element 0 of Montgomery constant R^2 mod N.
Definition ecdsa.c:109
void * point2
Curve point 2.
Definition ecdsa.c:127
void * scalar
Scalar value.
Definition ecdsa.c:129
bigint_element_t * one0
Element 0 of constant 1 (in Montgomery form).
Definition ecdsa.c:111
struct hmac_drbg_state * drbg
HMAC_DRBG state for random value generation.
Definition ecdsa.c:131
An ECDSA key.
Definition ecdsa.c:82
struct elliptic_curve * curve
Elliptic curve.
Definition ecdsa.c:84
const void * private
Private multiple of base curve point (if applicable).
Definition ecdsa.c:88
const void * public
Public curve point.
Definition ecdsa.c:86
An elliptic curve.
Definition crypto.h:246
const void * order
Order of the generator (if prime).
Definition crypto.h:256
size_t keysize
Scalar (and private key) size.
Definition crypto.h:252
size_t pointsize
Point (and public key) size.
Definition crypto.h:250
const void * base
Generator base point.
Definition crypto.h:254
HMAC_DRBG internal state.
Definition hmac_drbg.h:219
A private key.
Definition privkey.h:17
A public key algorithm.
Definition crypto.h:142
u16 keysize
Length of encryption key to be used, network byte order.
Definition wpa.h:10