diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pluto/Makefile.am | 1 | ||||
-rw-r--r-- | src/pluto/alg_info.c | 17 | ||||
-rw-r--r-- | src/pluto/constants.c | 25 | ||||
-rw-r--r-- | src/pluto/constants.h | 11 | ||||
-rw-r--r-- | src/pluto/crypto.c | 123 | ||||
-rw-r--r-- | src/pluto/crypto.h | 15 | ||||
-rw-r--r-- | src/pluto/ike_alg.c | 133 | ||||
-rw-r--r-- | src/pluto/ike_alg.h | 19 | ||||
-rw-r--r-- | src/pluto/ipsec_doi.c | 81 | ||||
-rw-r--r-- | src/pluto/spdb.c | 19 | ||||
-rw-r--r-- | src/pluto/state.c | 3 | ||||
-rw-r--r-- | src/pluto/state.h | 16 |
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 |