OSDN Git Service

fs crypto: move per-file encryption from f2fs tree to fs/crypto
[android-x86/kernel.git] / fs / crypto / keyinfo.c
1 /*
2  * key management facility for FS encryption support.
3  *
4  * Copyright (C) 2015, Google, Inc.
5  *
6  * This contains encryption key functions.
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 #include <crypto/hash.h>
17 #include <linux/fscrypto.h>
18
19 static void derive_crypt_complete(struct crypto_async_request *req, int rc)
20 {
21         struct fscrypt_completion_result *ecr = req->data;
22
23         if (rc == -EINPROGRESS)
24                 return;
25
26         ecr->res = rc;
27         complete(&ecr->completion);
28 }
29
30 /**
31  * derive_key_aes() - Derive a key using AES-128-ECB
32  * @deriving_key: Encryption key used for derivation.
33  * @source_key:   Source key to which to apply derivation.
34  * @derived_key:  Derived key.
35  *
36  * Return: Zero on success; non-zero otherwise.
37  */
38 static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE],
39                                 u8 source_key[FS_AES_256_XTS_KEY_SIZE],
40                                 u8 derived_key[FS_AES_256_XTS_KEY_SIZE])
41 {
42         int res = 0;
43         struct ablkcipher_request *req = NULL;
44         DECLARE_FS_COMPLETION_RESULT(ecr);
45         struct scatterlist src_sg, dst_sg;
46         struct crypto_ablkcipher *tfm = crypto_alloc_ablkcipher("ecb(aes)", 0,
47                                                                 0);
48
49         if (IS_ERR(tfm)) {
50                 res = PTR_ERR(tfm);
51                 tfm = NULL;
52                 goto out;
53         }
54         crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
55         req = ablkcipher_request_alloc(tfm, GFP_NOFS);
56         if (!req) {
57                 res = -ENOMEM;
58                 goto out;
59         }
60         ablkcipher_request_set_callback(req,
61                         CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
62                         derive_crypt_complete, &ecr);
63         res = crypto_ablkcipher_setkey(tfm, deriving_key,
64                                         FS_AES_128_ECB_KEY_SIZE);
65         if (res < 0)
66                 goto out;
67
68         sg_init_one(&src_sg, source_key, FS_AES_256_XTS_KEY_SIZE);
69         sg_init_one(&dst_sg, derived_key, FS_AES_256_XTS_KEY_SIZE);
70         ablkcipher_request_set_crypt(req, &src_sg, &dst_sg,
71                                         FS_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 out:
78         if (req)
79                 ablkcipher_request_free(req);
80         if (tfm)
81                 crypto_free_ablkcipher(tfm);
82         return res;
83 }
84
85 static void put_crypt_info(struct fscrypt_info *ci)
86 {
87         if (!ci)
88                 return;
89
90         if (ci->ci_keyring_key)
91                 key_put(ci->ci_keyring_key);
92         crypto_free_ablkcipher(ci->ci_ctfm);
93         kmem_cache_free(fscrypt_info_cachep, ci);
94 }
95
96 int get_crypt_info(struct inode *inode)
97 {
98         struct fscrypt_info *crypt_info;
99         u8 full_key_descriptor[FS_KEY_DESC_PREFIX_SIZE +
100                                 (FS_KEY_DESCRIPTOR_SIZE * 2) + 1];
101         struct key *keyring_key = NULL;
102         struct fscrypt_key *master_key;
103         struct fscrypt_context ctx;
104         const struct user_key_payload *ukp;
105         struct crypto_ablkcipher *ctfm;
106         const char *cipher_str;
107         u8 raw_key[FS_MAX_KEY_SIZE];
108         u8 mode;
109         int res;
110
111         res = fscrypt_initialize();
112         if (res)
113                 return res;
114
115         if (!inode->i_sb->s_cop->get_context)
116                 return -EOPNOTSUPP;
117 retry:
118         crypt_info = ACCESS_ONCE(inode->i_crypt_info);
119         if (crypt_info) {
120                 if (!crypt_info->ci_keyring_key ||
121                                 key_validate(crypt_info->ci_keyring_key) == 0)
122                         return 0;
123                 fscrypt_put_encryption_info(inode, crypt_info);
124                 goto retry;
125         }
126
127         res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
128         if (res < 0) {
129                 if (!fscrypt_dummy_context_enabled(inode))
130                         return res;
131                 ctx.contents_encryption_mode = FS_ENCRYPTION_MODE_AES_256_XTS;
132                 ctx.filenames_encryption_mode = FS_ENCRYPTION_MODE_AES_256_CTS;
133                 ctx.flags = 0;
134         } else if (res != sizeof(ctx)) {
135                 return -EINVAL;
136         }
137         res = 0;
138
139         crypt_info = kmem_cache_alloc(fscrypt_info_cachep, GFP_NOFS);
140         if (!crypt_info)
141                 return -ENOMEM;
142
143         crypt_info->ci_flags = ctx.flags;
144         crypt_info->ci_data_mode = ctx.contents_encryption_mode;
145         crypt_info->ci_filename_mode = ctx.filenames_encryption_mode;
146         crypt_info->ci_ctfm = NULL;
147         crypt_info->ci_keyring_key = NULL;
148         memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
149                                 sizeof(crypt_info->ci_master_key));
150         if (S_ISREG(inode->i_mode))
151                 mode = crypt_info->ci_data_mode;
152         else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
153                 mode = crypt_info->ci_filename_mode;
154         else
155                 BUG();
156
157         switch (mode) {
158         case FS_ENCRYPTION_MODE_AES_256_XTS:
159                 cipher_str = "xts(aes)";
160                 break;
161         case FS_ENCRYPTION_MODE_AES_256_CTS:
162                 cipher_str = "cts(cbc(aes))";
163                 break;
164         default:
165                 printk_once(KERN_WARNING
166                             "%s: unsupported key mode %d (ino %u)\n",
167                             __func__, mode, (unsigned) inode->i_ino);
168                 res = -ENOKEY;
169                 goto out;
170         }
171         if (fscrypt_dummy_context_enabled(inode)) {
172                 memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE);
173                 goto got_key;
174         }
175         memcpy(full_key_descriptor, FS_KEY_DESC_PREFIX,
176                                         FS_KEY_DESC_PREFIX_SIZE);
177         sprintf(full_key_descriptor + FS_KEY_DESC_PREFIX_SIZE,
178                                         "%*phN", FS_KEY_DESCRIPTOR_SIZE,
179                                         ctx.master_key_descriptor);
180         full_key_descriptor[FS_KEY_DESC_PREFIX_SIZE +
181                                         (2 * FS_KEY_DESCRIPTOR_SIZE)] = '\0';
182         keyring_key = request_key(&key_type_logon, full_key_descriptor, NULL);
183         if (IS_ERR(keyring_key)) {
184                 res = PTR_ERR(keyring_key);
185                 keyring_key = NULL;
186                 goto out;
187         }
188         crypt_info->ci_keyring_key = keyring_key;
189         if (keyring_key->type != &key_type_logon) {
190                 printk_once(KERN_WARNING
191                                 "%s: key type must be logon\n", __func__);
192                 res = -ENOKEY;
193                 goto out;
194         }
195         down_read(&keyring_key->sem);
196         ukp = user_key_payload(keyring_key);
197         if (ukp->datalen != sizeof(struct fscrypt_key)) {
198                 res = -EINVAL;
199                 up_read(&keyring_key->sem);
200                 goto out;
201         }
202         master_key = (struct fscrypt_key *)ukp->data;
203         BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE);
204
205         if (master_key->size != FS_AES_256_XTS_KEY_SIZE) {
206                 printk_once(KERN_WARNING
207                                 "%s: key size incorrect: %d\n",
208                                 __func__, master_key->size);
209                 res = -ENOKEY;
210                 up_read(&keyring_key->sem);
211                 goto out;
212         }
213         res = derive_key_aes(ctx.nonce, master_key->raw, raw_key);
214         up_read(&keyring_key->sem);
215         if (res)
216                 goto out;
217 got_key:
218         ctfm = crypto_alloc_ablkcipher(cipher_str, 0, 0);
219         if (!ctfm || IS_ERR(ctfm)) {
220                 res = ctfm ? PTR_ERR(ctfm) : -ENOMEM;
221                 printk(KERN_DEBUG
222                        "%s: error %d (inode %u) allocating crypto tfm\n",
223                        __func__, res, (unsigned) inode->i_ino);
224                 goto out;
225         }
226         crypt_info->ci_ctfm = ctfm;
227         crypto_ablkcipher_clear_flags(ctfm, ~0);
228         crypto_tfm_set_flags(crypto_ablkcipher_tfm(ctfm),
229                                         CRYPTO_TFM_REQ_WEAK_KEY);
230         res = crypto_ablkcipher_setkey(ctfm, raw_key, fscrypt_key_size(mode));
231         if (res)
232                 goto out;
233
234         memzero_explicit(raw_key, sizeof(raw_key));
235         if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) {
236                 put_crypt_info(crypt_info);
237                 goto retry;
238         }
239         return 0;
240
241 out:
242         if (res == -ENOKEY)
243                 res = 0;
244         put_crypt_info(crypt_info);
245         memzero_explicit(raw_key, sizeof(raw_key));
246         return res;
247 }
248
249 void fscrypt_put_encryption_info(struct inode *inode, struct fscrypt_info *ci)
250 {
251         struct fscrypt_info *prev;
252
253         if (ci == NULL)
254                 ci = ACCESS_ONCE(inode->i_crypt_info);
255         if (ci == NULL)
256                 return;
257
258         prev = cmpxchg(&inode->i_crypt_info, ci, NULL);
259         if (prev != ci)
260                 return;
261
262         put_crypt_info(ci);
263 }
264 EXPORT_SYMBOL(fscrypt_put_encryption_info);
265
266 int fscrypt_get_encryption_info(struct inode *inode)
267 {
268         struct fscrypt_info *ci = inode->i_crypt_info;
269
270         if (!ci ||
271                 (ci->ci_keyring_key &&
272                  (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
273                                                (1 << KEY_FLAG_REVOKED) |
274                                                (1 << KEY_FLAG_DEAD)))))
275                 return get_crypt_info(inode);
276         return 0;
277 }
278 EXPORT_SYMBOL(fscrypt_get_encryption_info);