* [PATCH 0/2] crypto,nvme: fixup HKDF-Expand-Label implementation @ 2025-08-20 9:12 hare 2025-08-20 9:12 ` [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() hare 2025-08-20 9:12 ` [PATCH 2/2] nvme-auth: use hkdf_expand_label() hare 0 siblings, 2 replies; 7+ messages in thread From: hare @ 2025-08-20 9:12 UTC (permalink / raw) To: Christoph Hellwig Cc: Keith Busch, Sagi Grimberg, Chris Leech, linux-nvme, Herbert Xu, David S . Miller, linux-crypto, Hannes Reinecke From: Hannes Reinecke <hare@kernel.org> As per RFC 8446 (TLS 1.3) the HKDF-Expand-Label function is using vectors for the 'label' and 'context' field, but defines these vectors as a string prefixed with the string length (in binary). The implementation in nvme is missing the length prefix which was causing interoperability issues with spec-conformant implementations. This patchset adds a function 'hkdf_expand_label()' to correctly implement the HKDF-Expand-Label functionality and modifies the nvme driver to utilize this function instead of the open-coded implementation. As usual, comments and reviews are welcome. Chris Leech (1): crypto: hkdf: add hkdf_expand_label() Hannes Reinecke (1): nvme-auth: use hkdf_expand_label() crypto/hkdf.c | 55 ++++++++++++++++++++++++++++++++++++++ drivers/nvme/common/auth.c | 33 +++++++++-------------- include/crypto/hkdf.h | 4 +++ 3 files changed, 72 insertions(+), 20 deletions(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() 2025-08-20 9:12 [PATCH 0/2] crypto,nvme: fixup HKDF-Expand-Label implementation hare @ 2025-08-20 9:12 ` hare 2025-08-20 18:46 ` Eric Biggers 2025-08-20 21:50 ` kernel test robot 2025-08-20 9:12 ` [PATCH 2/2] nvme-auth: use hkdf_expand_label() hare 1 sibling, 2 replies; 7+ messages in thread From: hare @ 2025-08-20 9:12 UTC (permalink / raw) To: Christoph Hellwig Cc: Keith Busch, Sagi Grimberg, Chris Leech, linux-nvme, Herbert Xu, David S . Miller, linux-crypto, Eric Biggers, Hannes Reinecke From: Chris Leech <cleech@redhat.com> Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label Cc: Eric Biggers <ebiggers@kernel.org> Signed-off-by: Chris Leech <cleech@redhat.com> Signed-off-by: Hannes Reinecke <hare@kernel.org> --- crypto/hkdf.c | 55 +++++++++++++++++++++++++++++++++++++++++++ include/crypto/hkdf.h | 4 ++++ 2 files changed, 59 insertions(+) diff --git a/crypto/hkdf.c b/crypto/hkdf.c index 82d1b32ca6ce..465bad6e6c93 100644 --- a/crypto/hkdf.c +++ b/crypto/hkdf.c @@ -11,6 +11,7 @@ #include <crypto/sha2.h> #include <crypto/hkdf.h> #include <linux/module.h> +#include <linux/unaligned.h> /* * HKDF consists of two steps: @@ -129,6 +130,60 @@ int hkdf_expand(struct crypto_shash *hmac_tfm, } EXPORT_SYMBOL_GPL(hkdf_expand); +/** + * hkdf_expand_label - HKDF-Expand-Label (RFC 8846 section 7.1) + * @hmac_tfm: hash context keyed with pseudorandom key + * @label: ASCII label without "tls13 " prefix + * @label_len: length of @label + * @context: context bytes + * @contextlen: length of @context + * @okm: output keying material + * @okmlen: length of @okm + * + * Build the TLS 1.3 HkdfLabel structure and invoke hkdf_expand(). + * + * Returns 0 on success with output keying material stored in @okm, + * or a negative errno value otherwise. + */ +int hkdf_expand_label(struct crypto_shash *hmac_tfm, + const u8 *label, unsigned int labellen, + const u8 *context, unsigned int contextlen, + u8 *okm, unsigned int okmlen) +{ + int err; + u8 *info; + unsigned int infolen; + static const char tls13_prefix[] = "tls13 "; + unsigned int prefixlen = sizeof(tls13_prefix) - 1; /* exclude NUL */ + + if (WARN_ON(labellen > (255 - prefixlen))) + return -EINVAL; + if (WARN_ON(contextlen > 255)) + return -EINVAL; + + infolen = 2 + (1 + prefixlen + labellen) + (1 + contextlen); + info = kzalloc(infolen, GFP_KERNEL); + if (!info) + return -ENOMEM; + + /* HkdfLabel.Length */ + put_unaligned_be16(okmlen, info); + + /* HkdfLabel.Label */ + info[2] = prefixlen + labellen; + memcpy(info + 3, tls13_prefix, prefixlen); + memcpy(info + 3 + prefixlen, label, labellen); + + /* HkdfLabel.Context */ + info[3 + prefixlen + labellen] = contextlen; + memcpy(info + 4 + prefixlen + labellen, context, contextlen); + + err = hkdf_expand(hmac_tfm, info, infolen, okm, okmlen); + kfree_sensitive(info); + return err; +} +EXPORT_SYMBOL_GPL(hkdf_expand_label); + struct hkdf_testvec { const char *test; const u8 *ikm; diff --git a/include/crypto/hkdf.h b/include/crypto/hkdf.h index 6a9678f508f5..5e75d17a58ab 100644 --- a/include/crypto/hkdf.h +++ b/include/crypto/hkdf.h @@ -17,4 +17,8 @@ int hkdf_extract(struct crypto_shash *hmac_tfm, const u8 *ikm, int hkdf_expand(struct crypto_shash *hmac_tfm, const u8 *info, unsigned int infolen, u8 *okm, unsigned int okmlen); +int hkdf_expand_label(struct crypto_shash *hmac_tfm, + const u8 *label, unsigned int labellen, + const u8 *context, unsigned int contextlen, + u8 *okm, unsigned int okmlen); #endif -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() 2025-08-20 9:12 ` [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() hare @ 2025-08-20 18:46 ` Eric Biggers 2025-08-20 19:48 ` Chris Leech 2025-08-20 21:50 ` kernel test robot 1 sibling, 1 reply; 7+ messages in thread From: Eric Biggers @ 2025-08-20 18:46 UTC (permalink / raw) To: hare Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Chris Leech, linux-nvme, Herbert Xu, David S . Miller, linux-crypto On Wed, Aug 20, 2025 at 11:12:10AM +0200, hare@kernel.org wrote: > From: Chris Leech <cleech@redhat.com> > > Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label > > Cc: Eric Biggers <ebiggers@kernel.org> > Signed-off-by: Chris Leech <cleech@redhat.com> > Signed-off-by: Hannes Reinecke <hare@kernel.org> > --- > crypto/hkdf.c | 55 +++++++++++++++++++++++++++++++++++++++++++ > include/crypto/hkdf.h | 4 ++++ > 2 files changed, 59 insertions(+) > > diff --git a/crypto/hkdf.c b/crypto/hkdf.c > index 82d1b32ca6ce..465bad6e6c93 100644 > --- a/crypto/hkdf.c > +++ b/crypto/hkdf.c > @@ -11,6 +11,7 @@ > #include <crypto/sha2.h> > #include <crypto/hkdf.h> > #include <linux/module.h> > +#include <linux/unaligned.h> > > /* > * HKDF consists of two steps: > @@ -129,6 +130,60 @@ int hkdf_expand(struct crypto_shash *hmac_tfm, > } > EXPORT_SYMBOL_GPL(hkdf_expand); > > +/** > + * hkdf_expand_label - HKDF-Expand-Label (RFC 8846 section 7.1) > + * @hmac_tfm: hash context keyed with pseudorandom key > + * @label: ASCII label without "tls13 " prefix > + * @label_len: length of @label > + * @context: context bytes > + * @contextlen: length of @context > + * @okm: output keying material > + * @okmlen: length of @okm > + * > + * Build the TLS 1.3 HkdfLabel structure and invoke hkdf_expand(). > + * > + * Returns 0 on success with output keying material stored in @okm, > + * or a negative errno value otherwise. > + */ > +int hkdf_expand_label(struct crypto_shash *hmac_tfm, > + const u8 *label, unsigned int labellen, > + const u8 *context, unsigned int contextlen, > + u8 *okm, unsigned int okmlen) > +{ > + int err; > + u8 *info; > + unsigned int infolen; > + static const char tls13_prefix[] = "tls13 "; > + unsigned int prefixlen = sizeof(tls13_prefix) - 1; /* exclude NUL */ > + > + if (WARN_ON(labellen > (255 - prefixlen))) > + return -EINVAL; > + if (WARN_ON(contextlen > 255)) > + return -EINVAL; > + > + infolen = 2 + (1 + prefixlen + labellen) + (1 + contextlen); > + info = kzalloc(infolen, GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + /* HkdfLabel.Length */ > + put_unaligned_be16(okmlen, info); > + > + /* HkdfLabel.Label */ > + info[2] = prefixlen + labellen; > + memcpy(info + 3, tls13_prefix, prefixlen); > + memcpy(info + 3 + prefixlen, label, labellen); > + > + /* HkdfLabel.Context */ > + info[3 + prefixlen + labellen] = contextlen; > + memcpy(info + 4 + prefixlen + labellen, context, contextlen); > + > + err = hkdf_expand(hmac_tfm, info, infolen, okm, okmlen); > + kfree_sensitive(info); > + return err; > +} > +EXPORT_SYMBOL_GPL(hkdf_expand_label); Does this belong in crypto/hkdf.c? It seems to be specific to a particular user of HKDF. - Eric ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() 2025-08-20 18:46 ` Eric Biggers @ 2025-08-20 19:48 ` Chris Leech 2025-08-21 6:44 ` Hannes Reinecke 0 siblings, 1 reply; 7+ messages in thread From: Chris Leech @ 2025-08-20 19:48 UTC (permalink / raw) To: Eric Biggers Cc: hare, Christoph Hellwig, Keith Busch, Sagi Grimberg, linux-nvme, Herbert Xu, David S . Miller, linux-crypto On Wed, Aug 20, 2025 at 11:46:33AM -0700, Eric Biggers wrote: > On Wed, Aug 20, 2025 at 11:12:10AM +0200, hare@kernel.org wrote: > > From: Chris Leech <cleech@redhat.com> > > > > Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label > > > > Cc: Eric Biggers <ebiggers@kernel.org> > > Signed-off-by: Chris Leech <cleech@redhat.com> > > Signed-off-by: Hannes Reinecke <hare@kernel.org> > > --- > > crypto/hkdf.c | 55 +++++++++++++++++++++++++++++++++++++++++++ > > include/crypto/hkdf.h | 4 ++++ > > 2 files changed, 59 insertions(+) > > > > ... > > Does this belong in crypto/hkdf.c? It seems to be specific to a > particular user of HKDF. While this is needed for NVMe/TLS, it's a case of the NVMe specifications referencing a function defined in the TLS 1.3 RFC to be used. I though it would be clearest to fix the open-coded implemenation by creating an RFC complient function, which is now no-longer specific to NVMe so I moved it out to crypto/hkdf.c I don't know that there will be other users, it just seemed to make the most sense there. - Chris ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() 2025-08-20 19:48 ` Chris Leech @ 2025-08-21 6:44 ` Hannes Reinecke 0 siblings, 0 replies; 7+ messages in thread From: Hannes Reinecke @ 2025-08-21 6:44 UTC (permalink / raw) To: Chris Leech, Eric Biggers Cc: hare, Christoph Hellwig, Keith Busch, Sagi Grimberg, linux-nvme, Herbert Xu, David S . Miller, linux-crypto On 8/20/25 21:48, Chris Leech wrote: > On Wed, Aug 20, 2025 at 11:46:33AM -0700, Eric Biggers wrote: >> On Wed, Aug 20, 2025 at 11:12:10AM +0200, hare@kernel.org wrote: >>> From: Chris Leech <cleech@redhat.com> >>> >>> Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label >>> >>> Cc: Eric Biggers <ebiggers@kernel.org> >>> Signed-off-by: Chris Leech <cleech@redhat.com> >>> Signed-off-by: Hannes Reinecke <hare@kernel.org> >>> --- >>> crypto/hkdf.c | 55 +++++++++++++++++++++++++++++++++++++++++++ >>> include/crypto/hkdf.h | 4 ++++ >>> 2 files changed, 59 insertions(+) >>> >>> ... >> >> Does this belong in crypto/hkdf.c? It seems to be specific to a >> particular user of HKDF. > > While this is needed for NVMe/TLS, it's a case of the NVMe > specifications referencing a function defined in the TLS 1.3 RFC to be > used. I though it would be clearest to fix the open-coded implemenation > by creating an RFC complient function, which is now no-longer specific > to NVMe so I moved it out to crypto/hkdf.c > > I don't know that there will be other users, it just seemed to make the > most sense there. > But having said that, we can easily move it into the nvme code, and let others move it into crypto if there is a need. Will be updating the patchset. Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() 2025-08-20 9:12 ` [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() hare 2025-08-20 18:46 ` Eric Biggers @ 2025-08-20 21:50 ` kernel test robot 1 sibling, 0 replies; 7+ messages in thread From: kernel test robot @ 2025-08-20 21:50 UTC (permalink / raw) To: hare, Christoph Hellwig Cc: oe-kbuild-all, Keith Busch, Sagi Grimberg, Chris Leech, linux-nvme, Herbert Xu, David S . Miller, linux-crypto, Eric Biggers, Hannes Reinecke Hi, kernel test robot noticed the following build warnings: [auto build test WARNING on herbert-cryptodev-2.6/master] [also build test WARNING on herbert-crypto-2.6/master linus/master v6.17-rc2 next-20250820] [cannot apply to hch-configfs/for-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/hare-kernel-org/crypto-hkdf-add-hkdf_expand_label/20250820-172750 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master patch link: https://lore.kernel.org/r/20250820091211.25368-2-hare%40kernel.org patch subject: [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() config: loongarch-randconfig-001-20250821 (https://download.01.org/0day-ci/archive/20250821/202508210523.p8BdHsR7-lkp@intel.com/config) compiler: loongarch64-linux-gcc (GCC) 14.3.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250821/202508210523.p8BdHsR7-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202508210523.p8BdHsR7-lkp@intel.com/ All warnings (new ones prefixed by >>): >> Warning: crypto/hkdf.c:151 function parameter 'labellen' not described in 'hkdf_expand_label' -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] nvme-auth: use hkdf_expand_label() 2025-08-20 9:12 [PATCH 0/2] crypto,nvme: fixup HKDF-Expand-Label implementation hare 2025-08-20 9:12 ` [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() hare @ 2025-08-20 9:12 ` hare 1 sibling, 0 replies; 7+ messages in thread From: hare @ 2025-08-20 9:12 UTC (permalink / raw) To: Christoph Hellwig Cc: Keith Busch, Sagi Grimberg, Chris Leech, linux-nvme, Herbert Xu, David S . Miller, linux-crypto, Hannes Reinecke From: Hannes Reinecke <hare@kernel.org> When generating keying material during an authentication transaction (secure channel concatenation), the HKDF-Expand-Label function is part of the specified key derivation process. The current open-coded implementation misses the length prefix requirements on the HkdfLabel label and context variable-length vectors (RFC 8446 Section 3.4). Instead, use the hkdf_expand_label() function. Signed-off-by: Chris Leech <cleech@redhat.com> Signed-off-by: Hannes Reinecke <hare@kernel.org> --- drivers/nvme/common/auth.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c index 91e273b89fea..5ea4d6d9a394 100644 --- a/drivers/nvme/common/auth.c +++ b/drivers/nvme/common/auth.c @@ -715,10 +715,10 @@ int nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len, { struct crypto_shash *hmac_tfm; const char *hmac_name; - const char *psk_prefix = "tls13 nvme-tls-psk"; + const char *label = "nvme-tls-psk"; static const char default_salt[HKDF_MAX_HASHLEN]; - size_t info_len, prk_len; - char *info; + size_t prk_len; + const char *ctx; unsigned char *prk, *tls_key; int ret; @@ -758,36 +758,29 @@ int nvme_auth_derive_tls_psk(int hmac_id, u8 *psk, size_t psk_len, if (ret) goto out_free_prk; - /* - * 2 additional bytes for the length field from HDKF-Expand-Label, - * 2 additional bytes for the HMAC ID, and one byte for the space - * separator. - */ - info_len = strlen(psk_digest) + strlen(psk_prefix) + 5; - info = kzalloc(info_len + 1, GFP_KERNEL); - if (!info) { + ctx = kasprintf(GFP_KERNEL, "%02d %s", hmac_id, psk_digest); + if (!ctx) { ret = -ENOMEM; goto out_free_prk; } - put_unaligned_be16(psk_len, info); - memcpy(info + 2, psk_prefix, strlen(psk_prefix)); - sprintf(info + 2 + strlen(psk_prefix), "%02d %s", hmac_id, psk_digest); - tls_key = kzalloc(psk_len, GFP_KERNEL); if (!tls_key) { ret = -ENOMEM; - goto out_free_info; + goto out_free_ctx; } - ret = hkdf_expand(hmac_tfm, info, info_len, tls_key, psk_len); + ret = hkdf_expand_label(hmac_tfm, + label, strlen(label), + ctx, strlen(ctx), + tls_key, psk_len); if (ret) { kfree(tls_key); - goto out_free_info; + goto out_free_ctx; } *ret_psk = tls_key; -out_free_info: - kfree(info); +out_free_ctx: + kfree(ctx); out_free_prk: kfree(prk); out_free_shash: -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-08-21 9:39 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-20 9:12 [PATCH 0/2] crypto,nvme: fixup HKDF-Expand-Label implementation hare 2025-08-20 9:12 ` [PATCH 1/2] crypto: hkdf: add hkdf_expand_label() hare 2025-08-20 18:46 ` Eric Biggers 2025-08-20 19:48 ` Chris Leech 2025-08-21 6:44 ` Hannes Reinecke 2025-08-20 21:50 ` kernel test robot 2025-08-20 9:12 ` [PATCH 2/2] nvme-auth: use hkdf_expand_label() hare
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).