re-factor dh_make_key() and variants

This commit is contained in:
Steffen Jaeckel 2017-06-27 21:54:16 +02:00
parent fbc54756c1
commit 9d6689fc08
5 changed files with 119 additions and 148 deletions

View File

@ -889,7 +889,7 @@ static void time_katja(void) { fprintf(stderr, "NO Katja\n"); }
/* time various DH operations */ /* time various DH operations */
static void time_dh(void) static void time_dh(void)
{ {
dh_key key; dh_key key = LTC_DH_KEY_INITIALIZER;
ulong64 t1, t2; ulong64 t1, t2;
unsigned long i, x, y; unsigned long i, x, y;
int err; int err;
@ -898,9 +898,14 @@ static void time_dh(void)
for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
t2 = 0; t2 = 0;
for (y = 0; y < 16; y++) { 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(); t_start();
t1 = t_read(); 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)); 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); exit(EXIT_FAILURE);
} }

View File

@ -217,32 +217,29 @@ typedef struct {
int dh_get_groupsize(dh_key *key); 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_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_import(const unsigned char *in, unsigned long inlen, dh_key *key);
int dh_set_pg(const unsigned char *p, unsigned long plen, int dh_set_pg(const unsigned char *p, unsigned long plen,
const unsigned char *g, unsigned long glen, const unsigned char *g, unsigned long glen,
dh_key *key); 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, int dh_set_key(const unsigned char *pub, unsigned long publen,
const unsigned char *priv, unsigned long privlen, const unsigned char *priv, unsigned long privlen,
dh_key *key); 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, int dh_export_radix(int radix,
void *out, unsigned long *outlen, void *out, unsigned long *outlen,
int type, dh_key *key); 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 #ifdef LTC_SOURCE
/* internal helper functions */ /* internal helper functions */
int dh_check_pubkey(dh_key *key); int dh_check_pubkey(dh_key *key);

View File

@ -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 char *buf;
unsigned long keysize; unsigned long keysize;
int err, max_iterations = PK_MAX_RETRIES; int err, max_iterations = PK_MAX_RETRIES;
LTC_ARGCHK(key != NULL); LTC_ARGCHK(key != NULL);
LTC_ARGCHK(prng != NULL); LTC_ARGCHK(key->x != NULL);
LTC_ARGCHK(prime != NULL); LTC_ARGCHK(key->y != NULL);
LTC_ARGCHK(base != NULL); LTC_ARGCHK(key->base != NULL);
LTC_ARGCHK(key->prime != NULL);
LTC_ARGCHK(ltc_mp.name != NULL);
LTC_ARGCHK(prng != NULL);
/* good prng? */ /* good prng? */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) { if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err; 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)); keysize = _dh_groupsize_to_keysize(mp_unsigned_bin_size(key->prime));
if (keysize == 0) { if (keysize == 0) {
err = CRYPT_INVALID_KEYSIZE; err = CRYPT_INVALID_KEYSIZE;
@ -106,100 +100,6 @@ freemp:
return err; 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 */ #endif /* LTC_MDH */
/* ref: $Format:%D$ */ /* ref: $Format:%D$ */

View File

@ -50,6 +50,82 @@ LBL_ERR:
return 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 Import DH key parts pub and priv from raw numbers

View File

@ -60,7 +60,7 @@ done:
static int _dhparam_test(void) static int _dhparam_test(void)
{ {
dh_key k; dh_key k = LTC_DH_KEY_INITIALIZER;
unsigned char buf[1024]; unsigned char buf[1024];
/* generated by: openssl dhparam -outform der -out dhparam.der 2048 */ /* generated by: openssl dhparam -outform der -out dhparam.der 2048 */
unsigned char dhparam_der[] = { unsigned char dhparam_der[] = {
@ -126,7 +126,8 @@ static int _dhparam_test(void)
0x98, 0xcb 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)) { if (mp_unsigned_bin_size(k.prime) > sizeof(buf)) {
printf("dhparam_test: short buf\n"); printf("dhparam_test: short buf\n");
dh_free(&k); dh_free(&k);
@ -316,11 +317,6 @@ static int _radix_test(void)
unsigned char key_parts[4][512]; unsigned char key_parts[4][512];
unsigned long key_lens[4]; 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 (i = 0; i < 4; i++) {
for (j = 0; j < 4; ++j) { for (j = 0; j < 4; ++j) {
key_lens[j] = sizeof(key_parts[j]); key_lens[j] = sizeof(key_parts[j]);
@ -408,8 +404,14 @@ static int _radix_test(void)
} }
dh_free(&k2); dh_free(&k2);
DO(dh_make_key_ex(&yarrow_prng, find_prng("yarrow"), test[i].radix, if(test[i].radix != 256) {
test[i].p, test[i].plen, test[i].g, test[i].glen, &k3)); 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); len = mp_unsigned_bin_size(k3.prime);
DO(mp_to_unsigned_bin(k3.prime, buf)); DO(mp_to_unsigned_bin(k3.prime, buf));
if (compare_testvector(buf, len, pbin, sizeof(pbin), "radix_test", i*10 + 8)) { 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 char buf[3][4096];
unsigned long x, y, z; unsigned long x, y, z;
int size; int size;
dh_key usera, userb; dh_key usera = LTC_DH_KEY_INITIALIZER;
dh_key userb = LTC_DH_KEY_INITIALIZER;
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;
}
/* make up two keys */ /* make up two keys */
DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), KEYSIZE/8, &usera)); DO(dh_set_pg_groupsize(KEYSIZE/8, &usera));
DO(dh_make_key (&yarrow_prng, find_prng ("yarrow"), KEYSIZE/8, &userb)); 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 */ /* make the shared secret */
x = KEYSIZE; x = KEYSIZE;
@ -492,17 +488,14 @@ static int _basic_test(void)
} }
for (x = 0; ltc_dh_sets[x].size != 0; x++) { 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); size = dh_get_groupsize(&usera);
dh_free(&usera); dh_free(&usera);
if (size != ltc_dh_sets[x].size) { if (size != ltc_dh_sets[x].size) {
fprintf(stderr, "dh_groupsize mismatch %d %d\n", size, ltc_dh_sets[x].size); fprintf(stderr, "dh_groupsize mismatch %d %d\n", size, ltc_dh_sets[x].size);
return CRYPT_ERROR; 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); dh_free(&usera);
} }