1 /*
2 * linux/fs/ext4/crypto_key.c
3 *
4 * Copyright (C) 2015, Google, Inc.
5 *
6 * This contains encryption key functions for ext4
7 *
8 * Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015.
9 */
10
11 #include <keys/encrypted-type.h>
12 #include <keys/user-type.h>
13 #include <linux/random.h>
14 #include <linux/scatterlist.h>
15 #include <uapi/linux/keyctl.h>
16
17 #include "ext4.h"
18 #include "xattr.h"
19
derive_crypt_complete(struct crypto_async_request * req,int rc)20 static void derive_crypt_complete(struct crypto_async_request *req, int rc)
21 {
22 struct ext4_completion_result *ecr = req->data;
23
24 if (rc == -EINPROGRESS)
25 return;
26
27 ecr->res = rc;
28 complete(&ecr->completion);
29 }
30
31 /**
32 * ext4_derive_key_v1() - Derive a key using AES-128-ECB
33 * @deriving_key: Encryption key used for derivation.
34 * @source_key: Source key to which to apply derivation.
35 * @derived_key: Derived key.
36 *
37 * Return: 0 on success, -errno on failure
38 */
ext4_derive_key_v1(const char deriving_key[EXT4_AES_128_ECB_KEY_SIZE],const char source_key[EXT4_AES_256_XTS_KEY_SIZE],char derived_key[EXT4_AES_256_XTS_KEY_SIZE])39 static int ext4_derive_key_v1(const char deriving_key[EXT4_AES_128_ECB_KEY_SIZE],
40 const char source_key[EXT4_AES_256_XTS_KEY_SIZE],
41 char derived_key[EXT4_AES_256_XTS_KEY_SIZE])
42 {
43 int res = 0;
44 struct ablkcipher_request *req = NULL;
45 DECLARE_EXT4_COMPLETION_RESULT(ecr);
46 struct scatterlist src_sg, dst_sg;
47 struct crypto_ablkcipher *tfm = crypto_alloc_ablkcipher("ecb(aes)", 0,
48 0);
49
50 if (IS_ERR(tfm)) {
51 res = PTR_ERR(tfm);
52 tfm = NULL;
53 goto out;
54 }
55 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
56 req = ablkcipher_request_alloc(tfm, GFP_NOFS);
57 if (!req) {
58 res = -ENOMEM;
59 goto out;
60 }
61 ablkcipher_request_set_callback(req,
62 CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
63 derive_crypt_complete, &ecr);
64 res = crypto_ablkcipher_setkey(tfm, deriving_key,
65 EXT4_AES_128_ECB_KEY_SIZE);
66 if (res < 0)
67 goto out;
68 sg_init_one(&src_sg, source_key, EXT4_AES_256_XTS_KEY_SIZE);
69 sg_init_one(&dst_sg, derived_key, EXT4_AES_256_XTS_KEY_SIZE);
70 ablkcipher_request_set_crypt(req, &src_sg, &dst_sg,
71 EXT4_AES_256_XTS_KEY_SIZE, NULL);
72 res = crypto_ablkcipher_encrypt(req);
73 if (res == -EINPROGRESS || res == -EBUSY) {
74 wait_for_completion(&ecr.completion);
75 res = ecr.res;
76 }
77
78 out:
79 if (req)
80 ablkcipher_request_free(req);
81 if (tfm)
82 crypto_free_ablkcipher(tfm);
83 return res;
84 }
85
86 /**
87 * ext4_derive_key_v2() - Derive a key non-reversibly
88 * @nonce: the nonce associated with the file
89 * @master_key: the master key referenced by the file
90 * @derived_key: (output) the resulting derived key
91 *
92 * This function computes the following:
93 * derived_key[0:127] = AES-256-ENCRYPT(master_key[0:255], nonce)
94 * derived_key[128:255] = AES-256-ENCRYPT(master_key[0:255], nonce ^ 0x01)
95 * derived_key[256:383] = AES-256-ENCRYPT(master_key[256:511], nonce)
96 * derived_key[384:511] = AES-256-ENCRYPT(master_key[256:511], nonce ^ 0x01)
97 *
98 * 'nonce ^ 0x01' denotes flipping the low order bit of the last byte.
99 *
100 * Unlike the v1 algorithm, the v2 algorithm is "non-reversible", meaning that
101 * compromising a derived key does not also compromise the master key.
102 *
103 * Return: 0 on success, -errno on failure
104 */
ext4_derive_key_v2(const char nonce[EXT4_KEY_DERIVATION_NONCE_SIZE],const char master_key[EXT4_MAX_KEY_SIZE],char derived_key[EXT4_MAX_KEY_SIZE])105 static int ext4_derive_key_v2(const char nonce[EXT4_KEY_DERIVATION_NONCE_SIZE],
106 const char master_key[EXT4_MAX_KEY_SIZE],
107 char derived_key[EXT4_MAX_KEY_SIZE])
108 {
109 const int noncelen = EXT4_KEY_DERIVATION_NONCE_SIZE;
110 struct crypto_cipher *tfm;
111 int err;
112 int i;
113
114 /*
115 * Since we only use each transform for a small number of encryptions,
116 * requesting just "aes" turns out to be significantly faster than
117 * "ecb(aes)", by about a factor of two.
118 */
119 tfm = crypto_alloc_cipher("aes", 0, 0);
120 if (IS_ERR(tfm))
121 return PTR_ERR(tfm);
122
123 BUILD_BUG_ON(4 * EXT4_KEY_DERIVATION_NONCE_SIZE != EXT4_MAX_KEY_SIZE);
124 BUILD_BUG_ON(2 * EXT4_AES_256_ECB_KEY_SIZE != EXT4_MAX_KEY_SIZE);
125 for (i = 0; i < 2; i++) {
126 memcpy(derived_key, nonce, noncelen);
127 memcpy(derived_key + noncelen, nonce, noncelen);
128 derived_key[2 * noncelen - 1] ^= 0x01;
129 err = crypto_cipher_setkey(tfm, master_key,
130 EXT4_AES_256_ECB_KEY_SIZE);
131 if (err)
132 break;
133 crypto_cipher_encrypt_one(tfm, derived_key, derived_key);
134 crypto_cipher_encrypt_one(tfm, derived_key + noncelen,
135 derived_key + noncelen);
136 master_key += EXT4_AES_256_ECB_KEY_SIZE;
137 derived_key += 2 * noncelen;
138 }
139 crypto_free_cipher(tfm);
140 return err;
141 }
142
143 /**
144 * ext4_derive_key() - Derive a per-file key from a nonce and master key
145 * @ctx: the encryption context associated with the file
146 * @master_key: the master key referenced by the file
147 * @derived_key: (output) the resulting derived key
148 *
149 * Return: 0 on success, -errno on failure
150 */
ext4_derive_key(const struct ext4_encryption_context * ctx,const char master_key[EXT4_MAX_KEY_SIZE],char derived_key[EXT4_MAX_KEY_SIZE])151 static int ext4_derive_key(const struct ext4_encryption_context *ctx,
152 const char master_key[EXT4_MAX_KEY_SIZE],
153 char derived_key[EXT4_MAX_KEY_SIZE])
154 {
155 BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE != EXT4_KEY_DERIVATION_NONCE_SIZE);
156 BUILD_BUG_ON(EXT4_AES_256_XTS_KEY_SIZE != EXT4_MAX_KEY_SIZE);
157
158 /*
159 * Although the key derivation algorithm is logically independent of the
160 * choice of encryption modes, in this kernel it is bundled with HEH
161 * encryption of filenames, which is another crypto improvement that
162 * requires an on-disk format change and requires userspace to specify
163 * different encryption policies.
164 */
165 if (ctx->filenames_encryption_mode == EXT4_ENCRYPTION_MODE_AES_256_HEH)
166 return ext4_derive_key_v2(ctx->nonce, master_key, derived_key);
167 else
168 return ext4_derive_key_v1(ctx->nonce, master_key, derived_key);
169 }
170
ext4_free_crypt_info(struct ext4_crypt_info * ci)171 void ext4_free_crypt_info(struct ext4_crypt_info *ci)
172 {
173 if (!ci)
174 return;
175
176 crypto_free_ablkcipher(ci->ci_ctfm);
177 kmem_cache_free(ext4_crypt_info_cachep, ci);
178 }
179
ext4_free_encryption_info(struct inode * inode,struct ext4_crypt_info * ci)180 void ext4_free_encryption_info(struct inode *inode,
181 struct ext4_crypt_info *ci)
182 {
183 struct ext4_inode_info *ei = EXT4_I(inode);
184 struct ext4_crypt_info *prev;
185
186 if (ci == NULL)
187 ci = ACCESS_ONCE(ei->i_crypt_info);
188 if (ci == NULL)
189 return;
190 prev = cmpxchg(&ei->i_crypt_info, ci, NULL);
191 if (prev != ci)
192 return;
193
194 ext4_free_crypt_info(ci);
195 }
196
ext4_get_encryption_info(struct inode * inode)197 int ext4_get_encryption_info(struct inode *inode)
198 {
199 struct ext4_inode_info *ei = EXT4_I(inode);
200 struct ext4_crypt_info *crypt_info;
201 char full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
202 (EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1];
203 struct key *keyring_key = NULL;
204 struct ext4_encryption_key *master_key;
205 struct ext4_encryption_context ctx;
206 const struct user_key_payload *ukp;
207 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
208 struct crypto_ablkcipher *ctfm;
209 const char *cipher_str;
210 char raw_key[EXT4_MAX_KEY_SIZE];
211 char mode;
212 int res;
213
214 if (ei->i_crypt_info)
215 return 0;
216
217 res = ext4_init_crypto();
218 if (res)
219 return res;
220
221 res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
222 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
223 &ctx, sizeof(ctx));
224 if (res < 0) {
225 if (!DUMMY_ENCRYPTION_ENABLED(sbi))
226 return res;
227 ctx.contents_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
228 ctx.filenames_encryption_mode =
229 EXT4_ENCRYPTION_MODE_AES_256_CTS;
230 ctx.flags = 0;
231 } else if (res != sizeof(ctx))
232 return -EINVAL;
233 res = 0;
234
235 crypt_info = kmem_cache_alloc(ext4_crypt_info_cachep, GFP_KERNEL);
236 if (!crypt_info)
237 return -ENOMEM;
238
239 crypt_info->ci_flags = ctx.flags;
240 crypt_info->ci_data_mode = ctx.contents_encryption_mode;
241 crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
242 crypt_info->ci_ctfm = NULL;
243 memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
244 sizeof(crypt_info->ci_master_key));
245 if (S_ISREG(inode->i_mode))
246 mode = crypt_info->ci_data_mode;
247 else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
248 mode = crypt_info->ci_filename_mode;
249 else
250 BUG();
251 switch (mode) {
252 case EXT4_ENCRYPTION_MODE_AES_256_XTS:
253 cipher_str = "xts(aes)";
254 break;
255 case EXT4_ENCRYPTION_MODE_AES_256_CTS:
256 cipher_str = "cts(cbc(aes))";
257 break;
258 case EXT4_ENCRYPTION_MODE_AES_256_HEH:
259 cipher_str = "heh(aes)";
260 break;
261 case EXT4_ENCRYPTION_MODE_SPECK128_256_XTS:
262 cipher_str = "xts(speck128)";
263 break;
264 case EXT4_ENCRYPTION_MODE_SPECK128_256_CTS:
265 cipher_str = "cts(cbc(speck128))";
266 break;
267 default:
268 printk_once(KERN_WARNING
269 "ext4: unsupported key mode %d (ino %u)\n",
270 mode, (unsigned) inode->i_ino);
271 res = -ENOKEY;
272 goto out;
273 }
274 if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
275 memset(raw_key, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
276 goto got_key;
277 }
278 memcpy(full_key_descriptor, EXT4_KEY_DESC_PREFIX,
279 EXT4_KEY_DESC_PREFIX_SIZE);
280 sprintf(full_key_descriptor + EXT4_KEY_DESC_PREFIX_SIZE,
281 "%*phN", EXT4_KEY_DESCRIPTOR_SIZE,
282 ctx.master_key_descriptor);
283 full_key_descriptor[EXT4_KEY_DESC_PREFIX_SIZE +
284 (2 * EXT4_KEY_DESCRIPTOR_SIZE)] = '\0';
285 keyring_key = request_key(&key_type_logon, full_key_descriptor, NULL);
286 if (IS_ERR(keyring_key)) {
287 res = PTR_ERR(keyring_key);
288 keyring_key = NULL;
289 goto out;
290 }
291 if (keyring_key->type != &key_type_logon) {
292 printk_once(KERN_WARNING
293 "ext4: key type must be logon\n");
294 res = -ENOKEY;
295 goto out;
296 }
297 down_read(&keyring_key->sem);
298 ukp = user_key_payload(keyring_key);
299 if (!ukp) {
300 /* key was revoked before we acquired its semaphore */
301 res = -EKEYREVOKED;
302 up_read(&keyring_key->sem);
303 goto out;
304 }
305 if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
306 res = -EINVAL;
307 up_read(&keyring_key->sem);
308 goto out;
309 }
310 master_key = (struct ext4_encryption_key *)ukp->data;
311 BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
312 EXT4_KEY_DERIVATION_NONCE_SIZE);
313 if (master_key->size != EXT4_AES_256_XTS_KEY_SIZE) {
314 printk_once(KERN_WARNING
315 "ext4: key size incorrect: %d\n",
316 master_key->size);
317 res = -ENOKEY;
318 up_read(&keyring_key->sem);
319 goto out;
320 }
321 res = ext4_derive_key(&ctx, master_key->raw, raw_key);
322 up_read(&keyring_key->sem);
323 if (res)
324 goto out;
325 got_key:
326 ctfm = crypto_alloc_ablkcipher(cipher_str, 0, 0);
327 if (!ctfm || IS_ERR(ctfm)) {
328 res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
329 printk(KERN_DEBUG
330 "%s: error %d (inode %u) allocating crypto tfm\n",
331 __func__, res, (unsigned) inode->i_ino);
332 goto out;
333 }
334 crypt_info->ci_ctfm = ctfm;
335 crypto_ablkcipher_clear_flags(ctfm, ~0);
336 crypto_tfm_set_flags(crypto_ablkcipher_tfm(ctfm),
337 CRYPTO_TFM_REQ_WEAK_KEY);
338 res = crypto_ablkcipher_setkey(ctfm, raw_key,
339 ext4_encryption_key_size(mode));
340 if (res)
341 goto out;
342
343 if (cmpxchg(&ei->i_crypt_info, NULL, crypt_info) == NULL)
344 crypt_info = NULL;
345 out:
346 if (res == -ENOKEY)
347 res = 0;
348 key_put(keyring_key);
349 ext4_free_crypt_info(crypt_info);
350 memzero_explicit(raw_key, sizeof(raw_key));
351 return res;
352 }
353
ext4_has_encryption_key(struct inode * inode)354 int ext4_has_encryption_key(struct inode *inode)
355 {
356 struct ext4_inode_info *ei = EXT4_I(inode);
357
358 return (ei->i_crypt_info != NULL);
359 }
360