xref: /openbmc/linux/security/keys/big_key.c (revision 3b23dc52)
1 /* Large capacity key type
2  *
3  * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4  * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public Licence
9  * as published by the Free Software Foundation; either version
10  * 2 of the Licence, or (at your option) any later version.
11  */
12 
13 #define pr_fmt(fmt) "big_key: "fmt
14 #include <linux/init.h>
15 #include <linux/seq_file.h>
16 #include <linux/file.h>
17 #include <linux/shmem_fs.h>
18 #include <linux/err.h>
19 #include <linux/scatterlist.h>
20 #include <linux/random.h>
21 #include <linux/vmalloc.h>
22 #include <keys/user-type.h>
23 #include <keys/big_key-type.h>
24 #include <crypto/aead.h>
25 #include <crypto/gcm.h>
26 
27 struct big_key_buf {
28 	unsigned int		nr_pages;
29 	void			*virt;
30 	struct scatterlist	*sg;
31 	struct page		*pages[];
32 };
33 
34 /*
35  * Layout of key payload words.
36  */
37 enum {
38 	big_key_data,
39 	big_key_path,
40 	big_key_path_2nd_part,
41 	big_key_len,
42 };
43 
44 /*
45  * Crypto operation with big_key data
46  */
47 enum big_key_op {
48 	BIG_KEY_ENC,
49 	BIG_KEY_DEC,
50 };
51 
52 /*
53  * If the data is under this limit, there's no point creating a shm file to
54  * hold it as the permanently resident metadata for the shmem fs will be at
55  * least as large as the data.
56  */
57 #define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
58 
59 /*
60  * Key size for big_key data encryption
61  */
62 #define ENC_KEY_SIZE 32
63 
64 /*
65  * Authentication tag length
66  */
67 #define ENC_AUTHTAG_SIZE 16
68 
69 /*
70  * big_key defined keys take an arbitrary string as the description and an
71  * arbitrary blob of data as the payload
72  */
73 struct key_type key_type_big_key = {
74 	.name			= "big_key",
75 	.preparse		= big_key_preparse,
76 	.free_preparse		= big_key_free_preparse,
77 	.instantiate		= generic_key_instantiate,
78 	.revoke			= big_key_revoke,
79 	.destroy		= big_key_destroy,
80 	.describe		= big_key_describe,
81 	.read			= big_key_read,
82 	/* no ->update(); don't add it without changing big_key_crypt() nonce */
83 };
84 
85 /*
86  * Crypto names for big_key data authenticated encryption
87  */
88 static const char big_key_alg_name[] = "gcm(aes)";
89 #define BIG_KEY_IV_SIZE		GCM_AES_IV_SIZE
90 
91 /*
92  * Crypto algorithms for big_key data authenticated encryption
93  */
94 static struct crypto_aead *big_key_aead;
95 
96 /*
97  * Since changing the key affects the entire object, we need a mutex.
98  */
99 static DEFINE_MUTEX(big_key_aead_lock);
100 
101 /*
102  * Encrypt/decrypt big_key data
103  */
104 static int big_key_crypt(enum big_key_op op, struct big_key_buf *buf, size_t datalen, u8 *key)
105 {
106 	int ret;
107 	struct aead_request *aead_req;
108 	/* We always use a zero nonce. The reason we can get away with this is
109 	 * because we're using a different randomly generated key for every
110 	 * different encryption. Notably, too, key_type_big_key doesn't define
111 	 * an .update function, so there's no chance we'll wind up reusing the
112 	 * key to encrypt updated data. Simply put: one key, one encryption.
113 	 */
114 	u8 zero_nonce[BIG_KEY_IV_SIZE];
115 
116 	aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL);
117 	if (!aead_req)
118 		return -ENOMEM;
119 
120 	memset(zero_nonce, 0, sizeof(zero_nonce));
121 	aead_request_set_crypt(aead_req, buf->sg, buf->sg, datalen, zero_nonce);
122 	aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
123 	aead_request_set_ad(aead_req, 0);
124 
125 	mutex_lock(&big_key_aead_lock);
126 	if (crypto_aead_setkey(big_key_aead, key, ENC_KEY_SIZE)) {
127 		ret = -EAGAIN;
128 		goto error;
129 	}
130 	if (op == BIG_KEY_ENC)
131 		ret = crypto_aead_encrypt(aead_req);
132 	else
133 		ret = crypto_aead_decrypt(aead_req);
134 error:
135 	mutex_unlock(&big_key_aead_lock);
136 	aead_request_free(aead_req);
137 	return ret;
138 }
139 
140 /*
141  * Free up the buffer.
142  */
143 static void big_key_free_buffer(struct big_key_buf *buf)
144 {
145 	unsigned int i;
146 
147 	if (buf->virt) {
148 		memset(buf->virt, 0, buf->nr_pages * PAGE_SIZE);
149 		vunmap(buf->virt);
150 	}
151 
152 	for (i = 0; i < buf->nr_pages; i++)
153 		if (buf->pages[i])
154 			__free_page(buf->pages[i]);
155 
156 	kfree(buf);
157 }
158 
159 /*
160  * Allocate a buffer consisting of a set of pages with a virtual mapping
161  * applied over them.
162  */
163 static void *big_key_alloc_buffer(size_t len)
164 {
165 	struct big_key_buf *buf;
166 	unsigned int npg = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
167 	unsigned int i, l;
168 
169 	buf = kzalloc(sizeof(struct big_key_buf) +
170 		      sizeof(struct page) * npg +
171 		      sizeof(struct scatterlist) * npg,
172 		      GFP_KERNEL);
173 	if (!buf)
174 		return NULL;
175 
176 	buf->nr_pages = npg;
177 	buf->sg = (void *)(buf->pages + npg);
178 	sg_init_table(buf->sg, npg);
179 
180 	for (i = 0; i < buf->nr_pages; i++) {
181 		buf->pages[i] = alloc_page(GFP_KERNEL);
182 		if (!buf->pages[i])
183 			goto nomem;
184 
185 		l = min_t(size_t, len, PAGE_SIZE);
186 		sg_set_page(&buf->sg[i], buf->pages[i], l, 0);
187 		len -= l;
188 	}
189 
190 	buf->virt = vmap(buf->pages, buf->nr_pages, VM_MAP, PAGE_KERNEL);
191 	if (!buf->virt)
192 		goto nomem;
193 
194 	return buf;
195 
196 nomem:
197 	big_key_free_buffer(buf);
198 	return NULL;
199 }
200 
201 /*
202  * Preparse a big key
203  */
204 int big_key_preparse(struct key_preparsed_payload *prep)
205 {
206 	struct big_key_buf *buf;
207 	struct path *path = (struct path *)&prep->payload.data[big_key_path];
208 	struct file *file;
209 	u8 *enckey;
210 	ssize_t written;
211 	size_t datalen = prep->datalen, enclen = datalen + ENC_AUTHTAG_SIZE;
212 	int ret;
213 
214 	if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
215 		return -EINVAL;
216 
217 	/* Set an arbitrary quota */
218 	prep->quotalen = 16;
219 
220 	prep->payload.data[big_key_len] = (void *)(unsigned long)datalen;
221 
222 	if (datalen > BIG_KEY_FILE_THRESHOLD) {
223 		/* Create a shmem file to store the data in.  This will permit the data
224 		 * to be swapped out if needed.
225 		 *
226 		 * File content is stored encrypted with randomly generated key.
227 		 */
228 		loff_t pos = 0;
229 
230 		buf = big_key_alloc_buffer(enclen);
231 		if (!buf)
232 			return -ENOMEM;
233 		memcpy(buf->virt, prep->data, datalen);
234 
235 		/* generate random key */
236 		enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
237 		if (!enckey) {
238 			ret = -ENOMEM;
239 			goto error;
240 		}
241 		ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE);
242 		if (unlikely(ret))
243 			goto err_enckey;
244 
245 		/* encrypt aligned data */
246 		ret = big_key_crypt(BIG_KEY_ENC, buf, datalen, enckey);
247 		if (ret)
248 			goto err_enckey;
249 
250 		/* save aligned data to file */
251 		file = shmem_kernel_file_setup("", enclen, 0);
252 		if (IS_ERR(file)) {
253 			ret = PTR_ERR(file);
254 			goto err_enckey;
255 		}
256 
257 		written = kernel_write(file, buf->virt, enclen, &pos);
258 		if (written != enclen) {
259 			ret = written;
260 			if (written >= 0)
261 				ret = -ENOMEM;
262 			goto err_fput;
263 		}
264 
265 		/* Pin the mount and dentry to the key so that we can open it again
266 		 * later
267 		 */
268 		prep->payload.data[big_key_data] = enckey;
269 		*path = file->f_path;
270 		path_get(path);
271 		fput(file);
272 		big_key_free_buffer(buf);
273 	} else {
274 		/* Just store the data in a buffer */
275 		void *data = kmalloc(datalen, GFP_KERNEL);
276 
277 		if (!data)
278 			return -ENOMEM;
279 
280 		prep->payload.data[big_key_data] = data;
281 		memcpy(data, prep->data, prep->datalen);
282 	}
283 	return 0;
284 
285 err_fput:
286 	fput(file);
287 err_enckey:
288 	kzfree(enckey);
289 error:
290 	big_key_free_buffer(buf);
291 	return ret;
292 }
293 
294 /*
295  * Clear preparsement.
296  */
297 void big_key_free_preparse(struct key_preparsed_payload *prep)
298 {
299 	if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {
300 		struct path *path = (struct path *)&prep->payload.data[big_key_path];
301 
302 		path_put(path);
303 	}
304 	kzfree(prep->payload.data[big_key_data]);
305 }
306 
307 /*
308  * dispose of the links from a revoked keyring
309  * - called with the key sem write-locked
310  */
311 void big_key_revoke(struct key *key)
312 {
313 	struct path *path = (struct path *)&key->payload.data[big_key_path];
314 
315 	/* clear the quota */
316 	key_payload_reserve(key, 0);
317 	if (key_is_positive(key) &&
318 	    (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
319 		vfs_truncate(path, 0);
320 }
321 
322 /*
323  * dispose of the data dangling from the corpse of a big_key key
324  */
325 void big_key_destroy(struct key *key)
326 {
327 	size_t datalen = (size_t)key->payload.data[big_key_len];
328 
329 	if (datalen > BIG_KEY_FILE_THRESHOLD) {
330 		struct path *path = (struct path *)&key->payload.data[big_key_path];
331 
332 		path_put(path);
333 		path->mnt = NULL;
334 		path->dentry = NULL;
335 	}
336 	kzfree(key->payload.data[big_key_data]);
337 	key->payload.data[big_key_data] = NULL;
338 }
339 
340 /*
341  * describe the big_key key
342  */
343 void big_key_describe(const struct key *key, struct seq_file *m)
344 {
345 	size_t datalen = (size_t)key->payload.data[big_key_len];
346 
347 	seq_puts(m, key->description);
348 
349 	if (key_is_positive(key))
350 		seq_printf(m, ": %zu [%s]",
351 			   datalen,
352 			   datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
353 }
354 
355 /*
356  * read the key data
357  * - the key's semaphore is read-locked
358  */
359 long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
360 {
361 	size_t datalen = (size_t)key->payload.data[big_key_len];
362 	long ret;
363 
364 	if (!buffer || buflen < datalen)
365 		return datalen;
366 
367 	if (datalen > BIG_KEY_FILE_THRESHOLD) {
368 		struct big_key_buf *buf;
369 		struct path *path = (struct path *)&key->payload.data[big_key_path];
370 		struct file *file;
371 		u8 *enckey = (u8 *)key->payload.data[big_key_data];
372 		size_t enclen = datalen + ENC_AUTHTAG_SIZE;
373 		loff_t pos = 0;
374 
375 		buf = big_key_alloc_buffer(enclen);
376 		if (!buf)
377 			return -ENOMEM;
378 
379 		file = dentry_open(path, O_RDONLY, current_cred());
380 		if (IS_ERR(file)) {
381 			ret = PTR_ERR(file);
382 			goto error;
383 		}
384 
385 		/* read file to kernel and decrypt */
386 		ret = kernel_read(file, buf->virt, enclen, &pos);
387 		if (ret >= 0 && ret != enclen) {
388 			ret = -EIO;
389 			goto err_fput;
390 		}
391 
392 		ret = big_key_crypt(BIG_KEY_DEC, buf, enclen, enckey);
393 		if (ret)
394 			goto err_fput;
395 
396 		ret = datalen;
397 
398 		/* copy decrypted data to user */
399 		if (copy_to_user(buffer, buf->virt, datalen) != 0)
400 			ret = -EFAULT;
401 
402 err_fput:
403 		fput(file);
404 error:
405 		big_key_free_buffer(buf);
406 	} else {
407 		ret = datalen;
408 		if (copy_to_user(buffer, key->payload.data[big_key_data],
409 				 datalen) != 0)
410 			ret = -EFAULT;
411 	}
412 
413 	return ret;
414 }
415 
416 /*
417  * Register key type
418  */
419 static int __init big_key_init(void)
420 {
421 	int ret;
422 
423 	/* init block cipher */
424 	big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
425 	if (IS_ERR(big_key_aead)) {
426 		ret = PTR_ERR(big_key_aead);
427 		pr_err("Can't alloc crypto: %d\n", ret);
428 		return ret;
429 	}
430 
431 	if (unlikely(crypto_aead_ivsize(big_key_aead) != BIG_KEY_IV_SIZE)) {
432 		WARN(1, "big key algorithm changed?");
433 		ret = -EINVAL;
434 		goto free_aead;
435 	}
436 
437 	ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE);
438 	if (ret < 0) {
439 		pr_err("Can't set crypto auth tag len: %d\n", ret);
440 		goto free_aead;
441 	}
442 
443 	ret = register_key_type(&key_type_big_key);
444 	if (ret < 0) {
445 		pr_err("Can't register type: %d\n", ret);
446 		goto free_aead;
447 	}
448 
449 	return 0;
450 
451 free_aead:
452 	crypto_free_aead(big_key_aead);
453 	return ret;
454 }
455 
456 late_initcall(big_key_init);
457