Browse Source

re-factor dh_make_key() and variants

Steffen Jaeckel 8 years ago
parent
commit
9d6689fc08
5 changed files with 119 additions and 148 deletions
  1. 7 2
      demos/timing.c
  2. 9 12
      src/headers/tomcrypt_pk.h
  3. 8 108
      src/pk/dh/dh_make_key.c
  4. 76 0
      src/pk/dh/dh_set.c
  5. 19 26
      tests/dh_test.c

+ 7 - 2
demos/timing.c

@@ -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);
            }
            }

+ 9 - 12
src/headers/tomcrypt_pk.h

@@ -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);

+ 8 - 108
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 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(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? */
    /* 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$ */

+ 76 - 0
src/pk/dh/dh_set.c

@@ -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
 
 

+ 19 - 26
tests/dh_test.c

@@ -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,
-                        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);
       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;
-
-   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 */
    /* 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 */
    /* 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);
    }
    }