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

Variables

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

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.

46#define EINVAL_POINTSIZE \
47 __einfo_error ( EINFO_EINVAL_POINTSIZE )

Referenced by ecdsa_parse_key().

◆ EINFO_EINVAL_POINTSIZE

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

Definition at line 48 of file ecdsa.c.

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

◆ EINVAL_KEYSIZE

#define EINVAL_KEYSIZE    __einfo_error ( EINFO_EINVAL_KEYSIZE )

Definition at line 50 of file ecdsa.c.

50#define EINVAL_KEYSIZE \
51 __einfo_error ( EINFO_EINVAL_KEYSIZE )

Referenced by ecdsa_parse_key(), and ecdsa_parse_signature().

◆ EINFO_EINVAL_KEYSIZE

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

Definition at line 52 of file ecdsa.c.

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

◆ EINVAL_COMPRESSION

#define EINVAL_COMPRESSION    __einfo_error ( EINFO_EINVAL_COMPRESSION )

Definition at line 54 of file ecdsa.c.

54#define EINVAL_COMPRESSION \
55 __einfo_error ( EINFO_EINVAL_COMPRESSION )

Referenced by ecdsa_parse_key().

◆ EINFO_EINVAL_COMPRESSION

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

Definition at line 56 of file ecdsa.c.

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

◆ EINVAL_INFINITY

#define EINVAL_INFINITY    __einfo_error ( EINFO_EINVAL_INFINITY )

Definition at line 58 of file ecdsa.c.

58#define EINVAL_INFINITY \
59 __einfo_error ( EINFO_EINVAL_INFINITY )

Referenced by ecdsa_parse_key().

◆ EINFO_EINVAL_INFINITY

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

Definition at line 60 of file ecdsa.c.

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

◆ EINVAL_SIGNATURE

#define EINVAL_SIGNATURE    __einfo_error ( EINFO_EINVAL_SIGNATURE )

Definition at line 62 of file ecdsa.c.

62#define EINVAL_SIGNATURE \
63 __einfo_error ( EINFO_EINVAL_SIGNATURE )

Referenced by ecdsa_verify_rs().

◆ EINFO_EINVAL_SIGNATURE

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

Definition at line 64 of file ecdsa.c.

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ ecdsa_parse_key()

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 {
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}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
__be32 raw[7]
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
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
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition asn1.c:280
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition asn1.c:231
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition asn1.c:311
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition asn1.h:99
static void asn1_invalidate_cursor(struct asn1_cursor *cursor)
Invalidate ASN.1 object cursor.
Definition asn1.h:468
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:479
ring len
Length.
Definition dwmac.h:226
#define EINVAL_INFINITY
Definition ecdsa.c:58
#define EINVAL_POINTSIZE
Definition ecdsa.c:46
#define EINVAL_COMPRESSION
Definition ecdsa.c:54
#define EINVAL_KEYSIZE
Definition ecdsa.c:50
#define ECDSA_UNCOMPRESSED
Uncompressed curve point.
Definition ecdsa.h:16
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition ieee80211.h:1
static int elliptic_is_infinity(struct elliptic_curve *curve, const void *point)
Definition crypto.h:322
void * memcpy(void *dest, const void *src, size_t len) __nonnull
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An ASN.1 OID-identified algorithm.
Definition asn1.h:408
An ASN.1 object cursor.
Definition asn1.h:21

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()

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}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition asn1.c:369
uint16_t size
Buffer size.
Definition dwmac.h:3
#define ERANGE
Result too large.
Definition errno.h:640
#define __attribute__(x)
Definition compiler.h:10
#define bigint_is_geq(value, reference)
Compare big integers.
Definition bigint.h:145
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition bigint.h:134
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
u16 keysize
Length of encryption key to be used, network byte order.
Definition wpa.h:10

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()

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}
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:11
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75

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

Referenced by ecdsa_sign().

◆ ecdsa_alloc()

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}
#define ENOMEM
Not enough space.
Definition errno.h:535
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:31
uint8_t product
Product string.
Definition smbios.h:5
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static const uint8_t r[3][4]
MD4 shift amounts.
Definition md4.c:54
static const uint32_t k[64]
MD5 constants.
Definition md5.c:54
An elliptic curve.
Definition crypto.h:178
size_t keysize
Scalar (and private key) size.
Definition crypto.h:184
size_t pointsize
Point (and public key) size.
Definition crypto.h:182

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

Referenced by ecdsa_init().

◆ ecdsa_free()

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}
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()

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}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define DBGC2(...)
Definition compiler.h:522
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:209
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition bigint.h:274
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:99
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition bigint.h:314
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:235
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition bigint.h:50
size_t digestsize
Digest size.
Definition crypto.h:27
const char * name
Algorithm name.
Definition crypto.h:21
const void * order
Order of the generator (if prime)
Definition crypto.h:188

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()

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 int ecdsa_parse_key(struct ecdsa_key *key, const struct asn1_cursor *raw)
Parse ECDSA key.
Definition ecdsa.c:141
static void ecdsa_init_values(struct ecdsa_context *ctx, struct digest_algorithm *digest, const void *value)
Initialise ECDSA values.
Definition ecdsa.c:438
static int ecdsa_alloc(struct ecdsa_context *ctx)
Allocate ECDSA context dynamic storage.
Definition ecdsa.c:371
static void ecdsa_free(struct ecdsa_context *ctx)
Free ECDSA context dynamic storage.
Definition ecdsa.c:425

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()

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}
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
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition bigint.h:330
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition bigint.h:260
void __asmcall int val
Definition setjmp.h:12

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()

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}
static void ecdsa_invert(struct ecdsa_context *ctx, bigint_element_t *val0)
Invert ECDSA value.
Definition ecdsa.c:529
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 bigint_add(addend, value)
Add big integers.
Definition bigint.h:87
static int elliptic_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Definition crypto.h:327
A message digest algorithm.
Definition crypto.h:19
const void * base
Generator base point.
Definition crypto.h:186

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, elliptic_curve::keysize, keysize, NULL, elliptic_curve::pointsize, product, r, rc, size, and strerror().

Referenced by ecdsa_sign().

◆ ecdsa_verify_rs()

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 EINVAL_SIGNATURE
Definition ecdsa.c:62
#define EINVAL
Invalid argument.
Definition errno.h:429
static int elliptic_add(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
Definition crypto.h:333

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(), elliptic_curve::keysize, keysize, elliptic_curve::pointsize, product, r, rc, size, and strerror().

Referenced by ecdsa_verify().

◆ ecdsa_encrypt()

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 __unused, ENOTTY, and key.

◆ ecdsa_decrypt()

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}

References __unused, ENOTTY, and key.

◆ ecdsa_sign()

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}
u8 signature
CPU signature.
Definition CIB_PRM.h:7
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition asn1.c:999
static int ecdsa_sign_rs(struct ecdsa_context *ctx)
Generate ECDSA "r" and "s" values.
Definition ecdsa.c:564
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
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
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
ECDSA context.
Definition ecdsa.c:92
struct digest_algorithm * digest
Digest algorithm.
Definition ecdsa.c:98

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()

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 int ecdsa_verify_rs(struct ecdsa_context *ctx)
Verify ECDSA "r" and "s" values.
Definition ecdsa.c:670
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

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()

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}
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
An ECDSA key.
Definition ecdsa.c:82
struct elliptic_curve * curve
Elliptic curve.
Definition ecdsa.c:84
A private key.
Definition privkey.h:17

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.

#define ASN1_OID_ECPUBLICKEY
ASN.1 OID for ecPublicKey (1.2.840.10045.2.1)
Definition asn1.h:132

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

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.

75 {
76 .name = "ecPublicKey",
78 .pubkey = &ecdsa_algorithm,
79};

◆ 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_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_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_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
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

ECDSA public-key algorithm.

Definition at line 937 of file ecdsa.c.

937 {
938 .name = "ecdsa",
939 .encrypt = ecdsa_encrypt,
940 .decrypt = ecdsa_decrypt,
941 .sign = ecdsa_sign,
942 .verify = ecdsa_verify,
943 .match = ecdsa_match,
944};

Referenced by __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), PUBKEY_SIGN_TEST(), PUBKEY_SIGN_TEST(), PUBKEY_SIGN_TEST(), and PUBKEY_SIGN_TEST().