use the Diffie-Hellman functionality of libstrongswan
This commit is contained in:
parent
770b408902
commit
52ccea657b
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue