Skip to content

Commit b7ac3af

Browse files
committed
Move RFC6979 hash alg to a new ecc signature options struct
Fixes #700 Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 4c6f234 commit b7ac3af

20 files changed

+500
-231
lines changed

demos/timing.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ static void time_ecc(void)
872872
unsigned char buf[2][256] = { 0 };
873873
unsigned long i, w, x, y, z;
874874
int err, stat;
875-
static unsigned long sizes[] = {
875+
const unsigned long sizes[] = {
876876
#ifdef LTC_ECC_SECP112R1
877877
112/8,
878878
#endif
@@ -898,6 +898,11 @@ static void time_ecc(void)
898898
521/8,
899899
#endif
900900
100000};
901+
ltc_ecc_sig_opts sig_opts = {
902+
.type = LTC_ECCSIG_RFC7518,
903+
.prng = &yarrow_prng,
904+
.wprng = find_prng ("yarrow")
905+
};
901906

902907
if (ltc_mp.name == NULL) return;
903908

@@ -969,8 +974,7 @@ static void time_ecc(void)
969974
t_start();
970975
t1 = t_read();
971976
z = sizeof(buf[1]);
972-
if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
973-
find_prng("yarrow"), &key)) != CRYPT_OK) {
977+
if ((err = ecc_sign_hash_v2(buf[0], 20, buf[1], &z, &sig_opts, &key)) != CRYPT_OK) {
974978
fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
975979
exit(EXIT_FAILURE);
976980
}
@@ -988,7 +992,7 @@ static void time_ecc(void)
988992
for (y = 0; y < 256; y++) {
989993
t_start();
990994
t1 = t_read();
991-
if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) {
995+
if ((err = ecc_verify_hash_v2(buf[1], z, buf[0], 20, &sig_opts, &stat, &key)) != CRYPT_OK) {
992996
fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
993997
exit(EXIT_FAILURE);
994998
}

src/headers/tomcrypt_pk.h

Lines changed: 80 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -297,20 +297,10 @@ typedef struct {
297297

298298
/** The private key */
299299
void *k;
300-
301-
/** The hash algorithm to use when creating a signature.
302-
* Setting this will enable RFC6979 compatible signature generation.
303-
* The macro ECC_SET_RFC6979_HASH_ALG() is provided as a helper
304-
* to set this.*/
305-
const char *rfc6979_hash_alg;
306300
} ecc_key;
307301

308-
#define ECC_SET_RFC6979_HASH_ALG(key, alg) do { \
309-
(key)->rfc6979_hash_alg = (alg); \
310-
} while(0)
311-
312302
/** Formats of ECC signatures */
313-
typedef enum ecc_signature_type_ {
303+
typedef enum ecc_signature_type {
314304
/* ASN.1 encoded, ANSI X9.62 */
315305
LTC_ECCSIG_ANSIX962 = 0x0,
316306
/* raw R, S values */
@@ -321,6 +311,28 @@ typedef enum ecc_signature_type_ {
321311
LTC_ECCSIG_RFC5656 = 0x3,
322312
} ecc_signature_type;
323313

314+
typedef struct ltc_ecc_sig_opts {
315+
/** Signature type */
316+
ecc_signature_type type;
317+
/** The PRNG to use.
318+
* This must be set in case deterministic signature generation
319+
* according to RFC6979 is not enabled.
320+
*/
321+
prng_state *prng;
322+
int wprng;
323+
324+
/** Enable generation of a recovery ID.
325+
* This must be set in case one requires the recovery ID of a
326+
* signature operation.
327+
*/
328+
int *recid;
329+
330+
/** The hash algorithm to use when creating a signature.
331+
* Setting this will enable RFC6979 compatible signature generation.
332+
*/
333+
const char *rfc6979_hash_alg;
334+
} ltc_ecc_sig_opts;
335+
324336
/** the ECC params provided */
325337
extern const ltc_ecc_curve ltc_ecc_curves[];
326338

@@ -356,6 +368,21 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_k
356368
int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key,
357369
unsigned char *out, unsigned long *outlen);
358370

371+
int ecc_sign_hash_v2(const unsigned char *in,
372+
unsigned long inlen,
373+
unsigned char *out,
374+
unsigned long *outlen,
375+
ltc_ecc_sig_opts *opts,
376+
const ecc_key *key);
377+
378+
int ecc_verify_hash_v2(const unsigned char *sig,
379+
unsigned long siglen,
380+
const unsigned char *hash,
381+
unsigned long hashlen,
382+
ltc_ecc_sig_opts *opts,
383+
int *stat,
384+
const ecc_key *key);
385+
359386
#if defined(LTC_DER)
360387
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
361388
unsigned char *out, unsigned long *outlen,
@@ -365,7 +392,42 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
365392
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
366393
unsigned char *out, unsigned long *outlen,
367394
const ecc_key *key);
368-
395+
#endif /* LTC_DER */
396+
397+
#define ltc_ecc_sign_hash(i, il, o, ol, p, wp, k) \
398+
ecc_sign_hash_v2(i, il, o, ol, \
399+
&(ltc_ecc_sig_opts){ \
400+
.type = LTC_ECCSIG_ANSIX962, \
401+
.prng = p, \
402+
.wprng = wp, \
403+
}, k)
404+
#define ltc_ecc_sign_hash_rfc7518(i, il, o, ol, p, wp, k) \
405+
ecc_sign_hash_v2(i, il, o, ol, \
406+
&(ltc_ecc_sig_opts){ \
407+
.type = LTC_ECCSIG_RFC7518, \
408+
.prng = p, \
409+
.wprng = wp, \
410+
}, k)
411+
412+
#define ltc_ecc_verify_hash(s, sl, h, hl, st, k) \
413+
ecc_verify_hash_v2(s, sl, h, hl, \
414+
&(ltc_ecc_sig_opts){ \
415+
.type = LTC_ECCSIG_ANSIX962, \
416+
}, st, k)
417+
#define ltc_ecc_verify_hash_rfc7518(s, sl, h, hl, st, k) \
418+
ecc_verify_hash_v2(s, sl, h, hl, \
419+
&(ltc_ecc_sig_opts){ \
420+
.type = LTC_ECCSIG_RFC7518, \
421+
}, st, k)
422+
423+
#ifdef LTC_NO_DEPRECATED_APIS
424+
#define ecc_sign_hash ltc_ecc_sign_hash
425+
#define ecc_verify_hash ltc_ecc_verify_hash
426+
#define ecc_sign_hash_rfc7518 ltc_ecc_sign_hash_rfc7518
427+
#define ecc_verify_hash_rfc7518 ltc_ecc_verify_hash_rfc7518
428+
#else /* LTC_NO_DEPRECATED_APIS */
429+
#if defined(LTC_DER)
430+
LTC_DEPRECATED(ecc_sign_hash_v2)
369431
int ecc_sign_hash(const unsigned char *in,
370432
unsigned long inlen,
371433
unsigned char *out,
@@ -374,14 +436,16 @@ int ecc_sign_hash(const unsigned char *in,
374436
int wprng,
375437
const ecc_key *key);
376438

439+
LTC_DEPRECATED(ecc_verify_hash_v2)
377440
int ecc_verify_hash(const unsigned char *sig,
378441
unsigned long siglen,
379442
const unsigned char *hash,
380443
unsigned long hashlen,
381444
int *stat,
382445
const ecc_key *key);
383-
#endif
446+
#endif /* LTC_DER */
384447

448+
LTC_DEPRECATED(ecc_sign_hash_v2)
385449
int ecc_sign_hash_rfc7518(const unsigned char *in,
386450
unsigned long inlen,
387451
unsigned char *out,
@@ -390,60 +454,20 @@ int ecc_sign_hash_rfc7518(const unsigned char *in,
390454
int wprng,
391455
const ecc_key *key);
392456

393-
int ecc_sign_hash_rfc7518_ex(const unsigned char *in,
394-
unsigned long inlen,
395-
unsigned char *out,
396-
unsigned long *outlen,
397-
prng_state *prng,
398-
int wprng,
399-
int *recid,
400-
const ecc_key *key);
401-
457+
LTC_DEPRECATED(ecc_verify_hash_v2)
402458
int ecc_verify_hash_rfc7518(const unsigned char *sig,
403459
unsigned long siglen,
404460
const unsigned char *hash,
405461
unsigned long hashlen,
406462
int *stat,
407463
const ecc_key *key);
408-
409-
#if defined(LTC_SSH)
410-
int ecc_sign_hash_rfc5656(const unsigned char *in,
411-
unsigned long inlen,
412-
unsigned char *out,
413-
unsigned long *outlen,
414-
prng_state *prng,
415-
int wprng,
416-
const ecc_key *key);
417-
418-
int ecc_verify_hash_rfc5656(const unsigned char *sig,
419-
unsigned long siglen,
420-
const unsigned char *hash,
421-
unsigned long hashlen,
422-
int *stat,
423-
const ecc_key *key);
424-
#endif
425-
426-
int ecc_sign_hash_eth27(const unsigned char *in,
427-
unsigned long inlen,
428-
unsigned char *out,
429-
unsigned long *outlen,
430-
prng_state *prng,
431-
int wprng,
432-
const ecc_key *key);
433-
434-
int ecc_verify_hash_eth27(const unsigned char *sig,
435-
unsigned long siglen,
436-
const unsigned char *hash,
437-
unsigned long hashlen,
438-
int *stat,
439-
const ecc_key *key);
464+
#endif /* LTC_NO_DEPRECATED_APIS */
440465

441466
int ecc_recover_key(const unsigned char *sig,
442467
unsigned long siglen,
443468
const unsigned char *hash,
444469
unsigned long hashlen,
445-
int recid,
446-
ecc_signature_type sigformat,
470+
ltc_ecc_sig_opts *opts,
447471
ecc_key *key);
448472

449473
#endif

src/headers/tomcrypt_private.h

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,15 +473,66 @@ int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_ke
473473
int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key);
474474
int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key);
475475

476+
int ecc_sign_hash_rfc7518_internal(const unsigned char *in,
477+
unsigned long inlen,
478+
unsigned char *out,
479+
unsigned long *outlen,
480+
ltc_ecc_sig_opts *opts,
481+
const ecc_key *key);
482+
483+
int ecc_verify_hash_rfc7518_internal(const unsigned char *sig,
484+
unsigned long siglen,
485+
const unsigned char *hash,
486+
unsigned long hashlen,
487+
int *stat,
488+
const ecc_key *key);
489+
490+
#ifdef LTC_DER
491+
int ecc_verify_hash_x962(const unsigned char *sig,
492+
unsigned long siglen,
493+
const unsigned char *hash,
494+
unsigned long hashlen,
495+
int *stat,
496+
const ecc_key *key);
497+
int ecc_sign_hash_x962(const unsigned char *in,
498+
unsigned long inlen,
499+
unsigned char *out,
500+
unsigned long *outlen,
501+
ltc_ecc_sig_opts *opts,
502+
const ecc_key *key);
503+
#endif
504+
505+
#if defined(LTC_SSH)
506+
int ecc_sign_hash_rfc5656(const unsigned char *in,
507+
unsigned long inlen,
508+
unsigned char *out,
509+
unsigned long *outlen,
510+
ltc_ecc_sig_opts *opts,
511+
const ecc_key *key);
512+
513+
int ecc_verify_hash_rfc5656(const unsigned char *sig,
514+
unsigned long siglen,
515+
const unsigned char *hash,
516+
unsigned long hashlen,
517+
int *stat,
518+
const ecc_key *key);
519+
#endif
520+
521+
int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen,
522+
unsigned char *out, unsigned long *outlen,
523+
ltc_ecc_sig_opts *opts, const ecc_key *key);
524+
525+
int ecc_verify_hash_eth27(const unsigned char *sig, unsigned long siglen,
526+
const unsigned char *hash, unsigned long hashlen,
527+
int *stat, const ecc_key *key);
476528
int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen,
477-
void *r, void *s, prng_state *prng, int wprng,
478-
int *recid, const ecc_key *key);
529+
void *r, void *s, ltc_ecc_sig_opts *opts, const ecc_key *key);
479530

480531
int ecc_verify_hash_internal(void *r, void *s,
481532
const unsigned char *hash, unsigned long hashlen,
482533
int *stat, const ecc_key *key);
483534

484-
int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key);
535+
int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, const char *rfc6979_hash_alg, ecc_key *key);
485536

486537
#ifdef LTC_SSH
487538
int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key);

src/misc/deprecated.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
4+
#include "tomcrypt_private.h"
5+
6+
#ifndef LTC_NO_DEPRECATED_APIS
7+
8+
#ifdef LTC_MECC
9+
/**
10+
Sign a message digest (ANSI X9.62 format)
11+
@param in The message digest to sign
12+
@param inlen The length of the digest
13+
@param out [out] The destination for the signature
14+
@param outlen [in/out] The max size and resulting size of the signature
15+
@param prng An active PRNG state
16+
@param wprng The index of the PRNG you wish to use
17+
@param key A private ECC key
18+
@return CRYPT_OK if successful
19+
*/
20+
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
21+
unsigned char *out, unsigned long *outlen,
22+
prng_state *prng, int wprng, const ecc_key *key)
23+
{
24+
return ltc_ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key);
25+
}
26+
27+
/**
28+
Verify an ECC signature (ANSI X9.62 format)
29+
@param sig The signature to verify
30+
@param siglen The length of the signature (octets)
31+
@param hash The hash (message digest) that was signed
32+
@param hashlen The length of the hash (octets)
33+
@param stat [out] Result of signature, 1==valid, 0==invalid
34+
@param key The corresponding public ECC key
35+
@return CRYPT_OK if successful (even if the signature is not valid)
36+
*/
37+
int ecc_verify_hash(const unsigned char *sig,
38+
unsigned long siglen,
39+
const unsigned char *hash,
40+
unsigned long hashlen,
41+
int *stat,
42+
const ecc_key *key)
43+
{
44+
return ltc_ecc_verify_hash(sig, siglen, hash, hashlen, stat, key);
45+
}
46+
47+
/**
48+
Sign a message digest (RFC7518 format)
49+
@param in The message digest to sign
50+
@param inlen The length of the digest
51+
@param out [out] The destination for the signature
52+
@param outlen [in/out] The max size and resulting size of the signature
53+
@param opts The signature options that shall be applied
54+
@param key A private ECC key
55+
@return CRYPT_OK if successful
56+
*/
57+
int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen,
58+
unsigned char *out, unsigned long *outlen,
59+
prng_state *prng, int wprng, const ecc_key *key)
60+
{
61+
return ltc_ecc_sign_hash_rfc7518(in, inlen, out, outlen, prng, wprng, key);
62+
}
63+
64+
/**
65+
Verify an ECC signature (RFC7518 format)
66+
@param sig The signature to verify
67+
@param siglen The length of the signature (octets)
68+
@param hash The hash (message digest) that was signed
69+
@param hashlen The length of the hash (octets)
70+
@param stat [out] Result of signature, 1==valid, 0==invalid
71+
@param key The corresponding public ECC key
72+
@return CRYPT_OK if successful (even if the signature is not valid)
73+
*/
74+
int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen,
75+
const unsigned char *hash, unsigned long hashlen,
76+
int *stat, const ecc_key *key)
77+
{
78+
return ltc_ecc_verify_hash_rfc7518(sig, siglen, hash, hashlen, stat, key);
79+
}
80+
#endif /* LTC_MECC */
81+
82+
#endif /* LTC_NO_DEPRECATED_APIS */

src/pk/ecc/ecc_make_key.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key)
5959
goto error;
6060
}
6161
key->type = PK_PRIVATE;
62-
key->rfc6979_hash_alg = NULL;
6362

6463
/* success */
6564
err = CRYPT_OK;

0 commit comments

Comments
 (0)