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" ) 76 .
name =
"ecPublicKey",
152 memcpy ( &cursor,
raw,
sizeof ( cursor ) );
170 DBGC (
key,
"ECDSA %p is in PKCS#8 format\n",
key );
173 memcpy ( &curve, &cursor,
sizeof ( curve ) );
187 memcpy ( &
private, &cursor,
sizeof (
private ) );
193 memcpy ( &curve, &cursor,
sizeof ( curve ) );
207 memcpy ( &curve, &cursor,
sizeof ( curve ) );
217 DBGC (
key,
"ECDSA %p unknown curve: %s\n",
224 key->curve->name, ( is_private ?
"private" :
"public" ) );
227 if ( cursor.
len != ( sizeof ( *compression ) +
228 key->curve->pointsize ) ) {
229 DBGC (
key,
"ECDSA %p invalid public key length %zd\n",
236 compression = cursor.
data;
238 DBGC (
key,
"ECDSA %p invalid compression %#02x\n",
245 key->public = ( cursor.
data +
sizeof ( *compression ) );
246 DBGC (
key,
"ECDSA %p public curve point:\n",
key );
251 DBGC (
key,
"ECDSA %p public curve point is infinity\n",
key );
259 if (
private.
len !=
key->curve->keysize ) {
260 DBGC (
key,
"ECDSA %p invalid private key length " 261 "%zd\n",
key,
private.
len );
267 key->private =
private.data;
268 DBGC (
key,
"ECDSA %p private multiplier:\n",
key );
294 ( (
void * )
ctx->modulus0 );
301 memcpy ( &cursor,
raw,
sizeof ( cursor ) );
303 DBGC (
ctx,
"ECDSA %p invalid integer:\n",
ctx );
310 DBGC (
ctx,
"ECDSA %p invalid signature value:\n",
ctx );
318 DBGC (
ctx,
"ECDSA %p out-of-range signature value:\n",
ctx );
352 len =
sizeof ( buf );
353 while ( (
len > 1 ) && (
data[0] == 0 ) && (
data[1] < 0x80 ) ) {
395 dynamic =
malloc (
sizeof ( *dynamic ) );
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;
440 const void *
value ) {
444 ( (
void * )
ctx->modulus0 );
446 ( (
void * )
ctx->fermat0 );
448 ( (
void * )
ctx->square0 );
450 ( (
void * )
ctx->one0 );
452 ( (
void * )
ctx->z0 );
454 ( (
void * )
ctx->product0 );
455 static const uint8_t two_raw[] = { 2 };
464 bigint_init ( square, two_raw,
sizeof ( two_raw ) );
469 DBGC2 (
ctx,
"ECDSA %p R^2 = %s mod N\n",
475 DBGC2 (
ctx,
"ECDSA %p R = %s mod N\n",
479 ctx->digest = digest;
480 zlen =
ctx->key.curve->keysize;
485 DBGC2 (
ctx,
"ECDSA %p z = %s (%s)\n",
501 const void *
value ) {
533 ( (
void * )
ctx->modulus0 );
535 ( (
void * )
ctx->fermat0 );
537 ( (
void * )
ctx->square0 );
539 ( (
void * )
ctx->one0 );
541 ( (
void * )
ctx->temp0 );
543 ( (
void * )
ctx->product0 );
571 ( (
void * )
ctx->modulus0 );
573 ( (
void * )
ctx->square0 );
575 ( (
void * )
ctx->one0 );
577 ( (
void * )
ctx->z0 );
579 ( (
void * )
ctx->k0 );
581 ( (
void * )
ctx->r0 );
583 ( (
void * )
ctx->s0 );
585 ( (
void * )
ctx->temp0 );
587 ( (
void * )
ctx->product0 );
590 void *point1 =
ctx->point1;
591 void *scalar =
ctx->scalar;
600 DBGC (
ctx,
"ECDSA %p could not generate: %s\n",
617 DBGC2 (
ctx,
"ECDSA %p x1 = %s mod N\n",
632 DBGC2 (
ctx,
"ECDSA %p (k^-1)R = %s mod N\n",
643 DBGC2 (
ctx,
"ECDSA %p r*dA = %s mod N\n",
648 DBGC2 (
ctx,
"ECDSA %p z+r*dA = %s mod N\n",
674 const void *
public =
ctx->key.public;
677 ( (
void * )
ctx->modulus0 );
679 ( (
void * )
ctx->one0 );
681 ( (
void * )
ctx->z0 );
683 ( (
void * )
ctx->r0 );
685 ( (
void * )
ctx->s0 );
687 ( (
void * )
ctx->temp0 );
689 ( (
void * )
ctx->product0 );
696 void *point1 =
ctx->point1;
697 void *point2 =
ctx->point2;
698 void *scalar =
ctx->scalar;
712 DBGC2 (
ctx,
"ECDSA %p u1 = %s mod N\n",
719 DBGC (
ctx,
"ECDSA %p could not calculate u1*G: %s\n",
728 DBGC2 (
ctx,
"ECDSA %p u2 = %s mod N\n",
734 DBGC (
ctx,
"ECDSA %p could not calculate u2*Qa: %s\n",
740 if ( (
rc =
elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
741 DBGC (
ctx,
"ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
748 DBGC (
ctx,
"ECDSA %p result is point at infinity\n",
ctx );
762 DBGC2 (
ctx,
"ECDSA %p signature is%s valid\n",
763 ctx, ( valid ?
"" :
" not" ) );
820 if ( !
ctx.key.private ) {
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.
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
#define EINVAL
Invalid argument.
bigint_element_t * temp0
Element 0 of temporary value.
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
An ASN.1 OID-identified algorithm.
struct arbelprm_rc_send_wqe rc
const void * public
Public curve point.
bigint_element_t * one0
Element 0 of constant 1 (in Montgomery form)
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
bigint_element_t * product0
Element 0 of product buffer.
const void * order
Order of the generator (if prime)
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
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.
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.
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
uint16_t size
Buffer size.
Elliptic curve digital signature algorithm (ECDSA)
struct elliptic_curve * curve
Elliptic curve.
const void * data
Start of data.
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
#define bigint_grow(source, dest)
Grow big integer.
static int ecdsa_parse_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, const struct asn1_cursor *raw)
Parse ECDSA signature value.
#define bigint_init(value, data, len)
Initialise big integer.
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.
struct golan_eq_context ctx
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
#define bigint_is_zero(value)
Test if big integer is equal to zero.
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
bigint_element_t * z0
Element 0 of digest value "z".
size_t zlen
Digest length.
size_t len
Length of data.
#define bigint_is_geq(value, reference)
Compare big integers.
#define ENOMEM
Not enough space.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct hmac_drbg_state * drbg
HMAC_DRBG state for random value generation.
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
bigint_element_t * r0
Element 0 of signature value "r".
pseudo_bit_t value[0x00020]
#define __unused
Declare a variable or data structure as unused.
#define bigint_copy(source, dest)
Copy big integer.
uint32_t bigint_element_t
Element of a big integer.
static int ecdsa_alloc(struct ecdsa_context *ctx)
Allocate ECDSA context dynamic storage.
#define EINVAL_COMPRESSION
#define bigint_done(value, out, len)
Finalise big integer.
bigint_element_t * k0
Element 0 of random key "k".
static int ecdsa_prepend_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, struct asn1_builder *builder)
Prepend ECDSA signature value.
size_t keysize
Scalar (and private key) size.
#define ERANGE
Result too large.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
static int ecdsa_decrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused)
Decrypt using ECDSA.
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
#define ECDSA_UNCOMPRESSED
Uncompressed curve point.
u16 keysize
Length of encryption key to be used, network byte order.
struct pubkey_algorithm ecdsa_algorithm
ECDSA public-key algorithm.
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
static const uint32_t k[64]
MD5 constants.
#define ASN1_SEQUENCE
ASN.1 sequence.
void * malloc(size_t size)
Allocate memory.
bigint_element_t * modulus0
Element 0 of modulus N (i.e.
void * point2
Curve point 2.
bigint_element_t * square0
Element 0 of Montgomery constant R^2 mod N.
#define ASN1_INTEGER
ASN.1 integer.
void * scalar
Scalar value.
static int elliptic_add(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
u16 algorithm
Authentication algorithm (Open System or Shared Key)
static int ecdsa_encrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused)
Encrypt using ECDSA.
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
HMAC_DRBG internal state.
#define ENOTTY
Inappropriate I/O control operation.
bigint_element_t * s0
Element 0 of signature value "s".
#define ASN1_OID_ECPUBLICKEY
ASN.1 OID for ecPublicKey (1.2.840.10045.2.1)
size_t digestsize
Digest size.
const char * name
Algorithm name.
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
static int ecdsa_init(struct ecdsa_context *ctx, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value)
Initialise ECDSA context.
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
A message digest algorithm.
uint8_t data[48]
Additional event data.
const void * base
Generator base point.
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
uint8_t product
Product string.
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
Generic elliptic curve container algorithm.
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
void * point1
Curve point 1.
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
#define bigint_subtract(subtrahend, value)
Subtract big integers.
size_t pointsize
Point (and public key) size.
#define ASN1_OCTET_STRING
ASN.1 octet string.
u8 signature
CPU signature.
#define bigint_add(addend, value)
Add big integers.
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define NULL
NULL pointer (VOID *)
static int ecdsa_sign_rs(struct ecdsa_context *ctx)
Generate ECDSA "r" and "s" values.
unsigned int size
Big integer size.
struct digest_algorithm * digest
Digest algorithm.
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.
const char * name
Algorithm name.
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
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.
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.
static const uint8_t r[3][4]
MD4 shift amounts.
static int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
static int ecdsa_match(const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching ECDSA public/private key pair.
bigint_element_t * fermat0
Element 0 of constant N-2 (for Fermat's little theorem)