* [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation
@ 2025-08-21 20:48 Chris Leech
2025-08-21 20:48 ` [PATCH v2 1/2] nvme-auth: add hkdf_expand_label() Chris Leech
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Chris Leech @ 2025-08-21 20:48 UTC (permalink / raw)
To: linux-nvme, Hannes Reinecke
Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Herbert Xu,
David S . Miller, linux-crypto, Eric Biggers
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.
Changes from v1:
- Moved hkdf_expand_label() from crypto/hkdf.c to nvme/common/auth.c.
It's not really an RFC 5869 HKDF function, it's defined for TLS but
currently only used by nvme in-kernel.
- Fixed kdoc label_len -> labellen
- Replaced "static const char []" with "const char *", it's just
clearer and generates the same code with a string literal assignment.
(I've left the crypto emails on this version, mostly to make it known
that hkdf_expand_label() has been moved as Eric asked.)
Chris Leech (2):
nvme-auth: add hkdf_expand_label()
nvme-auth: use hkdf_expand_label()
drivers/nvme/common/auth.c | 86 +++++++++++++++++++++++++++++---------
1 file changed, 66 insertions(+), 20 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] nvme-auth: add hkdf_expand_label()
2025-08-21 20:48 [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Chris Leech
@ 2025-08-21 20:48 ` Chris Leech
2025-08-21 20:48 ` [PATCH v2 2/2] nvme-auth: use hkdf_expand_label() Chris Leech
2025-08-22 1:09 ` [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Eric Biggers
2 siblings, 0 replies; 5+ messages in thread
From: Chris Leech @ 2025-08-21 20:48 UTC (permalink / raw)
To: linux-nvme, Hannes Reinecke
Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Herbert Xu,
David S . Miller, linux-crypto, Eric Biggers
Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label
Signed-off-by: Chris Leech <cleech@redhat.com>
Signed-off-by: Hannes Reinecke <hare@kernel.org>
---
drivers/nvme/common/auth.c | 53 ++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/nvme/common/auth.c b/drivers/nvme/common/auth.c
index 91e273b89fea3..c6eae8e6b6f99 100644
--- a/drivers/nvme/common/auth.c
+++ b/drivers/nvme/common/auth.c
@@ -683,6 +683,59 @@ int nvme_auth_generate_digest(u8 hmac_id, u8 *psk, size_t psk_len,
}
EXPORT_SYMBOL_GPL(nvme_auth_generate_digest);
+/**
+ * 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
+ * @labellen: 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.
+ */
+static 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;
+ const char *tls13_prefix = "tls13 ";
+ unsigned int prefixlen = strlen(tls13_prefix);
+
+ 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;
+}
+
/**
* nvme_auth_derive_tls_psk - Derive TLS PSK
* @hmac_id: Hash function identifier
--
2.50.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] nvme-auth: use hkdf_expand_label()
2025-08-21 20:48 [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Chris Leech
2025-08-21 20:48 ` [PATCH v2 1/2] nvme-auth: add hkdf_expand_label() Chris Leech
@ 2025-08-21 20:48 ` Chris Leech
2025-08-22 1:09 ` [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Eric Biggers
2 siblings, 0 replies; 5+ messages in thread
From: Chris Leech @ 2025-08-21 20:48 UTC (permalink / raw)
To: linux-nvme, Hannes Reinecke
Cc: Christoph Hellwig, Keith Busch, Sagi Grimberg, Herbert Xu,
David S . Miller, linux-crypto, Eric Biggers
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 c6eae8e6b6f99..1f51fbebd9fac 100644
--- a/drivers/nvme/common/auth.c
+++ b/drivers/nvme/common/auth.c
@@ -768,10 +768,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;
@@ -811,36 +811,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.50.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation
2025-08-21 20:48 [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Chris Leech
2025-08-21 20:48 ` [PATCH v2 1/2] nvme-auth: add hkdf_expand_label() Chris Leech
2025-08-21 20:48 ` [PATCH v2 2/2] nvme-auth: use hkdf_expand_label() Chris Leech
@ 2025-08-22 1:09 ` Eric Biggers
2025-08-22 6:08 ` Hannes Reinecke
2 siblings, 1 reply; 5+ messages in thread
From: Eric Biggers @ 2025-08-22 1:09 UTC (permalink / raw)
To: Chris Leech
Cc: linux-nvme, Hannes Reinecke, Christoph Hellwig, Keith Busch,
Sagi Grimberg, Herbert Xu, David S . Miller, linux-crypto
On Thu, Aug 21, 2025 at 01:48:14PM -0700, Chris Leech wrote:
> 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.
Well, it's nice that my review comment from last year is finally being
addressed: https://lore.kernel.org/r/20240723014715.GB2319848@google.com
- Eric
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation
2025-08-22 1:09 ` [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Eric Biggers
@ 2025-08-22 6:08 ` Hannes Reinecke
0 siblings, 0 replies; 5+ messages in thread
From: Hannes Reinecke @ 2025-08-22 6:08 UTC (permalink / raw)
To: Eric Biggers, Chris Leech
Cc: linux-nvme, Hannes Reinecke, Christoph Hellwig, Keith Busch,
Sagi Grimberg, Herbert Xu, David S . Miller, linux-crypto
On 8/22/25 03:09, Eric Biggers wrote:
> On Thu, Aug 21, 2025 at 01:48:14PM -0700, Chris Leech wrote:
>> 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.
>
> Well, it's nice that my review comment from last year is finally being
> addressed: https://lore.kernel.org/r/20240723014715.GB2319848@google.com
>
Yeah, because I misread your comments, and was only focussed on the
'length' field (which is a 16-bit field at the start), and not on the
length fields of the individual vectors.
Reading specs is hard...
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] 5+ messages in thread
end of thread, other threads:[~2025-08-22 14:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-21 20:48 [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Chris Leech
2025-08-21 20:48 ` [PATCH v2 1/2] nvme-auth: add hkdf_expand_label() Chris Leech
2025-08-21 20:48 ` [PATCH v2 2/2] nvme-auth: use hkdf_expand_label() Chris Leech
2025-08-22 1:09 ` [PATCH v2 0/2] nvme: fixup HKDF-Expand-Label implementation Eric Biggers
2025-08-22 6:08 ` Hannes Reinecke
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).