mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
synced 2025-10-03 23:37:34 +10:00
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>
This commit is contained in:
parent
6e07c5e166
commit
7941ad6965
@ -247,6 +247,21 @@ static inline void hmac_sha224_init(struct hmac_sha224_ctx *ctx,
|
||||
__hmac_sha256_init(&ctx->ctx, &key->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha224_init_usingrawkey() - Initialize an HMAC-SHA224 context for a new
|
||||
* message, using a raw key
|
||||
* @ctx: (output) the HMAC context to initialize
|
||||
* @raw_key: the raw HMAC-SHA224 key
|
||||
* @raw_key_len: the key length in bytes. All key lengths are supported.
|
||||
*
|
||||
* If you don't need incremental computation, consider hmac_sha224_usingrawkey()
|
||||
* instead.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
void hmac_sha224_init_usingrawkey(struct hmac_sha224_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len);
|
||||
|
||||
/**
|
||||
* hmac_sha224_update() - Update an HMAC-SHA224 context with message data
|
||||
* @ctx: the HMAC context to update; must have been initialized
|
||||
@ -405,6 +420,21 @@ static inline void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
|
||||
__hmac_sha256_init(&ctx->ctx, &key->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha256_init_usingrawkey() - Initialize an HMAC-SHA256 context for a new
|
||||
* message, using a raw key
|
||||
* @ctx: (output) the HMAC context to initialize
|
||||
* @raw_key: the raw HMAC-SHA256 key
|
||||
* @raw_key_len: the key length in bytes. All key lengths are supported.
|
||||
*
|
||||
* If you don't need incremental computation, consider hmac_sha256_usingrawkey()
|
||||
* instead.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
void hmac_sha256_init_usingrawkey(struct hmac_sha256_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len);
|
||||
|
||||
/**
|
||||
* hmac_sha256_update() - Update an HMAC-SHA256 context with message data
|
||||
* @ctx: the HMAC context to update; must have been initialized
|
||||
@ -597,6 +627,21 @@ static inline void hmac_sha384_init(struct hmac_sha384_ctx *ctx,
|
||||
__hmac_sha512_init(&ctx->ctx, &key->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha384_init_usingrawkey() - Initialize an HMAC-SHA384 context for a new
|
||||
* message, using a raw key
|
||||
* @ctx: (output) the HMAC context to initialize
|
||||
* @raw_key: the raw HMAC-SHA384 key
|
||||
* @raw_key_len: the key length in bytes. All key lengths are supported.
|
||||
*
|
||||
* If you don't need incremental computation, consider hmac_sha384_usingrawkey()
|
||||
* instead.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
void hmac_sha384_init_usingrawkey(struct hmac_sha384_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len);
|
||||
|
||||
/**
|
||||
* hmac_sha384_update() - Update an HMAC-SHA384 context with message data
|
||||
* @ctx: the HMAC context to update; must have been initialized
|
||||
@ -755,6 +800,21 @@ static inline void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
|
||||
__hmac_sha512_init(&ctx->ctx, &key->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* hmac_sha512_init_usingrawkey() - Initialize an HMAC-SHA512 context for a new
|
||||
* message, using a raw key
|
||||
* @ctx: (output) the HMAC context to initialize
|
||||
* @raw_key: the raw HMAC-SHA512 key
|
||||
* @raw_key_len: the key length in bytes. All key lengths are supported.
|
||||
*
|
||||
* If you don't need incremental computation, consider hmac_sha512_usingrawkey()
|
||||
* instead.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
void hmac_sha512_init_usingrawkey(struct hmac_sha512_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len);
|
||||
|
||||
/**
|
||||
* hmac_sha512_update() - Update an HMAC-SHA512 context with message data
|
||||
* @ctx: the HMAC context to update; must have been initialized
|
||||
|
@ -263,7 +263,8 @@ EXPORT_SYMBOL(sha256);
|
||||
|
||||
/* pre-boot environment (as indicated by __DISABLE_EXPORTS) doesn't need HMAC */
|
||||
#ifndef __DISABLE_EXPORTS
|
||||
static void __hmac_sha256_preparekey(struct __hmac_sha256_key *key,
|
||||
static void __hmac_sha256_preparekey(struct sha256_block_state *istate,
|
||||
struct sha256_block_state *ostate,
|
||||
const u8 *raw_key, size_t raw_key_len,
|
||||
const struct sha256_block_state *iv)
|
||||
{
|
||||
@ -283,14 +284,14 @@ static void __hmac_sha256_preparekey(struct __hmac_sha256_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;
|
||||
sha256_blocks(&key->istate, derived_key.b, 1);
|
||||
*istate = *iv;
|
||||
sha256_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;
|
||||
sha256_blocks(&key->ostate, derived_key.b, 1);
|
||||
*ostate = *iv;
|
||||
sha256_blocks(ostate, derived_key.b, 1);
|
||||
|
||||
memzero_explicit(&derived_key, sizeof(derived_key));
|
||||
}
|
||||
@ -298,14 +299,16 @@ static void __hmac_sha256_preparekey(struct __hmac_sha256_key *key,
|
||||
void hmac_sha224_preparekey(struct hmac_sha224_key *key,
|
||||
const u8 *raw_key, size_t raw_key_len)
|
||||
{
|
||||
__hmac_sha256_preparekey(&key->key, raw_key, raw_key_len, &sha224_iv);
|
||||
__hmac_sha256_preparekey(&key->key.istate, &key->key.ostate,
|
||||
raw_key, raw_key_len, &sha224_iv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha224_preparekey);
|
||||
|
||||
void hmac_sha256_preparekey(struct hmac_sha256_key *key,
|
||||
const u8 *raw_key, size_t raw_key_len)
|
||||
{
|
||||
__hmac_sha256_preparekey(&key->key, raw_key, raw_key_len, &sha256_iv);
|
||||
__hmac_sha256_preparekey(&key->key.istate, &key->key.ostate,
|
||||
raw_key, raw_key_len, &sha256_iv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha256_preparekey);
|
||||
|
||||
@ -317,6 +320,24 @@ void __hmac_sha256_init(struct __hmac_sha256_ctx *ctx,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__hmac_sha256_init);
|
||||
|
||||
void hmac_sha224_init_usingrawkey(struct hmac_sha224_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len)
|
||||
{
|
||||
__hmac_sha256_preparekey(&ctx->ctx.sha_ctx.state, &ctx->ctx.ostate,
|
||||
raw_key, raw_key_len, &sha224_iv);
|
||||
ctx->ctx.sha_ctx.bytecount = SHA256_BLOCK_SIZE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha224_init_usingrawkey);
|
||||
|
||||
void hmac_sha256_init_usingrawkey(struct hmac_sha256_ctx *ctx,
|
||||
const u8 *raw_key, size_t raw_key_len)
|
||||
{
|
||||
__hmac_sha256_preparekey(&ctx->ctx.sha_ctx.state, &ctx->ctx.ostate,
|
||||
raw_key, raw_key_len, &sha256_iv);
|
||||
ctx->ctx.sha_ctx.bytecount = SHA256_BLOCK_SIZE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha256_init_usingrawkey);
|
||||
|
||||
static void __hmac_sha256_final(struct __hmac_sha256_ctx *ctx,
|
||||
u8 *out, size_t digest_size)
|
||||
{
|
||||
@ -376,12 +397,11 @@ void hmac_sha224_usingrawkey(const u8 *raw_key, size_t raw_key_len,
|
||||
const u8 *data, size_t data_len,
|
||||
u8 out[SHA224_DIGEST_SIZE])
|
||||
{
|
||||
struct hmac_sha224_key key;
|
||||
struct hmac_sha224_ctx ctx;
|
||||
|
||||
hmac_sha224_preparekey(&key, raw_key, raw_key_len);
|
||||
hmac_sha224(&key, data, data_len, out);
|
||||
|
||||
memzero_explicit(&key, sizeof(key));
|
||||
hmac_sha224_init_usingrawkey(&ctx, raw_key, raw_key_len);
|
||||
hmac_sha224_update(&ctx, data, data_len);
|
||||
hmac_sha224_final(&ctx, out);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha224_usingrawkey);
|
||||
|
||||
@ -389,12 +409,11 @@ void hmac_sha256_usingrawkey(const u8 *raw_key, size_t raw_key_len,
|
||||
const u8 *data, size_t data_len,
|
||||
u8 out[SHA256_DIGEST_SIZE])
|
||||
{
|
||||
struct hmac_sha256_key key;
|
||||
struct hmac_sha256_ctx ctx;
|
||||
|
||||
hmac_sha256_preparekey(&key, raw_key, raw_key_len);
|
||||
hmac_sha256(&key, data, data_len, out);
|
||||
|
||||
memzero_explicit(&key, sizeof(key));
|
||||
hmac_sha256_init_usingrawkey(&ctx, raw_key, raw_key_len);
|
||||
hmac_sha256_update(&ctx, data, data_len);
|
||||
hmac_sha256_final(&ctx, out);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hmac_sha256_usingrawkey);
|
||||
#endif /* !__DISABLE_EXPORTS */
|
||||
|
@ -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;
|
||||
struct hmac_sha384_ctx ctx;
|
||||
|
||||
hmac_sha384_preparekey(&key, raw_key, raw_key_len);
|
||||
hmac_sha384(&key, data, data_len, out);
|
||||
|
||||
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;
|
||||
struct hmac_sha512_ctx ctx;
|
||||
|
||||
hmac_sha512_preparekey(&key, raw_key, raw_key_len);
|
||||
hmac_sha512(&key, data, data_len, out);
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user