diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index cfa9508..1996cd6 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -213,6 +213,8 @@ typedef struct { void *prime; } dh_key; +#define LTC_DH_KEY_INITIALIZER { PK_PUBLIC, NULL, NULL, NULL, NULL } + int dh_get_groupsize(dh_key *key); int dh_make_key(prng_state *prng, int wprng, int groupsize, dh_key *key); @@ -226,14 +228,17 @@ 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_key(const unsigned char *pub, unsigned long publen, + const unsigned char *priv, unsigned long privlen, + dh_key *key); + int dh_export_radix(int radix, void *out, unsigned long *outlen, int type, dh_key *key); -int dh_import_radix(int radix, - void *in, unsigned long inlen, - void *prime, unsigned long primelen, - void *base, unsigned long baselen, - int type, dh_key *key); int dh_shared_secret(dh_key *private_key, dh_key *public_key, unsigned char *out, unsigned long *outlen); diff --git a/src/pk/dh/dh_import_radix.c b/src/pk/dh/dh_import_radix.c deleted file mode 100644 index cbd6c41..0000000 --- a/src/pk/dh/dh_import_radix.c +++ /dev/null @@ -1,90 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - */ - -#include "tomcrypt.h" - -#ifdef LTC_MDH - -/** - Import a DH key from a binary string - @param in The string to read - @param inlen The length of the input packet - @param type The type of key (PK_PRIVATE or PK_PUBLIC) - @param base The base (generator) in hex string - @param prime The prime in hex string - @param key [out] Where to import the key to - @return CRYPT_OK if successful, on error all allocated memory is freed automatically -*/ -int dh_import_radix(int radix, - void *in, unsigned long inlen, - void *prime, unsigned long primelen, - void *base, unsigned long baselen, - int type, dh_key *key) -{ - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(base != NULL); - LTC_ARGCHK(prime != NULL); - LTC_ARGCHK(key != NULL); - - if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { - goto error; - } - if (radix == 256) { - if ((err = mp_read_unsigned_bin(key->base, base, baselen)) != CRYPT_OK) { goto error; } - if ((err = mp_read_unsigned_bin(key->prime, prime, primelen)) != CRYPT_OK) { goto error; } - } - else { - if ((err = mp_read_radix(key->base, base, radix)) != CRYPT_OK) { goto error; } - if ((err = mp_read_radix(key->prime, prime, radix)) != CRYPT_OK) { goto error; } - } - - if (type == PK_PRIVATE) { - /* load the x value */ - if (radix == 256) { - if ((err = mp_read_unsigned_bin(key->x, in, inlen)) != CRYPT_OK) { goto error; } - } - else { - if ((err = mp_read_radix(key->x, in, radix)) != CRYPT_OK) { goto error; } - } - /* compute y value */ - if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto error; } - key->type = PK_PRIVATE; - } - else { - /* load the y value */ - if (radix == 256) { - if ((err = mp_read_unsigned_bin(key->y, in, inlen)) != CRYPT_OK) { goto error; } - } - else { - if ((err = mp_read_radix(key->y, in, radix)) != CRYPT_OK) { goto error; } - } - key->type = PK_PUBLIC; - mp_clear(key->x); - key->x = NULL; - } - - /* check public key */ - if ((err = dh_check_pubkey(key)) != CRYPT_OK) { - goto error; - } - - return CRYPT_OK; - -error: - mp_clear_multi(key->prime, key->base, key->y, key->x, NULL); - return err; -} - -#endif /* LTC_MDH */ - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/src/pk/dh/dh_set.c b/src/pk/dh/dh_set.c new file mode 100644 index 0000000..6ca61d0 --- /dev/null +++ b/src/pk/dh/dh_set.c @@ -0,0 +1,110 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt.h" + +#ifdef LTC_MDH + +/** + Import DH key parts p and g from raw numbers + + @param p DH's p (prime) + @param plen DH's p's length + @param g DH's g (group) + @param glen DH's g's length + @param key [out] the destination for the imported key + @return CRYPT_OK if successful +*/ +int dh_set_pg(const unsigned char *p, unsigned long plen, + const unsigned char *g, unsigned long glen, + 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(p != NULL); + LTC_ARGCHK(g != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) { + return err; + } + + if ((err = mp_read_unsigned_bin(key->base, (unsigned char*)g, glen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = mp_read_unsigned_bin(key->prime, (unsigned char*)p, plen)) != 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 + + @param pub DH's pub (public key) (can be NULL if priv is valid) + @param publen DH's pub's length + @param priv DH's priv (private key) (can be NULL if pub is valid) + @param privlen DH's priv's length + @param key [out] the destination for the imported key + @return CRYPT_OK if successful +*/ +int dh_set_key(const unsigned char *pub, unsigned long publen, + const unsigned char *priv, unsigned long privlen, + 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); + + if(priv == NULL) { + if ((err = mp_read_unsigned_bin(key->y, (unsigned char*)pub, publen)) != CRYPT_OK) { goto LBL_ERR; } + key->type = PK_PUBLIC; + mp_clear(key->x); + key->x = NULL; + } + else { + if ((err = mp_read_unsigned_bin(key->x, (unsigned char*)priv, privlen)) != CRYPT_OK) { goto LBL_ERR; } + if (pub != NULL) { + if ((err = mp_read_unsigned_bin(key->y, (unsigned char*)pub, publen)) != CRYPT_OK) { goto LBL_ERR; } + } + else { + /* compute y value */ + if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto LBL_ERR; } + } + key->type = PK_PRIVATE; + } + + /* check public key */ + if ((err = dh_check_pubkey(key)) != CRYPT_OK) { + goto LBL_ERR; + } + + return CRYPT_OK; + +LBL_ERR: + dh_free(key); + return err; +} + +#endif /* LTC_MDH */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/tests/dh_test.c b/tests/dh_test.c index 5f48ca9..dae366d 100644 --- a/tests/dh_test.c +++ b/tests/dh_test.c @@ -149,10 +149,12 @@ static int _dhparam_test(void) static int _radix_test(void) { - dh_key k1, k2, k3; - unsigned char buf[DH_BUF_SIZE]; + dh_key k1 = LTC_DH_KEY_INITIALIZER; + dh_key k2 = LTC_DH_KEY_INITIALIZER; + dh_key k3 = LTC_DH_KEY_INITIALIZER; + unsigned char buf[4096]; unsigned long len; - int i; + int i, j; /* RADIX 16 */ char *ghex = "2"; char *phex = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22" @@ -311,6 +313,8 @@ static int _radix_test(void) 0xF3, 0x7E, 0xE9, 0x0A, 0x0D, 0xA9, 0x5B, 0xE9, 0x6F, 0xC9, 0x39, 0xE8, 0x8F, 0xE0, 0xBD, 0x2C, 0xD0, 0x9F, 0xC8, 0xF5, 0x24, 0x20, 0x8C }; + unsigned char key_parts[4][512]; + unsigned long key_lens[4]; if (register_prng(&yarrow_desc) == -1) { printf("Error registering yarrow PRNG\n"); @@ -318,7 +322,23 @@ static int _radix_test(void) } for (i = 0; i < 4; i++) { - DO(dh_import_radix(test[i].radix, test[i].x, test[i].xlen, test[i].p, test[i].plen, test[i].g, test[i].glen, PK_PRIVATE, &k1)); + for (j = 0; j < 4; ++j) { + key_lens[j] = sizeof(key_parts[j]); + } + if(test[i].radix != 256) { + DO(radix_to_bin(test[i].x, test[i].radix, key_parts[0], &key_lens[0])); + DO(radix_to_bin(test[i].y, test[i].radix, key_parts[1], &key_lens[1])); + DO(radix_to_bin(test[i].p, test[i].radix, key_parts[2], &key_lens[2])); + DO(radix_to_bin(test[i].g, test[i].radix, key_parts[3], &key_lens[3])); + + DO(dh_set_pg(key_parts[2], key_lens[2], key_parts[3], key_lens[3], &k1)); + DO(dh_set_key(NULL, 0, key_parts[0], key_lens[0], &k1)); + } + else { + DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k1)); + DO(dh_set_key(NULL, 0, test[i].x, test[i].xlen, &k1)); + } + len = sizeof(buf); DO(dh_export(buf, &len, PK_PRIVATE, &k1)); if (compare_testvector(buf, len, export_private, sizeof(export_private), "radix_test", i*10 + 0)) { @@ -363,7 +383,15 @@ static int _radix_test(void) } dh_free(&k1); - DO(dh_import_radix(test[i].radix, test[i].y, test[i].ylen, test[i].p, test[i].plen, test[i].g, test[i].glen, PK_PUBLIC, &k2)); + if(test[i].radix != 256) { + DO(dh_set_pg(key_parts[2], key_lens[2], key_parts[3], key_lens[3], &k2)); + DO(dh_set_key(key_parts[1], key_lens[1], NULL, 0, &k2)); + } + else { + DO(dh_set_pg(test[i].p, test[i].plen, test[i].g, test[i].glen, &k2)); + DO(dh_set_key(test[i].y, test[i].ylen, NULL, 0, &k2)); + } + len = sizeof(buf); DO(dh_export(buf, &len, PK_PUBLIC, &k2)); if (compare_testvector(buf, len, export_public, sizeof(export_public), "radix_test", i*10 + 6)) {