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