From: Niels Möller Date: Fri, 8 Mar 2024 16:52:51 +0000 (+0100) Subject: Fix ubsan issue in hash update functions. X-Git-Tag: nettle_3.10rc1~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=99e62003c3916fdef04a2d3327281f8f498b609e;p=thirdparty%2Fnettle.git Fix ubsan issue in hash update functions. --- diff --git a/ChangeLog b/ChangeLog index 69df1d18..4fa4a72f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2024-03-08 Niels Möller + + Fix ubsan issues for empty hash updates. + * macros.h (MD_UPDATE): Check upfront if length is zero. Avoids + calling memcpy(dst, NULL, 0), which is undefined behavior. + * sha256.c (sha256_update): Likewise. + * sha3.c (_nettle_sha3_update): Likewise. + * testsuite/testutils.c (test_hash): Test with message split into + two pieces in different ways, and also add an call to update(ctx, + 0, NULL) in the middle. + 2024-02-16 Niels Möller RSA-OAEP support contributed by Nicolas Mora and Daiki Ueno: diff --git a/macros.h b/macros.h index 990d32ee..320f61ce 100644 --- a/macros.h +++ b/macros.h @@ -180,6 +180,7 @@ do { \ length and data. */ #define MD_UPDATE(ctx, length, data, f, incr) \ do { \ + if (!length) goto __md_done; \ if ((ctx)->index) \ { \ /* Try to fill partial block */ \ diff --git a/sha256.c b/sha256.c index 0c9c21a0..44551224 100644 --- a/sha256.c +++ b/sha256.c @@ -105,6 +105,9 @@ sha256_update(struct sha256_ctx *ctx, size_t length, const uint8_t *data) { size_t blocks; + if (!length) + return; + if (ctx->index > 0) { /* Try to fill partial block */ diff --git a/sha3.c b/sha3.c index cd22041b..0eecfb22 100644 --- a/sha3.c +++ b/sha3.c @@ -67,6 +67,9 @@ _nettle_sha3_update (struct sha3_state *state, unsigned pos, size_t length, const uint8_t *data) { + if (!length) + return pos; + if (pos > 0) { unsigned left = block_size - pos; diff --git a/testsuite/testutils.c b/testsuite/testutils.c index 6fc8a8b8..ac9d8f63 100644 --- a/testsuite/testutils.c +++ b/testsuite/testutils.c @@ -1108,16 +1108,22 @@ test_hash(const struct nettle_hash *hash, ASSERT (digest->length == hash->digest_size); hash->init(ctx); - hash->update(ctx, msg->length, msg->data); - hash->digest(ctx, digest->length, buffer); - - if (MEMEQ(digest->length, digest->data, buffer) == 0) + for (offset = 0; offset <= msg->length && offset < 40; offset++) { - fprintf(stdout, "\nGot:\n"); - print_hex(digest->length, buffer); - fprintf(stdout, "\nExpected:\n"); - print_hex(digest->length, digest->data); - abort(); + hash->update(ctx, offset, msg->data); + hash->update(ctx, 0, NULL); + hash->update(ctx, msg->length - offset, msg->data + offset); + + hash->digest(ctx, digest->length, buffer); + + if (MEMEQ(digest->length, digest->data, buffer) == 0) + { + fprintf(stdout, "Offset %u\nGot:\n", offset); + print_hex(digest->length, buffer); + fprintf(stdout, "\nExpected:\n"); + print_hex(digest->length, digest->data); + abort(); + } } memset(buffer, 0, digest->length);