45 #define EINVAL_POINTSIZE \ 46 __einfo_error ( EINFO_EINVAL_POINTSIZE ) 47 #define EINFO_EINVAL_POINTSIZE \ 48 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid point size" ) 49 #define EINVAL_KEYSIZE \ 50 __einfo_error ( EINFO_EINVAL_KEYSIZE ) 51 #define EINFO_EINVAL_KEYSIZE \ 52 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid key size" ) 53 #define EINVAL_COMPRESSION \ 54 __einfo_error ( EINFO_EINVAL_COMPRESSION ) 55 #define EINFO_EINVAL_COMPRESSION \ 56 __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid compression") 57 #define EINVAL_INFINITY \ 58 __einfo_error ( EINFO_EINVAL_INFINITY ) 59 #define EINFO_EINVAL_INFINITY \ 60 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Point is infinity" ) 61 #define EINVAL_SIGNATURE \ 62 __einfo_error ( EINFO_EINVAL_SIGNATURE ) 63 #define EINFO_EINVAL_SIGNATURE \ 64 __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid signature" ) 75 .
name =
"ecPublicKey",
151 memcpy ( &cursor,
raw,
sizeof ( cursor ) );
169 DBGC (
key,
"ECDSA %p is in PKCS#8 format\n",
key );
172 memcpy ( &curve, &cursor,
sizeof ( curve ) );
186 memcpy ( &
private, &cursor,
sizeof (
private ) );
192 memcpy ( &curve, &cursor,
sizeof ( curve ) );
206 memcpy ( &curve, &cursor,
sizeof ( curve ) );
216 DBGC (
key,
"ECDSA %p unknown curve: %s\n",
223 key->curve->name, ( is_private ?
"private" :
"public" ) );
226 if ( cursor.
len != ( sizeof ( *compression ) +
227 key->curve->pointsize ) ) {
228 DBGC (
key,
"ECDSA %p invalid public key length %zd\n",
235 compression = cursor.
data;
237 DBGC (
key,
"ECDSA %p invalid compression %#02x\n",
244 key->public = ( cursor.
data +
sizeof ( *compression ) );
245 DBGC (
key,
"ECDSA %p public curve point:\n",
key );
250 DBGC (
key,
"ECDSA %p public curve point is infinity\n",
key );
258 if (
private.
len !=
key->curve->keysize ) {
259 DBGC (
key,
"ECDSA %p invalid private key length " 260 "%zd\n",
key,
private.
len );
266 key->private =
private.data;
267 DBGC (
key,
"ECDSA %p private multiplier:\n",
key );
293 ( (
void * )
ctx->modulus0 );
300 memcpy ( &cursor,
raw,
sizeof ( cursor ) );
302 DBGC (
ctx,
"ECDSA %p invalid integer:\n",
ctx );
309 DBGC (
ctx,
"ECDSA %p invalid signature value:\n",
ctx );
317 DBGC (
ctx,
"ECDSA %p out-of-range signature value:\n",
ctx );
351 len =
sizeof ( buf );
352 while ( (
len > 1 ) && (
data[0] == 0 ) && (
data[1] < 0x80 ) ) {
394 dynamic =
malloc (
sizeof ( *dynamic ) );
400 ctx->dynamic = dynamic;
401 ctx->modulus0 = dynamic->modulus.element;
402 ctx->fermat0 = dynamic->fermat.element;
403 ctx->square0 = dynamic->square.element;
404 ctx->one0 = dynamic->one.element;
405 ctx->z0 = dynamic->z.element;
406 ctx->k0 = dynamic->k.element;
407 ctx->r0 = dynamic->r.element;
408 ctx->s0 = dynamic->s.element;
409 ctx->temp0 = dynamic->temp.element;
410 ctx->product0 = dynamic->product.element;
411 ctx->point1 = dynamic->point1;
412 ctx->point2 = dynamic->point2;
413 ctx->scalar = dynamic->scalar;
414 ctx->drbg = &dynamic->drbg;
439 const void *
value ) {
443 ( (
void * )
ctx->modulus0 );
445 ( (
void * )
ctx->fermat0 );
447 ( (
void * )
ctx->square0 );
449 ( (
void * )
ctx->one0 );
451 ( (
void * )
ctx->z0 );
453 ( (
void * )
ctx->product0 );
454 static const uint8_t two_raw[] = { 2 };
463 bigint_init ( square, two_raw,
sizeof ( two_raw ) );
468 DBGC2 (
ctx,
"ECDSA %p R^2 = %s mod N\n",
474 DBGC2 (
ctx,
"ECDSA %p R = %s mod N\n",
478 ctx->digest = digest;
479 zlen =
ctx->key.curve->keysize;
484 DBGC2 (
ctx,
"ECDSA %p z = %s (%s)\n",
500 const void *
value ) {
532 ( (
void * )
ctx->modulus0 );
534 ( (
void * )
ctx->fermat0 );
536 ( (
void * )
ctx->square0 );
538 ( (
void * )
ctx->one0 );
540 ( (
void * )
ctx->temp0 );
542 ( (
void * )
ctx->product0 );
570 ( (
void * )
ctx->modulus0 );
572 ( (
void * )
ctx->square0 );
574 ( (
void * )
ctx->one0 );
576 ( (
void * )
ctx->z0 );
578 ( (
void * )
ctx->k0 );
580 ( (
void * )
ctx->r0 );
582 ( (
void * )
ctx->s0 );
584 ( (
void * )
ctx->temp0 );
586 ( (
void * )
ctx->product0 );
589 void *point1 =
ctx->point1;
590 void *scalar =
ctx->scalar;
599 DBGC (
ctx,
"ECDSA %p could not generate: %s\n",
616 DBGC2 (
ctx,
"ECDSA %p x1 = %s mod N\n",
631 DBGC2 (
ctx,
"ECDSA %p (k^-1)R = %s mod N\n",
642 DBGC2 (
ctx,
"ECDSA %p r*dA = %s mod N\n",
647 DBGC2 (
ctx,
"ECDSA %p z+r*dA = %s mod N\n",
673 const void *
public =
ctx->key.public;
676 ( (
void * )
ctx->modulus0 );
678 ( (
void * )
ctx->one0 );
680 ( (
void * )
ctx->z0 );
682 ( (
void * )
ctx->r0 );
684 ( (
void * )
ctx->s0 );
686 ( (
void * )
ctx->temp0 );
688 ( (
void * )
ctx->product0 );
695 void *point1 =
ctx->point1;
696 void *point2 =
ctx->point2;
697 void *scalar =
ctx->scalar;
711 DBGC2 (
ctx,
"ECDSA %p u1 = %s mod N\n",
718 DBGC (
ctx,
"ECDSA %p could not calculate u1*G: %s\n",
727 DBGC2 (
ctx,
"ECDSA %p u2 = %s mod N\n",
733 DBGC (
ctx,
"ECDSA %p could not calculate u2*Qa: %s\n",
739 if ( (
rc =
elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
740 DBGC (
ctx,
"ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
747 DBGC (
ctx,
"ECDSA %p result is point at infinity\n",
ctx );
761 DBGC2 (
ctx,
"ECDSA %p signature is%s valid\n",
762 ctx, ( valid ?
"" :
" not" ) );
819 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)