diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2025-05-02 13:30:56 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2025-05-05 18:20:45 +0800 |
commit | ff8f037d394f0900597ba527388a6eb95cd02695 (patch) | |
tree | bf0839318cae5a6bdd1f0803cf2bce46c148e26d | |
parent | 5b90a779bc547939421bfeb333e470658ba94fb6 (diff) |
crypto: sha256 - Use the partial block API for generic
The shash interface already handles partial blocks, use it for
sha224-generic and sha256-generic instead of going through the
lib/sha256 interface.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/sha256.c | 79 | ||||
-rw-r--r-- | include/crypto/sha2.h | 14 |
2 files changed, 54 insertions, 39 deletions
diff --git a/crypto/sha256.c b/crypto/sha256.c index 47ad7e4cc55f..cf190114574e 100644 --- a/crypto/sha256.c +++ b/crypto/sha256.c @@ -30,15 +30,26 @@ EXPORT_SYMBOL_GPL(sha256_zero_message_hash); static int crypto_sha256_init(struct shash_desc *desc) { - sha256_init(shash_desc_ctx(desc)); + sha256_block_init(shash_desc_ctx(desc)); return 0; } +static inline int crypto_sha256_update(struct shash_desc *desc, const u8 *data, + unsigned int len, bool force_generic) +{ + struct crypto_sha256_state *sctx = shash_desc_ctx(desc); + int remain = len % SHA256_BLOCK_SIZE; + + sctx->count += len - remain; + sha256_choose_blocks(sctx->state, data, len / SHA256_BLOCK_SIZE, + force_generic, !force_generic); + return remain; +} + static int crypto_sha256_update_generic(struct shash_desc *desc, const u8 *data, unsigned int len) { - sha256_update_generic(shash_desc_ctx(desc), data, len); - return 0; + return crypto_sha256_update(desc, data, len, true); } static int crypto_sha256_update_arch(struct shash_desc *desc, const u8 *data, @@ -48,26 +59,35 @@ static int crypto_sha256_update_arch(struct shash_desc *desc, const u8 *data, return 0; } -static int crypto_sha256_final_generic(struct shash_desc *desc, u8 *out) +static int crypto_sha256_final_arch(struct shash_desc *desc, u8 *out) { - sha256_final_generic(shash_desc_ctx(desc), out); + sha256_final(shash_desc_ctx(desc), out); return 0; } -static int crypto_sha256_final_arch(struct shash_desc *desc, u8 *out) +static __always_inline int crypto_sha256_finup(struct shash_desc *desc, + const u8 *data, + unsigned int len, u8 *out, + bool force_generic) { - sha256_final(shash_desc_ctx(desc), out); + struct crypto_sha256_state *sctx = shash_desc_ctx(desc); + unsigned int remain = len; + u8 *buf; + + if (len >= SHA256_BLOCK_SIZE) + remain = crypto_sha256_update(desc, data, len, force_generic); + sctx->count += remain; + buf = memcpy(sctx + 1, data + len - remain, remain); + sha256_finup(sctx, buf, remain, out, + crypto_shash_digestsize(desc->tfm), force_generic, + !force_generic); return 0; } static int crypto_sha256_finup_generic(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - struct sha256_state *sctx = shash_desc_ctx(desc); - - sha256_update_generic(sctx, data, len); - sha256_final_generic(sctx, out); - return 0; + return crypto_sha256_finup(desc, data, len, out, true); } static int crypto_sha256_finup_arch(struct shash_desc *desc, const u8 *data, @@ -83,12 +103,8 @@ static int crypto_sha256_finup_arch(struct shash_desc *desc, const u8 *data, static int crypto_sha256_digest_generic(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - struct sha256_state *sctx = shash_desc_ctx(desc); - - sha256_init(sctx); - sha256_update_generic(sctx, data, len); - sha256_final_generic(sctx, out); - return 0; + crypto_sha256_init(desc); + return crypto_sha256_finup_generic(desc, data, len, out); } static int crypto_sha256_digest_arch(struct shash_desc *desc, const u8 *data, @@ -100,13 +116,7 @@ static int crypto_sha256_digest_arch(struct shash_desc *desc, const u8 *data, static int crypto_sha224_init(struct shash_desc *desc) { - sha224_init(shash_desc_ctx(desc)); - return 0; -} - -static int crypto_sha224_final_generic(struct shash_desc *desc, u8 *out) -{ - sha224_final_generic(shash_desc_ctx(desc), out); + sha224_block_init(shash_desc_ctx(desc)); return 0; } @@ -147,35 +157,30 @@ static struct shash_alg algs[] = { .base.cra_name = "sha256", .base.cra_driver_name = "sha256-generic", .base.cra_priority = 100, + .base.cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY | + CRYPTO_AHASH_ALG_FINUP_MAX, .base.cra_blocksize = SHA256_BLOCK_SIZE, .base.cra_module = THIS_MODULE, .digestsize = SHA256_DIGEST_SIZE, .init = crypto_sha256_init, .update = crypto_sha256_update_generic, - .final = crypto_sha256_final_generic, .finup = crypto_sha256_finup_generic, .digest = crypto_sha256_digest_generic, - .descsize = sizeof(struct sha256_state), - .statesize = sizeof(struct crypto_sha256_state) + - SHA256_BLOCK_SIZE + 1, - .import = crypto_sha256_import_lib, - .export = crypto_sha256_export_lib, + .descsize = sizeof(struct crypto_sha256_state), }, { .base.cra_name = "sha224", .base.cra_driver_name = "sha224-generic", .base.cra_priority = 100, + .base.cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY | + CRYPTO_AHASH_ALG_FINUP_MAX, .base.cra_blocksize = SHA224_BLOCK_SIZE, .base.cra_module = THIS_MODULE, .digestsize = SHA224_DIGEST_SIZE, .init = crypto_sha224_init, .update = crypto_sha256_update_generic, - .final = crypto_sha224_final_generic, - .descsize = sizeof(struct sha256_state), - .statesize = sizeof(struct crypto_sha256_state) + - SHA256_BLOCK_SIZE + 1, - .import = crypto_sha256_import_lib, - .export = crypto_sha256_export_lib, + .finup = crypto_sha256_finup_generic, + .descsize = sizeof(struct crypto_sha256_state), }, { .base.cra_name = "sha256", diff --git a/include/crypto/sha2.h b/include/crypto/sha2.h index 9853cd2d1291..4912572578dc 100644 --- a/include/crypto/sha2.h +++ b/include/crypto/sha2.h @@ -88,7 +88,7 @@ struct sha512_state { u8 buf[SHA512_BLOCK_SIZE]; }; -static inline void sha256_init(struct sha256_state *sctx) +static inline void sha256_block_init(struct crypto_sha256_state *sctx) { sctx->state[0] = SHA256_H0; sctx->state[1] = SHA256_H1; @@ -100,11 +100,16 @@ static inline void sha256_init(struct sha256_state *sctx) sctx->state[7] = SHA256_H7; sctx->count = 0; } + +static inline void sha256_init(struct sha256_state *sctx) +{ + sha256_block_init(&sctx->ctx); +} void sha256_update(struct sha256_state *sctx, const u8 *data, size_t len); void sha256_final(struct sha256_state *sctx, u8 out[SHA256_DIGEST_SIZE]); void sha256(const u8 *data, size_t len, u8 out[SHA256_DIGEST_SIZE]); -static inline void sha224_init(struct sha256_state *sctx) +static inline void sha224_block_init(struct crypto_sha256_state *sctx) { sctx->state[0] = SHA224_H0; sctx->state[1] = SHA224_H1; @@ -116,6 +121,11 @@ static inline void sha224_init(struct sha256_state *sctx) sctx->state[7] = SHA224_H7; sctx->count = 0; } + +static inline void sha224_init(struct sha256_state *sctx) +{ + sha224_block_init(&sctx->ctx); +} /* Simply use sha256_update as it is equivalent to sha224_update. */ void sha224_final(struct sha256_state *sctx, u8 out[SHA224_DIGEST_SIZE]); |