Hi Marco,
On Tue, Jul 21, 2026 at 04:06:39PM +0200, Marco Baffo wrote:
> fscrypt and NVMe authentication each carry private HKDF
> implementations. Add HKDF-SHA256, HKDF-SHA384, and HKDF-SHA512
> functions to lib/crypto and convert both users.
>
> Patches 1-4 are intended for review and inclusion.
>
> Patch 5 is RFC only and is not intended to be applied. It shows how
> the OVPN epoch-key code currently under development can use the new
> HKDF API. That patch has an additional dependency on the OVPN epoch
> series. It is included here to allow the API to be reviewed against
> a third user. The OVPN conversion will be submitted separately once
> its prerequisite code is ready.
>
> HKDF-Expand accepts info as an array of segments and processes them as
> if concatenated. This preserves the byte ordering used by fscrypt and
> allows NVMe to encode HkdfLabel without allocating a temporary buffer.
>
> HKDF-Extract produces a prepared HMAC key, avoiding repeated key setup
> when the same PRK is expanded more than once. The implementation uses
> the direct HMAC library functions and neither allocates memory nor
> returns errors.
>
> The series is intended for the libcrypto tree. Patches 3 and 4 need
> review from the fscrypt and NVMe maintainers, respectively.
>
> Tested with:
>
> - HKDF KUnit tests
> - NVMe authentication KUnit tests
> - kvm-xfstests smoketest on ext4
> - kvm-xfstests generic/582, generic/583, and generic/584 on ext4 and f2fs
> - kvm-xfstests encrypt group on ext4 and f2fs
>
> The following shortlog and diffstat refers only to the first 4 patches.
>
> Marco Baffo (4):
> lib/crypto: add HKDF-SHA{256,384,512}
> lib/crypto: tests: add HKDF KUnit tests
> fscrypt: use HKDF library functions
> nvme-auth: use HKDF library functions for TLS PSK derivation
>
> drivers/nvme/common/auth.c | 120 ++++++++-------
> fs/crypto/hkdf.c | 56 ++-----
> include/crypto/hkdf.h | 131 ++++++++++++++++
> lib/crypto/.kunitconfig | 1 +
> lib/crypto/Makefile | 4 +-
> lib/crypto/hkdf-sha256.c | 22 +++
> lib/crypto/hkdf-sha512.c | 34 +++++
> lib/crypto/hkdf-template.h | 97 ++++++++++++
> lib/crypto/tests/Kconfig | 8 +
> lib/crypto/tests/Makefile | 1 +
> lib/crypto/tests/hkdf_kunit.c | 276 ++++++++++++++++++++++++++++++++++
> 11 files changed, 653 insertions(+), 97 deletions(-)
> create mode 100644 include/crypto/hkdf.h
> create mode 100644 lib/crypto/hkdf-sha256.c
> create mode 100644 lib/crypto/hkdf-sha512.c
> create mode 100644 lib/crypto/hkdf-template.h
> create mode 100644 lib/crypto/tests/hkdf_kunit.c
If we're going to reintroduce an HKDF library, this is probably the way
to do it (no crypto_shash dependency).
But I think the positive diffstat makes having an HKDF library at all in
the kernel still kind of questionable. HKDF is just a wrapper around
HMAC and it can "unroll" to as little as 1-2 HMAC calls. It's not
really like the other crypto algorithms where the implementations can be
very complex and we often have multiple arch-specific implementations.
In drivers/nvme/common/auth.c, using the library actually ended up as
more code than not using it.
And in fs/crypto/hkdf.c this patchset only saves a bit (with some of the
savings coming from deleting helpful comments).
In the ovpn case, the extraction step isn't actually used. Nor are
multiple expansion iterations needed, since all the keys needing to be
derived are at most the hash size. So vs. using hmac_sha256_* directly
it saves maybe 10-15 lines? (Note that the diffstat in patch 5 isn't
directly relevant, as the starting point was crypto_shash.)
So then we end up with quite a bit of additional code in lib/crypto/, to
support users where the diffstat is basically neutral.
And this is only HKDF, so this hardly solves key derivation in general.
Plenty of KDFs don't use HKDF at all, either ones based on block ciphers
or stream ciphers, or newer hash functions that aren't vulnerable to
length extension attacks so don't require the HMAC layer. There are
lots of other KDFs implemented in the kernel in various places. Just to
pick a couple random examples, extract_entropy() in
drivers/char/random.c is doing a KDF, tcp_ao_calc_traffic_key() in
net/ipv4/tcp_ao.c is doing a KDF. Do those need to be libraries too?
So overall I would suggest it might be best to hold off on this for now
and just call the hmac_sha256_* functions directly from
ovpn_expand_label(). (And again, only one iteration is actually needed
there, so it doesn't even need to be the full HKDF-Expand.)
- Eric