// SPDX-License-Identifier: GPL-2.01/*2* Implementation of HKDF ("HMAC-based Extract-and-Expand Key Derivation3* Function"), aka RFC 5869. See also the original paper (Krawczyk 2010):4* "Cryptographic Extraction and Key Derivation: The HKDF Scheme".5*6* This is used to derive keys from the fscrypt master keys (or from the7* "software secrets" which hardware derives from the fscrypt master keys, in8* the case that the fscrypt master keys are hardware-wrapped keys).9*10* Copyright 2019 Google LLC11*/1213#include "fscrypt_private.h"1415/*16* HKDF supports any unkeyed cryptographic hash algorithm, but fscrypt uses17* SHA-512 because it is well-established, secure, and reasonably efficient.18*19* HKDF-SHA256 was also considered, as its 256-bit security strength would be20* sufficient here. A 512-bit security strength is "nice to have", though.21* Also, on 64-bit CPUs, SHA-512 is usually just as fast as SHA-256. In the22* common case of deriving an AES-256-XTS key (512 bits), that can result in23* HKDF-SHA512 being much faster than HKDF-SHA256, as the longer digest size of24* SHA-512 causes HKDF-Expand to only need to do one iteration rather than two.25*/26#define HKDF_HASHLEN SHA512_DIGEST_SIZE2728/*29* HKDF consists of two steps:30*31* 1. HKDF-Extract: extract a pseudorandom key of length HKDF_HASHLEN bytes from32* the input keying material and optional salt.33* 2. HKDF-Expand: expand the pseudorandom key into output keying material of34* any length, parameterized by an application-specific info string.35*36* HKDF-Extract can be skipped if the input is already a pseudorandom key of37* length HKDF_HASHLEN bytes. However, cipher modes other than AES-256-XTS take38* shorter keys, and we don't want to force users of those modes to provide39* unnecessarily long master keys. Thus fscrypt still does HKDF-Extract. No40* salt is used, since fscrypt master keys should already be pseudorandom and41* there's no way to persist a random salt per master key from kernel mode.42*/4344/*45* Compute HKDF-Extract using 'master_key' as the input keying material, and46* prepare the resulting HMAC key in 'hkdf'. Afterwards, 'hkdf' can be used for47* HKDF-Expand many times without having to recompute HKDF-Extract each time.48*/49void fscrypt_init_hkdf(struct hmac_sha512_key *hkdf, const u8 *master_key,50unsigned int master_key_size)51{52static const u8 default_salt[HKDF_HASHLEN];53u8 prk[HKDF_HASHLEN];5455hmac_sha512_usingrawkey(default_salt, sizeof(default_salt),56master_key, master_key_size, prk);57hmac_sha512_preparekey(hkdf, prk, sizeof(prk));58memzero_explicit(prk, sizeof(prk));59}6061/*62* HKDF-Expand (RFC 5869 section 2.3). Expand the HMAC key 'hkdf' into 'okmlen'63* bytes of output keying material parameterized by the application-specific64* 'info' of length 'infolen' bytes, prefixed by "fscrypt\0" and the 'context'65* byte. This is thread-safe and may be called by multiple threads in parallel.66*67* ('context' isn't part of the HKDF specification; it's just a prefix fscrypt68* adds to its application-specific info strings to guarantee that it doesn't69* accidentally repeat an info string when using HKDF for different purposes.)70*/71void fscrypt_hkdf_expand(const struct hmac_sha512_key *hkdf, u8 context,72const u8 *info, unsigned int infolen,73u8 *okm, unsigned int okmlen)74{75struct hmac_sha512_ctx ctx;76u8 counter = 1;77u8 tmp[HKDF_HASHLEN];7879WARN_ON_ONCE(okmlen > 255 * HKDF_HASHLEN);8081for (unsigned int i = 0; i < okmlen; i += HKDF_HASHLEN) {82hmac_sha512_init(&ctx, hkdf);83if (i != 0)84hmac_sha512_update(&ctx, &okm[i - HKDF_HASHLEN],85HKDF_HASHLEN);86hmac_sha512_update(&ctx, "fscrypt\0", 8);87hmac_sha512_update(&ctx, &context, 1);88hmac_sha512_update(&ctx, info, infolen);89hmac_sha512_update(&ctx, &counter, 1);90if (okmlen - i < HKDF_HASHLEN) {91hmac_sha512_final(&ctx, tmp);92memcpy(&okm[i], tmp, okmlen - i);93memzero_explicit(tmp, sizeof(tmp));94} else {95hmac_sha512_final(&ctx, &okm[i]);96}97counter++;98}99}100101102