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.

nvme-auth: common: add HMAC helper functions

Add some helper functions for computing HMAC-SHA256, HMAC-SHA384, or
HMAC-SHA512 values using the crypto library instead of crypto_shash.
These will enable some significant simplifications and performance
improvements in nvme-auth.

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Eric Biggers and committed by
Keith Busch
4263ca1c 4454820b

+82
+2
drivers/nvme/common/Kconfig
··· 13 13 select CRYPTO_DH 14 14 select CRYPTO_DH_RFC7919_GROUPS 15 15 select CRYPTO_HKDF 16 + select CRYPTO_LIB_SHA256 17 + select CRYPTO_LIB_SHA512 16 18 17 19 config NVME_AUTH_KUNIT_TEST 18 20 tristate "KUnit tests for NVMe authentication" if !KUNIT_ALL_TESTS
+66
drivers/nvme/common/auth.c
··· 12 12 #include <crypto/hash.h> 13 13 #include <crypto/dh.h> 14 14 #include <crypto/hkdf.h> 15 + #include <crypto/sha2.h> 15 16 #include <linux/nvme.h> 16 17 #include <linux/nvme-auth.h> 17 18 ··· 234 233 kfree_sensitive(key); 235 234 } 236 235 EXPORT_SYMBOL_GPL(nvme_auth_free_key); 236 + 237 + /* 238 + * Start computing an HMAC value, given the algorithm ID and raw key. 239 + * 240 + * The context should be zeroized at the end of its lifetime. The caller can do 241 + * that implicitly by calling nvme_auth_hmac_final(), or explicitly (needed when 242 + * a context is abandoned without finalizing it) by calling memzero_explicit(). 243 + */ 244 + int nvme_auth_hmac_init(struct nvme_auth_hmac_ctx *hmac, u8 hmac_id, 245 + const u8 *key, size_t key_len) 246 + { 247 + hmac->hmac_id = hmac_id; 248 + switch (hmac_id) { 249 + case NVME_AUTH_HASH_SHA256: 250 + hmac_sha256_init_usingrawkey(&hmac->sha256, key, key_len); 251 + return 0; 252 + case NVME_AUTH_HASH_SHA384: 253 + hmac_sha384_init_usingrawkey(&hmac->sha384, key, key_len); 254 + return 0; 255 + case NVME_AUTH_HASH_SHA512: 256 + hmac_sha512_init_usingrawkey(&hmac->sha512, key, key_len); 257 + return 0; 258 + } 259 + pr_warn("%s: invalid hash algorithm %d\n", __func__, hmac_id); 260 + return -EINVAL; 261 + } 262 + EXPORT_SYMBOL_GPL(nvme_auth_hmac_init); 263 + 264 + void nvme_auth_hmac_update(struct nvme_auth_hmac_ctx *hmac, const u8 *data, 265 + size_t data_len) 266 + { 267 + switch (hmac->hmac_id) { 268 + case NVME_AUTH_HASH_SHA256: 269 + hmac_sha256_update(&hmac->sha256, data, data_len); 270 + return; 271 + case NVME_AUTH_HASH_SHA384: 272 + hmac_sha384_update(&hmac->sha384, data, data_len); 273 + return; 274 + case NVME_AUTH_HASH_SHA512: 275 + hmac_sha512_update(&hmac->sha512, data, data_len); 276 + return; 277 + } 278 + /* Unreachable because nvme_auth_hmac_init() validated hmac_id */ 279 + WARN_ON_ONCE(1); 280 + } 281 + EXPORT_SYMBOL_GPL(nvme_auth_hmac_update); 282 + 283 + /* Finish computing an HMAC value. Note that this zeroizes the HMAC context. */ 284 + void nvme_auth_hmac_final(struct nvme_auth_hmac_ctx *hmac, u8 *out) 285 + { 286 + switch (hmac->hmac_id) { 287 + case NVME_AUTH_HASH_SHA256: 288 + hmac_sha256_final(&hmac->sha256, out); 289 + return; 290 + case NVME_AUTH_HASH_SHA384: 291 + hmac_sha384_final(&hmac->sha384, out); 292 + return; 293 + case NVME_AUTH_HASH_SHA512: 294 + hmac_sha512_final(&hmac->sha512, out); 295 + return; 296 + } 297 + /* Unreachable because nvme_auth_hmac_init() validated hmac_id */ 298 + WARN_ON_ONCE(1); 299 + } 300 + EXPORT_SYMBOL_GPL(nvme_auth_hmac_final); 237 301 238 302 struct nvme_dhchap_key *nvme_auth_transform_key( 239 303 const struct nvme_dhchap_key *key, const char *nqn)
+14
include/linux/nvme-auth.h
··· 7 7 #define _NVME_AUTH_H 8 8 9 9 #include <crypto/kpp.h> 10 + #include <crypto/sha2.h> 10 11 11 12 struct nvme_dhchap_key { 12 13 size_t len; ··· 24 23 const char *nvme_auth_digest_name(u8 hmac_id); 25 24 size_t nvme_auth_hmac_hash_len(u8 hmac_id); 26 25 u8 nvme_auth_hmac_id(const char *hmac_name); 26 + struct nvme_auth_hmac_ctx { 27 + u8 hmac_id; 28 + union { 29 + struct hmac_sha256_ctx sha256; 30 + struct hmac_sha384_ctx sha384; 31 + struct hmac_sha512_ctx sha512; 32 + }; 33 + }; 34 + int nvme_auth_hmac_init(struct nvme_auth_hmac_ctx *hmac, u8 hmac_id, 35 + const u8 *key, size_t key_len); 36 + void nvme_auth_hmac_update(struct nvme_auth_hmac_ctx *hmac, const u8 *data, 37 + size_t data_len); 38 + void nvme_auth_hmac_final(struct nvme_auth_hmac_ctx *hmac, u8 *out); 27 39 28 40 u32 nvme_auth_key_struct_size(u32 key_len); 29 41 struct nvme_dhchap_key *nvme_auth_extract_key(const char *secret, u8 key_hash);