use the Diffie-Hellman functionality of libstrongswan
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 24 May 2009 09:26:00 +0000 (11:26 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 24 May 2009 09:26:00 +0000 (11:26 +0200)
12 files changed:
src/pluto/Makefile.am
src/pluto/alg_info.c
src/pluto/constants.c
src/pluto/constants.h
src/pluto/crypto.c
src/pluto/crypto.h
src/pluto/ike_alg.c
src/pluto/ike_alg.h
src/pluto/ipsec_doi.c
src/pluto/spdb.c
src/pluto/state.c
src/pluto/state.h

index d8f4e10..b389713 100644 (file)
@@ -55,6 +55,7 @@ x509.c x509.h \
 alg/ike_alg_3des.c alg/ike_alg_aes.c \
 alg/ike_alg_blowfish.c alg/ike_alg_twofish.c alg/ike_alg_serpent.c\
 alg/ike_alg_md5_sha1.c alg/ike_alg_sha2.c \
+alg/ike_alg_dh_groups.c \
 rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
 
 _pluto_adns_SOURCES = adns.c adns.h
index 4a05ec5..1caa980 100644 (file)
 
 #include <utils.h>
 #include <utils/lexparser.h>
+#include <crypto/diffie_hellman.h>
 #include <crypto/transform.h>
 #include <crypto/proposal/proposal_keywords.h>
-#include <crypto/proposal/proposal_keywords.h>
+
 
 #include "alg_info.h"
 #include "constants.h"
@@ -215,8 +216,8 @@ static void __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id,
  */
 
 static int default_ike_groups[] = { 
-       OAKLEY_GROUP_MODP1536,
-       OAKLEY_GROUP_MODP1024
+       MODP_1536_BIT,
+       MODP_1024_BIT
 };
 
 /*      
@@ -316,10 +317,6 @@ static status_t alg_info_add(chunk_t alg, unsigned protoid,
                                {
                                        return FAILED;
                                }
-                               if (token->algorithm > OAKLEY_GROUP_MODP8192)
-                               {
-                                       return FAILED;
-                               }
                                *dh_group = token->algorithm;
                        }
                        break;
@@ -636,11 +633,11 @@ int alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info)
 
        while (cnt--)
        {
-               struct encrypt_desc *enc_desc = ike_alg_get_encrypter(ike_info->ike_ealg);
+               struct encrypt_desc *enc_desc = ike_alg_get_crypter(ike_info->ike_ealg);
                struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg);
+               struct dh_desc *dh_desc = ike_alg_get_dh_group(ike_info->ike_modp);
 
-               if (enc_desc != NULL &&  hash_desc != NULL
-               && lookup_group(ike_info->ike_modp))
+               if (enc_desc &&  hash_desc && dh_desc)
                {
 
                        u_int eklen = (ike_info->ike_eklen)
index d34bc56..289787c 100644 (file)
@@ -909,12 +909,31 @@ static const char *const oakley_group_name_rfc3526[] = {
        "MODP_8192"
 };
 
+static const char *const oakley_group_name_rfc4753[] = {
+       "ECP_256",
+       "ECP_384",
+       "ECP_521"
+};
+
+static const char *const oakley_group_name_rfc5114[] = {
+       "ECP_192",
+       "ECP_224"
+};
+
+enum_names oakley_group_names_rfc5114 =
+       { ECP_192_BIT, ECP_224_BIT,
+                       oakley_group_name_rfc5114, NULL };
+
+enum_names oakley_group_names_rfc4753 =
+       { ECP_256_BIT, ECP_521_BIT,
+                       oakley_group_name_rfc4753, &oakley_group_names_rfc5114 };
+
 enum_names oakley_group_names_rfc3526 =
-       { OAKLEY_GROUP_MODP2048, OAKLEY_GROUP_MODP8192,
-                       oakley_group_name_rfc3526, NULL };
+       { MODP_2048_BIT, MODP_8192_BIT,
+                       oakley_group_name_rfc3526, &oakley_group_names_rfc4753 };
 
 enum_names oakley_group_names =
-       { OAKLEY_GROUP_MODP768, OAKLEY_GROUP_MODP1536
+       { MODP_768_BIT, MODP_1536_BIT
                        oakley_group_name, &oakley_group_names_rfc3526 };
 
 /* Oakley Group Type attribute */
index 63ec6be..60b14f8 100644 (file)
@@ -1085,17 +1085,6 @@ extern enum_names oakley_auth_names;
  */
 extern enum_names oakley_group_names;
 
-#define OAKLEY_GROUP_MODP768       1
-#define OAKLEY_GROUP_MODP1024      2
-#define OAKLEY_GROUP_GP155         3
-#define OAKLEY_GROUP_GP185         4
-#define OAKLEY_GROUP_MODP1536      5
-
-#define OAKLEY_GROUP_MODP2048      14
-#define OAKLEY_GROUP_MODP3072      15
-#define OAKLEY_GROUP_MODP4096      16
-#define OAKLEY_GROUP_MODP6144      17
-#define OAKLEY_GROUP_MODP8192      18
 /*      you must also touch: constants.c, crypto.c */
 
 /* Oakley Group Type attribute
index dd6dd52..8ea6d87 100644 (file)
@@ -13,8 +13,6 @@
  * for more details.
  */
 
-#include <gmp.h>
-
 #include <freeswan.h>
 #include <ipsec_policy.h>
 
@@ -37,26 +35,26 @@ extern struct hash_desc hash_desc_sha2_256;
 extern struct hash_desc hash_desc_sha2_384;
 extern struct hash_desc hash_desc_sha2_512;
 
-/* moduli and generator. */
-
-static MP_INT
-       modp1024_modulus,
-       modp1536_modulus,
-       modp2048_modulus,
-       modp3072_modulus,
-       modp4096_modulus,
-       modp6144_modulus,
-       modp8192_modulus;
-
-MP_INT groupgenerator;  /* MODP group generator (2) */
-
+extern struct dh_desc dh_desc_modp_1024;
+extern struct dh_desc dh_desc_modp_1536;
+extern struct dh_desc dh_desc_modp_2048;
+extern struct dh_desc dh_desc_modp_3072;
+extern struct dh_desc dh_desc_modp_4096;
+extern struct dh_desc dh_desc_modp_6144;
+extern struct dh_desc dh_desc_modp_8192;
 
+extern struct dh_desc dh_desc_ecp_256;
+extern struct dh_desc dh_desc_ecp_384;
+extern struct dh_desc dh_desc_ecp_521;
+extern struct dh_desc dh_desc_ecp_192;
+extern struct dh_desc dh_desc_ecp_224;
 
 void init_crypto(void)
 {
        enumerator_t *enumerator;
        encryption_algorithm_t encryption_alg;
        hash_algorithm_t hash_alg;
+       diffie_hellman_group_t dh_group;
        bool no_md5  = TRUE;
        bool no_sha1 = TRUE;
 
@@ -130,17 +128,56 @@ void init_crypto(void)
        }
        enumerator->destroy(enumerator);
 
-       if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0
-        || mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp1536_modulus, MODP1536_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp2048_modulus, MODP2048_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp3072_modulus, MODP3072_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp4096_modulus, MODP4096_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
-        || mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
+       enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &dh_group))
        {
-               exit_log("mpz_init_set_str() failed in init_crypto()");
+               const struct dh_desc *desc;
+
+               switch (dh_group)
+               {
+                       case MODP_1024_BIT:
+                               desc = &dh_desc_modp_1024;
+                               break;
+                       case MODP_1536_BIT:
+                               desc = &dh_desc_modp_1536;
+                               break;
+                       case MODP_2048_BIT:
+                               desc = &dh_desc_modp_2048;
+                               break;
+                       case MODP_3072_BIT:
+                               desc = &dh_desc_modp_3072;
+                               break;
+                       case MODP_4096_BIT:
+                               desc = &dh_desc_modp_4096;
+                               break;
+                       case MODP_6144_BIT:
+                               desc = &dh_desc_modp_6144;
+                               break;
+                       case MODP_8192_BIT:
+                               desc = &dh_desc_modp_8192;
+                               break;
+                       case ECP_256_BIT:
+                               desc = &dh_desc_ecp_256;
+                               break;
+                       case ECP_384_BIT:
+                               desc = &dh_desc_ecp_384;
+                               break;
+                       case ECP_521_BIT:
+                               desc = &dh_desc_ecp_521;
+                               break;
+                       case ECP_192_BIT:
+                               desc = &dh_desc_ecp_192;
+                               break;
+                       case ECP_224_BIT:
+                               desc = &dh_desc_ecp_224;
+                               break;
+                       default:
+                               continue;
+               }
+               ike_alg_add((struct ike_alg *)desc);
        }
+       enumerator->destroy(enumerator);
+
 #ifdef SELF_TEST
        if (!ike_alg_test())
        {
@@ -151,43 +188,7 @@ void init_crypto(void)
 
 void free_crypto(void)
 {
-       mpz_clear(&groupgenerator);
-       mpz_clear(&modp1024_modulus);
-       mpz_clear(&modp1536_modulus);
-       mpz_clear(&modp2048_modulus);
-       mpz_clear(&modp3072_modulus);
-       mpz_clear(&modp4096_modulus);
-       mpz_clear(&modp6144_modulus);
-       mpz_clear(&modp8192_modulus);
-}
-
-/* Oakley group description
- *
- * See RFC2409 "The Internet key exchange (IKE)" 6.
- */
-
-const struct oakley_group_desc unset_group = {0, NULL, 0};      /* magic signifier */
-
-const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = {
-#   define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE)
-       { OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
-       { OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
-       { OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
-       { OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
-       { OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
-       { OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
-       { OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
-#   undef BYTES
-};
-
-const struct oakley_group_desc *lookup_group(u_int16_t group)
-{
-       int i;
-
-       for (i = 0; i != countof(oakley_group); i++)
-               if (group == oakley_group[i].group)
-                       return &oakley_group[i];
-       return NULL;
+       /* currently nothing to do */
 }
 
 /**
index 0f8741e..0c9bc8e 100644 (file)
 extern void init_crypto(void);
 extern void free_crypto(void);
 
-/* Oakley group descriptions */
-
-extern MP_INT groupgenerator;   /* MODP group generator (2) */
-
-struct oakley_group_desc {
-       u_int16_t group;
-       MP_INT *modulus;
-       size_t bytes;
-};
-
-extern const struct oakley_group_desc unset_group;      /* magic signifier */
-extern const struct oakley_group_desc *lookup_group(u_int16_t group);
-#define OAKLEY_GROUP_SIZE 7
-extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
+extern const struct dh_desc unset_group;      /* magic signifier */
 
 /* unification of cryptographic encoding/decoding algorithms
  * The IV is taken from and returned to st->st_new_iv.
index 8b8849c..42c71e9 100644 (file)
@@ -111,38 +111,31 @@ struct hash_desc *ike_alg_get_hasher(u_int alg)
 /**
  * Get IKE encryption algorithm
  */
-struct encrypt_desc *ike_alg_get_encrypter(u_int alg)
+struct encrypt_desc *ike_alg_get_crypter(u_int alg)
 {
        return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
 }
 
 /**
- * Check if IKE hash algorithm is present
+ * Get IKE dh group
  */
-bool ike_alg_hash_present(u_int halg)
+struct dh_desc *ike_alg_get_dh_group(u_int alg)
 {
-       return ike_alg_get_hasher(halg) != NULL;
-}
-
-/**
- * check if IKE encryption algorithm is present
- */
-bool ike_alg_enc_present(u_int ealg)
-{
-       return ike_alg_get_encrypter(ealg) != NULL;
+       return (struct dh_desc *) ike_alg_find(IKE_ALG_DH_GROUP, alg, 0);
 }
 
 /**
  * Get pfsgroup for this connection
  */
-const struct oakley_group_desc *ike_alg_pfsgroup(struct connection *c, lset_t policy)
+const struct dh_desc *ike_alg_pfsgroup(struct connection *c, lset_t policy)
 {
-       const struct oakley_group_desc * ret = NULL;
+       const struct dh_desc *ret = NULL;
 
-       if ((policy & POLICY_PFS)
-       && c->alg_info_esp
-       && c->alg_info_esp->esp_pfsgroup)
-               ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
+       if ((policy & POLICY_PFS) &&
+               c->alg_info_esp && c->alg_info_esp->esp_pfsgroup)
+       {
+               ret = ike_alg_get_dh_group(c->alg_info_esp->esp_pfsgroup);
+       }
        return ret;
 }
 
@@ -177,34 +170,25 @@ struct db_context *ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
                modp = ike_info->ike_modp;
                eklen= ike_info->ike_eklen;
 
-               if (!ike_alg_enc_present(ealg))
+               if (!ike_alg_get_crypter(ealg))
                {
-                       DBG_log("ike_alg: ike enc ealg=%d not present"
-                                       , ealg);
+                       DBG_log("ike_alg: ike crypter %s not present",
+                                       enum_show(&oakley_enc_names, ealg));
                        continue;
                }
-
-               if (!ike_alg_hash_present(halg)) 
+               if (!ike_alg_get_hasher(halg)) 
                {
-                       DBG_log("ike_alg: ike hash halg=%d not present"
-                                       , halg);
+                       DBG_log("ike_alg: ike hasher %s not present",
+                                       enum_show(&oakley_hash_names, halg));
                        continue;
                }
-
-               enc_desc = ike_alg_get_encrypter(ealg);
-               passert(enc_desc != NULL);
-
-               if (eklen
-               && (eklen < enc_desc->keyminlen || eklen >  enc_desc->keymaxlen))
+               if (!ike_alg_get_dh_group(modp)) 
                {
-                       DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
-                                       , ealg
-                                       , eklen
-                                       , enc_desc->keyminlen
-                                       , enc_desc->keymaxlen
-                       );
+                       DBG_log("ike_alg: ike dh group %s not present",
+                                       enum_show(&oakley_group_names, modp));
                        continue;
                }
+               enc_desc = ike_alg_get_crypter(ealg);
 
                if (policy & POLICY_RSASIG)
                {
@@ -261,54 +245,59 @@ fail:
  */
 void ike_alg_list(void)
 {
-       u_int i;
+       char buf[BUF_LEN];
+       char *pos;
+       int n, len;
        struct ike_alg *a;
 
        whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
+       whack_log(RC_COMMENT, "List of registered IKEv1 Algorithms:");
        whack_log(RC_COMMENT, " ");
 
+       pos = buf;
+       *pos = '\0';
+       len = BUF_LEN;
        for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
        {
-               struct encrypt_desc *desc = (struct encrypt_desc*)a;
-
-               whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
-                       , a->algo_id
-                       , enum_name(&oakley_enc_names, a->algo_id)
-                       , (int)desc->enc_blocksize*BITS_PER_BYTE
-                       , desc->keyminlen
-                       , desc->keydeflen
-                       , desc->keymaxlen
-               );
+           n = snprintf(pos, len, " %s", enum_name(&oakley_enc_names, a->algo_id));
+               pos += n;
+               len -= n;
+               if (len <= 0)
+               {
+                       break;
+               }
        }
+       whack_log(RC_COMMENT, "  encryption:%s", buf);
 
-       whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
-       whack_log(RC_COMMENT, " ");
-
+       pos = buf;
+       *pos = '\0';
+       len = BUF_LEN;
        for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
        {
-               whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
-                       , a->algo_id
-                       , enum_name(&oakley_hash_names, a->algo_id)
-                       , (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
-               );
+           n = snprintf(pos, len, " %s", enum_name(&oakley_hash_names, a->algo_id));
+               pos += n;
+               len -= n;
+               if (len <= 0)
+               {
+                       break;
+               }
        }
+       whack_log(RC_COMMENT, "  hasher:    %s", buf);
 
-       whack_log(RC_COMMENT, " ");
-       whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
-       whack_log(RC_COMMENT, " ");
-
-       for (i = 0; i < countof(oakley_group); i++)
+       pos = buf;
+       *pos = '\0';
+       len = BUF_LEN;
+       for (a = ike_alg_base[IKE_ALG_DH_GROUP]; a != NULL; a = a->algo_next)
        {
-               const struct oakley_group_desc *gdesc=oakley_group + i;
-
-               whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
-                       , gdesc->group
-                       , enum_name(&oakley_group_names, gdesc->group)
-                       , (int)gdesc->bytes*BITS_PER_BYTE
-               );
+           n = snprintf(pos, len, " %s", enum_name(&oakley_group_names, a->algo_id));
+               pos += n;
+               len -= n;
+               if (len <= 0)
+               {
+                       break;
+               }
        }
+       whack_log(RC_COMMENT, "  dh-group:  %s", buf);
 }
 
 /**
@@ -328,7 +317,7 @@ void ike_alg_show_connection(struct connection *c, const char *instance)
                                        c->name, instance,
                                        enum_show(&oakley_enc_names, st->st_oakley.encrypt),
                                        enum_show(&oakley_hash_names, st->st_oakley.hash),
-                                       enum_show(&oakley_group_names, st->st_oakley.group->group)
+                                       enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
                        );
                }
                else
@@ -339,7 +328,7 @@ void ike_alg_show_connection(struct connection *c, const char *instance)
                                        enum_show(&oakley_enc_names, st->st_oakley.encrypt),
                                        st->st_oakley.enckeylen,
                                        enum_show(&oakley_hash_names, st->st_oakley.hash),
-                                       enum_show(&oakley_group_names, st->st_oakley.group->group)
+                                       enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
                        );
                }
        }
index 14647e2..9a2ad92 100644 (file)
@@ -75,17 +75,24 @@ struct hash_desc {
        const hmac_testvector_t *hmac_testvectors;
 };
 
+struct dh_desc {
+       u_int16_t algo_type;
+       u_int16_t algo_id;
+       struct ike_alg *algo_next;
+
+       size_t modulus_size;
+};
+
 #define IKE_ALG_ENCRYPT         0
 #define IKE_ALG_HASH            1
-#define IKE_ALG_MAX             IKE_ALG_HASH
+#define IKE_ALG_DH_GROUP               2
+#define IKE_ALG_MAX             IKE_ALG_DH_GROUP
 
 extern int ike_alg_add(struct ike_alg *a);
 extern struct hash_desc *ike_alg_get_hasher(u_int alg);
-extern struct encrypt_desc *ike_alg_get_encrypter(u_int alg);
-extern bool ike_alg_enc_present(u_int ealg);
-extern bool ike_alg_hash_present(u_int halg);
-extern const struct oakley_group_desc* ike_alg_pfsgroup(struct connection *c
-       , lset_t policy);
+extern struct encrypt_desc *ike_alg_get_crypter(u_int alg);
+extern struct dh_desc *ike_alg_get_dh_group(u_int alg);
+extern const struct dh_desc* ike_alg_pfsgroup(struct connection *c, lset_t policy);
 extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy);
 extern void ike_alg_list(void);
 extern void ike_alg_show_connection(struct connection *c, const char *instance);
index 57c2624..38fe1dd 100644 (file)
@@ -122,37 +122,11 @@ echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
  * We make the leap that the length should be that of the group
  * (see quoted passage at start of ACCEPT_KE).
  */
-static void compute_dh_shared(struct state *st, const chunk_t g,
-                                                         const struct oakley_group_desc *group)
+static void compute_dh_shared(struct state *st, const chunk_t g)
 {
-       MP_INT mp_g, mp_shared;
-       struct timeval tv0, tv1;
-       unsigned long tv_diff;
-
-       gettimeofday(&tv0, NULL);
-       passert(st->st_sec_in_use);
-       n_to_mpz(&mp_g, g.ptr, g.len);
-       mpz_init(&mp_shared);
-       mpz_powm(&mp_shared, &mp_g, &st->st_sec, group->modulus);
-       mpz_clear(&mp_g);
-       free(st->st_shared.ptr);    /* happens in odd error cases */
-       st->st_shared = mpz_to_n(&mp_shared, group->bytes);
-       mpz_clear(&mp_shared);
-       gettimeofday(&tv1, NULL);
-       tv_diff=(tv1.tv_sec  - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec);
-       DBG(DBG_CRYPT, 
-               DBG_log("compute_dh_shared(): time elapsed (%s): %ld usec"
-                               , enum_show(&oakley_group_names, st->st_oakley.group->group)
-                               , tv_diff);
-          );
-       /* if took more than 200 msec ... */
-       if (tv_diff > 200000) {
-               loglog(RC_LOG_SERIOUS, "WARNING: compute_dh_shared(): for %s took "
-                                               "%ld usec"
-                               , enum_show(&oakley_group_names, st->st_oakley.group->group)
-                               , tv_diff);
-       }
-
+       passert(st->st_dh);
+       st->st_dh->set_other_public_value(st->st_dh, g);
+       st->st_dh->get_shared_secret(st->st_dh, &st->st_shared);
        DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared);
 }
 
@@ -160,30 +134,23 @@ static void compute_dh_shared(struct state *st, const chunk_t g,
  * the corresponding public value (g).  This is emitted as a KE payload.
  */
 static bool build_and_ship_KE(struct state *st, chunk_t *g,
-                                                         const struct oakley_group_desc *group,
+                                                         const struct dh_desc *group,
                                                          pb_stream *outs, u_int8_t np)
 {
-       if (!st->st_sec_in_use)
+       if (st->st_dh == NULL)
        {
-               u_char tmp[LOCALSECRETSIZE];
-               MP_INT mp_g;
-               rng_t *rng;
-               
-               rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
-               rng->get_bytes(rng, LOCALSECRETSIZE, tmp);
-               rng->destroy(rng);
-               st->st_sec_in_use = TRUE;
-               n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE);
-
-               mpz_init(&mp_g);
-               mpz_powm(&mp_g, &groupgenerator, &st->st_sec, group->modulus);
-               free(g->ptr);   /* happens in odd error cases */
-               *g = mpz_to_n(&mp_g, group->bytes);
-               mpz_clear(&mp_g);
-               DBG(DBG_CRYPT,
-                       DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE);
-                       DBG_dump_chunk("Public DH value sent:\n", *g));
+               st->st_dh = lib->crypto->create_dh(lib->crypto, group->algo_id);
+               if (st->st_dh == NULL)
+               {
+                       plog("Diffie Hellman group %N is not available",
+                                diffie_hellman_group_names, group->algo_id);
+                       return FALSE;
+               }
        }
+       st->st_dh->get_my_public_value(st->st_dh, g);
+       DBG(DBG_CRYPT,
+               DBG_dump_chunk("Public DH value sent:\n", *g)
+       )
        return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value");
 }
 
@@ -197,13 +164,13 @@ static bool build_and_ship_KE(struct state *st, chunk_t *g,
  *  value with zeros.
  */
 static notification_t accept_KE(chunk_t *dest, const char *val_name,
-                                                               const struct oakley_group_desc *gr,
+                                                               const struct dh_desc *gr,
                                                                pb_stream *pbs)
 {
-       if (pbs_left(pbs) != gr->bytes)
+       if (pbs_left(pbs) != gr->modulus_size)
        {
                loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required"
-                       , (unsigned) pbs_left(pbs), (unsigned) gr->bytes);
+                       , (unsigned) pbs_left(pbs), gr->modulus_size);
                /* XXX Could send notification back */
                return INVALID_KEY_INFORMATION;
        }
@@ -3473,7 +3440,7 @@ stf_status main_inI2_outR2(struct msg_digest *md)
        /* next message will be encrypted, but not this one.
         * We could defer this calculation.
         */
-       compute_dh_shared(st, st->st_gi, st->st_oakley.group);
+       compute_dh_shared(st, st->st_gi);
        if (!generate_skeyids_iv(st))
                return STF_FAIL + AUTHENTICATION_FAILED;
        update_iv(st);
@@ -3535,7 +3502,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
        send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
 
        /* done parsing; initialize crypto  */
-       compute_dh_shared(st, st->st_gr, st->st_oakley.group);
+       compute_dh_shared(st, st->st_gr);
        if (!generate_skeyids_iv(st))
                return STF_FAIL + AUTHENTICATION_FAILED;
 
@@ -4946,7 +4913,7 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
                                        return STF_INTERNAL_ERROR;
 
                        /* MPZ-Operations might be done after sending the packet... */
-                       compute_dh_shared(st, st->st_gi, st->st_pfs_group);
+                       compute_dh_shared(st, st->st_gi);
                }
 
                /* [ IDci, IDcr ] out */
@@ -5061,7 +5028,7 @@ stf_status quick_inR1_outI2(struct msg_digest *md)
        RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1"));
 
        if (st->st_pfs_group != NULL)
-               compute_dh_shared(st, st->st_gr, st->st_pfs_group);
+               compute_dh_shared(st, st->st_gr);
 
        /* [ IDci, IDcr ] in; these must match what we sent */
 
index 3b40271..5ab6916 100644 (file)
@@ -485,7 +485,7 @@ out_sa(pb_stream *outs
                                {
                                        passert(!oakley_mode);
                                        passert(st->st_pfs_group != &unset_group);
-                                       out_attr(GROUP_DESCRIPTION, st->st_pfs_group->group
+                                       out_attr(GROUP_DESCRIPTION, st->st_pfs_group->algo_id
                                                , attr_desc, attr_val_descs
                                                , &trans_pbs);
                                }
@@ -939,10 +939,10 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
                        switch (a.isaat_af_type)
                        {
                        case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV:
-                               if (ike_alg_enc_present(val))
+                               if (ike_alg_get_crypter(val))
                                {
                                        ta.encrypt = val;
-                                       ta.encrypter = ike_alg_get_encrypter(val);
+                                       ta.encrypter = ike_alg_get_crypter(val);
                                        ta.enckeylen = ta.encrypter->keydeflen;
                                }
                                else
@@ -953,7 +953,7 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
                                break;
 
                        case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV:
-                               if (ike_alg_hash_present(val))
+                               if (ike_alg_get_hasher(val))
                                {
                                        ta.hash = val;
                                        ta.hasher = ike_alg_get_hasher(val);
@@ -1049,10 +1049,11 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
                                break;
 
                        case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
-                               ta.group = lookup_group(val);
+                               ta.group = ike_alg_get_dh_group(val);
                                if (ta.group == NULL)
                                {
-                                       ugh = "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported";
+                                       ugh = builddiag("%s is not supported"
+                                                       , enum_show(&oakley_group_names, val));
                                }
                                break;
 
@@ -1183,7 +1184,7 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
                if (ugh == NULL)
                {
                        if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,
-                               ta.group ? ta.group->group : -1, c->alg_info_ike))
+                               ta.group ? ta.group->algo_id : -1, c->alg_info_ike))
                        {
                                ugh = "OAKLEY proposal refused";
                        }
@@ -1336,7 +1337,7 @@ parse_ipsec_transform(struct isakmp_transform *trans
        lset_t seen_attrs = 0;
        lset_t seen_durations = 0;
        u_int16_t life_type = 0;
-       const struct oakley_group_desc *pfs_group = NULL;
+       const struct dh_desc *pfs_group = NULL;
 
        if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
                return FALSE;
@@ -1462,7 +1463,7 @@ parse_ipsec_transform(struct isakmp_transform *trans
                                                , "IPCA (IPcomp SA) contains GROUP_DESCRIPTION."
                                                "  Ignoring inapproprate attribute.");
                                }
-                               pfs_group = lookup_group(val);
+                               pfs_group = ike_alg_get_dh_group(val);
                                if (pfs_group == NULL)
                                {
                                        loglog(RC_LOG_SERIOUS, "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported for PFS");
index b19b2ca..6ce0d50 100644 (file)
@@ -344,8 +344,7 @@ void delete_state(struct state *st)
 
        unreference_key(&st->st_peer_pubkey);
 
-       if (st->st_sec_in_use)
-               mpz_clear(&(st->st_sec));
+       DESTROY_IF(st->st_dh);
 
        free(st->st_tpacket.ptr);
        free(st->st_rpacket.ptr);
index 1c6948c..a059c52 100644 (file)
@@ -1,6 +1,7 @@
 /* state and event objects
  * Copyright (C) 1997 Angelos D. Keromytis.
  * Copyright (C) 1998-2001  D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -17,7 +18,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <time.h>
-#include <gmp.h>    /* GNU MP library */
+
+#include <crypto/diffie_hellman.h>
 
 #include "connections.h"
 
@@ -54,11 +56,11 @@ extern msgid_t generate_msgid(struct state *isakmp_sa);
 struct oakley_trans_attrs {
        u_int16_t encrypt;          /* Encryption algorithm */
        u_int16_t enckeylen;        /* encryption key len (bits) */
-       const struct encrypt_desc *encrypter;       /* package of encryption routines */
+       const struct encrypt_desc *encrypter;   /* package of encryption routines */
        u_int16_t hash;             /* Hash algorithm */
-       const struct hash_desc *hasher;     /* package of hashing routines */
+       const struct hash_desc *hasher;         /* package of hashing routines */
        u_int16_t auth;             /* Authentication method */
-       const struct oakley_group_desc *group;      /* Oakley group */
+       const struct dh_desc *group;            /* Diffie-Hellman group */
        time_t life_seconds;        /* When this SA expires (seconds) */
        u_int32_t life_kilobytes;   /* When this SA is exhausted (kilobytes) */
 #if 0 /* not yet */
@@ -126,7 +128,7 @@ struct state
        ipsec_spi_t        st_tunnel_out_spi;         /* KLUDGE */
 #endif
 
-       const struct oakley_group_desc *st_pfs_group;       /* group for Phase 2 PFS */
+       const struct dh_desc *st_pfs_group;        /* group for Phase 2 PFS */
 
        u_int32_t          st_doi;                 /* Domain of Interpretation */
        u_int32_t          st_situation;
@@ -169,9 +171,7 @@ struct state
 
 /* end of symmetric stuff */
 
-       u_int8_t           st_sec_in_use;          /* bool: does st_sec hold a value */
-       MP_INT             st_sec;                 /* Our local secret value */
-
+       diffie_hellman_t  *st_dh;                  /* Our local DH secret value */
        chunk_t            st_shared;              /* Derived shared secret
                                                                                                * Note: during Quick Mode,
                                                                                                * presence indicates PFS