summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2006-05-04 14:37:52 +0000
committerDamien Miller <djm@cvs.openbsd.org>2006-05-04 14:37:52 +0000
commit934fda8adaf04a4b4fc4f0efd441b9b5d3efb659 (patch)
treed6839409979ab65488a7549f3575369926887472
parent04ffe450ccdc05851f8a95806c9e4678e65266c5 (diff)
check for degenerate Diffie-Hellman public exponents;
ok markus@ hshoexer@ deraadt@
-rw-r--r--sbin/isakmpd/dh.c6
-rw-r--r--sbin/isakmpd/math_group.c90
-rw-r--r--sbin/isakmpd/math_group.h3
3 files changed, 78 insertions, 21 deletions
diff --git a/sbin/isakmpd/dh.c b/sbin/isakmpd/dh.c
index 46519b905aa..9a8ff6bff2c 100644
--- a/sbin/isakmpd/dh.c
+++ b/sbin/isakmpd/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.10 2005/04/08 22:32:09 cloder Exp $ */
+/* $OpenBSD: dh.c,v 1.11 2006/05/04 14:37:51 djm Exp $ */
/* $EOM: dh.c,v 1.5 1999/04/17 23:20:22 niklas Exp $ */
/*
@@ -59,6 +59,8 @@ dh_create_exchange(struct group *group, u_int8_t *buf)
return -1;
if (group->operation(group, group->a, group->gen, group->c))
return -1;
+ if (group->validate_public(group, group->a))
+ return -1;
group->getraw(group, group->a, buf);
return 0;
}
@@ -75,6 +77,8 @@ dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
return -1;
if (group->operation(group, group->a, group->b, group->c))
return -1;
+ if (group->validate_public(group, group->a))
+ return -1;
group->getraw(group, group->a, secret);
return 0;
}
diff --git a/sbin/isakmpd/math_group.c b/sbin/isakmpd/math_group.c
index d7ff68aaf20..36d9ea0a934 100644
--- a/sbin/isakmpd/math_group.c
+++ b/sbin/isakmpd/math_group.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: math_group.c,v 1.27 2005/04/08 22:32:10 cloder Exp $ */
+/* $OpenBSD: math_group.c,v 1.28 2006/05/04 14:37:51 djm Exp $ */
/* $EOM: math_group.c,v 1.25 2000/04/07 19:53:26 niklas Exp $ */
/*
@@ -47,12 +47,14 @@ void modp_getraw(struct group *, math_mp_t, u_int8_t *);
int modp_setraw(struct group *, math_mp_t, u_int8_t *, int);
int modp_setrandom(struct group *, math_mp_t);
int modp_operation(struct group *, math_mp_t, math_mp_t, math_mp_t);
+int modp_validate_public(struct group *, math_mp_t);
int ec2n_getlen(struct group *);
void ec2n_getraw(struct group *, ec2np_ptr, u_int8_t *);
int ec2n_setraw(struct group *, ec2np_ptr, u_int8_t *, int);
int ec2n_setrandom(struct group *, ec2np_ptr);
int ec2n_operation(struct group *, ec2np_ptr, ec2np_ptr, ec2np_ptr);
+int ec2n_validate_public(struct group *, ec2np_ptr);
struct ec2n_group {
ec2np_t gen; /* Generator */
@@ -298,7 +300,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
MODP, OAKLEY_GRP_2, 0, &oakley_modp[1], 0, 0, 0, 0, 0,
@@ -306,7 +309,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
EC2N, OAKLEY_GRP_3, 0, &oakley_ec2n[0], 0, 0, 0, 0, 0,
@@ -314,7 +318,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) ec2n_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) ec2n_setraw,
(int (*) (struct group *, void *)) ec2n_setrandom,
- (int (*) (struct group *, void *, void *, void *)) ec2n_operation
+ (int (*) (struct group *, void *, void *, void *)) ec2n_operation,
+ (int (*) (struct group *, void *)) ec2n_validate_public
},
{
EC2N, OAKLEY_GRP_4, 0, &oakley_ec2n[1], 0, 0, 0, 0, 0,
@@ -322,7 +327,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) ec2n_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) ec2n_setraw,
(int (*) (struct group *, void *)) ec2n_setrandom,
- (int (*) (struct group *, void *, void *, void *)) ec2n_operation
+ (int (*) (struct group *, void *, void *, void *)) ec2n_operation,
+ (int (*) (struct group *, void *)) ec2n_validate_public
},
{
MODP, OAKLEY_GRP_5, 0, &oakley_modp[2], 0, 0, 0, 0, 0,
@@ -330,7 +336,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
/* XXX Higher EC2N group go here... */
/* XXX group 6 to 13 are not yet defined (draft-ike-ecc) */
@@ -372,7 +379,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
MODP, OAKLEY_GRP_15, 0, &oakley_modp[4], 0, 0, 0, 0, 0,
@@ -380,7 +388,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
MODP, OAKLEY_GRP_16, 0, &oakley_modp[5], 0, 0, 0, 0, 0,
@@ -388,7 +397,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
MODP, OAKLEY_GRP_17, 0, &oakley_modp[6], 0, 0, 0, 0, 0,
@@ -396,7 +406,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
{
MODP, OAKLEY_GRP_18, 0, &oakley_modp[7], 0, 0, 0, 0, 0,
@@ -404,7 +415,8 @@ struct group groups[] = {
(void (*) (struct group *, void *, u_int8_t *)) modp_getraw,
(int (*) (struct group *, void *, u_int8_t *, int)) modp_setraw,
(int (*) (struct group *, void *)) modp_setrandom,
- (int (*) (struct group *, void *, void *, void *)) modp_operation
+ (int (*) (struct group *, void *, void *, void *)) modp_operation,
+ (int (*) (struct group *, void *)) modp_validate_public
},
};
@@ -697,16 +709,11 @@ modp_getraw(struct group *grp, math_mp_t v, u_int8_t *d)
}
int
-modp_setraw(struct group *grp, math_mp_t d, u_int8_t *s, int l)
+modp_setraw(struct group *group, math_mp_t d, u_int8_t *s, int l)
{
- u_int32_t i;
+ if (BN_bin2bn(s, l, d) == NULL)
+ return (-1);
- /* XXX bin2bn? */
- BN_set_word(d, 0);
- for (i = 0; i < l; i++) {
- BN_mul_word(d, 256);
- BN_add_word(d, s[i]);
- }
return 0;
}
@@ -741,6 +748,44 @@ modp_operation(struct group *group, math_mp_t d, math_mp_t a, math_mp_t e)
}
int
+modp_validate_public(struct group *group, math_mp_t pub_exp)
+{
+ struct modp_group *grp = (struct modp_group *)group->group;
+ int i, len, bits_set;
+ math_mp_t tmp;
+
+ /*
+ * Sanity checks from RFC2142 section 2.3.1.1:
+ * Ensure that peer does not send us <0, 0, 1, p-1 or >= p
+ */
+ if (BN_cmp(pub_exp, BN_value_one()) != 1) /* pub_exp <= 1 */
+ return (-1);
+ if ((tmp = BN_new()) == NULL)
+ return (-1);
+ if (!BN_sub(tmp, grp->p, BN_value_one()) ||
+ BN_cmp(pub_exp, tmp) != -1) { /* pub_exp > p-2 */
+ BN_clear_free(tmp);
+ return (-1);
+ }
+ BN_clear_free(tmp);
+
+ /*
+ * Another sanity check: when the generator is 2 and the
+ * population count of the public exponent is 1, then
+ * computing log_g(pub_exp) is trivial.
+ */
+ len = BN_num_bits(pub_exp);
+ for (bits_set = i = 0; i < len; i++) {
+ if (BN_is_bit_set(pub_exp, i))
+ bits_set++;
+ }
+ if (bits_set <= 1)
+ return (-1);
+
+ return (0);
+}
+
+int
ec2n_getlen(struct group *group)
{
struct ec2n_group *grp = (struct ec2n_group *)group->group;
@@ -824,3 +869,10 @@ ec2n_operation(struct group *grp, ec2np_ptr d, ec2np_ptr a, ec2np_ptr e)
return ec2np_mul(d, a, ex, group->grp);
}
+
+int
+ec2n_validate_public(struct group *grp, ec2np_ptr p)
+{
+ /* XXX: needs similar checks to modp_validate_public() */
+ return (0);
+}
diff --git a/sbin/isakmpd/math_group.h b/sbin/isakmpd/math_group.h
index d5a19bcc76d..4949b710b88 100644
--- a/sbin/isakmpd/math_group.h
+++ b/sbin/isakmpd/math_group.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: math_group.h,v 1.10 2004/04/15 18:39:26 deraadt Exp $ */
+/* $OpenBSD: math_group.h,v 1.11 2006/05/04 14:37:51 djm Exp $ */
/* $EOM: math_group.h,v 1.7 1999/04/17 23:20:40 niklas Exp $ */
/*
@@ -56,6 +56,7 @@ struct group {
int (*setraw) (struct group *, void *, u_int8_t *, int);
int (*setrandom) (struct group *, void *);
int (*operation) (struct group *, void *, void *, void *);
+ int (*validate_public) (struct group *, void *);
};
/* Description of an Elliptic Group over GF(2**n) for Boot-Strapping */