Browse Source

replace dh_import_radix() by dh_set_{pg,key}

Steffen Jaeckel 8 years ago
parent
commit
fbc54756c1
4 changed files with 153 additions and 100 deletions
  1. 10 5
      src/headers/tomcrypt_pk.h
  2. 0 90
      src/pk/dh/dh_import_radix.c
  3. 110 0
      src/pk/dh/dh_set.c
  4. 33 5
      tests/dh_test.c

+ 10 - 5
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);

+ 0 - 90
src/pk/dh/dh_import_radix.c

@@ -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$ */

+ 110 - 0
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$ */

+ 33 - 5
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)) {