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