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,