Commit 2d3bd088b3 for openssl.org

commit 2d3bd088b3c43e5b10dcf298bcf01b5637e32e7f
Author: slontis <shane.lontis@oracle.com>
Date:   Fri Oct 17 16:11:11 2025 +1100

    SHA3 - Move the buffered absorb function into sha3.c
    This code was sitting inside the sha3 provider where it could not be
    called directly.

    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/28941)

diff --git a/crypto/sha/sha3.c b/crypto/sha/sha3.c
index 21e1070bee..226f911306 100644
--- a/crypto/sha/sha3.c
+++ b/crypto/sha/sha3.c
@@ -12,6 +12,7 @@
 #include "crypto/s390x_arch.h"
 #endif
 #include "internal/sha3.h"
+#include "internal/common.h"

 void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r, int next);

@@ -127,6 +128,43 @@ int ossl_sha3_final(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen)
     return 1;
 }

+/* This is a buffered absorb function. */
+int ossl_sha3_absorb(KECCAK1600_CTX *ctx, const unsigned char *inp, size_t len)
+{
+    const size_t bsz = ctx->block_size;
+    size_t num, rem;
+
+    if (ossl_unlikely(len == 0))
+        return 1;
+
+    /* Is there anything in the buffer already ? */
+    if (ossl_likely((num = ctx->bufsz) != 0)) {
+        /* Calculate how much space is left in the buffer */
+        rem = bsz - num;
+        /* If the new input does not fill the buffer then just add it */
+        if (len < rem) {
+            memcpy(ctx->buf + num, inp, len);
+            ctx->bufsz += len;
+            return 1;
+        }
+        /* otherwise fill up the buffer and absorb the buffer */
+        memcpy(ctx->buf + num, inp, rem);
+        /* Update the input pointer */
+        inp += rem;
+        len -= rem;
+        ctx->meth.absorb(ctx, ctx->buf, bsz);
+        ctx->bufsz = 0;
+    }
+    /* Absorb the input - rem = leftover part of the input < blocksize) */
+    rem = ctx->meth.absorb(ctx, inp, len);
+    /* Copy the leftover bit of the input into the buffer */
+    if (ossl_likely(rem)) {
+        memcpy(ctx->buf, inp + len - rem, rem);
+        ctx->bufsz = rem;
+    }
+    return 1;
+}
+
 /*
  * This method can be called multiple times.
  * Rather than heavily modifying assembler for SHA3_squeeze(),
diff --git a/include/internal/sha3.h b/include/internal/sha3.h
index d52780a660..6b3f76a5b8 100644
--- a/include/internal/sha3.h
+++ b/include/internal/sha3.h
@@ -55,6 +55,7 @@ int ossl_keccak_init(KECCAK1600_CTX *ctx, unsigned char pad,
 int ossl_sha3_update(KECCAK1600_CTX *ctx, const void *_inp, size_t len);
 int ossl_sha3_final(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen);
 int ossl_sha3_squeeze(KECCAK1600_CTX *ctx, unsigned char *out, size_t outlen);
+int ossl_sha3_absorb(KECCAK1600_CTX *ctx, const unsigned char *inp, size_t len);

 size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
     size_t r);
diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c
index 57adcc2efd..38b7c6ee77 100644
--- a/providers/implementations/digests/sha3_prov.c
+++ b/providers/implementations/digests/sha3_prov.c
@@ -103,39 +103,7 @@ static int keccak_init_params(void *vctx, const OSSL_PARAM params[])

 static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
 {
-    KECCAK1600_CTX *ctx = vctx;
-    const size_t bsz = ctx->block_size;
-    size_t num, rem;
-
-    if (ossl_unlikely(len == 0))
-        return 1;
-
-    /* Is there anything in the buffer already ? */
-    if (ossl_likely((num = ctx->bufsz) != 0)) {
-        /* Calculate how much space is left in the buffer */
-        rem = bsz - num;
-        /* If the new input does not fill the buffer then just add it */
-        if (len < rem) {
-            memcpy(ctx->buf + num, inp, len);
-            ctx->bufsz += len;
-            return 1;
-        }
-        /* otherwise fill up the buffer and absorb the buffer */
-        memcpy(ctx->buf + num, inp, rem);
-        /* Update the input pointer */
-        inp += rem;
-        len -= rem;
-        ctx->meth.absorb(ctx, ctx->buf, bsz);
-        ctx->bufsz = 0;
-    }
-    /* Absorb the input - rem = leftover part of the input < blocksize) */
-    rem = ctx->meth.absorb(ctx, inp, len);
-    /* Copy the leftover bit of the input into the buffer */
-    if (ossl_likely(rem)) {
-        memcpy(ctx->buf, inp + len - rem, rem);
-        ctx->bufsz = rem;
-    }
-    return 1;
+    return ossl_sha3_absorb((KECCAK1600_CTX *)vctx, inp, len);
 }

 static int keccak_final(void *vctx, unsigned char *out, size_t *outl,