On Wed, Aug 20, 2025 at 11:12:10AM +0200, hare@xxxxxxxxxx wrote: > From: Chris Leech <cleech@xxxxxxxxxx> > > Provide an implementation of RFC 8446 (TLS 1.3) HKDF-Expand-Label > > Cc: Eric Biggers <ebiggers@xxxxxxxxxx> > Signed-off-by: Chris Leech <cleech@xxxxxxxxxx> > Signed-off-by: Hannes Reinecke <hare@xxxxxxxxxx> > --- > 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