aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pluto/Makefile.am1
-rw-r--r--src/pluto/alg_info.c17
-rw-r--r--src/pluto/constants.c25
-rw-r--r--src/pluto/constants.h11
-rw-r--r--src/pluto/crypto.c123
-rw-r--r--src/pluto/crypto.h15
-rw-r--r--src/pluto/ike_alg.c133
-rw-r--r--src/pluto/ike_alg.h19
-rw-r--r--src/pluto/ipsec_doi.c81
-rw-r--r--src/pluto/spdb.c19
-rw-r--r--src/pluto/state.c3
-rw-r--r--src/pluto/state.h16
12 files changed, 210 insertions, 253 deletions
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index d8f4e1060..b389713d3 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -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
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c
index 4a05ec57d..1caa980de 100644
--- a/src/pluto/alg_info.c
+++ b/src/pluto/alg_info.c
@@ -31,9 +31,10 @@
#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)
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
index d34bc56b5..289787c11 100644
--- a/src/pluto/constants.c
+++ b/src/pluto/constants.c
@@ -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 */
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
index 63ec6be29..60b14f8e1 100644
--- a/src/pluto/constants.h
+++ b/src/pluto/constants.h
@@ -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
diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c
index dd6dd5228..8ea6d87f6 100644
--- a/src/pluto/crypto.c
+++ b/src/pluto/crypto.c
@@ -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 */
}
/**
diff --git a/src/pluto/crypto.h b/src/pluto/crypto.h
index 0f8741e01..0c9bc8eb8 100644
--- a/src/pluto/crypto.h
+++ b/src/pluto/crypto.h
@@ -22,20 +22,7 @@
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.
diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c
index 8b8849c2a..42c71e953 100644
--- a/src/pluto/ike_alg.c
+++ b/src/pluto/ike_alg.c
@@ -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)
);
}
}
diff --git a/src/pluto/ike_alg.h b/src/pluto/ike_alg.h
index 14647e20c..9a2ad92e0 100644
--- a/src/pluto/ike_alg.h
+++ b/src/pluto/ike_alg.h
@@ -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);
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 57c262487..38fe1dd52 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -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 */
diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c
index 3b4027160..5ab6916a0 100644
--- a/src/pluto/spdb.c
+++ b/src/pluto/spdb.c
@@ -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");
diff --git a/src/pluto/state.c b/src/pluto/state.c
index b19b2cae5..6ce0d50e5 100644
--- a/src/pluto/state.c
+++ b/src/pluto/state.c
@@ -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);
diff --git a/src/pluto/state.h b/src/pluto/state.h
index 1c6948c71..a059c52b4 100644
--- a/src/pluto/state.h
+++ b/src/pluto/state.h
@@ -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