diff options
author | jsing <> | 2015-09-13 11:49:44 +0000 |
---|---|---|
committer | jsing <> | 2015-09-13 11:49:44 +0000 |
commit | 21654feacf896dbd0001798f2c549c31b9974412 (patch) | |
tree | 26ad5794d56d0f5b57b98ae4229d0178ef464bb9 /src/lib/libcrypto/ecdh/ech_ossl.c | |
parent | 647e0b210017623cf0a87fdbeee7d38a16907ec3 (diff) | |
download | openbsd-21654feacf896dbd0001798f2c549c31b9974412.tar.gz openbsd-21654feacf896dbd0001798f2c549c31b9974412.tar.bz2 openbsd-21654feacf896dbd0001798f2c549c31b9974412.zip |
Check ECDH output buffer length and avoid truncation.
Currently, if you call ECDH_compute_key() it will silently truncate the
resulting key if the output buffer is less than the key size. Instead,
detect this condition and return an error. If the buffer provided is larger
than the key length, zero the remainder.
ok beck@ miod@ "+ shivers"
Diffstat (limited to 'src/lib/libcrypto/ecdh/ech_ossl.c')
-rw-r--r-- | src/lib/libcrypto/ecdh/ech_ossl.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/lib/libcrypto/ecdh/ech_ossl.c b/src/lib/libcrypto/ecdh/ech_ossl.c index f05db87f78..746eb12ea3 100644 --- a/src/lib/libcrypto/ecdh/ech_ossl.c +++ b/src/lib/libcrypto/ecdh/ech_ossl.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ech_ossl.c,v 1.10 2015/09/13 10:46:20 jsing Exp $ */ | 1 | /* $OpenBSD: ech_ossl.c,v 1.11 2015/09/13 11:49:44 jsing Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | 3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. |
4 | * | 4 | * |
@@ -115,7 +115,8 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | |||
115 | unsigned char *buf = NULL; | 115 | unsigned char *buf = NULL; |
116 | 116 | ||
117 | if (outlen > INT_MAX) { | 117 | if (outlen > INT_MAX) { |
118 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */ | 118 | /* Sort of, anyway. */ |
119 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); | ||
119 | return -1; | 120 | return -1; |
120 | } | 121 | } |
121 | 122 | ||
@@ -171,6 +172,11 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | |||
171 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); | 172 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); |
172 | goto err; | 173 | goto err; |
173 | } | 174 | } |
175 | if (outlen < buflen) { | ||
176 | /* The resulting key would be truncated. */ | ||
177 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KEY_TRUNCATION); | ||
178 | goto err; | ||
179 | } | ||
174 | if ((buf = malloc(buflen)) == NULL) { | 180 | if ((buf = malloc(buflen)) == NULL) { |
175 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); | 181 | ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); |
176 | goto err; | 182 | goto err; |
@@ -189,9 +195,11 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | |||
189 | } | 195 | } |
190 | ret = outlen; | 196 | ret = outlen; |
191 | } else { | 197 | } else { |
192 | /* no KDF, just copy as much as we can */ | 198 | /* No KDF, just copy as much as we can and zero the rest. */ |
193 | if (outlen > buflen) | 199 | if (outlen > buflen) { |
200 | memset(out + buflen, 0, outlen - buflen); | ||
194 | outlen = buflen; | 201 | outlen = buflen; |
202 | } | ||
195 | memcpy(out, buf, outlen); | 203 | memcpy(out, buf, outlen); |
196 | ret = outlen; | 204 | ret = outlen; |
197 | } | 205 | } |