Branch data Line data Source code
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. 8 : : * 9 : : * Copyright 2019 Google LLC 10 : : */ 11 : : 12 : : #include <crypto/hash.h> 13 : : #include <crypto/sha.h> 14 : : 15 : : #include "fscrypt_private.h" 16 : : 17 : : /* 18 : : * HKDF supports any unkeyed cryptographic hash algorithm, but fscrypt uses 19 : : * SHA-512 because it is reasonably secure and efficient; and since it produces 20 : : * a 64-byte digest, deriving an AES-256-XTS key preserves all 64 bytes of 21 : : * entropy from the master key and requires only one iteration of HKDF-Expand. 22 : : */ 23 : : #define HKDF_HMAC_ALG "hmac(sha512)" 24 : : #define HKDF_HASHLEN SHA512_DIGEST_SIZE 25 : : 26 : : /* 27 : : * HKDF consists of two steps: 28 : : * 29 : : * 1. HKDF-Extract: extract a pseudorandom key of length HKDF_HASHLEN bytes from 30 : : * the input keying material and optional salt. 31 : : * 2. HKDF-Expand: expand the pseudorandom key into output keying material of 32 : : * any length, parameterized by an application-specific info string. 33 : : * 34 : : * HKDF-Extract can be skipped if the input is already a pseudorandom key of 35 : : * length HKDF_HASHLEN bytes. However, cipher modes other than AES-256-XTS take 36 : : * shorter keys, and we don't want to force users of those modes to provide 37 : : * unnecessarily long master keys. Thus fscrypt still does HKDF-Extract. No 38 : : * salt is used, since fscrypt master keys should already be pseudorandom and 39 : : * there's no way to persist a random salt per master key from kernel mode. 40 : : */ 41 : : 42 : : /* HKDF-Extract (RFC 5869 section 2.2), unsalted */ 43 : 0 : static int hkdf_extract(struct crypto_shash *hmac_tfm, const u8 *ikm, 44 : : unsigned int ikmlen, u8 prk[HKDF_HASHLEN]) 45 : : { 46 : : static const u8 default_salt[HKDF_HASHLEN]; 47 : : SHASH_DESC_ON_STACK(desc, hmac_tfm); 48 : : int err; 49 : : 50 : 0 : err = crypto_shash_setkey(hmac_tfm, default_salt, HKDF_HASHLEN); 51 : 0 : if (err) 52 : : return err; 53 : : 54 : 0 : desc->tfm = hmac_tfm; 55 : 0 : err = crypto_shash_digest(desc, ikm, ikmlen, prk); 56 : : shash_desc_zero(desc); 57 : 0 : return err; 58 : : } 59 : : 60 : : /* 61 : : * Compute HKDF-Extract using the given master key as the input keying material, 62 : : * and prepare an HMAC transform object keyed by the resulting pseudorandom key. 63 : : * 64 : : * Afterwards, the keyed HMAC transform object can be used for HKDF-Expand many 65 : : * times without having to recompute HKDF-Extract each time. 66 : : */ 67 : 0 : int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key, 68 : : unsigned int master_key_size) 69 : : { 70 : : struct crypto_shash *hmac_tfm; 71 : : u8 prk[HKDF_HASHLEN]; 72 : : int err; 73 : : 74 : 0 : hmac_tfm = crypto_alloc_shash(HKDF_HMAC_ALG, 0, 0); 75 : 0 : if (IS_ERR(hmac_tfm)) { 76 : 0 : fscrypt_err(NULL, "Error allocating " HKDF_HMAC_ALG ": %ld", 77 : : PTR_ERR(hmac_tfm)); 78 : 0 : return PTR_ERR(hmac_tfm); 79 : : } 80 : : 81 : 0 : if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != sizeof(prk))) { 82 : : err = -EINVAL; 83 : : goto err_free_tfm; 84 : : } 85 : : 86 : 0 : err = hkdf_extract(hmac_tfm, master_key, master_key_size, prk); 87 : 0 : if (err) 88 : : goto err_free_tfm; 89 : : 90 : 0 : err = crypto_shash_setkey(hmac_tfm, prk, sizeof(prk)); 91 : 0 : if (err) 92 : : goto err_free_tfm; 93 : : 94 : 0 : hkdf->hmac_tfm = hmac_tfm; 95 : 0 : goto out; 96 : : 97 : : err_free_tfm: 98 : : crypto_free_shash(hmac_tfm); 99 : : out: 100 : : memzero_explicit(prk, sizeof(prk)); 101 : 0 : return err; 102 : : } 103 : : 104 : : /* 105 : : * HKDF-Expand (RFC 5869 section 2.3). This expands the pseudorandom key, which 106 : : * was already keyed into 'hkdf->hmac_tfm' by fscrypt_init_hkdf(), into 'okmlen' 107 : : * bytes of output keying material parameterized by the application-specific 108 : : * 'info' of length 'infolen' bytes, prefixed by "fscrypt\0" and the 'context' 109 : : * byte. This is thread-safe and may be called by multiple threads in parallel. 110 : : * 111 : : * ('context' isn't part of the HKDF specification; it's just a prefix fscrypt 112 : : * adds to its application-specific info strings to guarantee that it doesn't 113 : : * accidentally repeat an info string when using HKDF for different purposes.) 114 : : */ 115 : 0 : int fscrypt_hkdf_expand(struct fscrypt_hkdf *hkdf, u8 context, 116 : : const u8 *info, unsigned int infolen, 117 : : u8 *okm, unsigned int okmlen) 118 : : { 119 : : SHASH_DESC_ON_STACK(desc, hkdf->hmac_tfm); 120 : : u8 prefix[9]; 121 : : unsigned int i; 122 : : int err; 123 : : const u8 *prev = NULL; 124 : 0 : u8 counter = 1; 125 : : u8 tmp[HKDF_HASHLEN]; 126 : : 127 : 0 : if (WARN_ON(okmlen > 255 * HKDF_HASHLEN)) 128 : : return -EINVAL; 129 : : 130 : 0 : desc->tfm = hkdf->hmac_tfm; 131 : : 132 : 0 : memcpy(prefix, "fscrypt\0", 8); 133 : 0 : prefix[8] = context; 134 : : 135 : 0 : for (i = 0; i < okmlen; i += HKDF_HASHLEN) { 136 : : 137 : : err = crypto_shash_init(desc); 138 : 0 : if (err) 139 : : goto out; 140 : : 141 : 0 : if (prev) { 142 : 0 : err = crypto_shash_update(desc, prev, HKDF_HASHLEN); 143 : 0 : if (err) 144 : : goto out; 145 : : } 146 : : 147 : 0 : err = crypto_shash_update(desc, prefix, sizeof(prefix)); 148 : 0 : if (err) 149 : : goto out; 150 : : 151 : 0 : err = crypto_shash_update(desc, info, infolen); 152 : 0 : if (err) 153 : : goto out; 154 : : 155 : : BUILD_BUG_ON(sizeof(counter) != 1); 156 : 0 : if (okmlen - i < HKDF_HASHLEN) { 157 : 0 : err = crypto_shash_finup(desc, &counter, 1, tmp); 158 : 0 : if (err) 159 : : goto out; 160 : 0 : memcpy(&okm[i], tmp, okmlen - i); 161 : : memzero_explicit(tmp, sizeof(tmp)); 162 : : } else { 163 : 0 : err = crypto_shash_finup(desc, &counter, 1, &okm[i]); 164 : 0 : if (err) 165 : : goto out; 166 : : } 167 : 0 : counter++; 168 : 0 : prev = &okm[i]; 169 : : } 170 : : err = 0; 171 : : out: 172 : 0 : if (unlikely(err)) 173 : : memzero_explicit(okm, okmlen); /* so caller doesn't need to */ 174 : : shash_desc_zero(desc); 175 : 0 : return err; 176 : : } 177 : : 178 : 0 : void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf) 179 : : { 180 : 0 : crypto_free_shash(hkdf->hmac_tfm); 181 : 0 : }