The BLOCK_HASH_UPDATE_BLOCKS macro is difficult to read. For now, let's just write the update explicitly in the straightforward way, mirroring sha512_update(). It's possible that we'll bring back a macro for this later, but it needs to be properly justified and hopefully a bit more readable.
Signed-off-by: Eric Biggers <ebigg...@kernel.org> --- lib/crypto/sha256.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c index 68936d5cd7745..808438d4f4278 100644 --- a/lib/crypto/sha256.c +++ b/lib/crypto/sha256.c @@ -8,11 +8,10 @@ * Copyright (c) 2014 Red Hat Inc. * Copyright 2025 Google LLC */ #include <crypto/hmac.h> -#include <crypto/internal/blockhash.h> #include <crypto/sha2.h> #include <linux/export.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/string.h> @@ -178,12 +177,35 @@ EXPORT_SYMBOL_GPL(sha256_init); void __sha256_update(struct __sha256_ctx *ctx, const u8 *data, size_t len) { size_t partial = ctx->bytecount % SHA256_BLOCK_SIZE; ctx->bytecount += len; - BLOCK_HASH_UPDATE_BLOCKS(sha256_blocks, &ctx->state, data, len, - SHA256_BLOCK_SIZE, ctx->buf, partial); + + if (partial + len >= SHA256_BLOCK_SIZE) { + size_t nblocks; + + if (partial) { + size_t l = SHA256_BLOCK_SIZE - partial; + + memcpy(&ctx->buf[partial], data, l); + data += l; + len -= l; + + sha256_blocks(&ctx->state, ctx->buf, 1); + } + + nblocks = len / SHA256_BLOCK_SIZE; + len %= SHA256_BLOCK_SIZE; + + if (nblocks) { + sha256_blocks(&ctx->state, data, nblocks); + data += nblocks * SHA256_BLOCK_SIZE; + } + partial = 0; + } + if (len) + memcpy(&ctx->buf[partial], data, len); } EXPORT_SYMBOL(__sha256_update); static void __sha256_final(struct __sha256_ctx *ctx, u8 *out, size_t digest_size) -- 2.50.0