From 9d6689fc086df22cd51fa3d98f9b6f56e77419d0 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 27 Jun 2017 21:54:16 +0200 Subject: [PATCH] re-factor dh_make_key() and variants --- demos/timing.c | 9 ++- src/headers/tomcrypt_pk.h | 21 +++---- src/pk/dh/dh_make_key.c | 116 +++----------------------------------- src/pk/dh/dh_set.c | 76 +++++++++++++++++++++++++ tests/dh_test.c | 45 +++++++-------- 5 files changed, 119 insertions(+), 148 deletions(-) diff --git a/demos/timing.c b/demos/timing.c index aa7c9a5..cb249a5 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -889,7 +889,7 @@ static void time_katja(void) { fprintf(stderr, "NO Katja\n"); } /* time various DH operations */ static void time_dh(void) { - dh_key key; + dh_key key = LTC_DH_KEY_INITIALIZER; ulong64 t1, t2; unsigned long i, x, y; int err; @@ -898,9 +898,14 @@ static void time_dh(void) for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { t2 = 0; for (y = 0; y < 16; y++) { + if((err = dh_set_pg_groupsize(x, &key)) != CRYPT_OK) { + fprintf(stderr, "\n\ndh_set_pg_groupsize says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); + exit(EXIT_FAILURE); + } + t_start(); t1 = t_read(); - if ((err = dh_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { + if ((err = dh_make_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 1996cd6..fcb74da 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -217,32 +217,29 @@ typedef struct { int dh_get_groupsize(dh_key *key); -int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key); -int dh_make_key_ex(prng_state *prng, int wprng, int radix, - void *prime, unsigned long primelen, - void *base, unsigned long baselen, - dh_key *key); -int dh_make_key_dhparam(prng_state *prng, int wprng, unsigned char *dhparam, unsigned long dhparamlen, dh_key *key); -void dh_free(dh_key *key); - int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key); int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); int dh_set_pg(const unsigned char *p, unsigned long plen, const unsigned char *g, unsigned long glen, dh_key *key); -/* here we can support either one or both */ +int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key); +int dh_set_pg_groupsize(int groupsize, dh_key *key); + int dh_set_key(const unsigned char *pub, unsigned long publen, const unsigned char *priv, unsigned long privlen, dh_key *key); +int dh_make_key(prng_state *prng, int wprng, dh_key *key); + +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen); + +void dh_free(dh_key *key); int dh_export_radix(int radix, void *out, unsigned long *outlen, int type, dh_key *key); -int dh_shared_secret(dh_key *private_key, dh_key *public_key, - unsigned char *out, unsigned long *outlen); - #ifdef LTC_SOURCE /* internal helper functions */ int dh_check_pubkey(dh_key *key); diff --git a/src/pk/dh/dh_make_key.c b/src/pk/dh/dh_make_key.c index 96bd364..69eaf3c 100644 --- a/src/pk/dh/dh_make_key.c +++ b/src/pk/dh/dh_make_key.c @@ -42,31 +42,25 @@ static int _dh_groupsize_to_keysize(int groupsize) } } -static int _dh_make_key(prng_state *prng, int wprng, void *prime, void *base, dh_key *key) +int dh_make_key(prng_state *prng, int wprng, dh_key *key) { unsigned char *buf; unsigned long keysize; int err, max_iterations = PK_MAX_RETRIES; - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(prng != NULL); - LTC_ARGCHK(prime != NULL); - LTC_ARGCHK(base != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->x != NULL); + LTC_ARGCHK(key->y != NULL); + LTC_ARGCHK(key->base != NULL); + LTC_ARGCHK(key->prime != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(prng != NULL); /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } - /* init big numbers */ - if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { - return err; - } - - /* load the prime and the base */ - if ((err = mp_copy(base, key->base)) != CRYPT_OK) { goto freemp; } - if ((err = mp_copy(prime, key->prime)) != CRYPT_OK) { goto freemp; } - keysize = _dh_groupsize_to_keysize(mp_unsigned_bin_size(key->prime)); if (keysize == 0) { err = CRYPT_INVALID_KEYSIZE; @@ -106,100 +100,6 @@ freemp: return err; } -/** - Make a DH key (custom DH group) [private key pair] - @param prng An active PRNG state - @param wprng The index for the PRNG you desire to use - @param prime_hex The prime p (hexadecimal string) - @param base_hex The base g (hexadecimal string) - @param key [out] Where the newly created DH key will be stored - @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. -*/ -int dh_make_key_ex(prng_state *prng, int wprng, int radix, - void *prime, unsigned long primelen, - void *base, unsigned long baselen, - dh_key *key) -{ - void *p, *b; - int err; - - LTC_ARGCHK(prime != NULL); - LTC_ARGCHK(base != NULL); - LTC_ARGCHK((radix >= 2 && radix <= 64) || radix == 256); - - if ((err = mp_init_multi(&p, &b, NULL)) != CRYPT_OK) { return err; } - if (radix == 256) { - if ((err = mp_read_unsigned_bin(b, base, baselen)) != CRYPT_OK) { goto error; } - if ((err = mp_read_unsigned_bin(p, prime, primelen)) != CRYPT_OK) { goto error; } - } - else { - if ((err = mp_read_radix(b, base, radix)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(p, prime, radix)) != CRYPT_OK) { goto error; } - } - err = _dh_make_key(prng, wprng, p, b, key); - -error: - mp_clear_multi(p, b, NULL); - return err; -} - -/** - Make a DH key (use built-in DH groups) [private key pair] - @param prng An active PRNG state - @param wprng The index for the PRNG you desire to use - @param groupsize The size (octets) of used DH group - @param key [out] Where the newly created DH key will be stored - @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. -*/ -int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key) -{ - int i; - - LTC_ARGCHK(groupsize > 0); - - for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++); - if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE; - - return dh_make_key_ex(prng, wprng, 16, - ltc_dh_sets[i].prime, strlen(ltc_dh_sets[i].prime) + 1, - ltc_dh_sets[i].base, strlen(ltc_dh_sets[i].base) + 1, - key); -} - -/** - Make a DH key (dhparam data: openssl dhparam -outform DER -out dhparam.der 2048) - @param prng An active PRNG state - @param wprng The index for the PRNG you desire to use - @param dhparam The DH param DER encoded data - @param dhparamlen The length of dhparam data - @param key [out] Where the newly created DH key will be stored - @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. -*/ -int dh_make_key_dhparam(prng_state *prng, int wprng, unsigned char *dhparam, unsigned long dhparamlen, dh_key *key) -{ - void *prime, *base; - int err; - - LTC_ARGCHK(dhparam != NULL); - LTC_ARGCHK(dhparamlen > 0); - - if ((err = mp_init_multi(&prime, &base, NULL)) != CRYPT_OK) { - return err; - } - if ((err = der_decode_sequence_multi(dhparam, dhparamlen, - LTC_ASN1_INTEGER, 1UL, prime, - LTC_ASN1_INTEGER, 1UL, base, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto error; - } - err = _dh_make_key(prng, wprng, prime, base, key); - -error: - mp_clear_multi(prime, base, NULL); - return err; -} - - #endif /* LTC_MDH */ /* ref: $Format:%D$ */ diff --git a/src/pk/dh/dh_set.c b/src/pk/dh/dh_set.c index 6ca61d0..820ca22 100644 --- a/src/pk/dh/dh_set.c +++ b/src/pk/dh/dh_set.c @@ -50,6 +50,82 @@ LBL_ERR: return err; } +/** + Import DH key parts p and g from dhparam + + dhparam data: openssl dhparam -outform DER -out dhparam.der 2048 + + @param dhparam The DH param DER encoded data + @param dhparamlen The length of dhparam data + @param key [out] Where the newly created DH key will be stored + @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. +*/ +int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key) +{ + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->x == NULL); + LTC_ARGCHK(key->y == NULL); + LTC_ARGCHK(key->base == NULL); + LTC_ARGCHK(key->prime == NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(dhparam != NULL); + LTC_ARGCHK(dhparamlen > 0); + + if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { + return err; + } + if ((err = der_decode_sequence_multi(dhparam, dhparamlen, + LTC_ASN1_INTEGER, 1UL, key->prime, + LTC_ASN1_INTEGER, 1UL, key->base, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + return CRYPT_OK; + +LBL_ERR: + dh_free(key); + return err; +} + +/** + Import DH key parts p and g from built-in DH groups + + @param dhparam The DH param DER encoded data + @param dhparamlen The length of dhparam data + @param key [out] Where the newly created DH key will be stored + @return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically. +*/ +int dh_set_pg_groupsize(int groupsize, dh_key *key) +{ + int err, i; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key->x == NULL); + LTC_ARGCHK(key->y == NULL); + LTC_ARGCHK(key->base == NULL); + LTC_ARGCHK(key->prime == NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + LTC_ARGCHK(groupsize > 0); + + for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++); + if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE; + + if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { + return err; + } + if ((err = mp_read_radix(key->base, ltc_dh_sets[i].base, 16)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_radix(key->prime, ltc_dh_sets[i].prime, 16)) != CRYPT_OK) { goto LBL_ERR; } + + return CRYPT_OK; + +LBL_ERR: + dh_free(key); + return err; +} + /** Import DH key parts pub and priv from raw numbers diff --git a/tests/dh_test.c b/tests/dh_test.c index dae366d..077157c 100644 --- a/tests/dh_test.c +++ b/tests/dh_test.c @@ -60,7 +60,7 @@ done: static int _dhparam_test(void) { - dh_key k; + dh_key k = LTC_DH_KEY_INITIALIZER; unsigned char buf[1024]; /* generated by: openssl dhparam -outform der -out dhparam.der 2048 */ unsigned char dhparam_der[] = { @@ -126,7 +126,8 @@ static int _dhparam_test(void) 0x98, 0xcb }; - DO(dh_make_key_dhparam(&yarrow_prng, find_prng ("yarrow"), dhparam_der, sizeof(dhparam_der), &k)); + DO(dh_set_pg_dhparam(dhparam_der, sizeof(dhparam_der), &k)); + DO(dh_make_key(&yarrow_prng, find_prng ("yarrow"), &k)); if (mp_unsigned_bin_size(k.prime) > sizeof(buf)) { printf("dhparam_test: short buf\n"); dh_free(&k); @@ -316,11 +317,6 @@ static int _radix_test(void) unsigned char key_parts[4][512]; unsigned long key_lens[4]; - if (register_prng(&yarrow_desc) == -1) { - printf("Error registering yarrow PRNG\n"); - return CRYPT_ERROR; - } - for (i = 0; i < 4; i++) { for (j = 0; j < 4; ++j) { key_lens[j] = sizeof(key_parts[j]); @@ -408,8 +404,14 @@ static int _radix_test(void) } dh_free(&k2); - DO(dh_make_key_ex(&yarrow_prng, find_prng("yarrow"), test[i].radix, - test[i].p, test[i].plen, test[i].g, test[i].glen, &k3)); + if(test[i].radix != 256) { + DO(dh_set_pg(key_parts[2], key_lens[2], key_parts[3], key_lens[3], &k3)); + } + else { + DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k3)); + } + + DO(dh_make_key(&yarrow_prng, find_prng("yarrow"), &k3)); len = mp_unsigned_bin_size(k3.prime); DO(mp_to_unsigned_bin(k3.prime, buf)); if (compare_testvector(buf, len, pbin, sizeof(pbin), "radix_test", i*10 + 8)) { @@ -435,20 +437,14 @@ static int _basic_test(void) unsigned char buf[3][4096]; unsigned long x, y, z; int size; - dh_key usera, userb; - - if (register_prng(&yarrow_desc) == -1) { - printf("Error registering yarrow PRNG\n"); - return CRYPT_ERROR; - } - if (register_hash(&md5_desc) == -1) { - printf("Error registering md5 hash\n"); - return CRYPT_ERROR; - } + dh_key usera = LTC_DH_KEY_INITIALIZER; + dh_key userb = LTC_DH_KEY_INITIALIZER; /* make up two keys */ - DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), KEYSIZE/8, &usera)); - DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), KEYSIZE/8, &userb)); + DO(dh_set_pg_groupsize(KEYSIZE/8, &usera)); + DO(dh_make_key(&yarrow_prng, find_prng ("yarrow"), &usera)); + DO(dh_set_pg_groupsize(KEYSIZE/8, &userb)); + DO(dh_make_key(&yarrow_prng, find_prng ("yarrow"), &userb)); /* make the shared secret */ x = KEYSIZE; @@ -492,17 +488,14 @@ static int _basic_test(void) } for (x = 0; ltc_dh_sets[x].size != 0; x++) { - DO(dh_make_key(&yarrow_prng, find_prng ("yarrow"), ltc_dh_sets[x].size, &usera)); + DO(dh_set_pg_groupsize(ltc_dh_sets[x].size, &usera)); + DO(dh_make_key(&yarrow_prng, find_prng ("yarrow"), &usera)); size = dh_get_groupsize(&usera); dh_free(&usera); if (size != ltc_dh_sets[x].size) { fprintf(stderr, "dh_groupsize mismatch %d %d\n", size, ltc_dh_sets[x].size); return CRYPT_ERROR; } - DO(dh_make_key_ex(&yarrow_prng, find_prng ("yarrow"), 16, - ltc_dh_sets[x].prime, strlen(ltc_dh_sets[x].prime) + 1, - ltc_dh_sets[x].base, strlen(ltc_dh_sets[x].base) + 1, - &usera)); dh_free(&usera); }