iPXE
Data Structures | Macros | Functions | Variables
ecdsa.c File Reference

Elliptic curve digital signature algorithm (ECDSA) More...

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <ipxe/crypto.h>
#include <ipxe/bigint.h>
#include <ipxe/hmac_drbg.h>
#include <ipxe/ecdsa.h>

Go to the source code of this file.

Data Structures

struct  ecdsa_key
 An ECDSA key. More...
 
struct  ecdsa_context
 ECDSA context. More...
 

Macros

#define EINVAL_POINTSIZE   __einfo_error ( EINFO_EINVAL_POINTSIZE )
 
#define EINFO_EINVAL_POINTSIZE   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid point size" )
 
#define EINVAL_KEYSIZE   __einfo_error ( EINFO_EINVAL_KEYSIZE )
 
#define EINFO_EINVAL_KEYSIZE   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid key size" )
 
#define EINVAL_COMPRESSION   __einfo_error ( EINFO_EINVAL_COMPRESSION )
 
#define EINFO_EINVAL_COMPRESSION   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid compression")
 
#define EINVAL_INFINITY   __einfo_error ( EINFO_EINVAL_INFINITY )
 
#define EINFO_EINVAL_INFINITY   __einfo_uniqify ( EINFO_EINVAL, 0x04, "Point is infinity" )
 
#define EINVAL_SIGNATURE   __einfo_error ( EINFO_EINVAL_SIGNATURE )
 
#define EINFO_EINVAL_SIGNATURE   __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid signature" )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int ecdsa_parse_key (struct ecdsa_key *key, const struct asn1_cursor *raw)
 Parse ECDSA key. More...
 
static int ecdsa_parse_signature (struct ecdsa_context *ctx, bigint_element_t *rs0, const struct asn1_cursor *raw)
 Parse ECDSA signature value. More...
 
static int ecdsa_prepend_signature (struct ecdsa_context *ctx, bigint_element_t *rs0, struct asn1_builder *builder)
 Prepend ECDSA signature value. More...
 
static int ecdsa_alloc (struct ecdsa_context *ctx)
 Allocate ECDSA context dynamic storage. More...
 
static void ecdsa_free (struct ecdsa_context *ctx)
 Free ECDSA context dynamic storage. More...
 
static void ecdsa_init_values (struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
 Initialise ECDSA values. More...
 
static int ecdsa_init (struct ecdsa_context *ctx, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value)
 Initialise ECDSA context. More...
 
static void ecdsa_invert (struct ecdsa_context *ctx, bigint_element_t *val0)
 Invert ECDSA value. More...
 
static int ecdsa_sign_rs (struct ecdsa_context *ctx)
 Generate ECDSA "r" and "s" values. More...
 
static int ecdsa_verify_rs (struct ecdsa_context *ctx)
 Verify ECDSA "r" and "s" values. More...
 
static int ecdsa_encrypt (const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused)
 Encrypt using ECDSA. More...
 
static int ecdsa_decrypt (const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused)
 Decrypt using ECDSA. More...
 
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. More...
 
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. More...
 
static int ecdsa_match (const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
 Check for matching ECDSA public/private key pair. More...
 

Variables

static uint8_t oid_ecpublickey [] = { ASN1_OID_ECPUBLICKEY }
 "ecPublicKey" object identifier More...
 
struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
 Generic elliptic curve container algorithm. More...
 
struct pubkey_algorithm ecdsa_algorithm
 ECDSA public-key algorithm. More...
 

Detailed Description

Elliptic curve digital signature algorithm (ECDSA)

The elliptic curve public key format is documented in RFC 5480. The original private key format is documented in RFC 5915, and the generic container PKCS#8 format documented in RFC 5208.

Definition in file ecdsa.c.

Macro Definition Documentation

◆ EINVAL_POINTSIZE

#define EINVAL_POINTSIZE   __einfo_error ( EINFO_EINVAL_POINTSIZE )

Definition at line 45 of file ecdsa.c.

◆ EINFO_EINVAL_POINTSIZE

#define EINFO_EINVAL_POINTSIZE   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid point size" )

Definition at line 47 of file ecdsa.c.

◆ EINVAL_KEYSIZE

#define EINVAL_KEYSIZE   __einfo_error ( EINFO_EINVAL_KEYSIZE )

Definition at line 49 of file ecdsa.c.

◆ EINFO_EINVAL_KEYSIZE

#define EINFO_EINVAL_KEYSIZE   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid key size" )

Definition at line 51 of file ecdsa.c.

◆ EINVAL_COMPRESSION

#define EINVAL_COMPRESSION   __einfo_error ( EINFO_EINVAL_COMPRESSION )

Definition at line 53 of file ecdsa.c.

◆ EINFO_EINVAL_COMPRESSION

#define EINFO_EINVAL_COMPRESSION   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid compression")

Definition at line 55 of file ecdsa.c.

◆ EINVAL_INFINITY

#define EINVAL_INFINITY   __einfo_error ( EINFO_EINVAL_INFINITY )

Definition at line 57 of file ecdsa.c.

◆ EINFO_EINVAL_INFINITY

#define EINFO_EINVAL_INFINITY   __einfo_uniqify ( EINFO_EINVAL, 0x04, "Point is infinity" )

Definition at line 59 of file ecdsa.c.

◆ EINVAL_SIGNATURE

#define EINVAL_SIGNATURE   __einfo_error ( EINFO_EINVAL_SIGNATURE )

Definition at line 61 of file ecdsa.c.

◆ EINFO_EINVAL_SIGNATURE

#define EINFO_EINVAL_SIGNATURE   __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid signature" )

Definition at line 63 of file ecdsa.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ ecdsa_parse_key()

static int ecdsa_parse_key ( struct ecdsa_key key,
const struct asn1_cursor raw 
)
static

Parse ECDSA key.

Parameters
keyECDSA key
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 140 of file ecdsa.c.

141  {
142  struct asn1_algorithm *algorithm;
143  struct asn1_cursor cursor;
144  struct asn1_cursor curve;
145  struct asn1_cursor private;
146  const uint8_t *compression;
147  int is_private;
148  int rc;
149 
150  /* Enter subjectPublicKeyInfo/ECPrivateKey */
151  memcpy ( &cursor, raw, sizeof ( cursor ) );
152  asn1_enter ( &cursor, ASN1_SEQUENCE );
153  asn1_invalidate_cursor ( &curve );
154  asn1_invalidate_cursor ( &private );
155 
156  /* Determine key format */
157  if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
158 
159  /* Private key */
160  is_private = 1;
161 
162  /* Skip version */
163  asn1_skip_any ( &cursor );
164 
165  /* Parse privateKeyAlgorithm, if present */
166  if ( asn1_type ( &cursor ) == ASN1_SEQUENCE ) {
167 
168  /* PKCS#8 format */
169  DBGC ( key, "ECDSA %p is in PKCS#8 format\n", key );
170 
171  /* Parse privateKeyAlgorithm */
172  memcpy ( &curve, &cursor, sizeof ( curve ) );
173  asn1_skip_any ( &cursor );
174 
175  /* Enter privateKey */
176  asn1_enter ( &cursor, ASN1_OCTET_STRING );
177 
178  /* Enter ECPrivateKey */
179  asn1_enter ( &cursor, ASN1_SEQUENCE );
180 
181  /* Skip version */
182  asn1_skip ( &cursor, ASN1_INTEGER );
183  }
184 
185  /* Parse privateKey */
186  memcpy ( &private, &cursor, sizeof ( private ) );
187  asn1_enter ( &private, ASN1_OCTET_STRING );
188  asn1_skip_any ( &cursor );
189 
190  /* Parse parameters, if present */
191  if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
192  memcpy ( &curve, &cursor, sizeof ( curve ) );
193  asn1_enter_any ( &curve );
194  asn1_skip_any ( &cursor );
195  }
196 
197  /* Enter publicKey */
198  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 1 ) );
199 
200  } else {
201 
202  /* Public key */
203  is_private = 0;
204 
205  /* Parse algorithm */
206  memcpy ( &curve, &cursor, sizeof ( curve ) );
207  asn1_skip_any ( &cursor );
208  }
209 
210  /* Enter publicKey */
211  asn1_enter_bits ( &cursor, NULL );
212 
213  /* Identify curve */
214  if ( ( rc = asn1_curve_algorithm ( &curve, &ecpubkey_algorithm,
215  &algorithm ) ) != 0 ) {
216  DBGC ( key, "ECDSA %p unknown curve: %s\n",
217  key, strerror ( rc ) );
218  DBGC_HDA ( key, 0, raw->data, raw->len );
219  return rc;
220  }
221  key->curve = algorithm->curve;
222  DBGC ( key, "ECDSA %p is a %s (%s) %s key\n", key, algorithm->name,
223  key->curve->name, ( is_private ? "private" : "public" ) );
224 
225  /* Check public key length */
226  if ( cursor.len != ( sizeof ( *compression ) +
227  key->curve->pointsize ) ) {
228  DBGC ( key, "ECDSA %p invalid public key length %zd\n",
229  key, cursor.len );
230  DBGC_HDA ( key, 0, raw->data, raw->len );
231  return -EINVAL_POINTSIZE;
232  }
233 
234  /* Check that key is uncompressed */
235  compression = cursor.data;
236  if ( *compression != ECDSA_UNCOMPRESSED ) {
237  DBGC ( key, "ECDSA %p invalid compression %#02x\n",
238  key, *compression );
239  DBGC_HDA ( key, 0, raw->data, raw->len );
240  return -EINVAL_COMPRESSION;
241  }
242 
243  /* Extract public curve point */
244  key->public = ( cursor.data + sizeof ( *compression ) );
245  DBGC ( key, "ECDSA %p public curve point:\n", key );
246  DBGC_HDA ( key, 0, key->public, key->curve->pointsize );
247 
248  /* Check that public key is not the point at infinity */
249  if ( elliptic_is_infinity ( key->curve, key->public ) ) {
250  DBGC ( key, "ECDSA %p public curve point is infinity\n", key );
251  return -EINVAL_INFINITY;
252  }
253 
254  /* Extract private key, if applicable */
255  if ( is_private ) {
256 
257  /* Check private key length */
258  if ( private.len != key->curve->keysize ) {
259  DBGC ( key, "ECDSA %p invalid private key length "
260  "%zd\n", key, private.len );
261  DBGC_HDA ( key, 0, raw->data, raw->len );
262  return -EINVAL_KEYSIZE;
263  }
264 
265  /* Extract private key */
266  key->private = private.data;
267  DBGC ( key, "ECDSA %p private multiplier:\n", key );
268  DBGC_HDA ( key, 0, key->private, key->curve->keysize );
269 
270  } else {
271 
272  /* No private key */
273  key->private = NULL;
274  }
275 
276  return 0;
277 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:407
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EINVAL_POINTSIZE
Definition: ecdsa.c:45
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:168
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition: crypto.h:321
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition: asn1.c:310
#define DBGC(...)
Definition: compiler.h:505
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:478
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:289
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
ring len
Length.
Definition: dwmac.h:231
#define EINVAL_COMPRESSION
Definition: ecdsa.c:53
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition: asn1.h:467
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition: asn1.c:279
unsigned char uint8_t
Definition: stdint.h:10
#define ECDSA_UNCOMPRESSED
Uncompressed curve point.
Definition: ecdsa.h:15
#define EINVAL_INFINITY
Definition: ecdsa.c:57
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
#define EINVAL_KEYSIZE
Definition: ecdsa.c:49
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:230
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:98
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:68
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
An ASN.1 object cursor.
Definition: asn1.h:20
union @391 key
Sense key.
Definition: scsi.h:17
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:658

References algorithm, asn1_curve_algorithm(), asn1_enter(), asn1_enter_any(), asn1_enter_bits(), ASN1_EXPLICIT_TAG, ASN1_INTEGER, asn1_invalidate_cursor(), ASN1_OCTET_STRING, ASN1_SEQUENCE, asn1_skip(), asn1_skip_any(), asn1_type(), asn1_cursor::data, DBGC, DBGC_HDA, ECDSA_UNCOMPRESSED, EINVAL_COMPRESSION, EINVAL_INFINITY, EINVAL_KEYSIZE, EINVAL_POINTSIZE, elliptic_is_infinity(), key, asn1_cursor::len, len, memcpy(), NULL, raw, rc, and strerror().

Referenced by ecdsa_init(), and ecdsa_match().

◆ ecdsa_parse_signature()

static int ecdsa_parse_signature ( struct ecdsa_context ctx,
bigint_element_t rs0,
const struct asn1_cursor raw 
)
static

Parse ECDSA signature value.

Parameters
ctxECDSA context
rs0Element 0 of signature "r" or "s" value
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 287 of file ecdsa.c.

289  {
290  size_t keysize = ctx->key.curve->keysize;
291  unsigned int size = ctx->size;
292  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
293  ( ( void * ) ctx->modulus0 );
294  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
295  ( ( void * ) rs0 );
296  struct asn1_cursor cursor;
297  int rc;
298 
299  /* Enter integer */
300  memcpy ( &cursor, raw, sizeof ( cursor ) );
301  if ( ( rc = asn1_enter_unsigned ( &cursor ) ) != 0 ) {
302  DBGC ( ctx, "ECDSA %p invalid integer:\n", ctx );
303  DBGC_HDA ( ctx, 0, raw->data, raw->len );
304  return rc;
305  }
306 
307  /* Extract value */
308  if ( cursor.len > keysize ) {
309  DBGC ( ctx, "ECDSA %p invalid signature value:\n", ctx );
310  DBGC_HDA ( ctx, 0, raw->data, raw->len );
311  return -EINVAL_KEYSIZE;
312  }
313  bigint_init ( rs, cursor.data, cursor.len );
314 
315  /* Check that value is within the required range */
316  if ( bigint_is_zero ( rs ) || bigint_is_geq ( rs, modulus ) ) {
317  DBGC ( ctx, "ECDSA %p out-of-range signature value:\n", ctx );
318  DBGC_HDA ( ctx, 0, raw->data, raw->len );
319  return -ERANGE;
320  }
321 
322  return 0;
323 }
#define __attribute__(x)
Definition: compiler.h:10
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition: asn1.c:368
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:144
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
#define ERANGE
Result too large.
Definition: errno.h:639
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
#define EINVAL_KEYSIZE
Definition: ecdsa.c:49
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:20
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References __attribute__, asn1_enter_unsigned(), bigint_init, bigint_is_geq, bigint_is_zero, bigint_t(), ctx, asn1_cursor::data, DBGC, DBGC_HDA, EINVAL_KEYSIZE, ERANGE, keysize, asn1_cursor::len, memcpy(), raw, rc, and size.

Referenced by ecdsa_verify().

◆ ecdsa_prepend_signature()

static int ecdsa_prepend_signature ( struct ecdsa_context ctx,
bigint_element_t rs0,
struct asn1_builder builder 
)
static

Prepend ECDSA signature value.

Parameters
ctxECDSA context
rs0Element 0 of signature "r" or "s" value
builderASN.1 builder
Return values
rcReturn status code

Definition at line 333 of file ecdsa.c.

335  {
336  size_t keysize = ctx->key.curve->keysize;
337  unsigned int size = ctx->size;
338  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
339  ( ( void * ) rs0 );
340  uint8_t buf[ 1 /* potential sign byte */ + keysize ];
341  uint8_t *data;
342  size_t len;
343  int rc;
344 
345  /* Construct value */
346  buf[0] = 0;
347  bigint_done ( rs, &buf[1], keysize );
348 
349  /* Strip leading zeros */
350  data = buf;
351  len = sizeof ( buf );
352  while ( ( len > 1 ) && ( data[0] == 0 ) && ( data[1] < 0x80 ) ) {
353  data++;
354  len--;
355  }
356 
357  /* Prepend integer */
358  if ( ( rc = asn1_prepend ( builder, ASN1_INTEGER, data, len ) ) != 0 )
359  return rc;
360 
361  return 0;
362 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
ring len
Length.
Definition: dwmac.h:231
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:74
unsigned char uint8_t
Definition: stdint.h:10
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
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:971
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References __attribute__, ASN1_INTEGER, asn1_prepend(), bigint_done, bigint_t(), ctx, data, keysize, len, rc, and size.

Referenced by ecdsa_sign().

◆ ecdsa_alloc()

static int ecdsa_alloc ( struct ecdsa_context ctx)
static

Allocate ECDSA context dynamic storage.

Parameters
ctxECDSA context
Return values
rcReturn status code

Definition at line 370 of file ecdsa.c.

370  {
371  struct elliptic_curve *curve = ctx->key.curve;
372  size_t pointsize = curve->pointsize;
373  size_t keysize = curve->keysize;
374  unsigned int size =
375  bigint_required_size ( keysize + 1 /* for addition */ );
376  struct {
377  bigint_t ( size ) modulus;
378  bigint_t ( size ) fermat;
379  bigint_t ( size ) square;
380  bigint_t ( size ) one;
381  bigint_t ( size ) z;
382  bigint_t ( size ) k;
383  bigint_t ( size ) r;
384  bigint_t ( size ) s;
385  bigint_t ( size ) temp;
386  bigint_t ( size * 2 ) product;
387  uint8_t point1[pointsize];
388  uint8_t point2[pointsize];
389  uint8_t scalar[keysize];
390  struct hmac_drbg_state drbg;
391  } *dynamic;
392 
393  /* Allocate dynamic storage */
394  dynamic = malloc ( sizeof ( *dynamic ) );
395  if ( ! dynamic )
396  return -ENOMEM;
397 
398  /* Populate context */
399  ctx->size = size;
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;
415 
416  return 0;
417 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:534
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:183
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:30
unsigned char uint8_t
Definition: stdint.h:10
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
static const uint32_t k[64]
MD5 constants.
Definition: md5.c:53
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
HMAC_DRBG internal state.
Definition: hmac_drbg.h:218
An elliptic curve.
Definition: crypto.h:177
uint8_t product
Product string.
Definition: smbios.h:16
size_t pointsize
Point (and public key) size.
Definition: crypto.h:181
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
static const uint8_t r[3][4]
MD4 shift amounts.
Definition: md4.c:53

References bigint_required_size, bigint_t(), ctx, ENOMEM, k, keysize, elliptic_curve::keysize, malloc(), elliptic_curve::pointsize, product, r, and size.

Referenced by ecdsa_init().

◆ ecdsa_free()

static void ecdsa_free ( struct ecdsa_context ctx)
static

Free ECDSA context dynamic storage.

Parameters
ctxECDSA context

Definition at line 424 of file ecdsa.c.

424  {
425 
426  /* Free dynamic storage */
427  free ( ctx->dynamic );
428 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

References ctx, and free.

Referenced by ecdsa_init(), ecdsa_sign(), and ecdsa_verify().

◆ ecdsa_init_values()

static void ecdsa_init_values ( struct ecdsa_context ctx,
struct digest_algorithm digest,
const void *  value 
)
static

Initialise ECDSA values.

Parameters
ctxECDSA context
digestDigest algorithm
valueDigest value

Definition at line 437 of file ecdsa.c.

439  {
440  struct elliptic_curve *curve = ctx->key.curve;
441  unsigned int size = ctx->size;
442  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
443  ( ( void * ) ctx->modulus0 );
444  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
445  ( ( void * ) ctx->fermat0 );
446  bigint_t ( size ) __attribute__ (( may_alias )) *square =
447  ( ( void * ) ctx->square0 );
448  bigint_t ( size ) __attribute__ (( may_alias )) *one =
449  ( ( void * ) ctx->one0 );
450  bigint_t ( size ) __attribute__ (( may_alias )) *z =
451  ( ( void * ) ctx->z0 );
452  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
453  ( ( void * ) ctx->product0 );
454  static const uint8_t two_raw[] = { 2 };
455  size_t zlen;
456 
457  /* Initialise modulus N */
458  bigint_init ( modulus, curve->order, curve->keysize );
459  DBGC2 ( ctx, "ECDSA %p N = %s\n", ctx, bigint_ntoa ( modulus ) );
460 
461  /* Calculate N-2 (using Montgomery constant as temporary buffer) */
462  bigint_copy ( modulus, fermat );
463  bigint_init ( square, two_raw, sizeof ( two_raw ) );
464  bigint_subtract ( square, fermat );
465 
466  /* Calculate Montgomery constant */
467  bigint_reduce ( modulus, square );
468  DBGC2 ( ctx, "ECDSA %p R^2 = %s mod N\n",
469  ctx, bigint_ntoa ( square ) );
470 
471  /* Construct one in Montgomery form */
472  bigint_grow ( square, product );
473  bigint_montgomery ( modulus, product, one );
474  DBGC2 ( ctx, "ECDSA %p R = %s mod N\n",
475  ctx, bigint_ntoa ( one ) );
476 
477  /* Initialise digest */
478  ctx->digest = digest;
479  zlen = ctx->key.curve->keysize;
480  if ( zlen > digest->digestsize )
481  zlen = digest->digestsize;
482  ctx->zlen = zlen;
483  bigint_init ( z, value, zlen );
484  DBGC2 ( ctx, "ECDSA %p z = %s (%s)\n",
485  ctx, bigint_ntoa ( z ), digest->name );
486 }
#define __attribute__(x)
Definition: compiler.h:10
const void * order
Order of the generator (if prime)
Definition: crypto.h:187
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:208
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:183
unsigned char uint8_t
Definition: stdint.h:10
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:313
An elliptic curve.
Definition: crypto.h:177
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition: bigint.h:273
uint8_t product
Product string.
Definition: smbios.h:16
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:98
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References __attribute__, bigint_copy, bigint_grow, bigint_init, bigint_montgomery, bigint_ntoa, bigint_reduce, bigint_subtract, bigint_t(), ctx, DBGC2, digest_algorithm::digestsize, elliptic_curve::keysize, digest_algorithm::name, elliptic_curve::order, product, size, and value.

Referenced by ecdsa_init().

◆ ecdsa_init()

static int ecdsa_init ( struct ecdsa_context ctx,
const struct asn1_cursor key,
struct digest_algorithm digest,
const void *  value 
)
static

Initialise ECDSA context.

Parameters
ctxECDSA context
keyKey
digestDigest algorithm
valueDigest value
Return values
rcReturn status code

Definition at line 497 of file ecdsa.c.

500  {
501  int rc;
502 
503  /* Parse key */
504  if ( ( rc = ecdsa_parse_key ( &ctx->key, key ) ) != 0 )
505  goto err_parse;
506 
507  /* Allocate dynamic storage */
508  if ( ( rc = ecdsa_alloc ( ctx ) ) != 0 )
509  goto err_alloc;
510 
511  /* Initialise values */
512  ecdsa_init_values ( ctx, digest, value );
513 
514  return 0;
515 
516  ecdsa_free ( ctx );
517  err_alloc:
518  err_parse:
519  return rc;
520 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:424
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition: ecdsa.c:140
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static int ecdsa_alloc(struct ecdsa_context *ctx)
Allocate ECDSA context dynamic storage.
Definition: ecdsa.c:370
union @391 key
Sense key.
Definition: scsi.h:17
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
Definition: ecdsa.c:437

References ctx, ecdsa_alloc(), ecdsa_free(), ecdsa_init_values(), ecdsa_parse_key(), key, rc, and value.

Referenced by ecdsa_sign(), and ecdsa_verify().

◆ ecdsa_invert()

static void ecdsa_invert ( struct ecdsa_context ctx,
bigint_element_t val0 
)
static

Invert ECDSA value.

Parameters
ctxECDSA context
val0Element 0 of value to invert

Definition at line 528 of file ecdsa.c.

529  {
530  unsigned int size = ctx->size;
531  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
532  ( ( void * ) ctx->modulus0 );
533  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
534  ( ( void * ) ctx->fermat0 );
535  bigint_t ( size ) __attribute__ (( may_alias )) *square =
536  ( ( void * ) ctx->square0 );
537  bigint_t ( size ) __attribute__ (( may_alias )) *one =
538  ( ( void * ) ctx->one0 );
539  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
540  ( ( void * ) ctx->temp0 );
541  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
542  ( ( void * ) ctx->product0 );
543  bigint_t ( size ) __attribute__ (( may_alias )) *val =
544  ( ( void * ) val0 );
545 
546  /* Convert value to Montgomery form */
547  bigint_multiply ( val, square, product );
548  bigint_montgomery ( modulus, product, temp );
549 
550  /* Invert value via Fermat's little theorem */
551  bigint_copy ( one, val );
552  bigint_ladder ( val, temp, fermat, bigint_mod_exp_ladder, modulus,
553  product );
554 }
#define __attribute__(x)
Definition: compiler.h:10
void __asmcall int val
Definition: setjmp.h:12
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:313
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:259
uint8_t product
Product string.
Definition: smbios.h:16
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:329
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
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:719

References __attribute__, bigint_copy, bigint_ladder, bigint_mod_exp_ladder(), bigint_montgomery, bigint_multiply, bigint_t(), ctx, product, size, and val.

Referenced by ecdsa_sign_rs(), and ecdsa_verify_rs().

◆ ecdsa_sign_rs()

static int ecdsa_sign_rs ( struct ecdsa_context ctx)
static

Generate ECDSA "r" and "s" values.

Parameters
ctxECDSA context
sigSignature
Return values
rcReturn status code

Definition at line 563 of file ecdsa.c.

563  {
564  struct digest_algorithm *digest = ctx->digest;
565  struct elliptic_curve *curve = ctx->key.curve;
566  size_t pointsize = curve->pointsize;
567  size_t keysize = curve->keysize;
568  unsigned int size = ctx->size;
569  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
570  ( ( void * ) ctx->modulus0 );
571  bigint_t ( size ) __attribute__ (( may_alias )) *square =
572  ( ( void * ) ctx->square0 );
573  bigint_t ( size ) __attribute__ (( may_alias )) *one =
574  ( ( void * ) ctx->one0 );
575  bigint_t ( size ) __attribute__ (( may_alias )) *z =
576  ( ( void * ) ctx->z0 );
577  bigint_t ( size ) __attribute__ (( may_alias )) *k =
578  ( ( void * ) ctx->k0 );
579  bigint_t ( size ) __attribute__ (( may_alias )) *r =
580  ( ( void * ) ctx->r0 );
581  bigint_t ( size ) __attribute__ (( may_alias )) *s =
582  ( ( void * ) ctx->s0 );
583  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
584  ( ( void * ) ctx->temp0 );
585  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
586  ( ( void * ) ctx->product0 );
587  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
588  ( ( void * ) temp );
589  void *point1 = ctx->point1;
590  void *scalar = ctx->scalar;
591  int rc;
592 
593  /* Loop until a suitable signature is generated */
594  while ( 1 ) {
595 
596  /* Generate pseudo-random data */
597  if ( ( rc = hmac_drbg_generate ( digest, ctx->drbg, NULL, 0,
598  scalar, keysize ) ) != 0 ) {
599  DBGC ( ctx, "ECDSA %p could not generate: %s\n",
600  ctx, strerror ( rc ) );
601  return rc;
602  }
603 
604  /* Check suitability of pseudo-random data */
605  bigint_init ( k, scalar, keysize );
606  DBGC2 ( ctx, "ECDSA %p k = %s\n",
607  ctx, bigint_ntoa ( k ) );
608  if ( bigint_is_zero ( k ) )
609  continue;
610  if ( bigint_is_geq ( k, modulus ) )
611  continue;
612 
613  /* Calculate (x1,y1) = k*G */
614  elliptic_multiply ( curve, curve->base, scalar, point1 );
615  bigint_init ( x1, point1, ( pointsize / 2 ) );
616  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n",
617  ctx, bigint_ntoa ( x1 ) );
618 
619  /* Calculate r = x1 mod N */
620  bigint_multiply ( x1, one, product );
621  bigint_montgomery ( modulus, product, r );
622  DBGC2 ( ctx, "ECDSA %p r = %s\n",
623  ctx, bigint_ntoa ( r ) );
624 
625  /* Check suitability of r */
626  if ( bigint_is_zero ( r ) )
627  continue;
628 
629  /* Calculate k^-1 mod N (in Montgomery form) */
630  ecdsa_invert ( ctx, k->element );
631  DBGC2 ( ctx, "ECDSA %p (k^-1)R = %s mod N\n",
632  ctx, bigint_ntoa ( k ) );
633 
634  /* Calculate r * dA */
635  bigint_init ( temp, ctx->key.private, keysize );
636  DBGC2 ( ctx, "ECDSA %p dA = %s\n",
637  ctx, bigint_ntoa ( temp ) );
638  bigint_multiply ( r, temp, product );
639  bigint_montgomery ( modulus, product, temp );
640  bigint_multiply ( temp, square, product );
641  bigint_montgomery ( modulus, product, temp );
642  DBGC2 ( ctx, "ECDSA %p r*dA = %s mod N\n",
643  ctx, bigint_ntoa ( temp ) );
644 
645  /* Calculate k^-1 * (z + r*dA) */
646  bigint_add ( z, temp );
647  DBGC2 ( ctx, "ECDSA %p z+r*dA = %s mod N\n",
648  ctx, bigint_ntoa ( temp ) );
649  bigint_multiply ( k, temp, product );
650  bigint_montgomery ( modulus, product, s );
651  DBGC2 ( ctx, "ECDSA %p s = %s\n",
652  ctx, bigint_ntoa ( s ) );
653 
654  /* Check suitability of s */
655  if ( bigint_is_zero ( s ) )
656  continue;
657 
658  return 0;
659  }
660 }
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:306
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Definition: crypto.h:326
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
Definition: ecdsa.c:528
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:144
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:183
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
static const uint32_t k[64]
MD5 constants.
Definition: md5.c:53
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:313
An elliptic curve.
Definition: crypto.h:177
#define DBGC2(...)
Definition: compiler.h:522
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:259
A message digest algorithm.
Definition: crypto.h:18
const void * base
Generator base point.
Definition: crypto.h:185
uint8_t product
Product string.
Definition: smbios.h:16
size_t pointsize
Point (and public key) size.
Definition: crypto.h:181
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:86
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
static const uint8_t r[3][4]
MD4 shift amounts.
Definition: md4.c:53

References __attribute__, elliptic_curve::base, bigint_add, bigint_init, bigint_is_geq, bigint_is_zero, bigint_montgomery, bigint_multiply, bigint_ntoa, bigint_t(), ctx, DBGC, DBGC2, ecdsa_invert(), elliptic_multiply(), hmac_drbg_generate(), k, keysize, elliptic_curve::keysize, NULL, elliptic_curve::pointsize, product, r, rc, size, and strerror().

Referenced by ecdsa_sign().

◆ ecdsa_verify_rs()

static int ecdsa_verify_rs ( struct ecdsa_context ctx)
static

Verify ECDSA "r" and "s" values.

Parameters
ctxECDSA context
sigSignature
Return values
rcReturn status code

Definition at line 669 of file ecdsa.c.

669  {
670  struct elliptic_curve *curve = ctx->key.curve;
671  size_t pointsize = curve->pointsize;
672  size_t keysize = curve->keysize;
673  const void *public = ctx->key.public;
674  unsigned int size = ctx->size;
675  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
676  ( ( void * ) ctx->modulus0 );
677  bigint_t ( size ) __attribute__ (( may_alias )) *one =
678  ( ( void * ) ctx->one0 );
679  bigint_t ( size ) __attribute__ (( may_alias )) *z =
680  ( ( void * ) ctx->z0 );
681  bigint_t ( size ) __attribute__ (( may_alias )) *r =
682  ( ( void * ) ctx->r0 );
683  bigint_t ( size ) __attribute__ (( may_alias )) *s =
684  ( ( void * ) ctx->s0 );
685  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
686  ( ( void * ) ctx->temp0 );
687  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
688  ( ( void * ) ctx->product0 );
689  bigint_t ( size ) __attribute__ (( may_alias )) *u1 =
690  ( ( void * ) temp );
691  bigint_t ( size ) __attribute__ (( may_alias )) *u2 =
692  ( ( void * ) temp );
693  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
694  ( ( void * ) temp );
695  void *point1 = ctx->point1;
696  void *point2 = ctx->point2;
697  void *scalar = ctx->scalar;
698  int valid;
699  int rc;
700 
701  DBGC2 ( ctx, "ECDSA %p r = %s\n", ctx, bigint_ntoa ( r ) );
702  DBGC2 ( ctx, "ECDSA %p s = %s\n", ctx, bigint_ntoa ( s ) );
703 
704  /* Calculate s^-1 mod N (in Montgomery form) */
705  ecdsa_invert ( ctx, s->element );
706  DBGC2 ( ctx, "ECDSA %p (s^-1)R = %s mod N\n", ctx, bigint_ntoa ( s ) );
707 
708  /* Calculate u1 = (z * s^-1) mod N */
709  bigint_multiply ( z, s, product );
710  bigint_montgomery ( modulus, product, u1 );
711  DBGC2 ( ctx, "ECDSA %p u1 = %s mod N\n",
712  ctx, bigint_ntoa ( u1 ) );
713  bigint_done ( u1, scalar, keysize );
714 
715  /* Calculate u1 * G */
716  if ( ( rc = elliptic_multiply ( curve, curve->base, scalar,
717  point1 ) ) != 0 ) {
718  DBGC ( ctx, "ECDSA %p could not calculate u1*G: %s\n",
719  ctx, strerror ( rc ) );
720  return rc;
721  }
722 
723  /* Calculate u2 = (r * s^-1) mod N */
724  bigint_multiply ( r, s, product );
725  bigint_montgomery ( modulus, product, u2 );
726  bigint_done ( u2, scalar, keysize );
727  DBGC2 ( ctx, "ECDSA %p u2 = %s mod N\n",
728  ctx, bigint_ntoa ( u2 ) );
729 
730  /* Calculate u2 * Qa */
731  if ( ( rc = elliptic_multiply ( curve, public, scalar,
732  point2 ) ) != 0 ) {
733  DBGC ( ctx, "ECDSA %p could not calculate u2*Qa: %s\n",
734  ctx, strerror ( rc ) );
735  return rc;
736  }
737 
738  /* Calculate u1 * G + u2 * Qa */
739  if ( ( rc = elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
740  DBGC ( ctx, "ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
741  ctx, strerror ( rc ) );
742  return rc;
743  }
744 
745  /* Check that result is not the point at infinity */
746  if ( elliptic_is_infinity ( curve, point1 ) ) {
747  DBGC ( ctx, "ECDSA %p result is point at infinity\n", ctx );
748  return -EINVAL;
749  }
750 
751  /* Calculate x1 mod N */
752  bigint_init ( x1, point1, ( pointsize / 2 ) );
753  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n", ctx, bigint_ntoa ( x1 ) );
754  bigint_multiply ( x1, one, product );
755  bigint_montgomery ( modulus, product, x1 );
756  DBGC2 ( ctx, "ECDSA %p x1 = %s\n", ctx, bigint_ntoa ( x1 ) );
757 
758  /* Check signature */
759  bigint_subtract ( x1, r );
760  valid = bigint_is_zero ( r );
761  DBGC2 ( ctx, "ECDSA %p signature is%s valid\n",
762  ctx, ( valid ? "" : " not" ) );
763 
764  return ( valid ? 0 : -EINVAL_SIGNATURE );
765 }
#define __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Definition: crypto.h:326
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition: crypto.h:321
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
Definition: ecdsa.c:528
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:74
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:183
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define EINVAL_SIGNATURE
Definition: ecdsa.c:61
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
static int elliptic_add(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
Definition: crypto.h:332
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:313
An elliptic curve.
Definition: crypto.h:177
#define DBGC2(...)
Definition: compiler.h:522
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:259
const void * base
Generator base point.
Definition: crypto.h:185
uint8_t product
Product string.
Definition: smbios.h:16
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:98
size_t pointsize
Point (and public key) size.
Definition: crypto.h:181
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
static const uint8_t r[3][4]
MD4 shift amounts.
Definition: md4.c:53

References __attribute__, elliptic_curve::base, bigint_done, bigint_init, bigint_is_zero, bigint_montgomery, bigint_multiply, bigint_ntoa, bigint_subtract, bigint_t(), ctx, DBGC, DBGC2, ecdsa_invert(), EINVAL, EINVAL_SIGNATURE, elliptic_add(), elliptic_is_infinity(), elliptic_multiply(), keysize, elliptic_curve::keysize, elliptic_curve::pointsize, product, r, rc, size, and strerror().

Referenced by ecdsa_verify().

◆ ecdsa_encrypt()

static int ecdsa_encrypt ( const struct asn1_cursor *key  __unused,
const struct asn1_cursor *plaintext  __unused,
struct asn1_builder *ciphertext  __unused 
)
static

Encrypt using ECDSA.

Parameters
keyKey
plaintextPlaintext
ciphertextCiphertext
Return values
rcReturn status code

Definition at line 775 of file ecdsa.c.

777  {
778 
779  /* Not a defined operation for ECDSA */
780  return -ENOTTY;
781 }
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594

References ENOTTY.

◆ ecdsa_decrypt()

static int ecdsa_decrypt ( const struct asn1_cursor *key  __unused,
const struct asn1_cursor *ciphertext  __unused,
struct asn1_builder *plaintext  __unused 
)
static

Decrypt using ECDSA.

Parameters
keyKey
ciphertextCiphertext
plaintextPlaintext
Return values
rcReturn status code

Definition at line 791 of file ecdsa.c.

793  {
794 
795  /* Not a defined operation for ECDSA */
796  return -ENOTTY;
797 }
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594

References ENOTTY.

◆ ecdsa_sign()

static int ecdsa_sign ( const struct asn1_cursor key,
struct digest_algorithm digest,
const void *  value,
struct asn1_builder signature 
)
static

Sign digest value using ECDSA.

Parameters
keyKey
digestDigest algorithm
valueDigest value
signatureSignature
Return values
rcReturn status code

Definition at line 808 of file ecdsa.c.

810  {
811  struct ecdsa_context ctx;
812  int rc;
813 
814  /* Initialise context */
815  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
816  goto err_init;
817 
818  /* Fail unless we have a private key */
819  if ( ! ctx.key.private ) {
820  rc = -ENOTTY;
821  goto err_no_key;
822  }
823 
824  /* Instantiate DRBG */
825  hmac_drbg_instantiate ( digest, ctx.drbg, ctx.key.private,
826  ctx.key.curve->keysize, value, ctx.zlen );
827 
828  /* Create signature */
829  if ( ( rc = ecdsa_sign_rs ( &ctx ) ) != 0 )
830  goto err_signature;
831 
832  /* Construct "r" and "s" values */
833  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.s0, signature ) ) != 0)
834  goto err_s;
835  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.r0, signature ) ) != 0)
836  goto err_r;
837  if ( ( rc = asn1_wrap ( signature, ASN1_SEQUENCE ) ) != 0 )
838  goto err_wrap;
839 
840  /* Free context */
841  ecdsa_free ( &ctx );
842 
843  return 0;
844 
845  err_wrap:
846  err_r:
847  err_s:
848  err_signature:
849  err_no_key:
850  ecdsa_free ( &ctx );
851  err_init:
852  return rc;
853 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:424
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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:206
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static int ecdsa_prepend_signature(struct ecdsa_context *ctx, bigint_element_t *rs0, struct asn1_builder *builder)
Prepend ECDSA signature value.
Definition: ecdsa.c:333
ECDSA context.
Definition: ecdsa.c:91
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:998
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
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:497
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
static int ecdsa_sign_rs(struct ecdsa_context *ctx)
Generate ECDSA "r" and "s" values.
Definition: ecdsa.c:563
struct digest_algorithm * digest
Digest algorithm.
Definition: ecdsa.c:97
union @391 key
Sense key.
Definition: scsi.h:17

References ASN1_SEQUENCE, asn1_wrap(), ctx, ecdsa_context::digest, ecdsa_free(), ecdsa_init(), ecdsa_prepend_signature(), ecdsa_sign_rs(), ENOTTY, hmac_drbg_instantiate(), key, rc, signature, and value.

◆ ecdsa_verify()

static int ecdsa_verify ( const struct asn1_cursor key,
struct digest_algorithm digest,
const void *  value,
const struct asn1_cursor signature 
)
static

Verify signed digest using ECDSA.

Parameters
keyKey
digestDigest algorithm
valueDigest value
signatureSignature
Return values
rcReturn status code

Definition at line 864 of file ecdsa.c.

866  {
867  struct ecdsa_context ctx;
868  struct asn1_cursor cursor;
869  int rc;
870 
871  /* Initialise context */
872  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
873  goto err_init;
874 
875  /* Enter sequence */
876  memcpy ( &cursor, signature, sizeof ( cursor ) );
877  asn1_enter ( &cursor, ASN1_SEQUENCE );
878 
879  /* Extract "r" and "s" values */
880  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.r0, &cursor ) ) != 0 )
881  goto err_r;
882  asn1_skip_any ( &cursor );
883  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.s0, &cursor ) ) != 0 )
884  goto err_s;
885 
886  /* Verify signature */
887  if ( ( rc = ecdsa_verify_rs ( &ctx ) ) != 0 )
888  goto err_verify;
889 
890  /* Free context */
891  ecdsa_free ( &ctx );
892 
893  return 0;
894 
895  err_verify:
896  err_s:
897  err_r:
898  ecdsa_free ( &ctx );
899  err_init:
900  return rc;
901 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:424
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:168
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:287
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:289
void * memcpy(void *dest, const void *src, size_t len) __nonnull
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
ECDSA context.
Definition: ecdsa.c:91
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
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:497
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
An ASN.1 object cursor.
Definition: asn1.h:20
union @391 key
Sense key.
Definition: scsi.h:17
static int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
Definition: ecdsa.c:669

References asn1_enter(), ASN1_SEQUENCE, asn1_skip_any(), ctx, ecdsa_free(), ecdsa_init(), ecdsa_parse_signature(), ecdsa_verify_rs(), key, memcpy(), rc, signature, and value.

◆ ecdsa_match()

static int ecdsa_match ( const struct asn1_cursor private_key,
const struct asn1_cursor public_key 
)
static

Check for matching ECDSA public/private key pair.

Parameters
private_keyPrivate key
public_keyPublic key
Return values
rcReturn status code

Definition at line 910 of file ecdsa.c.

911  {
912  struct elliptic_curve *curve;
913  struct ecdsa_key privkey;
914  struct ecdsa_key pubkey;
915  int rc;
916 
917  /* Parse keys */
918  if ( ( rc = ecdsa_parse_key ( &privkey, private_key ) ) != 0 )
919  return rc;
920  if ( ( rc = ecdsa_parse_key ( &pubkey, public_key ) ) != 0 )
921  return rc;
922 
923  /* Compare curves */
924  if ( privkey.curve != pubkey.curve )
925  return -ENOTTY;
926  curve = privkey.curve;
927 
928  /* Compare public curve points */
929  if ( memcmp ( privkey.public, pubkey.public, curve->pointsize ) != 0 )
930  return -ENOTTY;
931 
932  return 0;
933 }
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition: ecdsa.c:140
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct elliptic_curve * curve
Elliptic curve.
Definition: ecdsa.c:83
An ECDSA key.
Definition: ecdsa.c:81
An elliptic curve.
Definition: crypto.h:177
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
A private key.
Definition: privkey.h:16
size_t pointsize
Point (and public key) size.
Definition: crypto.h:181
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114

References ecdsa_key::curve, ecdsa_parse_key(), ENOTTY, memcmp(), elliptic_curve::pointsize, ecdsa_key::public, and rc.

Variable Documentation

◆ oid_ecpublickey

uint8_t oid_ecpublickey[] = { ASN1_OID_ECPUBLICKEY }
static

"ecPublicKey" object identifier

Definition at line 67 of file ecdsa.c.

◆ __asn1_algorithm

struct asn1_algorithm ecpubkey_algorithm __asn1_algorithm
Initial value:
= {
.name = "ecPublicKey",
.pubkey = &ecdsa_algorithm,
}
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:401
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
Definition: ecdsa.c:67
struct pubkey_algorithm ecdsa_algorithm
ECDSA public-key algorithm.
Definition: ecdsa.c:936

Generic elliptic curve container algorithm.

The actual curve to be used is identified via the algorithm parameters, rather than the top-level OID.

Definition at line 74 of file ecdsa.c.

◆ ecdsa_algorithm

struct pubkey_algorithm ecdsa_algorithm
Initial value:
= {
.name = "ecdsa",
.encrypt = ecdsa_encrypt,
.decrypt = ecdsa_decrypt,
.sign = ecdsa_sign,
.verify = ecdsa_verify,
.match = ecdsa_match,
}
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:808
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:864
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:791
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:775
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:910

ECDSA public-key algorithm.

Definition at line 936 of file ecdsa.c.