Poly1305: Use |size_t|; assert |poly1305_state| is large enough.
Clarify that there are no truncation issues on targets where the range
of |unsigned| is smaller than the range of |size_t|.
Ensure that |poly1305_state| is (still) large enough. This is a good
idea independently of this change, but is especially important because
switching the fields to |size_t| might have enlarged the structures.
Change-Id: I16e408229c28fcba6c3592603ddb9431cf1f142d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/44244
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/poly1305/poly1305.c b/crypto/poly1305/poly1305.c
index a6dd145..31a567d 100644
--- a/crypto/poly1305/poly1305.c
+++ b/crypto/poly1305/poly1305.c
@@ -46,10 +46,14 @@
uint32_t s1, s2, s3, s4;
uint32_t h0, h1, h2, h3, h4;
uint8_t buf[16];
- unsigned int buf_used;
+ size_t buf_used;
uint8_t key[16];
};
+OPENSSL_STATIC_ASSERT(
+ sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state),
+ "poly1305_state isn't large enough to hold aligned poly1305_state_st");
+
static inline struct poly1305_state_st *poly1305_aligned_state(
poly1305_state *state) {
return (struct poly1305_state_st *)(((uintptr_t)state + 63) & ~63);
@@ -200,7 +204,6 @@
void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
size_t in_len) {
- unsigned int i;
struct poly1305_state_st *state = poly1305_aligned_state(statep);
#if defined(OPENSSL_POLY1305_NEON)
@@ -211,11 +214,11 @@
#endif
if (state->buf_used) {
- unsigned todo = 16 - state->buf_used;
+ size_t todo = 16 - state->buf_used;
if (todo > in_len) {
- todo = (unsigned)in_len;
+ todo = in_len;
}
- for (i = 0; i < todo; i++) {
+ for (size_t i = 0; i < todo; i++) {
state->buf[state->buf_used + i] = in[i];
}
state->buf_used += todo;
@@ -236,10 +239,10 @@
}
if (in_len) {
- for (i = 0; i < in_len; i++) {
+ for (size_t i = 0; i < in_len; i++) {
state->buf[i] = in[i];
}
- state->buf_used = (unsigned)in_len;
+ state->buf_used = in_len;
}
}
diff --git a/crypto/poly1305/poly1305_arm.c b/crypto/poly1305/poly1305_arm.c
index 004221d..d6f034c 100644
--- a/crypto/poly1305/poly1305_arm.c
+++ b/crypto/poly1305/poly1305_arm.c
@@ -36,7 +36,7 @@
const fe1305x2 *c);
extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in,
- unsigned int inlen);
+ size_t inlen);
static void freeze(fe1305x2 *r) {
int i;
@@ -136,7 +136,7 @@
}
static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x, size_t xlen) {
- unsigned i;
+ size_t i;
uint8_t t[17];
for (i = 0; (i < 16) && (i < xlen); i++) {
@@ -179,17 +179,20 @@
struct poly1305_state_st {
uint8_t data[sizeof(fe1305x2[5]) + 128];
uint8_t buf[32];
- unsigned int buf_used;
+ size_t buf_used;
uint8_t key[16];
};
+OPENSSL_STATIC_ASSERT(
+ sizeof(struct poly1305_state_st) + 63 <= sizeof(poly1305_state),
+ "poly1305_state isn't large enough to hold aligned poly1305_state_st.");
+
void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) {
struct poly1305_state_st *st = (struct poly1305_state_st *)(state);
fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data)));
fe1305x2 *const h = r + 1;
fe1305x2 *const c = h + 1;
fe1305x2 *const precomp = c + 1;
- unsigned int j;
r->v[1] = r->v[0] = 0x3ffffff & load32(key);
r->v[3] = r->v[2] = 0x3ffff03 & (load32(key + 3) >> 2);
@@ -197,7 +200,7 @@
r->v[7] = r->v[6] = 0x3f03fff & (load32(key + 9) >> 6);
r->v[9] = r->v[8] = 0x00fffff & (load32(key + 12) >> 8);
- for (j = 0; j < 10; j++) {
+ for (size_t j = 0; j < 10; j++) {
h->v[j] = 0; // XXX: should fast-forward a bit
}
@@ -215,14 +218,13 @@
fe1305x2 *const h = r + 1;
fe1305x2 *const c = h + 1;
fe1305x2 *const precomp = c + 1;
- unsigned int i;
if (st->buf_used) {
- unsigned int todo = 32 - st->buf_used;
+ size_t todo = 32 - st->buf_used;
if (todo > in_len) {
todo = in_len;
}
- for (i = 0; i < todo; i++) {
+ for (size_t i = 0; i < todo; i++) {
st->buf[st->buf_used + i] = in[i];
}
st->buf_used += todo;
@@ -232,7 +234,7 @@
if (st->buf_used == sizeof(st->buf) && in_len) {
addmulmod(h, h, precomp, &zero);
fe1305x2_frombytearray(c, st->buf, sizeof(st->buf));
- for (i = 0; i < 10; i++) {
+ for (size_t i = 0; i < 10; i++) {
h->v[i] += c->v[i];
}
st->buf_used = 0;
@@ -240,7 +242,7 @@
}
while (in_len > 32) {
- unsigned int tlen = 1048576;
+ size_t tlen = 1048576;
if (in_len < tlen) {
tlen = in_len;
}
@@ -250,7 +252,7 @@
}
if (in_len) {
- for (i = 0; i < in_len; i++) {
+ for (size_t i = 0; i < in_len; i++) {
st->buf[i] = in[i];
}
st->buf_used = in_len;
diff --git a/crypto/poly1305/poly1305_vec.c b/crypto/poly1305/poly1305_vec.c
index 29cd5c3..83f1efe 100644
--- a/crypto/poly1305/poly1305_vec.c
+++ b/crypto/poly1305/poly1305_vec.c
@@ -92,6 +92,10 @@
} poly1305_state_internal; /* 448 bytes total + 63 bytes for
alignment = 511 bytes raw */
+OPENSSL_STATIC_ASSERT(
+ sizeof(struct poly1305_state_internal_t) + 63 <= sizeof(poly1305_state),
+ "poly1305_state isn't large enough to hold aligned poly1305_state_internal_t");
+
static inline poly1305_state_internal *poly1305_aligned_state(
poly1305_state *state) {
return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);