Don't overflow state->calls on 16TiB RAND_bytes calls. This is an extremely important and practical use case. The comment that state->calls is bounded by the reseed interval isn't quite true. We only check on entry to the function, which means that it may exceed it by one call's worth. Switch it to a size_t (which doesn't actually increase memory because the struct was already padded). Change-Id: Ia7646fd5b4142789c1d613280223baa4cd1a4a9b Reviewed-on: https://boringssl-review.googlesource.com/c/32804 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/fipsmodule/rand/rand.c b/crypto/fipsmodule/rand/rand.c index 02e63bc..e6b4bb4 100644 --- a/crypto/fipsmodule/rand/rand.c +++ b/crypto/fipsmodule/rand/rand.c
@@ -109,8 +109,9 @@ // next forms a NULL-terminated linked-list of all free |rand_state| objects. struct rand_state *next; // calls is the number of generate calls made on |drbg| since it was last - // (re)seeded. This is bound by |kReseedInterval|. - unsigned calls; + // (re)seeded. This is bound by + // |kReseedInterval - 1 + SIZE_MAX / CTR_DRBG_MAX_GENERATE_LENGTH|. + size_t calls; #if defined(BORINGSSL_FIPS) // next_all forms another NULL-terminated linked-list, this time of all @@ -351,6 +352,8 @@ out += todo; out_len -= todo; + // Though we only check before entering the loop, this cannot add enough to + // overflow a |size_t|. state->calls++; first_call = 0; }