aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-04-15 20:35:45 +0200
committerChristian Grothoff <christian@grothoff.org>2020-04-15 20:35:45 +0200
commitc894cf82d59f81529c8f50edec91ca27bd39023d (patch)
tree3a8a50bdcce3843bc153e0dd8f5a41b8b50dcf62 /src/util
parent839badf7cf98669b7945010739d4040a1eeec87a (diff)
downloadgnunet-c894cf82d59f81529c8f50edec91ca27bd39023d.tar.gz
gnunet-c894cf82d59f81529c8f50edec91ca27bd39023d.zip
add integer overflow guards and avoid (unlimited) stack allocation
Diffstat (limited to 'src/util')
-rw-r--r--src/util/crypto_hkdf.c33
1 files 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,
175 175
176 ctx_len = 0; 176 ctx_len = 0;
177 while (NULL != va_arg (args, void *)) 177 while (NULL != va_arg (args, void *))
178 ctx_len += va_arg (args, size_t); 178 {
179 size_t nxt = va_arg (args, size_t);
180 if (nxt + ctx_len < nxt)
181 {
182 /* integer overflow */
183 GNUNET_break (0);
184 va_end (args);
185 goto hkdf_error;
186 }
187 ctx_len += nxt;
188 }
179 189
180 va_end (args); 190 va_end (args);
181 191
192 if ( (k + ctx_len < ctx_len) ||
193 (k + ctx_len + 1 < ctx_len) )
194 {
195 /* integer overflow */
196 GNUNET_break (0);
197 goto hkdf_error;
198 }
199
182 memset (result, 0, out_len); 200 memset (result, 0, out_len);
183 if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) != GNUNET_YES) 201 if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) != GNUNET_YES)
184 goto hkdf_error; 202 goto hkdf_error;
@@ -192,10 +210,11 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
192 /* K(1) */ 210 /* K(1) */
193 { 211 {
194 size_t plain_len = k + ctx_len + 1; 212 size_t plain_len = k + ctx_len + 1;
195 char plain[plain_len]; 213 char *plain;
196 const void *ctx; 214 const void *ctx;
197 char *dst; 215 char *dst;
198 216
217 plain = GNUNET_malloc (plain_len);
199 dst = plain + k; 218 dst = plain + k;
200 va_copy (args, argp); 219 va_copy (args, argp);
201 while ((ctx = va_arg (args, void *))) 220 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,
216#endif 235#endif
217 hc = doHMAC (prf, prk, xtr_len, &plain[k], ctx_len + 1); 236 hc = doHMAC (prf, prk, xtr_len, &plain[k], ctx_len + 1);
218 if (hc == NULL) 237 if (hc == NULL)
238 {
239 GNUNET_free (plain);
219 goto hkdf_error; 240 goto hkdf_error;
241 }
220 GNUNET_memcpy (result, hc, k); 242 GNUNET_memcpy (result, hc, k);
221 result += k; 243 result += k;
222 } 244 }
@@ -232,7 +254,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
232#endif 254#endif
233 hc = doHMAC (prf, prk, xtr_len, plain, plain_len); 255 hc = doHMAC (prf, prk, xtr_len, plain, plain_len);
234 if (hc == NULL) 256 if (hc == NULL)
257 {
258 GNUNET_free (plain);
235 goto hkdf_error; 259 goto hkdf_error;
260 }
236 GNUNET_memcpy (result, hc, k); 261 GNUNET_memcpy (result, hc, k);
237 result += k; 262 result += k;
238 } 263 }
@@ -255,7 +280,10 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
255 else 280 else
256 hc = doHMAC (prf, prk, xtr_len, plain + k, plain_len - k); 281 hc = doHMAC (prf, prk, xtr_len, plain + k, plain_len - k);
257 if (hc == NULL) 282 if (hc == NULL)
283 {
284 GNUNET_free (plain);
258 goto hkdf_error; 285 goto hkdf_error;
286 }
259 GNUNET_memcpy (result, hc, d); 287 GNUNET_memcpy (result, hc, d);
260 } 288 }
261#if DEBUG_HKDF 289#if DEBUG_HKDF
@@ -263,6 +291,7 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo,
263#endif 291#endif
264 292
265 ret = GNUNET_YES; 293 ret = GNUNET_YES;
294 GNUNET_free (plain);
266 goto hkdf_ok; 295 goto hkdf_ok;
267 } 296 }
268hkdf_error: 297hkdf_error: