Skip to content

Commit 6897f52

Browse files
committed
Move RFC6979 hash alg to a new ecc signature options struct
Fixes #700 Signed-off-by: Steffen Jaeckel <[email protected]>
1 parent c421e57 commit 6897f52

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
@@ -281,20 +281,10 @@ typedef struct {
281281

282282
/** The private key */
283283
void *k;
284-
285-
/** The hash algorithm to use when creating a signature.
286-
* Setting this will enable RFC6979 compatible signature generation.
287-
* The macro ECC_SET_RFC6979_HASH_ALG() is provided as a helper
288-
* to set this.*/
289-
const char *rfc6979_hash_alg;
290284
} ecc_key;
291285

292-
#define ECC_SET_RFC6979_HASH_ALG(key, alg) do { \
293-
(key)->rfc6979_hash_alg = (alg); \
294-
} while(0)
295-
296286
/** Formats of ECC signatures */
297-
typedef enum ecc_signature_type_ {
287+
typedef enum ecc_signature_type {
298288
/* ASN.1 encoded, ANSI X9.62 */
299289
LTC_ECCSIG_ANSIX962 = 0x0,
300290
/* raw R, S values */
@@ -305,6 +295,28 @@ typedef enum ecc_signature_type_ {
305295
LTC_ECCSIG_RFC5656 = 0x3,
306296
} ecc_signature_type;
307297

298+
typedef struct ltc_ecc_sig_opts {
299+
/** Signature type */
300+
ecc_signature_type type;
301+
/** The PRNG to use.
302+
* This must be set in case deterministic signature generation
303+
* according to RFC6979 is not enabled.
304+
*/
305+
prng_state *prng;
306+
int wprng;
307+
308+
/** Enable generation of a recovery ID.
309+
* This must be set in case one requires the recovery ID of a
310+
* signature operation.
311+
*/
312+
int *recid;
313+
314+
/** The hash algorithm to use when creating a signature.
315+
* Setting this will enable RFC6979 compatible signature generation.
316+
*/
317+
const char *rfc6979_hash_alg;
318+
} ltc_ecc_sig_opts;
319+
308320
/** the ECC params provided */
309321
extern const ltc_ecc_curve ltc_ecc_curves[];
310322

@@ -340,6 +352,21 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_k
340352
int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key,
341353
unsigned char *out, unsigned long *outlen);
342354

355+
int ecc_sign_hash_v2(const unsigned char *in,
356+
unsigned long inlen,
357+
unsigned char *out,
358+
unsigned long *outlen,
359+
ltc_ecc_sig_opts *opts,
360+
const ecc_key *key);
361+
362+
int ecc_verify_hash_v2(const unsigned char *sig,
363+
unsigned long siglen,
364+
const unsigned char *hash,
365+
unsigned long hashlen,
366+
ltc_ecc_sig_opts *opts,
367+
int *stat,
368+
const ecc_key *key);
369+
343370
#if defined(LTC_DER)
344371
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
345372
unsigned char *out, unsigned long *outlen,
@@ -349,7 +376,42 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
349376
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
350377
unsigned char *out, unsigned long *outlen,
351378
const ecc_key *key);
352-
379+
#endif /* LTC_DER */
380+
381+
#define ltc_ecc_sign_hash(i, il, o, ol, p, wp, k) \
382+
ecc_sign_hash_v2(i, il, o, ol, \
383+
&(ltc_ecc_sig_opts){ \
384+
.type = LTC_ECCSIG_ANSIX962, \
385+
.prng = p, \
386+
.wprng = wp, \
387+
}, k)
388+
#define ltc_ecc_sign_hash_rfc7518(i, il, o, ol, p, wp, k) \
389+
ecc_sign_hash_v2(i, il, o, ol, \
390+
&(ltc_ecc_sig_opts){ \
391+
.type = LTC_ECCSIG_RFC7518, \
392+
.prng = p, \
393+
.wprng = wp, \
394+
}, k)
395+
396+
#define ltc_ecc_verify_hash(s, sl, h, hl, st, k) \
397+
ecc_verify_hash_v2(s, sl, h, hl, \
398+
&(ltc_ecc_sig_opts){ \
399+
.type = LTC_ECCSIG_ANSIX962, \
400+
}, st, k)
401+
#define ltc_ecc_verify_hash_rfc7518(s, sl, h, hl, st, k) \
402+
ecc_verify_hash_v2(s, sl, h, hl, \
403+
&(ltc_ecc_sig_opts){ \
404+
.type = LTC_ECCSIG_RFC7518, \
405+
}, st, k)
406+
407+
#ifdef LTC_NO_DEPRECATED_APIS
408+
#define ecc_sign_hash ltc_ecc_sign_hash
409+
#define ecc_verify_hash ltc_ecc_verify_hash
410+
#define ecc_sign_hash_rfc7518 ltc_ecc_sign_hash_rfc7518
411+
#define ecc_verify_hash_rfc7518 ltc_ecc_verify_hash_rfc7518
412+
#else /* LTC_NO_DEPRECATED_APIS */
413+
#if defined(LTC_DER)
414+
LTC_DEPRECATED(ecc_sign_hash_v2)
353415
int ecc_sign_hash(const unsigned char *in,
354416
unsigned long inlen,
355417
unsigned char *out,
@@ -358,14 +420,16 @@ int ecc_sign_hash(const unsigned char *in,
358420
int wprng,
359421
const ecc_key *key);
360422

423+
LTC_DEPRECATED(ecc_verify_hash_v2)
361424
int ecc_verify_hash(const unsigned char *sig,
362425
unsigned long siglen,
363426
const unsigned char *hash,
364427
unsigned long hashlen,
365428
int *stat,
366429
const ecc_key *key);
367-
#endif
430+
#endif /* LTC_DER */
368431

432+
LTC_DEPRECATED(ecc_sign_hash_v2)
369433
int ecc_sign_hash_rfc7518(const unsigned char *in,
370434
unsigned long inlen,
371435
unsigned char *out,
@@ -374,60 +438,20 @@ int ecc_sign_hash_rfc7518(const unsigned char *in,
374438
int wprng,
375439
const ecc_key *key);
376440

377-
int ecc_sign_hash_rfc7518_ex(const unsigned char *in,
378-
unsigned long inlen,
379-
unsigned char *out,
380-
unsigned long *outlen,
381-
prng_state *prng,
382-
int wprng,
383-
int *recid,
384-
const ecc_key *key);
385-
441+
LTC_DEPRECATED(ecc_verify_hash_v2)
386442
int ecc_verify_hash_rfc7518(const unsigned char *sig,
387443
unsigned long siglen,
388444
const unsigned char *hash,
389445
unsigned long hashlen,
390446
int *stat,
391447
const ecc_key *key);
392-
393-
#if defined(LTC_SSH)
394-
int ecc_sign_hash_rfc5656(const unsigned char *in,
395-
unsigned long inlen,
396-
unsigned char *out,
397-
unsigned long *outlen,
398-
prng_state *prng,
399-
int wprng,
400-
const ecc_key *key);
401-
402-
int ecc_verify_hash_rfc5656(const unsigned char *sig,
403-
unsigned long siglen,
404-
const unsigned char *hash,
405-
unsigned long hashlen,
406-
int *stat,
407-
const ecc_key *key);
408-
#endif
409-
410-
int ecc_sign_hash_eth27(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_eth27(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);
448+
#endif /* LTC_NO_DEPRECATED_APIS */
424449

425450
int ecc_recover_key(const unsigned char *sig,
426451
unsigned long siglen,
427452
const unsigned char *hash,
428453
unsigned long hashlen,
429-
int recid,
430-
ecc_signature_type sigformat,
454+
ltc_ecc_sig_opts *opts,
431455
ecc_key *key);
432456

433457
#endif

src/headers/tomcrypt_private.h

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

444+
int ecc_sign_hash_rfc7518_internal(const unsigned char *in,
445+
unsigned long inlen,
446+
unsigned char *out,
447+
unsigned long *outlen,
448+
ltc_ecc_sig_opts *opts,
449+
const ecc_key *key);
450+
451+
int ecc_verify_hash_rfc7518_internal(const unsigned char *sig,
452+
unsigned long siglen,
453+
const unsigned char *hash,
454+
unsigned long hashlen,
455+
int *stat,
456+
const ecc_key *key);
457+
458+
#ifdef LTC_DER
459+
int ecc_verify_hash_x962(const unsigned char *sig,
460+
unsigned long siglen,
461+
const unsigned char *hash,
462+
unsigned long hashlen,
463+
int *stat,
464+
const ecc_key *key);
465+
int ecc_sign_hash_x962(const unsigned char *in,
466+
unsigned long inlen,
467+
unsigned char *out,
468+
unsigned long *outlen,
469+
ltc_ecc_sig_opts *opts,
470+
const ecc_key *key);
471+
#endif
472+
473+
#if defined(LTC_SSH)
474+
int ecc_sign_hash_rfc5656(const unsigned char *in,
475+
unsigned long inlen,
476+
unsigned char *out,
477+
unsigned long *outlen,
478+
ltc_ecc_sig_opts *opts,
479+
const ecc_key *key);
480+
481+
int ecc_verify_hash_rfc5656(const unsigned char *sig,
482+
unsigned long siglen,
483+
const unsigned char *hash,
484+
unsigned long hashlen,
485+
int *stat,
486+
const ecc_key *key);
487+
#endif
488+
489+
int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen,
490+
unsigned char *out, unsigned long *outlen,
491+
ltc_ecc_sig_opts *opts, const ecc_key *key);
492+
493+
int ecc_verify_hash_eth27(const unsigned char *sig, unsigned long siglen,
494+
const unsigned char *hash, unsigned long hashlen,
495+
int *stat, const ecc_key *key);
444496
int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen,
445-
void *r, void *s, prng_state *prng, int wprng,
446-
int *recid, const ecc_key *key);
497+
void *r, void *s, ltc_ecc_sig_opts *opts, const ecc_key *key);
447498

448499
int ecc_verify_hash_internal(void *r, void *s,
449500
const unsigned char *hash, unsigned long hashlen,
450501
int *stat, const ecc_key *key);
451502

452-
int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key);
503+
int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, const char *rfc6979_hash_alg, ecc_key *key);
453504

454505
#ifdef LTC_SSH
455506
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)