* lib/sha3.c (sha3_read_ctx): When using OpenSSL, don’t update the internal context; we’re supposed to read it, not write it. Instead, clone it and update the clone. * tests/test-sha3-224-buffer.c: * tests/test-sha3-256-buffer.c: * tests/test-sha3-384-buffer.c: * tests/test-sha3-512-buffer.c: (check): Test for the bug. --- ChangeLog | 10 ++++++++++ lib/sha3.c | 17 +++++++++++++++-- tests/test-sha3-224-buffer.c | 8 ++++++-- tests/test-sha3-256-buffer.c | 8 ++++++-- tests/test-sha3-384-buffer.c | 8 ++++++-- tests/test-sha3-512-buffer.c | 8 ++++++-- 6 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/ChangeLog b/ChangeLog index 9750ee1e80..18c2dd56d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2026-02-22 Paul Eggert <[email protected]> + crypto/sha3: fix sha3_read_ctx reset bug + * lib/sha3.c (sha3_read_ctx): When using OpenSSL, don’t update the + internal context; we’re supposed to read it, not write it. + Instead, clone it and update the clone. + * tests/test-sha3-224-buffer.c: + * tests/test-sha3-256-buffer.c: + * tests/test-sha3-384-buffer.c: + * tests/test-sha3-512-buffer.c: + (check): Test for the bug. + crypto/sha3: EVP_MD_CTX_create → EVP_MD_CTX_new * lib/sha3.c (sha3_##SIZE##_init_ctx): Avoid deprecated macro name. diff --git a/lib/sha3.c b/lib/sha3.c index 2c3b932b91..ec893fc003 100644 --- a/lib/sha3.c +++ b/lib/sha3.c @@ -374,8 +374,21 @@ sha3_free_ctx (struct sha3_ctx *ctx) void * sha3_read_ctx (const struct sha3_ctx *ctx, void *resbuf) { - /* Assume any unprocessed bytes in ctx are not to be ignored. */ - return sha3_finish_ctx ((struct sha3_ctx *) ctx, resbuf); + void *result = NULL; + int err = ENOMEM; + EVP_MD_CTX *evp_ctx = EVP_MD_CTX_new (); + if (evp_ctx) + { + if (EVP_MD_CTX_copy_ex (evp_ctx, ctx->evp_ctx)) + { + if (EVP_DigestFinal_ex (evp_ctx, resbuf, 0)) + result = resbuf; + err = EINVAL; + } + EVP_MD_CTX_free (evp_ctx); + } + errno = err; /* OK to set errno even if successful. */ + return result; } void * diff --git a/tests/test-sha3-224-buffer.c b/tests/test-sha3-224-buffer.c index 3b6dd22bf8..33190be91b 100644 --- a/tests/test-sha3-224-buffer.c +++ b/tests/test-sha3-224-buffer.c @@ -74,11 +74,15 @@ check (char const *message, size_t len, char const *expect) sha3_224_init_ctx (&ctx); int part = SHA3_224_BLOCK_SIZE / 3; sha3_process_bytes (message, part, &ctx); + sha3_read_ctx (&ctx, buf); sha3_process_bytes (message + part, SHA3_224_BLOCK_SIZE - part, &ctx); char buf2[SHA3_224_DIGEST_SIZE]; sha3_finish_ctx (&ctx, buf2); - failed |= mismatch (sha3_224_buffer (message, SHA3_224_BLOCK_SIZE, buf), - buf2); + if (mismatch (sha3_224_buffer (message, SHA3_224_BLOCK_SIZE, buf), buf2)) + { + failed = 1; + break; + } message += SHA3_224_BLOCK_SIZE; len -= SHA3_224_BLOCK_SIZE; } diff --git a/tests/test-sha3-256-buffer.c b/tests/test-sha3-256-buffer.c index ee97c95c21..4f03654c2b 100644 --- a/tests/test-sha3-256-buffer.c +++ b/tests/test-sha3-256-buffer.c @@ -75,11 +75,15 @@ check (char const *message, size_t len, char const *expect) sha3_256_init_ctx (&ctx); int part = SHA3_256_BLOCK_SIZE / 3; sha3_process_bytes (message, part, &ctx); + sha3_read_ctx (&ctx, buf); sha3_process_bytes (message + part, SHA3_256_BLOCK_SIZE - part, &ctx); char buf2[SHA3_256_DIGEST_SIZE]; sha3_finish_ctx (&ctx, buf2); - failed |= mismatch (sha3_256_buffer (message, SHA3_256_BLOCK_SIZE, buf), - buf2); + if (mismatch (sha3_256_buffer (message, SHA3_256_BLOCK_SIZE, buf), buf2)) + { + failed = 1; + break; + } message += SHA3_256_BLOCK_SIZE; len -= SHA3_256_BLOCK_SIZE; } diff --git a/tests/test-sha3-384-buffer.c b/tests/test-sha3-384-buffer.c index 7452b138f9..c2cbd4f8d9 100644 --- a/tests/test-sha3-384-buffer.c +++ b/tests/test-sha3-384-buffer.c @@ -79,11 +79,15 @@ check (char const *message, size_t len, char const *expect) sha3_384_init_ctx (&ctx); int part = SHA3_384_BLOCK_SIZE / 3; sha3_process_bytes (message, part, &ctx); + sha3_read_ctx (&ctx, buf); sha3_process_bytes (message + part, SHA3_384_BLOCK_SIZE - part, &ctx); char buf2[SHA3_384_DIGEST_SIZE]; sha3_finish_ctx (&ctx, buf2); - failed |= mismatch (sha3_384_buffer (message, SHA3_384_BLOCK_SIZE, buf), - buf2); + if (mismatch (sha3_384_buffer (message, SHA3_384_BLOCK_SIZE, buf), buf2)) + { + failed = 1; + break; + } message += SHA3_384_BLOCK_SIZE; len -= SHA3_384_BLOCK_SIZE; } diff --git a/tests/test-sha3-512-buffer.c b/tests/test-sha3-512-buffer.c index 303f75d61e..186cd2da00 100644 --- a/tests/test-sha3-512-buffer.c +++ b/tests/test-sha3-512-buffer.c @@ -83,11 +83,15 @@ check (char const *message, size_t len, char const *expect) sha3_512_init_ctx (&ctx); int part = SHA3_512_BLOCK_SIZE / 3; sha3_process_bytes (message, part, &ctx); + sha3_read_ctx (&ctx, buf); sha3_process_bytes (message + part, SHA3_512_BLOCK_SIZE - part, &ctx); char buf2[SHA3_512_DIGEST_SIZE]; sha3_finish_ctx (&ctx, buf2); - failed |= mismatch (sha3_512_buffer (message, SHA3_512_BLOCK_SIZE, buf), - buf2); + if (mismatch (sha3_512_buffer (message, SHA3_512_BLOCK_SIZE, buf), buf2)) + { + failed = 1; + break; + } message += SHA3_512_BLOCK_SIZE; len -= SHA3_512_BLOCK_SIZE; } -- 2.51.0
