diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2011-06-15 10:35:48 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2011-06-15 10:35:48 +0000 |
commit | d5197df77301177f78f208941fbed20b5cef39b3 (patch) | |
tree | 73d05c87311287ad5ba3f1d6fc147cdb52b7b9a6 | |
parent | 902175ed45929edc16a99c241c40fac67a81c00a (diff) |
When BN_bn2bin converts a bignum to the binary representation
it skips leading zeroes if there are any. To accommodate the
difference with the protocol we need to prepend those zeroes
ourselves.
Fixes PR 6601, tested by Pawel Wieleba, sthen, otto.
Huge thanks to Pawel for spending nearly a week testing diffs.
ok sthen
-rw-r--r-- | sbin/isakmpd/dh.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sbin/isakmpd/dh.c b/sbin/isakmpd/dh.c index 9998b0b550e..645e5c1ff95 100644 --- a/sbin/isakmpd/dh.c +++ b/sbin/isakmpd/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.13 2010/11/29 22:49:26 markus Exp $ */ +/* $OpenBSD: dh.c,v 1.14 2011/06/15 10:35:47 mikeb Exp $ */ /* $vantronix: dh.c,v 1.13 2010/05/28 15:34:35 reyk Exp $ */ /* @@ -402,12 +402,22 @@ int modp_create_exchange(struct group *group, u_int8_t *buf) { DH *dh = group->dh; + int len, ret; if (!DH_generate_key(dh)) return (-1); - if (!BN_bn2bin(dh->pub_key, buf)) + ret = BN_bn2bin(dh->pub_key, buf); + if (!ret) return (-1); + len = dh_getlen(group); + + /* add zero padding */ + if (ret < len) { + bcopy(buf, buf + (len - ret), ret); + bzero(buf, len - ret); + } + return (0); } @@ -415,9 +425,11 @@ int modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) { BIGNUM *ex; - int ret; + int len, ret; - if ((ex = BN_bin2bn(exchange, dh_getlen(group), NULL)) == NULL) + len = dh_getlen(group); + + if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL) return (-1); ret = DH_compute_key(secret, ex, group->dh); @@ -425,6 +437,12 @@ modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) if (!ret) return (-1); + /* add zero padding */ + if (ret < len) { + bcopy(secret, secret + (len - ret), ret); + bzero(secret, len - ret); + } + return (0); } |