hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/security/keys/big_key.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Large capacity key type
23 *
3
- * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4
+ * Copyright (C) 2017-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
45 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
56 * 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.
117 */
128
139 #define pr_fmt(fmt) "big_key: "fmt
....@@ -16,20 +12,10 @@
1612 #include <linux/file.h>
1713 #include <linux/shmem_fs.h>
1814 #include <linux/err.h>
19
-#include <linux/scatterlist.h>
2015 #include <linux/random.h>
21
-#include <linux/vmalloc.h>
2216 #include <keys/user-type.h>
2317 #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
-};
18
+#include <crypto/chacha20poly1305.h>
3319
3420 /*
3521 * Layout of key payload words.
....@@ -42,29 +28,11 @@
4228 };
4329
4430 /*
45
- * Crypto operation with big_key data
46
- */
47
-enum big_key_op {
48
- BIG_KEY_ENC,
49
- BIG_KEY_DEC,
50
-};
51
-
52
-/*
5331 * If the data is under this limit, there's no point creating a shm file to
5432 * hold it as the permanently resident metadata for the shmem fs will be at
5533 * least as large as the data.
5634 */
5735 #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
6836
6937 /*
7038 * big_key defined keys take an arbitrary string as the description and an
....@@ -79,136 +47,20 @@
7947 .destroy = big_key_destroy,
8048 .describe = big_key_describe,
8149 .read = big_key_read,
82
- /* no ->update(); don't add it without changing big_key_crypt() nonce */
50
+ .update = big_key_update,
8351 };
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
-}
20052
20153 /*
20254 * Preparse a big key
20355 */
20456 int big_key_preparse(struct key_preparsed_payload *prep)
20557 {
206
- struct big_key_buf *buf;
20758 struct path *path = (struct path *)&prep->payload.data[big_key_path];
20859 struct file *file;
209
- u8 *enckey;
60
+ u8 *buf, *enckey;
21061 ssize_t written;
211
- size_t datalen = prep->datalen, enclen = datalen + ENC_AUTHTAG_SIZE;
62
+ size_t datalen = prep->datalen;
63
+ size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE;
21264 int ret;
21365
21466 if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data)
....@@ -224,28 +76,28 @@
22476 * to be swapped out if needed.
22577 *
22678 * File content is stored encrypted with randomly generated key.
79
+ * Since the key is random for each file, we can set the nonce
80
+ * to zero, provided we never define a ->update() call.
22781 */
22882 loff_t pos = 0;
22983
230
- buf = big_key_alloc_buffer(enclen);
84
+ buf = kvmalloc(enclen, GFP_KERNEL);
23185 if (!buf)
23286 return -ENOMEM;
233
- memcpy(buf->virt, prep->data, datalen);
23487
23588 /* generate random key */
236
- enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);
89
+ enckey = kmalloc(CHACHA20POLY1305_KEY_SIZE, GFP_KERNEL);
23790 if (!enckey) {
23891 ret = -ENOMEM;
23992 goto error;
24093 }
241
- ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE);
94
+ ret = get_random_bytes_wait(enckey, CHACHA20POLY1305_KEY_SIZE);
24295 if (unlikely(ret))
24396 goto err_enckey;
24497
245
- /* encrypt aligned data */
246
- ret = big_key_crypt(BIG_KEY_ENC, buf, datalen, enckey);
247
- if (ret)
248
- goto err_enckey;
98
+ /* encrypt data */
99
+ chacha20poly1305_encrypt(buf, prep->data, datalen, NULL, 0,
100
+ 0, enckey);
249101
250102 /* save aligned data to file */
251103 file = shmem_kernel_file_setup("", enclen, 0);
....@@ -254,11 +106,11 @@
254106 goto err_enckey;
255107 }
256108
257
- written = kernel_write(file, buf->virt, enclen, &pos);
109
+ written = kernel_write(file, buf, enclen, &pos);
258110 if (written != enclen) {
259111 ret = written;
260112 if (written >= 0)
261
- ret = -ENOMEM;
113
+ ret = -EIO;
262114 goto err_fput;
263115 }
264116
....@@ -269,7 +121,8 @@
269121 *path = file->f_path;
270122 path_get(path);
271123 fput(file);
272
- big_key_free_buffer(buf);
124
+ memzero_explicit(buf, enclen);
125
+ kvfree(buf);
273126 } else {
274127 /* Just store the data in a buffer */
275128 void *data = kmalloc(datalen, GFP_KERNEL);
....@@ -285,9 +138,10 @@
285138 err_fput:
286139 fput(file);
287140 err_enckey:
288
- kzfree(enckey);
141
+ kfree_sensitive(enckey);
289142 error:
290
- big_key_free_buffer(buf);
143
+ memzero_explicit(buf, enclen);
144
+ kvfree(buf);
291145 return ret;
292146 }
293147
....@@ -301,7 +155,7 @@
301155
302156 path_put(path);
303157 }
304
- kzfree(prep->payload.data[big_key_data]);
158
+ kfree_sensitive(prep->payload.data[big_key_data]);
305159 }
306160
307161 /*
....@@ -333,8 +187,25 @@
333187 path->mnt = NULL;
334188 path->dentry = NULL;
335189 }
336
- kzfree(key->payload.data[big_key_data]);
190
+ kfree_sensitive(key->payload.data[big_key_data]);
337191 key->payload.data[big_key_data] = NULL;
192
+}
193
+
194
+/*
195
+ * Update a big key
196
+ */
197
+int big_key_update(struct key *key, struct key_preparsed_payload *prep)
198
+{
199
+ int ret;
200
+
201
+ ret = key_payload_reserve(key, prep->datalen);
202
+ if (ret < 0)
203
+ return ret;
204
+
205
+ if (key_is_positive(key))
206
+ big_key_destroy(key);
207
+
208
+ return generic_key_instantiate(key, prep);
338209 }
339210
340211 /*
....@@ -365,14 +236,13 @@
365236 return datalen;
366237
367238 if (datalen > BIG_KEY_FILE_THRESHOLD) {
368
- struct big_key_buf *buf;
369239 struct path *path = (struct path *)&key->payload.data[big_key_path];
370240 struct file *file;
371
- u8 *enckey = (u8 *)key->payload.data[big_key_data];
372
- size_t enclen = datalen + ENC_AUTHTAG_SIZE;
241
+ u8 *buf, *enckey = (u8 *)key->payload.data[big_key_data];
242
+ size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE;
373243 loff_t pos = 0;
374244
375
- buf = big_key_alloc_buffer(enclen);
245
+ buf = kvmalloc(enclen, GFP_KERNEL);
376246 if (!buf)
377247 return -ENOMEM;
378248
....@@ -383,25 +253,28 @@
383253 }
384254
385255 /* read file to kernel and decrypt */
386
- ret = kernel_read(file, buf->virt, enclen, &pos);
387
- if (ret >= 0 && ret != enclen) {
388
- ret = -EIO;
256
+ ret = kernel_read(file, buf, enclen, &pos);
257
+ if (ret != enclen) {
258
+ if (ret >= 0)
259
+ ret = -EIO;
389260 goto err_fput;
390261 }
391262
392
- ret = big_key_crypt(BIG_KEY_DEC, buf, enclen, enckey);
393
- if (ret)
263
+ ret = chacha20poly1305_decrypt(buf, buf, enclen, NULL, 0, 0,
264
+ enckey) ? 0 : -EBADMSG;
265
+ if (unlikely(ret))
394266 goto err_fput;
395267
396268 ret = datalen;
397269
398270 /* copy out decrypted data */
399
- memcpy(buffer, buf->virt, datalen);
271
+ memcpy(buffer, buf, datalen);
400272
401273 err_fput:
402274 fput(file);
403275 error:
404
- big_key_free_buffer(buf);
276
+ memzero_explicit(buf, enclen);
277
+ kvfree(buf);
405278 } else {
406279 ret = datalen;
407280 memcpy(buffer, key->payload.data[big_key_data], datalen);
....@@ -415,39 +288,7 @@
415288 */
416289 static int __init big_key_init(void)
417290 {
418
- int ret;
419
-
420
- /* init block cipher */
421
- big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
422
- if (IS_ERR(big_key_aead)) {
423
- ret = PTR_ERR(big_key_aead);
424
- pr_err("Can't alloc crypto: %d\n", ret);
425
- return ret;
426
- }
427
-
428
- if (unlikely(crypto_aead_ivsize(big_key_aead) != BIG_KEY_IV_SIZE)) {
429
- WARN(1, "big key algorithm changed?");
430
- ret = -EINVAL;
431
- goto free_aead;
432
- }
433
-
434
- ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE);
435
- if (ret < 0) {
436
- pr_err("Can't set crypto auth tag len: %d\n", ret);
437
- goto free_aead;
438
- }
439
-
440
- ret = register_key_type(&key_type_big_key);
441
- if (ret < 0) {
442
- pr_err("Can't register type: %d\n", ret);
443
- goto free_aead;
444
- }
445
-
446
- return 0;
447
-
448
-free_aead:
449
- crypto_free_aead(big_key_aead);
450
- return ret;
291
+ return register_key_type(&key_type_big_key);
451292 }
452293
453294 late_initcall(big_key_init);