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)
 
 FILE_SECBOOT (PERMITTED)
 
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 46 of file ecdsa.c.

◆ EINFO_EINVAL_POINTSIZE

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

Definition at line 48 of file ecdsa.c.

◆ EINVAL_KEYSIZE

#define EINVAL_KEYSIZE   __einfo_error ( EINFO_EINVAL_KEYSIZE )

Definition at line 50 of file ecdsa.c.

◆ EINFO_EINVAL_KEYSIZE

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

Definition at line 52 of file ecdsa.c.

◆ EINVAL_COMPRESSION

#define EINVAL_COMPRESSION   __einfo_error ( EINFO_EINVAL_COMPRESSION )

Definition at line 54 of file ecdsa.c.

◆ EINFO_EINVAL_COMPRESSION

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

Definition at line 56 of file ecdsa.c.

◆ EINVAL_INFINITY

#define EINVAL_INFINITY   __einfo_error ( EINFO_EINVAL_INFINITY )

Definition at line 58 of file ecdsa.c.

◆ EINFO_EINVAL_INFINITY

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

Definition at line 60 of file ecdsa.c.

◆ EINVAL_SIGNATURE

#define EINVAL_SIGNATURE   __einfo_error ( EINFO_EINVAL_SIGNATURE )

Definition at line 62 of file ecdsa.c.

◆ EINFO_EINVAL_SIGNATURE

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

Definition at line 64 of file ecdsa.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ 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 141 of file ecdsa.c.

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

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 288 of file ecdsa.c.

290  {
291  size_t keysize = ctx->key.curve->keysize;
292  unsigned int size = ctx->size;
293  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
294  ( ( void * ) ctx->modulus0 );
295  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
296  ( ( void * ) rs0 );
297  struct asn1_cursor cursor;
298  int rc;
299 
300  /* Enter integer */
301  memcpy ( &cursor, raw, sizeof ( cursor ) );
302  if ( ( rc = asn1_enter_unsigned ( &cursor ) ) != 0 ) {
303  DBGC ( ctx, "ECDSA %p invalid integer:\n", ctx );
304  DBGC_HDA ( ctx, 0, raw->data, raw->len );
305  return rc;
306  }
307 
308  /* Extract value */
309  if ( cursor.len > keysize ) {
310  DBGC ( ctx, "ECDSA %p invalid signature value:\n", ctx );
311  DBGC_HDA ( ctx, 0, raw->data, raw->len );
312  return -EINVAL_KEYSIZE;
313  }
314  bigint_init ( rs, cursor.data, cursor.len );
315 
316  /* Check that value is within the required range */
317  if ( bigint_is_zero ( rs ) || bigint_is_geq ( rs, modulus ) ) {
318  DBGC ( ctx, "ECDSA %p out-of-range signature value:\n", ctx );
319  DBGC_HDA ( ctx, 0, raw->data, raw->len );
320  return -ERANGE;
321  }
322 
323  return 0;
324 }
#define __attribute__(x)
Definition: compiler.h:10
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition: asn1.c:369
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:62
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:134
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:145
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:640
u16 keysize
Length of encryption key to be used, network byte order.
Definition: wpa.h:37
#define EINVAL_KEYSIZE
Definition: ecdsa.c:50
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:21
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 334 of file ecdsa.c.

336  {
337  size_t keysize = ctx->key.curve->keysize;
338  unsigned int size = ctx->size;
339  bigint_t ( size ) __attribute__ (( may_alias )) *rs =
340  ( ( void * ) rs0 );
341  uint8_t buf[ 1 /* potential sign byte */ + keysize ];
342  uint8_t *data;
343  size_t len;
344  int rc;
345 
346  /* Construct value */
347  buf[0] = 0;
348  bigint_done ( rs, &buf[1], keysize );
349 
350  /* Strip leading zeros */
351  data = buf;
352  len = sizeof ( buf );
353  while ( ( len > 1 ) && ( data[0] == 0 ) && ( data[1] < 0x80 ) ) {
354  data++;
355  len--;
356  }
357 
358  /* Prepend integer */
359  if ( ( rc = asn1_prepend ( builder, ASN1_INTEGER, data, len ) ) != 0 )
360  return rc;
361 
362  return 0;
363 }
#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:75
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:63
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
Definition: asn1.c:972
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 371 of file ecdsa.c.

371  {
372  struct elliptic_curve *curve = ctx->key.curve;
373  size_t pointsize = curve->pointsize;
374  size_t keysize = curve->keysize;
375  unsigned int size =
376  bigint_required_size ( keysize + 1 /* for addition */ );
377  struct {
378  bigint_t ( size ) modulus;
379  bigint_t ( size ) fermat;
380  bigint_t ( size ) square;
381  bigint_t ( size ) one;
382  bigint_t ( size ) z;
383  bigint_t ( size ) k;
384  bigint_t ( size ) r;
385  bigint_t ( size ) s;
386  bigint_t ( size ) temp;
387  bigint_t ( size * 2 ) product;
388  uint8_t point1[pointsize];
389  uint8_t point2[pointsize];
390  uint8_t scalar[keysize];
391  struct hmac_drbg_state drbg;
392  } *dynamic;
393 
394  /* Allocate dynamic storage */
395  dynamic = malloc ( sizeof ( *dynamic ) );
396  if ( ! dynamic )
397  return -ENOMEM;
398 
399  /* Populate context */
400  ctx->size = size;
401  ctx->dynamic = dynamic;
402  ctx->modulus0 = dynamic->modulus.element;
403  ctx->fermat0 = dynamic->fermat.element;
404  ctx->square0 = dynamic->square.element;
405  ctx->one0 = dynamic->one.element;
406  ctx->z0 = dynamic->z.element;
407  ctx->k0 = dynamic->k.element;
408  ctx->r0 = dynamic->r.element;
409  ctx->s0 = dynamic->s.element;
410  ctx->temp0 = dynamic->temp.element;
411  ctx->product0 = dynamic->product.element;
412  ctx->point1 = dynamic->point1;
413  ctx->point2 = dynamic->point2;
414  ctx->scalar = dynamic->scalar;
415  ctx->drbg = &dynamic->drbg;
416 
417  return 0;
418 }
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:535
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:31
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:54
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
HMAC_DRBG internal state.
Definition: hmac_drbg.h:219
An elliptic curve.
Definition: crypto.h:178
uint8_t product
Product string.
Definition: smbios.h:17
size_t pointsize
Point (and public key) size.
Definition: crypto.h:182
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:54

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 425 of file ecdsa.c.

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

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 438 of file ecdsa.c.

440  {
441  struct elliptic_curve *curve = ctx->key.curve;
442  unsigned int size = ctx->size;
443  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
444  ( ( void * ) ctx->modulus0 );
445  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
446  ( ( void * ) ctx->fermat0 );
447  bigint_t ( size ) __attribute__ (( may_alias )) *square =
448  ( ( void * ) ctx->square0 );
449  bigint_t ( size ) __attribute__ (( may_alias )) *one =
450  ( ( void * ) ctx->one0 );
451  bigint_t ( size ) __attribute__ (( may_alias )) *z =
452  ( ( void * ) ctx->z0 );
453  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
454  ( ( void * ) ctx->product0 );
455  static const uint8_t two_raw[] = { 2 };
456  size_t zlen;
457 
458  /* Initialise modulus N */
459  bigint_init ( modulus, curve->order, curve->keysize );
460  DBGC2 ( ctx, "ECDSA %p N = %s\n", ctx, bigint_ntoa ( modulus ) );
461 
462  /* Calculate N-2 (using Montgomery constant as temporary buffer) */
463  bigint_copy ( modulus, fermat );
464  bigint_init ( square, two_raw, sizeof ( two_raw ) );
465  bigint_subtract ( square, fermat );
466 
467  /* Calculate Montgomery constant */
468  bigint_reduce ( modulus, square );
469  DBGC2 ( ctx, "ECDSA %p R^2 = %s mod N\n",
470  ctx, bigint_ntoa ( square ) );
471 
472  /* Construct one in Montgomery form */
473  bigint_grow ( square, product );
474  bigint_montgomery ( modulus, product, one );
475  DBGC2 ( ctx, "ECDSA %p R = %s mod N\n",
476  ctx, bigint_ntoa ( one ) );
477 
478  /* Initialise digest */
479  ctx->digest = digest;
480  zlen = ctx->key.curve->keysize;
481  if ( zlen > digest->digestsize )
482  zlen = digest->digestsize;
483  ctx->zlen = zlen;
484  bigint_init ( z, value, zlen );
485  DBGC2 ( ctx, "ECDSA %p z = %s (%s)\n",
486  ctx, bigint_ntoa ( z ), digest->name );
487 }
#define __attribute__(x)
Definition: compiler.h:10
const void * order
Order of the generator (if prime)
Definition: crypto.h:188
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:209
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
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:235
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
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:314
An elliptic curve.
Definition: crypto.h:178
#define DBGC2(...)
Definition: compiler.h:522
size_t digestsize
Digest size.
Definition: crypto.h:27
const char * name
Algorithm name.
Definition: crypto.h:21
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition: bigint.h:274
uint8_t product
Product string.
Definition: smbios.h:17
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
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 498 of file ecdsa.c.

501  {
502  int rc;
503 
504  /* Parse key */
505  if ( ( rc = ecdsa_parse_key ( &ctx->key, key ) ) != 0 )
506  goto err_parse;
507 
508  /* Allocate dynamic storage */
509  if ( ( rc = ecdsa_alloc ( ctx ) ) != 0 )
510  goto err_alloc;
511 
512  /* Initialise values */
513  ecdsa_init_values ( ctx, digest, value );
514 
515  return 0;
516 
517  ecdsa_free ( ctx );
518  err_alloc:
519  err_parse:
520  return rc;
521 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:425
static int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition: ecdsa.c:141
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:371
union @391 key
Sense key.
Definition: scsi.h:18
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
Definition: ecdsa.c:438

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 529 of file ecdsa.c.

530  {
531  unsigned int size = ctx->size;
532  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
533  ( ( void * ) ctx->modulus0 );
534  bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
535  ( ( void * ) ctx->fermat0 );
536  bigint_t ( size ) __attribute__ (( may_alias )) *square =
537  ( ( void * ) ctx->square0 );
538  bigint_t ( size ) __attribute__ (( may_alias )) *one =
539  ( ( void * ) ctx->one0 );
540  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
541  ( ( void * ) ctx->temp0 );
542  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
543  ( ( void * ) ctx->product0 );
544  bigint_t ( size ) __attribute__ (( may_alias )) *val =
545  ( ( void * ) val0 );
546 
547  /* Convert value to Montgomery form */
548  bigint_multiply ( val, square, product );
549  bigint_montgomery ( modulus, product, temp );
550 
551  /* Invert value via Fermat's little theorem */
552  bigint_copy ( one, val );
553  bigint_ladder ( val, temp, fermat, bigint_mod_exp_ladder, modulus,
554  product );
555 }
#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:235
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
uint8_t product
Product string.
Definition: smbios.h:17
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:330
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:720

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 564 of file ecdsa.c.

564  {
565  struct digest_algorithm *digest = ctx->digest;
566  struct elliptic_curve *curve = ctx->key.curve;
567  size_t pointsize = curve->pointsize;
568  size_t keysize = curve->keysize;
569  unsigned int size = ctx->size;
570  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
571  ( ( void * ) ctx->modulus0 );
572  bigint_t ( size ) __attribute__ (( may_alias )) *square =
573  ( ( void * ) ctx->square0 );
574  bigint_t ( size ) __attribute__ (( may_alias )) *one =
575  ( ( void * ) ctx->one0 );
576  bigint_t ( size ) __attribute__ (( may_alias )) *z =
577  ( ( void * ) ctx->z0 );
578  bigint_t ( size ) __attribute__ (( may_alias )) *k =
579  ( ( void * ) ctx->k0 );
580  bigint_t ( size ) __attribute__ (( may_alias )) *r =
581  ( ( void * ) ctx->r0 );
582  bigint_t ( size ) __attribute__ (( may_alias )) *s =
583  ( ( void * ) ctx->s0 );
584  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
585  ( ( void * ) ctx->temp0 );
586  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
587  ( ( void * ) ctx->product0 );
588  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
589  ( ( void * ) temp );
590  void *point1 = ctx->point1;
591  void *scalar = ctx->scalar;
592  int rc;
593 
594  /* Loop until a suitable signature is generated */
595  while ( 1 ) {
596 
597  /* Generate pseudo-random data */
598  if ( ( rc = hmac_drbg_generate ( digest, ctx->drbg, NULL, 0,
599  scalar, keysize ) ) != 0 ) {
600  DBGC ( ctx, "ECDSA %p could not generate: %s\n",
601  ctx, strerror ( rc ) );
602  return rc;
603  }
604 
605  /* Check suitability of pseudo-random data */
606  bigint_init ( k, scalar, keysize );
607  DBGC2 ( ctx, "ECDSA %p k = %s\n",
608  ctx, bigint_ntoa ( k ) );
609  if ( bigint_is_zero ( k ) )
610  continue;
611  if ( bigint_is_geq ( k, modulus ) )
612  continue;
613 
614  /* Calculate (x1,y1) = k*G */
615  elliptic_multiply ( curve, curve->base, scalar, point1 );
616  bigint_init ( x1, point1, ( pointsize / 2 ) );
617  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n",
618  ctx, bigint_ntoa ( x1 ) );
619 
620  /* Calculate r = x1 mod N */
621  bigint_multiply ( x1, one, product );
622  bigint_montgomery ( modulus, product, r );
623  DBGC2 ( ctx, "ECDSA %p r = %s\n",
624  ctx, bigint_ntoa ( r ) );
625 
626  /* Check suitability of r */
627  if ( bigint_is_zero ( r ) )
628  continue;
629 
630  /* Calculate k^-1 mod N (in Montgomery form) */
631  ecdsa_invert ( ctx, k->element );
632  DBGC2 ( ctx, "ECDSA %p (k^-1)R = %s mod N\n",
633  ctx, bigint_ntoa ( k ) );
634 
635  /* Calculate r * dA */
636  bigint_init ( temp, ctx->key.private, keysize );
637  DBGC2 ( ctx, "ECDSA %p dA = %s\n",
638  ctx, bigint_ntoa ( temp ) );
639  bigint_multiply ( r, temp, product );
640  bigint_montgomery ( modulus, product, temp );
641  bigint_multiply ( temp, square, product );
642  bigint_montgomery ( modulus, product, temp );
643  DBGC2 ( ctx, "ECDSA %p r*dA = %s mod N\n",
644  ctx, bigint_ntoa ( temp ) );
645 
646  /* Calculate k^-1 * (z + r*dA) */
647  bigint_add ( z, temp );
648  DBGC2 ( ctx, "ECDSA %p z+r*dA = %s mod N\n",
649  ctx, bigint_ntoa ( temp ) );
650  bigint_multiply ( k, temp, product );
651  bigint_montgomery ( modulus, product, s );
652  DBGC2 ( ctx, "ECDSA %p s = %s\n",
653  ctx, bigint_ntoa ( s ) );
654 
655  /* Check suitability of s */
656  if ( bigint_is_zero ( s ) )
657  continue;
658 
659  return 0;
660  }
661 }
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
#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:327
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:529
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
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:134
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:145
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
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:54
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
An elliptic curve.
Definition: crypto.h:178
#define DBGC2(...)
Definition: compiler.h:522
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
A message digest algorithm.
Definition: crypto.h:19
const void * base
Generator base point.
Definition: crypto.h:186
uint8_t product
Product string.
Definition: smbios.h:17
size_t pointsize
Point (and public key) size.
Definition: crypto.h:182
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:87
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
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:54

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 670 of file ecdsa.c.

670  {
671  struct elliptic_curve *curve = ctx->key.curve;
672  size_t pointsize = curve->pointsize;
673  size_t keysize = curve->keysize;
674  const void *public = ctx->key.public;
675  unsigned int size = ctx->size;
676  bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
677  ( ( void * ) ctx->modulus0 );
678  bigint_t ( size ) __attribute__ (( may_alias )) *one =
679  ( ( void * ) ctx->one0 );
680  bigint_t ( size ) __attribute__ (( may_alias )) *z =
681  ( ( void * ) ctx->z0 );
682  bigint_t ( size ) __attribute__ (( may_alias )) *r =
683  ( ( void * ) ctx->r0 );
684  bigint_t ( size ) __attribute__ (( may_alias )) *s =
685  ( ( void * ) ctx->s0 );
686  bigint_t ( size ) __attribute__ (( may_alias )) *temp =
687  ( ( void * ) ctx->temp0 );
688  bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
689  ( ( void * ) ctx->product0 );
690  bigint_t ( size ) __attribute__ (( may_alias )) *u1 =
691  ( ( void * ) temp );
692  bigint_t ( size ) __attribute__ (( may_alias )) *u2 =
693  ( ( void * ) temp );
694  bigint_t ( size ) __attribute__ (( may_alias )) *x1 =
695  ( ( void * ) temp );
696  void *point1 = ctx->point1;
697  void *point2 = ctx->point2;
698  void *scalar = ctx->scalar;
699  int valid;
700  int rc;
701 
702  DBGC2 ( ctx, "ECDSA %p r = %s\n", ctx, bigint_ntoa ( r ) );
703  DBGC2 ( ctx, "ECDSA %p s = %s\n", ctx, bigint_ntoa ( s ) );
704 
705  /* Calculate s^-1 mod N (in Montgomery form) */
706  ecdsa_invert ( ctx, s->element );
707  DBGC2 ( ctx, "ECDSA %p (s^-1)R = %s mod N\n", ctx, bigint_ntoa ( s ) );
708 
709  /* Calculate u1 = (z * s^-1) mod N */
710  bigint_multiply ( z, s, product );
711  bigint_montgomery ( modulus, product, u1 );
712  DBGC2 ( ctx, "ECDSA %p u1 = %s mod N\n",
713  ctx, bigint_ntoa ( u1 ) );
714  bigint_done ( u1, scalar, keysize );
715 
716  /* Calculate u1 * G */
717  if ( ( rc = elliptic_multiply ( curve, curve->base, scalar,
718  point1 ) ) != 0 ) {
719  DBGC ( ctx, "ECDSA %p could not calculate u1*G: %s\n",
720  ctx, strerror ( rc ) );
721  return rc;
722  }
723 
724  /* Calculate u2 = (r * s^-1) mod N */
725  bigint_multiply ( r, s, product );
726  bigint_montgomery ( modulus, product, u2 );
727  bigint_done ( u2, scalar, keysize );
728  DBGC2 ( ctx, "ECDSA %p u2 = %s mod N\n",
729  ctx, bigint_ntoa ( u2 ) );
730 
731  /* Calculate u2 * Qa */
732  if ( ( rc = elliptic_multiply ( curve, public, scalar,
733  point2 ) ) != 0 ) {
734  DBGC ( ctx, "ECDSA %p could not calculate u2*Qa: %s\n",
735  ctx, strerror ( rc ) );
736  return rc;
737  }
738 
739  /* Calculate u1 * G + u2 * Qa */
740  if ( ( rc = elliptic_add ( curve, point1, point2, point1 ) ) != 0 ) {
741  DBGC ( ctx, "ECDSA %p could not calculate u1*G+u2*Qa: %s\n",
742  ctx, strerror ( rc ) );
743  return rc;
744  }
745 
746  /* Check that result is not the point at infinity */
747  if ( elliptic_is_infinity ( curve, point1 ) ) {
748  DBGC ( ctx, "ECDSA %p result is point at infinity\n", ctx );
749  return -EINVAL;
750  }
751 
752  /* Calculate x1 mod N */
753  bigint_init ( x1, point1, ( pointsize / 2 ) );
754  DBGC2 ( ctx, "ECDSA %p x1 = %s mod N\n", ctx, bigint_ntoa ( x1 ) );
755  bigint_multiply ( x1, one, product );
756  bigint_montgomery ( modulus, product, x1 );
757  DBGC2 ( ctx, "ECDSA %p x1 = %s\n", ctx, bigint_ntoa ( x1 ) );
758 
759  /* Check signature */
760  bigint_subtract ( x1, r );
761  valid = bigint_is_zero ( r );
762  DBGC2 ( ctx, "ECDSA %p signature is%s valid\n",
763  ctx, ( valid ? "" : " not" ) );
764 
765  return ( valid ? 0 : -EINVAL_SIGNATURE );
766 }
#define __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:429
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:327
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition: crypto.h:322
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:529
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
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:134
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:75
size_t keysize
Scalar (and private key) size.
Definition: crypto.h:184
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define EINVAL_SIGNATURE
Definition: ecdsa.c:62
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:333
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
An elliptic curve.
Definition: crypto.h:178
#define DBGC2(...)
Definition: compiler.h:522
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
const void * base
Generator base point.
Definition: crypto.h:186
uint8_t product
Product string.
Definition: smbios.h:17
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
size_t pointsize
Point (and public key) size.
Definition: crypto.h:182
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
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:54

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 776 of file ecdsa.c.

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

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 792 of file ecdsa.c.

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

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 809 of file ecdsa.c.

811  {
812  struct ecdsa_context ctx;
813  int rc;
814 
815  /* Initialise context */
816  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
817  goto err_init;
818 
819  /* Fail unless we have a private key */
820  if ( ! ctx.key.private ) {
821  rc = -ENOTTY;
822  goto err_no_key;
823  }
824 
825  /* Instantiate DRBG */
826  hmac_drbg_instantiate ( digest, ctx.drbg, ctx.key.private,
827  ctx.key.curve->keysize, value, ctx.zlen );
828 
829  /* Create signature */
830  if ( ( rc = ecdsa_sign_rs ( &ctx ) ) != 0 )
831  goto err_signature;
832 
833  /* Construct "r" and "s" values */
834  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.s0, signature ) ) != 0)
835  goto err_s;
836  if ( ( rc = ecdsa_prepend_signature ( &ctx, ctx.r0, signature ) ) != 0)
837  goto err_r;
838  if ( ( rc = asn1_wrap ( signature, ASN1_SEQUENCE ) ) != 0 )
839  goto err_wrap;
840 
841  /* Free context */
842  ecdsa_free ( &ctx );
843 
844  return 0;
845 
846  err_wrap:
847  err_r:
848  err_s:
849  err_signature:
850  err_no_key:
851  ecdsa_free ( &ctx );
852  err_init:
853  return rc;
854 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:425
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:207
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:334
ECDSA context.
Definition: ecdsa.c:92
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:999
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:90
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
static int ecdsa_init(struct ecdsa_context *ctx, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value)
Initialise ECDSA context.
Definition: ecdsa.c:498
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:564
struct digest_algorithm * digest
Digest algorithm.
Definition: ecdsa.c:98
union @391 key
Sense key.
Definition: scsi.h:18

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 865 of file ecdsa.c.

867  {
868  struct ecdsa_context ctx;
869  struct asn1_cursor cursor;
870  int rc;
871 
872  /* Initialise context */
873  if ( ( rc = ecdsa_init ( &ctx, key, digest, value ) ) != 0 )
874  goto err_init;
875 
876  /* Enter sequence */
877  memcpy ( &cursor, signature, sizeof ( cursor ) );
878  asn1_enter ( &cursor, ASN1_SEQUENCE );
879 
880  /* Extract "r" and "s" values */
881  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.r0, &cursor ) ) != 0 )
882  goto err_r;
883  asn1_skip_any ( &cursor );
884  if ( ( rc = ecdsa_parse_signature ( &ctx, ctx.s0, &cursor ) ) != 0 )
885  goto err_s;
886 
887  /* Verify signature */
888  if ( ( rc = ecdsa_verify_rs ( &ctx ) ) != 0 )
889  goto err_verify;
890 
891  /* Free context */
892  ecdsa_free ( &ctx );
893 
894  return 0;
895 
896  err_verify:
897  err_s:
898  err_r:
899  ecdsa_free ( &ctx );
900  err_init:
901  return rc;
902 }
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition: ecdsa.c:425
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:169
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
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:290
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:92
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:90
static int ecdsa_init(struct ecdsa_context *ctx, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value)
Initialise ECDSA context.
Definition: ecdsa.c:498
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
An ASN.1 object cursor.
Definition: asn1.h:21
union @391 key
Sense key.
Definition: scsi.h:18
static int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
Definition: ecdsa.c:670

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 911 of file ecdsa.c.

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

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 68 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:402
static uint8_t oid_ecpublickey[]
"ecPublicKey" object identifier
Definition: ecdsa.c:68
struct pubkey_algorithm ecdsa_algorithm
ECDSA public-key algorithm.
Definition: ecdsa.c:937

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 75 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:809
static int ecdsa_verify(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Verify signed digest using ECDSA.
Definition: ecdsa.c:865
static int ecdsa_decrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused)
Decrypt using ECDSA.
Definition: ecdsa.c:792
static int ecdsa_encrypt(const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused)
Encrypt using ECDSA.
Definition: ecdsa.c:776
static int ecdsa_match(const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching ECDSA public/private key pair.
Definition: ecdsa.c:911

ECDSA public-key algorithm.

Definition at line 937 of file ecdsa.c.