summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2012-06-04 09:14:29 +0000
committermikeb <mikeb@openbsd.org>2012-06-04 09:14:29 +0000
commit45b72fd1a26b2a335007f92d655420371e70caaa (patch)
treecd1ec6523419fa69e80d8324ebce57752b4e5096
parentfix autodetection, somehow I managed to lose that commit earlier ? (diff)
downloadwireguard-openbsd-45b72fd1a26b2a335007f92d655420371e70caaa.tar.xz
wireguard-openbsd-45b72fd1a26b2a335007f92d655420371e70caaa.zip
Rounding up a number of bytes in a bignum returned by the BN_num_bytes()
has implications when dealing with leading zeroes. Prevent an incorrect conversion of the EC point to the binary representation by inferring the X and Y components' lengths from the EC group length and zeroing out the appropriate chunks of the target buffer. From hshoexer@
-rw-r--r--sbin/iked/dh.c14
-rw-r--r--sbin/isakmpd/dh.c14
2 files changed, 20 insertions, 8 deletions
diff --git a/sbin/iked/dh.c b/sbin/iked/dh.c
index 5b38f417440..ae7d638c6e6 100644
--- a/sbin/iked/dh.c
+++ b/sbin/iked/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.6 2011/07/03 20:20:23 mikeb Exp $ */
+/* $OpenBSD: dh.c,v 1.7 2012/06/04 09:14:29 mikeb Exp $ */
/* $vantronix: dh.c,v 1.13 2010/05/28 15:34:35 reyk Exp $ */
/*
@@ -461,6 +461,7 @@ ec_getlen(struct group *group)
{
if (group->spec == NULL)
return (0);
+ /* NB: Return value will always be even */
return ((roundup(group->spec->bits, 8) * 2) / 8);
}
@@ -517,7 +518,7 @@ ec_point2raw(struct group *group, const EC_POINT *point,
BN_CTX *bnctx = NULL;
BIGNUM *x = NULL, *y = NULL;
int ret = -1;
- size_t xlen, ylen;
+ size_t eclen, xlen, ylen;
off_t xoff, yoff;
if ((bnctx = BN_CTX_new()) == NULL)
@@ -527,6 +528,11 @@ ec_point2raw(struct group *group, const EC_POINT *point,
(y = BN_CTX_get(bnctx)) == NULL)
goto done;
+ eclen = ec_getlen(group);
+ if (len < eclen)
+ goto done;
+ xlen = ylen = eclen / 2;
+
if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
goto done;
@@ -541,13 +547,13 @@ ec_point2raw(struct group *group, const EC_POINT *point,
goto done;
}
- xlen = roundup(BN_num_bytes(x), 2);
xoff = xlen - BN_num_bytes(x);
+ bzero(buf, xoff);
if (!BN_bn2bin(x, buf + xoff))
goto done;
- ylen = roundup(BN_num_bytes(y), 2);
yoff = (ylen - BN_num_bytes(y)) + xlen;
+ bzero(buf + xlen, yoff - xlen);
if (!BN_bn2bin(y, buf + yoff))
goto done;
diff --git a/sbin/isakmpd/dh.c b/sbin/isakmpd/dh.c
index 645e5c1ff95..1750312f854 100644
--- a/sbin/isakmpd/dh.c
+++ b/sbin/isakmpd/dh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.c,v 1.14 2011/06/15 10:35:47 mikeb Exp $ */
+/* $OpenBSD: dh.c,v 1.15 2012/06/04 09:14:29 mikeb Exp $ */
/* $vantronix: dh.c,v 1.13 2010/05/28 15:34:35 reyk Exp $ */
/*
@@ -461,6 +461,7 @@ ec_getlen(struct group *group)
{
if (group->spec == NULL)
return (0);
+ /* NB: Return value will always be even */
return ((roundup(group->spec->bits, 8) * 2) / 8);
}
@@ -517,7 +518,7 @@ ec_point2raw(struct group *group, const EC_POINT *point,
BN_CTX *bnctx = NULL;
BIGNUM *x = NULL, *y = NULL;
int ret = -1;
- size_t xlen, ylen;
+ size_t eclen, xlen, ylen;
off_t xoff, yoff;
if ((bnctx = BN_CTX_new()) == NULL)
@@ -527,6 +528,11 @@ ec_point2raw(struct group *group, const EC_POINT *point,
(y = BN_CTX_get(bnctx)) == NULL)
goto done;
+ eclen = ec_getlen(group);
+ if (len < eclen)
+ goto done;
+ xlen = ylen = eclen / 2;
+
if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
goto done;
@@ -541,13 +547,13 @@ ec_point2raw(struct group *group, const EC_POINT *point,
goto done;
}
- xlen = roundup(BN_num_bytes(x), 2);
xoff = xlen - BN_num_bytes(x);
+ bzero(buf, xoff);
if (!BN_bn2bin(x, buf + xoff))
goto done;
- ylen = roundup(BN_num_bytes(y), 2);
yoff = (ylen - BN_num_bytes(y)) + xlen;
+ bzero(buf + xlen, yoff - xlen);
if (!BN_bn2bin(y, buf + yoff))
goto done;