From c894cf82d59f81529c8f50edec91ca27bd39023d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 15 Apr 2020 20:35:45 +0200 Subject: [PATCH] add integer overflow guards and avoid (unlimited) stack allocation --- src/util/crypto_hkdf.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c index 9cdb9d9bc..86a814b12 100644 --- a/src/util/crypto_hkdf.c +++ b/src/util/crypto_hkdf.c @@ -175,10 +175,28 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, ctx_len = 0; while (NULL != va_arg (args, void *)) - ctx_len += va_arg (args, size_t); + { + size_t nxt = va_arg (args, size_t); + if (nxt + ctx_len < nxt) + { + /* integer overflow */ + GNUNET_break (0); + va_end (args); + goto hkdf_error; + } + ctx_len += nxt; + } va_end (args); + if ( (k + ctx_len < ctx_len) || + (k + ctx_len + 1 < ctx_len) ) + { + /* integer overflow */ + GNUNET_break (0); + goto hkdf_error; + } + memset (result, 0, out_len); if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) != GNUNET_YES) goto hkdf_error; @@ -192,10 +210,11 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, /* K(1) */ { size_t plain_len = k + ctx_len + 1; - char plain[plain_len]; + char *plain; const void *ctx; char *dst; + plain = GNUNET_malloc (plain_len); dst = plain + k; va_copy (args, argp); while ((ctx = va_arg (args, void *))) @@ -216,7 +235,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, #endif hc = doHMAC (prf, prk, xtr_len, &plain[k], ctx_len + 1); if (hc == NULL) + { + GNUNET_free (plain); goto hkdf_error; + } GNUNET_memcpy (result, hc, k); result += k; } @@ -232,7 +254,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, #endif hc = doHMAC (prf, prk, xtr_len, plain, plain_len); if (hc == NULL) + { + GNUNET_free (plain); goto hkdf_error; + } GNUNET_memcpy (result, hc, k); result += k; } @@ -255,7 +280,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, else hc = doHMAC (prf, prk, xtr_len, plain + k, plain_len - k); if (hc == NULL) + { + GNUNET_free (plain); goto hkdf_error; + } GNUNET_memcpy (result, hc, d); } #if DEBUG_HKDF @@ -263,6 +291,7 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, #endif ret = GNUNET_YES; + GNUNET_free (plain); goto hkdf_ok; } hkdf_error: -- 2.25.1