summaryrefslogtreecommitdiff
path: root/lib/crypto/sha512.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@kernel.org>2025-07-11 14:58:43 -0700
committerEric Biggers <ebiggers@kernel.org>2025-07-14 08:20:37 -0700
commit7941ad696506917fa6228f44be2df0c2f0909a62 (patch)
tree615fc21f7dea8b8ea5b975bc522fa1f72950c513 /lib/crypto/sha512.c
parent6e07c5e166597de1d7943ecf2539cad18c0e2ce1 (diff)
lib/crypto: sha2: Add hmac_sha*_init_usingrawkey()
While the HMAC library functions support both incremental and one-shot computation and both prepared and raw keys, the combination of raw key + incremental was missing. It turns out that several potential users of the HMAC library functions (tpm2-sessions.c, smb2transport.c, trusted_tpm1.c) want exactly that. Therefore, add the missing functions hmac_sha*_init_usingrawkey(). Implement them in an optimized way that directly initializes the HMAC context without a separate key preparation step. Reimplement the one-shot raw key functions hmac_sha*_usingrawkey() on top of the new functions, which makes them a bit more efficient. Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Link: https://lore.kernel.org/r/20250711215844.41715-1-ebiggers@kernel.org Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Diffstat (limited to 'lib/crypto/sha512.c')
-rw-r--r--lib/crypto/sha512.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/lib/crypto/sha512.c b/lib/crypto/sha512.c
index d514721491ca..d8062188be98 100644
--- a/lib/crypto/sha512.c
+++ b/lib/crypto/sha512.c
@@ -249,7 +249,8 @@ void sha512(const u8 *data, size_t len, u8 out[SHA512_DIGEST_SIZE])
}
EXPORT_SYMBOL_GPL(sha512);
-static void __hmac_sha512_preparekey(struct __hmac_sha512_key *key,
+static void __hmac_sha512_preparekey(struct sha512_block_state *istate,
+ struct sha512_block_state *ostate,
const u8 *raw_key, size_t raw_key_len,
const struct sha512_block_state *iv)
{
@@ -269,14 +270,14 @@ static void __hmac_sha512_preparekey(struct __hmac_sha512_key *key,
for (size_t i = 0; i < ARRAY_SIZE(derived_key.w); i++)
derived_key.w[i] ^= REPEAT_BYTE(HMAC_IPAD_VALUE);
- key->istate = *iv;
- sha512_blocks(&key->istate, derived_key.b, 1);
+ *istate = *iv;
+ sha512_blocks(istate, derived_key.b, 1);
for (size_t i = 0; i < ARRAY_SIZE(derived_key.w); i++)
derived_key.w[i] ^= REPEAT_BYTE(HMAC_OPAD_VALUE ^
HMAC_IPAD_VALUE);
- key->ostate = *iv;
- sha512_blocks(&key->ostate, derived_key.b, 1);
+ *ostate = *iv;
+ sha512_blocks(ostate, derived_key.b, 1);
memzero_explicit(&derived_key, sizeof(derived_key));
}
@@ -284,14 +285,16 @@ static void __hmac_sha512_preparekey(struct __hmac_sha512_key *key,
void hmac_sha384_preparekey(struct hmac_sha384_key *key,
const u8 *raw_key, size_t raw_key_len)
{
- __hmac_sha512_preparekey(&key->key, raw_key, raw_key_len, &sha384_iv);
+ __hmac_sha512_preparekey(&key->key.istate, &key->key.ostate,
+ raw_key, raw_key_len, &sha384_iv);
}
EXPORT_SYMBOL_GPL(hmac_sha384_preparekey);
void hmac_sha512_preparekey(struct hmac_sha512_key *key,
const u8 *raw_key, size_t raw_key_len)
{
- __hmac_sha512_preparekey(&key->key, raw_key, raw_key_len, &sha512_iv);
+ __hmac_sha512_preparekey(&key->key.istate, &key->key.ostate,
+ raw_key, raw_key_len, &sha512_iv);
}
EXPORT_SYMBOL_GPL(hmac_sha512_preparekey);
@@ -303,6 +306,26 @@ void __hmac_sha512_init(struct __hmac_sha512_ctx *ctx,
}
EXPORT_SYMBOL_GPL(__hmac_sha512_init);
+void hmac_sha384_init_usingrawkey(struct hmac_sha384_ctx *ctx,
+ const u8 *raw_key, size_t raw_key_len)
+{
+ __hmac_sha512_preparekey(&ctx->ctx.sha_ctx.state, &ctx->ctx.ostate,
+ raw_key, raw_key_len, &sha384_iv);
+ ctx->ctx.sha_ctx.bytecount_lo = SHA512_BLOCK_SIZE;
+ ctx->ctx.sha_ctx.bytecount_hi = 0;
+}
+EXPORT_SYMBOL_GPL(hmac_sha384_init_usingrawkey);
+
+void hmac_sha512_init_usingrawkey(struct hmac_sha512_ctx *ctx,
+ const u8 *raw_key, size_t raw_key_len)
+{
+ __hmac_sha512_preparekey(&ctx->ctx.sha_ctx.state, &ctx->ctx.ostate,
+ raw_key, raw_key_len, &sha512_iv);
+ ctx->ctx.sha_ctx.bytecount_lo = SHA512_BLOCK_SIZE;
+ ctx->ctx.sha_ctx.bytecount_hi = 0;
+}
+EXPORT_SYMBOL_GPL(hmac_sha512_init_usingrawkey);
+
static void __hmac_sha512_final(struct __hmac_sha512_ctx *ctx,
u8 *out, size_t digest_size)
{
@@ -362,12 +385,11 @@ void hmac_sha384_usingrawkey(const u8 *raw_key, size_t raw_key_len,
const u8 *data, size_t data_len,
u8 out[SHA384_DIGEST_SIZE])
{
- struct hmac_sha384_key key;
-
- hmac_sha384_preparekey(&key, raw_key, raw_key_len);
- hmac_sha384(&key, data, data_len, out);
+ struct hmac_sha384_ctx ctx;
- memzero_explicit(&key, sizeof(key));
+ hmac_sha384_init_usingrawkey(&ctx, raw_key, raw_key_len);
+ hmac_sha384_update(&ctx, data, data_len);
+ hmac_sha384_final(&ctx, out);
}
EXPORT_SYMBOL_GPL(hmac_sha384_usingrawkey);
@@ -375,12 +397,11 @@ void hmac_sha512_usingrawkey(const u8 *raw_key, size_t raw_key_len,
const u8 *data, size_t data_len,
u8 out[SHA512_DIGEST_SIZE])
{
- struct hmac_sha512_key key;
-
- hmac_sha512_preparekey(&key, raw_key, raw_key_len);
- hmac_sha512(&key, data, data_len, out);
+ struct hmac_sha512_ctx ctx;
- memzero_explicit(&key, sizeof(key));
+ hmac_sha512_init_usingrawkey(&ctx, raw_key, raw_key_len);
+ hmac_sha512_update(&ctx, data, data_len);
+ hmac_sha512_final(&ctx, out);
}
EXPORT_SYMBOL_GPL(hmac_sha512_usingrawkey);