On Thu, Apr 30, 2026 at 1:30 PM Tiago Matos via dev <[email protected]> wrote:
> The sha1_update() and sha1_bytes() functions previously accepted > buffer lengths as uint32_t, which silently truncated larger size_t > values passed by callers. This manifested as incorrect SHA1 hashes > when compacting an OVSDB database larger than 4GB: the truncated > length was forwarded to OpenSSL's EVP_DigestUpdate(), causing it to > hash only the low 32 bits' worth of bytes. > > Change the length parameter of sha1_update() and sha1_bytes() from > uint32_t to size_t so the full buffer length is preserved. > > Signed-off-by: Tiago Matos <[email protected]> > Thanks for updating this patch Tiago, comments below. > --- > lib/sha1.c | 21 ++++++++++++--------- > lib/sha1.h | 8 ++++---- > tests/test-sha1.c | 5 +++-- > 3 files changed, 19 insertions(+), 15 deletions(-) > > diff --git a/lib/sha1.c b/lib/sha1.c > index 871ff55ed..fa4bd278c 100644 > --- a/lib/sha1.c > +++ b/lib/sha1.c > @@ -30,6 +30,7 @@ > */ > > #include <config.h> > +#include <stddef.h> > #include "sha1.h" > > #ifdef HAVE_OPENSSL > @@ -80,7 +81,7 @@ sha1_init(struct sha1_ctx *sha_info) > * inputLen: The length of the input buffer. > */ > void > -sha1_update(struct sha1_ctx *ctx, const void *buffer_, uint32_t count) > +sha1_update(struct sha1_ctx *ctx, const void *buffer_, size_t count) > { > #ifdef HAVE_OPENSSL > if (!EVP_DigestUpdate(ctx->ctx, buffer_, count)) { > @@ -114,7 +115,7 @@ sha1_final(struct sha1_ctx *ctx, uint8_t > digest[SHA1_DIGEST_SIZE]) > > /* Computes the hash of 'n' bytes in 'data' into 'digest'. */ > void > -sha1_bytes(const void *data, uint32_t n, uint8_t digest[SHA1_DIGEST_SIZE]) > +sha1_bytes(const void *data, size_t n, uint8_t digest[SHA1_DIGEST_SIZE]) > { > struct sha1_ctx ctx; > > @@ -316,20 +317,22 @@ ovs_sha1_init(struct sha1_ctx *sha_info) > * inputLen: The length of the input buffer. > */ > void > -ovs_sha1_update(struct sha1_ctx *ctx, const void *buffer_, uint32_t count) > +ovs_sha1_update(struct sha1_ctx *ctx, const void *buffer_, size_t count) > { > const uint8_t *buffer = buffer_; > unsigned int i; > + uint32_t lo_add = (uint32_t)((uint64_t)count << 3); > + uint32_t hi_add = (uint32_t)((uint64_t)count >> 29); > > - if ((ctx->count_lo + (count << 3)) < ctx->count_lo) { > + if (ctx->count_lo + lo_add < ctx->count_lo) { > ctx->count_hi++; > } > - ctx->count_lo += count << 3; > - ctx->count_hi += count >> 29; > + ctx->count_lo += lo_add; > + ctx->count_hi += hi_add; > if (ctx->local) { > i = SHA_BLOCK_SIZE - ctx->local; > Checkpatch alerted on some missing spaces in casting, but I think there are more casts and types here than needed. Something like this should work: -ovs_sha1_update(struct sha1_ctx *ctx, const void *buffer_, uint32_t count) +ovs_sha1_update(struct sha1_ctx *ctx, const void *buffer_, size_t count) { const uint8_t *buffer = buffer_; - unsigned int i; + uint32_t lo_add = count << 3; + uint32_t hi_add = count >> 29; - if ((ctx->count_lo + (count << 3)) < ctx->count_lo) { + if (ctx->count_lo + lo_add < ctx->count_lo) { ctx->count_hi++; } - ctx->count_lo += count << 3; - ctx->count_hi += count >> 29; + ctx->count_lo += lo_add; + ctx->count_hi += hi_add; if (ctx->local) { - i = SHA_BLOCK_SIZE - ctx->local; + size_t i = SHA_BLOCK_SIZE - ctx->local; if (i > count) { i = count; } > if (i > count) { > - i = count; > + i = (unsigned int)count; > } > memcpy(((uint8_t *) ctx->data) + ctx->local, buffer, i); > count -= i; > @@ -350,7 +353,7 @@ ovs_sha1_update(struct sha1_ctx *ctx, const void > *buffer_, uint32_t count) > sha_transform(ctx); > } > memcpy(ctx->data, buffer, count); > - ctx->local = count; > + ctx->local = (int)count; > I don't think this cast is needed. But given how it's used ctx->local should probably be size_t. Cheers, M > } > > /* > @@ -393,7 +396,7 @@ ovs_sha1_final(struct sha1_ctx *ctx, uint8_t > digest[SHA1_DIGEST_SIZE]) > > /* Computes the hash of 'n' bytes in 'data' into 'digest'. */ > void > -ovs_sha1_bytes(const void *data, uint32_t n, uint8_t > digest[SHA1_DIGEST_SIZE]) > +ovs_sha1_bytes(const void *data, size_t n, uint8_t > digest[SHA1_DIGEST_SIZE]) > { > struct sha1_ctx ctx; > > diff --git a/lib/sha1.h b/lib/sha1.h > index 710e5751c..fdf523302 100644 > --- a/lib/sha1.h > +++ b/lib/sha1.h > @@ -56,9 +56,9 @@ struct sha1_ctx { > }; > > void sha1_init(struct sha1_ctx *); > -void sha1_update(struct sha1_ctx *, const void *, uint32_t size); > +void sha1_update(struct sha1_ctx *, const void *, size_t size); > void sha1_final(struct sha1_ctx *, uint8_t digest[SHA1_DIGEST_SIZE]); > -void sha1_bytes(const void *, uint32_t size, uint8_t > digest[SHA1_DIGEST_SIZE]); > +void sha1_bytes(const void *, size_t size, uint8_t > digest[SHA1_DIGEST_SIZE]); > > #define SHA1_FMT \ > "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \ > @@ -77,9 +77,9 @@ bool sha1_from_hex(uint8_t digest[SHA1_DIGEST_SIZE], > const char *hex); > /* Generic implementation for the case where OpenSSL is not available. > * This API should not be used directly. Exposed for unit testing. */ > void ovs_sha1_init(struct sha1_ctx *); > -void ovs_sha1_update(struct sha1_ctx *, const void *, uint32_t size); > +void ovs_sha1_update(struct sha1_ctx *, const void *, size_t size); > void ovs_sha1_final(struct sha1_ctx *, uint8_t digest[SHA1_DIGEST_SIZE]); > -void ovs_sha1_bytes(const void *, uint32_t size, > +void ovs_sha1_bytes(const void *, size_t size, > uint8_t digest[SHA1_DIGEST_SIZE]); > > #endif /* sha1.h */ > diff --git a/tests/test-sha1.c b/tests/test-sha1.c > index f5a310bc9..bd3fa7bbb 100644 > --- a/tests/test-sha1.c > +++ b/tests/test-sha1.c > @@ -15,6 +15,7 @@ > */ > > #include <config.h> > +#include <stddef.h> > #undef NDEBUG > #include "sha1.h" > #include <assert.h> > @@ -34,9 +35,9 @@ struct test_vector { > > struct test_api { > void (*sha1_init)(struct sha1_ctx *); > - void (*sha1_update)(struct sha1_ctx *, const void *, uint32_t size); > + void (*sha1_update)(struct sha1_ctx *, const void *, size_t size); > void (*sha1_final)(struct sha1_ctx *, uint8_t > digest[SHA1_DIGEST_SIZE]); > - void (*sha1_bytes)(const void *, uint32_t size, > + void (*sha1_bytes)(const void *, size_t size, > uint8_t digest[SHA1_DIGEST_SIZE]); > }; > > -- > 2.54.0 > > > -- > > > > > _'Esta mensagem é direcionada apenas para os endereços constantes no > cabeçalho inicial. Se você não está listado nos endereços constantes no > cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa > mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas > estão > imediatamente anuladas e proibidas'._ > > > * **'Apesar do Magazine Luiza tomar > todas as precauções razoáveis para assegurar que nenhum vírus esteja > presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por > quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.* > > > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
