From 21654feacf896dbd0001798f2c549c31b9974412 Mon Sep 17 00:00:00 2001 From: jsing <> Date: Sun, 13 Sep 2015 11:49:44 +0000 Subject: 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" --- src/lib/libssl/src/crypto/ecdh/ecdh.h | 3 ++- src/lib/libssl/src/crypto/ecdh/ech_err.c | 3 ++- src/lib/libssl/src/crypto/ecdh/ech_ossl.c | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/lib/libssl') diff --git a/src/lib/libssl/src/crypto/ecdh/ecdh.h b/src/lib/libssl/src/crypto/ecdh/ecdh.h index 3bcb8b045e..e1cc8404d0 100644 --- a/src/lib/libssl/src/crypto/ecdh/ecdh.h +++ b/src/lib/libssl/src/crypto/ecdh/ecdh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ecdh.h,v 1.3 2015/09/13 10:46:20 jsing Exp $ */ +/* $OpenBSD: ecdh.h,v 1.4 2015/09/13 11:49:44 jsing Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -116,6 +116,7 @@ void ERR_load_ECDH_strings(void); /* Reason codes. */ #define ECDH_R_KDF_FAILED 102 +#define ECDH_R_KEY_TRUNCATION 104 #define ECDH_R_NON_FIPS_METHOD 103 #define ECDH_R_NO_PRIVATE_VALUE 100 #define ECDH_R_POINT_ARITHMETIC_FAILURE 101 diff --git a/src/lib/libssl/src/crypto/ecdh/ech_err.c b/src/lib/libssl/src/crypto/ecdh/ech_err.c index 2899b573c3..afe5ff3af8 100644 --- a/src/lib/libssl/src/crypto/ecdh/ech_err.c +++ b/src/lib/libssl/src/crypto/ecdh/ech_err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ech_err.c,v 1.4 2015/09/13 10:46:20 jsing Exp $ */ +/* $OpenBSD: ech_err.c,v 1.5 2015/09/13 11:49:44 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * @@ -80,6 +80,7 @@ static ERR_STRING_DATA ECDH_str_functs[]= { static ERR_STRING_DATA ECDH_str_reasons[]= { {ERR_REASON(ECDH_R_KDF_FAILED) , "KDF failed"}, + {ERR_REASON(ECDH_R_KEY_TRUNCATION), "key would be truncated"}, {ERR_REASON(ECDH_R_NON_FIPS_METHOD) , "non fips method"}, {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE) , "no private value"}, {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, diff --git a/src/lib/libssl/src/crypto/ecdh/ech_ossl.c b/src/lib/libssl/src/crypto/ecdh/ech_ossl.c index f05db87f78..746eb12ea3 100644 --- a/src/lib/libssl/src/crypto/ecdh/ech_ossl.c +++ b/src/lib/libssl/src/crypto/ecdh/ech_ossl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ech_ossl.c,v 1.10 2015/09/13 10:46:20 jsing Exp $ */ +/* $OpenBSD: ech_ossl.c,v 1.11 2015/09/13 11:49:44 jsing Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -115,7 +115,8 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, unsigned char *buf = NULL; if (outlen > INT_MAX) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */ + /* Sort of, anyway. */ + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); return -1; } @@ -171,6 +172,11 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); goto err; } + if (outlen < buflen) { + /* The resulting key would be truncated. */ + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KEY_TRUNCATION); + goto err; + } if ((buf = malloc(buflen)) == NULL) { ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; @@ -189,9 +195,11 @@ ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, } ret = outlen; } else { - /* no KDF, just copy as much as we can */ - if (outlen > buflen) + /* No KDF, just copy as much as we can and zero the rest. */ + if (outlen > buflen) { + memset(out + buflen, 0, outlen - buflen); outlen = buflen; + } memcpy(out, buf, outlen); ret = outlen; } -- cgit v1.2.3-55-g6feb