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;
}