Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lib/crypto: sha256: Add HMAC-SHA224 and HMAC-SHA256 support

Since HMAC support is commonly needed and is fairly simple, include it
as a first-class citizen of the SHA-256 library.

The API supports both incremental and one-shot computation, and either
preparing the key ahead of time or just using a raw key. The
implementation is much more streamlined than crypto/hmac.c.

I've kept it consistent with the HMAC-SHA384 and HMAC-SHA512 code as
much as possible.

Testing of these functions will be via sha224_kunit and sha256_kunit,
added by a later commit.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250630160645.3198-9-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>

+364 -5
+222
include/crypto/sha2.h
··· 131 131 }; 132 132 void __sha256_update(struct __sha256_ctx *ctx, const u8 *data, size_t len); 133 133 134 + /* 135 + * HMAC key and message context structs, shared by HMAC-SHA224 and HMAC-SHA256. 136 + * The hmac_sha224_* and hmac_sha256_* structs wrap this one so that the API has 137 + * proper typing and doesn't allow mixing the functions arbitrarily. 138 + */ 139 + struct __hmac_sha256_key { 140 + struct sha256_block_state istate; 141 + struct sha256_block_state ostate; 142 + }; 143 + struct __hmac_sha256_ctx { 144 + struct __sha256_ctx sha_ctx; 145 + struct sha256_block_state ostate; 146 + }; 147 + void __hmac_sha256_init(struct __hmac_sha256_ctx *ctx, 148 + const struct __hmac_sha256_key *key); 149 + 134 150 /** 135 151 * struct sha224_ctx - Context for hashing a message with SHA-224 136 152 * @ctx: private ··· 165 149 void sha224(const u8 *data, size_t len, u8 out[SHA224_DIGEST_SIZE]); 166 150 167 151 /** 152 + * struct hmac_sha224_key - Prepared key for HMAC-SHA224 153 + * @key: private 154 + */ 155 + struct hmac_sha224_key { 156 + struct __hmac_sha256_key key; 157 + }; 158 + 159 + /** 160 + * struct hmac_sha224_ctx - Context for computing HMAC-SHA224 of a message 161 + * @ctx: private 162 + */ 163 + struct hmac_sha224_ctx { 164 + struct __hmac_sha256_ctx ctx; 165 + }; 166 + 167 + /** 168 + * hmac_sha224_preparekey() - Prepare a key for HMAC-SHA224 169 + * @key: (output) the key structure to initialize 170 + * @raw_key: the raw HMAC-SHA224 key 171 + * @raw_key_len: the key length in bytes. All key lengths are supported. 172 + * 173 + * Note: the caller is responsible for zeroizing both the struct hmac_sha224_key 174 + * and the raw key once they are no longer needed. 175 + * 176 + * Context: Any context. 177 + */ 178 + void hmac_sha224_preparekey(struct hmac_sha224_key *key, 179 + const u8 *raw_key, size_t raw_key_len); 180 + 181 + /** 182 + * hmac_sha224_init() - Initialize an HMAC-SHA224 context for a new message 183 + * @ctx: (output) the HMAC context to initialize 184 + * @key: the prepared HMAC key 185 + * 186 + * If you don't need incremental computation, consider hmac_sha224() instead. 187 + * 188 + * Context: Any context. 189 + */ 190 + static inline void hmac_sha224_init(struct hmac_sha224_ctx *ctx, 191 + const struct hmac_sha224_key *key) 192 + { 193 + __hmac_sha256_init(&ctx->ctx, &key->key); 194 + } 195 + 196 + /** 197 + * hmac_sha224_update() - Update an HMAC-SHA224 context with message data 198 + * @ctx: the HMAC context to update; must have been initialized 199 + * @data: the message data 200 + * @data_len: the data length in bytes 201 + * 202 + * This can be called any number of times. 203 + * 204 + * Context: Any context. 205 + */ 206 + static inline void hmac_sha224_update(struct hmac_sha224_ctx *ctx, 207 + const u8 *data, size_t data_len) 208 + { 209 + __sha256_update(&ctx->ctx.sha_ctx, data, data_len); 210 + } 211 + 212 + /** 213 + * hmac_sha224_final() - Finish computing an HMAC-SHA224 value 214 + * @ctx: the HMAC context to finalize; must have been initialized 215 + * @out: (output) the resulting HMAC-SHA224 value 216 + * 217 + * After finishing, this zeroizes @ctx. So the caller does not need to do it. 218 + * 219 + * Context: Any context. 220 + */ 221 + void hmac_sha224_final(struct hmac_sha224_ctx *ctx, u8 out[SHA224_DIGEST_SIZE]); 222 + 223 + /** 224 + * hmac_sha224() - Compute HMAC-SHA224 in one shot, using a prepared key 225 + * @key: the prepared HMAC key 226 + * @data: the message data 227 + * @data_len: the data length in bytes 228 + * @out: (output) the resulting HMAC-SHA224 value 229 + * 230 + * If you're using the key only once, consider using hmac_sha224_usingrawkey(). 231 + * 232 + * Context: Any context. 233 + */ 234 + void hmac_sha224(const struct hmac_sha224_key *key, 235 + const u8 *data, size_t data_len, u8 out[SHA224_DIGEST_SIZE]); 236 + 237 + /** 238 + * hmac_sha224_usingrawkey() - Compute HMAC-SHA224 in one shot, using a raw key 239 + * @raw_key: the raw HMAC-SHA224 key 240 + * @raw_key_len: the key length in bytes. All key lengths are supported. 241 + * @data: the message data 242 + * @data_len: the data length in bytes 243 + * @out: (output) the resulting HMAC-SHA224 value 244 + * 245 + * If you're using the key multiple times, prefer to use 246 + * hmac_sha224_preparekey() followed by multiple calls to hmac_sha224() instead. 247 + * 248 + * Context: Any context. 249 + */ 250 + void hmac_sha224_usingrawkey(const u8 *raw_key, size_t raw_key_len, 251 + const u8 *data, size_t data_len, 252 + u8 out[SHA224_DIGEST_SIZE]); 253 + 254 + /** 168 255 * struct sha256_ctx - Context for hashing a message with SHA-256 169 256 * @ctx: private 170 257 */ ··· 283 164 } 284 165 void sha256_final(struct sha256_ctx *ctx, u8 out[SHA256_DIGEST_SIZE]); 285 166 void sha256(const u8 *data, size_t len, u8 out[SHA256_DIGEST_SIZE]); 167 + 168 + /** 169 + * struct hmac_sha256_key - Prepared key for HMAC-SHA256 170 + * @key: private 171 + */ 172 + struct hmac_sha256_key { 173 + struct __hmac_sha256_key key; 174 + }; 175 + 176 + /** 177 + * struct hmac_sha256_ctx - Context for computing HMAC-SHA256 of a message 178 + * @ctx: private 179 + */ 180 + struct hmac_sha256_ctx { 181 + struct __hmac_sha256_ctx ctx; 182 + }; 183 + 184 + /** 185 + * hmac_sha256_preparekey() - Prepare a key for HMAC-SHA256 186 + * @key: (output) the key structure to initialize 187 + * @raw_key: the raw HMAC-SHA256 key 188 + * @raw_key_len: the key length in bytes. All key lengths are supported. 189 + * 190 + * Note: the caller is responsible for zeroizing both the struct hmac_sha256_key 191 + * and the raw key once they are no longer needed. 192 + * 193 + * Context: Any context. 194 + */ 195 + void hmac_sha256_preparekey(struct hmac_sha256_key *key, 196 + const u8 *raw_key, size_t raw_key_len); 197 + 198 + /** 199 + * hmac_sha256_init() - Initialize an HMAC-SHA256 context for a new message 200 + * @ctx: (output) the HMAC context to initialize 201 + * @key: the prepared HMAC key 202 + * 203 + * If you don't need incremental computation, consider hmac_sha256() instead. 204 + * 205 + * Context: Any context. 206 + */ 207 + static inline void hmac_sha256_init(struct hmac_sha256_ctx *ctx, 208 + const struct hmac_sha256_key *key) 209 + { 210 + __hmac_sha256_init(&ctx->ctx, &key->key); 211 + } 212 + 213 + /** 214 + * hmac_sha256_update() - Update an HMAC-SHA256 context with message data 215 + * @ctx: the HMAC context to update; must have been initialized 216 + * @data: the message data 217 + * @data_len: the data length in bytes 218 + * 219 + * This can be called any number of times. 220 + * 221 + * Context: Any context. 222 + */ 223 + static inline void hmac_sha256_update(struct hmac_sha256_ctx *ctx, 224 + const u8 *data, size_t data_len) 225 + { 226 + __sha256_update(&ctx->ctx.sha_ctx, data, data_len); 227 + } 228 + 229 + /** 230 + * hmac_sha256_final() - Finish computing an HMAC-SHA256 value 231 + * @ctx: the HMAC context to finalize; must have been initialized 232 + * @out: (output) the resulting HMAC-SHA256 value 233 + * 234 + * After finishing, this zeroizes @ctx. So the caller does not need to do it. 235 + * 236 + * Context: Any context. 237 + */ 238 + void hmac_sha256_final(struct hmac_sha256_ctx *ctx, u8 out[SHA256_DIGEST_SIZE]); 239 + 240 + /** 241 + * hmac_sha256() - Compute HMAC-SHA256 in one shot, using a prepared key 242 + * @key: the prepared HMAC key 243 + * @data: the message data 244 + * @data_len: the data length in bytes 245 + * @out: (output) the resulting HMAC-SHA256 value 246 + * 247 + * If you're using the key only once, consider using hmac_sha256_usingrawkey(). 248 + * 249 + * Context: Any context. 250 + */ 251 + void hmac_sha256(const struct hmac_sha256_key *key, 252 + const u8 *data, size_t data_len, u8 out[SHA256_DIGEST_SIZE]); 253 + 254 + /** 255 + * hmac_sha256_usingrawkey() - Compute HMAC-SHA256 in one shot, using a raw key 256 + * @raw_key: the raw HMAC-SHA256 key 257 + * @raw_key_len: the key length in bytes. All key lengths are supported. 258 + * @data: the message data 259 + * @data_len: the data length in bytes 260 + * @out: (output) the resulting HMAC-SHA256 value 261 + * 262 + * If you're using the key multiple times, prefer to use 263 + * hmac_sha256_preparekey() followed by multiple calls to hmac_sha256() instead. 264 + * 265 + * Context: Any context. 266 + */ 267 + void hmac_sha256_usingrawkey(const u8 *raw_key, size_t raw_key_len, 268 + const u8 *data, size_t data_len, 269 + u8 out[SHA256_DIGEST_SIZE]); 286 270 287 271 /* State for the SHA-512 (and SHA-384) compression function */ 288 272 struct sha512_block_state {
+142 -5
lib/crypto/sha256.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * SHA-256, as specified in 4 - * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf 5 - * 6 - * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>. 3 + * SHA-224, SHA-256, HMAC-SHA224, and HMAC-SHA256 library functions 7 4 * 8 5 * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> 9 6 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> ··· 8 11 * Copyright (c) 2014 Red Hat Inc. 9 12 */ 10 13 14 + #include <crypto/hmac.h> 11 15 #include <crypto/internal/blockhash.h> 12 16 #include <crypto/internal/sha2.h> 13 17 #include <linux/export.h> 14 18 #include <linux/kernel.h> 15 19 #include <linux/module.h> 16 20 #include <linux/string.h> 21 + #include <linux/wordpart.h> 17 22 18 23 static const struct sha256_block_state sha224_iv = { 19 24 .h = { ··· 135 136 } 136 137 EXPORT_SYMBOL(sha256); 137 138 138 - MODULE_DESCRIPTION("SHA-256 Algorithm"); 139 + /* pre-boot environment (as indicated by __DISABLE_EXPORTS) doesn't need HMAC */ 140 + #ifndef __DISABLE_EXPORTS 141 + static void __hmac_sha256_preparekey(struct __hmac_sha256_key *key, 142 + const u8 *raw_key, size_t raw_key_len, 143 + const struct sha256_block_state *iv) 144 + { 145 + union { 146 + u8 b[SHA256_BLOCK_SIZE]; 147 + unsigned long w[SHA256_BLOCK_SIZE / sizeof(unsigned long)]; 148 + } derived_key = { 0 }; 149 + 150 + if (unlikely(raw_key_len > SHA256_BLOCK_SIZE)) { 151 + if (iv == &sha224_iv) 152 + sha224(raw_key, raw_key_len, derived_key.b); 153 + else 154 + sha256(raw_key, raw_key_len, derived_key.b); 155 + } else { 156 + memcpy(derived_key.b, raw_key, raw_key_len); 157 + } 158 + 159 + for (size_t i = 0; i < ARRAY_SIZE(derived_key.w); i++) 160 + derived_key.w[i] ^= REPEAT_BYTE(HMAC_IPAD_VALUE); 161 + key->istate = *iv; 162 + sha256_blocks(&key->istate, derived_key.b, 1); 163 + 164 + for (size_t i = 0; i < ARRAY_SIZE(derived_key.w); i++) 165 + derived_key.w[i] ^= REPEAT_BYTE(HMAC_OPAD_VALUE ^ 166 + HMAC_IPAD_VALUE); 167 + key->ostate = *iv; 168 + sha256_blocks(&key->ostate, derived_key.b, 1); 169 + 170 + memzero_explicit(&derived_key, sizeof(derived_key)); 171 + } 172 + 173 + void hmac_sha224_preparekey(struct hmac_sha224_key *key, 174 + const u8 *raw_key, size_t raw_key_len) 175 + { 176 + __hmac_sha256_preparekey(&key->key, raw_key, raw_key_len, &sha224_iv); 177 + } 178 + EXPORT_SYMBOL_GPL(hmac_sha224_preparekey); 179 + 180 + void hmac_sha256_preparekey(struct hmac_sha256_key *key, 181 + const u8 *raw_key, size_t raw_key_len) 182 + { 183 + __hmac_sha256_preparekey(&key->key, raw_key, raw_key_len, &sha256_iv); 184 + } 185 + EXPORT_SYMBOL_GPL(hmac_sha256_preparekey); 186 + 187 + void __hmac_sha256_init(struct __hmac_sha256_ctx *ctx, 188 + const struct __hmac_sha256_key *key) 189 + { 190 + __sha256_init(&ctx->sha_ctx, &key->istate, SHA256_BLOCK_SIZE); 191 + ctx->ostate = key->ostate; 192 + } 193 + EXPORT_SYMBOL_GPL(__hmac_sha256_init); 194 + 195 + static void __hmac_sha256_final(struct __hmac_sha256_ctx *ctx, 196 + u8 *out, size_t digest_size) 197 + { 198 + /* Generate the padded input for the outer hash in ctx->sha_ctx.buf. */ 199 + __sha256_final(&ctx->sha_ctx, ctx->sha_ctx.buf, digest_size); 200 + memset(&ctx->sha_ctx.buf[digest_size], 0, 201 + SHA256_BLOCK_SIZE - digest_size); 202 + ctx->sha_ctx.buf[digest_size] = 0x80; 203 + *(__be32 *)&ctx->sha_ctx.buf[SHA256_BLOCK_SIZE - 4] = 204 + cpu_to_be32(8 * (SHA256_BLOCK_SIZE + digest_size)); 205 + 206 + /* Compute the outer hash, which gives the HMAC value. */ 207 + sha256_blocks(&ctx->ostate, ctx->sha_ctx.buf, 1); 208 + for (size_t i = 0; i < digest_size; i += 4) 209 + put_unaligned_be32(ctx->ostate.h[i / 4], out + i); 210 + 211 + memzero_explicit(ctx, sizeof(*ctx)); 212 + } 213 + 214 + void hmac_sha224_final(struct hmac_sha224_ctx *ctx, 215 + u8 out[SHA224_DIGEST_SIZE]) 216 + { 217 + __hmac_sha256_final(&ctx->ctx, out, SHA224_DIGEST_SIZE); 218 + } 219 + EXPORT_SYMBOL_GPL(hmac_sha224_final); 220 + 221 + void hmac_sha256_final(struct hmac_sha256_ctx *ctx, 222 + u8 out[SHA256_DIGEST_SIZE]) 223 + { 224 + __hmac_sha256_final(&ctx->ctx, out, SHA256_DIGEST_SIZE); 225 + } 226 + EXPORT_SYMBOL_GPL(hmac_sha256_final); 227 + 228 + void hmac_sha224(const struct hmac_sha224_key *key, 229 + const u8 *data, size_t data_len, u8 out[SHA224_DIGEST_SIZE]) 230 + { 231 + struct hmac_sha224_ctx ctx; 232 + 233 + hmac_sha224_init(&ctx, key); 234 + hmac_sha224_update(&ctx, data, data_len); 235 + hmac_sha224_final(&ctx, out); 236 + } 237 + EXPORT_SYMBOL_GPL(hmac_sha224); 238 + 239 + void hmac_sha256(const struct hmac_sha256_key *key, 240 + const u8 *data, size_t data_len, u8 out[SHA256_DIGEST_SIZE]) 241 + { 242 + struct hmac_sha256_ctx ctx; 243 + 244 + hmac_sha256_init(&ctx, key); 245 + hmac_sha256_update(&ctx, data, data_len); 246 + hmac_sha256_final(&ctx, out); 247 + } 248 + EXPORT_SYMBOL_GPL(hmac_sha256); 249 + 250 + void hmac_sha224_usingrawkey(const u8 *raw_key, size_t raw_key_len, 251 + const u8 *data, size_t data_len, 252 + u8 out[SHA224_DIGEST_SIZE]) 253 + { 254 + struct hmac_sha224_key key; 255 + 256 + hmac_sha224_preparekey(&key, raw_key, raw_key_len); 257 + hmac_sha224(&key, data, data_len, out); 258 + 259 + memzero_explicit(&key, sizeof(key)); 260 + } 261 + EXPORT_SYMBOL_GPL(hmac_sha224_usingrawkey); 262 + 263 + void hmac_sha256_usingrawkey(const u8 *raw_key, size_t raw_key_len, 264 + const u8 *data, size_t data_len, 265 + u8 out[SHA256_DIGEST_SIZE]) 266 + { 267 + struct hmac_sha256_key key; 268 + 269 + hmac_sha256_preparekey(&key, raw_key, raw_key_len); 270 + hmac_sha256(&key, data, data_len, out); 271 + 272 + memzero_explicit(&key, sizeof(key)); 273 + } 274 + EXPORT_SYMBOL_GPL(hmac_sha256_usingrawkey); 275 + #endif /* !__DISABLE_EXPORTS */ 276 + 277 + MODULE_DESCRIPTION("SHA-224, SHA-256, HMAC-SHA224, and HMAC-SHA256 library functions"); 139 278 MODULE_LICENSE("GPL");