use the Diffie-Hellman functionality of libstrongswan

This commit is contained in:
Andreas Steffen 2009-05-24 11:26:00 +02:00
parent 770b408902
commit 52ccea657b
12 changed files with 210 additions and 253 deletions

View 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

View File

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

View 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 */

View 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

View 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 */
}
/**

View File

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

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

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

View 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 */

View 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");

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

View 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