commit c894cf82d59f81529c8f50edec91ca27bd39023d
parent 839badf7cf98669b7945010739d4040a1eeec87a
Author: Christian Grothoff <christian@grothoff.org>
Date: Wed, 15 Apr 2020 20:35:45 +0200
add integer overflow guards and avoid (unlimited) stack allocation
Diffstat:
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git 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: