1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/key.h>
3 #include <linux/keyctl.h>
4 #include <keys/user-type.h>
5 #include <linux/crash_dump.h>
6 #include <linux/cc_platform.h>
7 #include <linux/configfs.h>
8 #include <linux/module.h>
9
10 #define KEY_NUM_MAX 128 /* maximum dm crypt keys */
11 #define KEY_SIZE_MAX 256 /* maximum dm crypt key size */
12 #define KEY_DESC_MAX_LEN 128 /* maximum dm crypt key description size */
13
14 static unsigned int key_count;
15
16 struct dm_crypt_key {
17 unsigned int key_size;
18 char key_desc[KEY_DESC_MAX_LEN];
19 u8 data[KEY_SIZE_MAX];
20 };
21
22 static struct keys_header {
23 unsigned int total_keys;
24 struct dm_crypt_key keys[] __counted_by(total_keys);
25 } *keys_header;
26
get_keys_header_size(size_t total_keys)27 static size_t get_keys_header_size(size_t total_keys)
28 {
29 return struct_size(keys_header, keys, total_keys);
30 }
31
32 unsigned long long dm_crypt_keys_addr;
33 EXPORT_SYMBOL_GPL(dm_crypt_keys_addr);
34
setup_dmcryptkeys(char * arg)35 static int __init setup_dmcryptkeys(char *arg)
36 {
37 char *end;
38
39 if (!arg)
40 return -EINVAL;
41 dm_crypt_keys_addr = memparse(arg, &end);
42 if (end > arg)
43 return 0;
44
45 dm_crypt_keys_addr = 0;
46 return -EINVAL;
47 }
48
49 early_param("dmcryptkeys", setup_dmcryptkeys);
50
51 /*
52 * Architectures may override this function to read dm crypt keys
53 */
dm_crypt_keys_read(char * buf,size_t count,u64 * ppos)54 ssize_t __weak dm_crypt_keys_read(char *buf, size_t count, u64 *ppos)
55 {
56 struct kvec kvec = { .iov_base = buf, .iov_len = count };
57 struct iov_iter iter;
58
59 iov_iter_kvec(&iter, READ, &kvec, 1, count);
60 return read_from_oldmem(&iter, count, ppos, cc_platform_has(CC_ATTR_MEM_ENCRYPT));
61 }
62
add_key_to_keyring(struct dm_crypt_key * dm_key,key_ref_t keyring_ref)63 static int add_key_to_keyring(struct dm_crypt_key *dm_key,
64 key_ref_t keyring_ref)
65 {
66 key_ref_t key_ref;
67 int r;
68
69 /* create or update the requested key and add it to the target keyring */
70 key_ref = key_create_or_update(keyring_ref, "user", dm_key->key_desc,
71 dm_key->data, dm_key->key_size,
72 KEY_USR_ALL, KEY_ALLOC_IN_QUOTA);
73
74 if (!IS_ERR(key_ref)) {
75 r = key_ref_to_ptr(key_ref)->serial;
76 key_ref_put(key_ref);
77 kexec_dprintk("Success adding key %s", dm_key->key_desc);
78 } else {
79 r = PTR_ERR(key_ref);
80 kexec_dprintk("Error when adding key");
81 }
82
83 key_ref_put(keyring_ref);
84 return r;
85 }
86
get_keys_from_kdump_reserved_memory(void)87 static void get_keys_from_kdump_reserved_memory(void)
88 {
89 struct keys_header *keys_header_loaded;
90
91 arch_kexec_unprotect_crashkres();
92
93 keys_header_loaded = kmap_local_page(pfn_to_page(
94 kexec_crash_image->dm_crypt_keys_addr >> PAGE_SHIFT));
95
96 memcpy(keys_header, keys_header_loaded, get_keys_header_size(key_count));
97 kunmap_local(keys_header_loaded);
98 arch_kexec_protect_crashkres();
99 }
100
restore_dm_crypt_keys_to_thread_keyring(void)101 static int restore_dm_crypt_keys_to_thread_keyring(void)
102 {
103 struct dm_crypt_key *key;
104 size_t keys_header_size;
105 key_ref_t keyring_ref;
106 u64 addr;
107
108 /* find the target keyring (which must be writable) */
109 keyring_ref =
110 lookup_user_key(KEY_SPEC_USER_KEYRING, 0x01, KEY_NEED_WRITE);
111 if (IS_ERR(keyring_ref)) {
112 kexec_dprintk("Failed to get the user keyring\n");
113 return PTR_ERR(keyring_ref);
114 }
115
116 addr = dm_crypt_keys_addr;
117 dm_crypt_keys_read((char *)&key_count, sizeof(key_count), &addr);
118 if (key_count < 0 || key_count > KEY_NUM_MAX) {
119 kexec_dprintk("Failed to read the number of dm-crypt keys\n");
120 return -1;
121 }
122
123 kexec_dprintk("There are %u keys\n", key_count);
124 addr = dm_crypt_keys_addr;
125
126 keys_header_size = get_keys_header_size(key_count);
127 keys_header = kzalloc(keys_header_size, GFP_KERNEL);
128 if (!keys_header)
129 return -ENOMEM;
130
131 dm_crypt_keys_read((char *)keys_header, keys_header_size, &addr);
132
133 for (int i = 0; i < keys_header->total_keys; i++) {
134 key = &keys_header->keys[i];
135 kexec_dprintk("Get key (size=%u)\n", key->key_size);
136 add_key_to_keyring(key, keyring_ref);
137 }
138
139 return 0;
140 }
141
read_key_from_user_keying(struct dm_crypt_key * dm_key)142 static int read_key_from_user_keying(struct dm_crypt_key *dm_key)
143 {
144 const struct user_key_payload *ukp;
145 struct key *key;
146 int ret = 0;
147
148 kexec_dprintk("Requesting logon key %s", dm_key->key_desc);
149 key = request_key(&key_type_logon, dm_key->key_desc, NULL);
150
151 if (IS_ERR(key)) {
152 pr_warn("No such logon key %s\n", dm_key->key_desc);
153 return PTR_ERR(key);
154 }
155
156 down_read(&key->sem);
157 ukp = user_key_payload_locked(key);
158 if (!ukp) {
159 ret = -EKEYREVOKED;
160 goto out;
161 }
162
163 if (ukp->datalen > KEY_SIZE_MAX) {
164 pr_err("Key size %u exceeds maximum (%u)\n", ukp->datalen, KEY_SIZE_MAX);
165 ret = -EINVAL;
166 goto out;
167 }
168
169 memcpy(dm_key->data, ukp->data, ukp->datalen);
170 dm_key->key_size = ukp->datalen;
171 kexec_dprintk("Get dm crypt key (size=%u) %s: %8ph\n", dm_key->key_size,
172 dm_key->key_desc, dm_key->data);
173
174 out:
175 up_read(&key->sem);
176 key_put(key);
177 return ret;
178 }
179
180 struct config_key {
181 struct config_item item;
182 const char *description;
183 };
184
to_config_key(struct config_item * item)185 static inline struct config_key *to_config_key(struct config_item *item)
186 {
187 return container_of(item, struct config_key, item);
188 }
189
config_key_description_show(struct config_item * item,char * page)190 static ssize_t config_key_description_show(struct config_item *item, char *page)
191 {
192 return sprintf(page, "%s\n", to_config_key(item)->description);
193 }
194
config_key_description_store(struct config_item * item,const char * page,size_t count)195 static ssize_t config_key_description_store(struct config_item *item,
196 const char *page, size_t count)
197 {
198 struct config_key *config_key = to_config_key(item);
199 size_t len;
200 int ret;
201
202 ret = -EINVAL;
203 len = strcspn(page, "\n");
204
205 if (len > KEY_DESC_MAX_LEN) {
206 pr_err("The key description shouldn't exceed %u characters", KEY_DESC_MAX_LEN);
207 return ret;
208 }
209
210 if (!len)
211 return ret;
212
213 kfree(config_key->description);
214 ret = -ENOMEM;
215 config_key->description = kmemdup_nul(page, len, GFP_KERNEL);
216 if (!config_key->description)
217 return ret;
218
219 return count;
220 }
221
222 CONFIGFS_ATTR(config_key_, description);
223
224 static struct configfs_attribute *config_key_attrs[] = {
225 &config_key_attr_description,
226 NULL,
227 };
228
config_key_release(struct config_item * item)229 static void config_key_release(struct config_item *item)
230 {
231 kfree(to_config_key(item));
232 key_count--;
233 }
234
235 static const struct configfs_item_operations config_key_item_ops = {
236 .release = config_key_release,
237 };
238
239 static const struct config_item_type config_key_type = {
240 .ct_item_ops = &config_key_item_ops,
241 .ct_attrs = config_key_attrs,
242 .ct_owner = THIS_MODULE,
243 };
244
config_keys_make_item(struct config_group * group,const char * name)245 static struct config_item *config_keys_make_item(struct config_group *group,
246 const char *name)
247 {
248 struct config_key *config_key;
249
250 if (key_count > KEY_NUM_MAX) {
251 pr_err("Only %u keys at maximum to be created\n", KEY_NUM_MAX);
252 return ERR_PTR(-EINVAL);
253 }
254
255 config_key = kzalloc_obj(struct config_key);
256 if (!config_key)
257 return ERR_PTR(-ENOMEM);
258
259 config_item_init_type_name(&config_key->item, name, &config_key_type);
260
261 key_count++;
262
263 return &config_key->item;
264 }
265
config_keys_count_show(struct config_item * item,char * page)266 static ssize_t config_keys_count_show(struct config_item *item, char *page)
267 {
268 return sprintf(page, "%d\n", key_count);
269 }
270
271 CONFIGFS_ATTR_RO(config_keys_, count);
272
273 static bool is_dm_key_reused;
274
config_keys_reuse_show(struct config_item * item,char * page)275 static ssize_t config_keys_reuse_show(struct config_item *item, char *page)
276 {
277 return sprintf(page, "%d\n", is_dm_key_reused);
278 }
279
config_keys_reuse_store(struct config_item * item,const char * page,size_t count)280 static ssize_t config_keys_reuse_store(struct config_item *item,
281 const char *page, size_t count)
282 {
283 if (!kexec_crash_image || !kexec_crash_image->dm_crypt_keys_addr) {
284 kexec_dprintk(
285 "dm-crypt keys haven't be saved to crash-reserved memory\n");
286 return -EINVAL;
287 }
288
289 if (kstrtobool(page, &is_dm_key_reused))
290 return -EINVAL;
291
292 if (is_dm_key_reused)
293 get_keys_from_kdump_reserved_memory();
294
295 return count;
296 }
297
298 CONFIGFS_ATTR(config_keys_, reuse);
299
300 static struct configfs_attribute *config_keys_attrs[] = {
301 &config_keys_attr_count,
302 &config_keys_attr_reuse,
303 NULL,
304 };
305
306 /*
307 * Note that, since no extra work is required on ->drop_item(),
308 * no ->drop_item() is provided.
309 */
310 static const struct configfs_group_operations config_keys_group_ops = {
311 .make_item = config_keys_make_item,
312 };
313
314 static const struct config_item_type config_keys_type = {
315 .ct_group_ops = &config_keys_group_ops,
316 .ct_attrs = config_keys_attrs,
317 .ct_owner = THIS_MODULE,
318 };
319
320 static bool restore;
321
config_keys_restore_show(struct config_item * item,char * page)322 static ssize_t config_keys_restore_show(struct config_item *item, char *page)
323 {
324 return sprintf(page, "%d\n", restore);
325 }
326
config_keys_restore_store(struct config_item * item,const char * page,size_t count)327 static ssize_t config_keys_restore_store(struct config_item *item,
328 const char *page, size_t count)
329 {
330 if (!restore)
331 restore_dm_crypt_keys_to_thread_keyring();
332
333 if (kstrtobool(page, &restore))
334 return -EINVAL;
335
336 return count;
337 }
338
339 CONFIGFS_ATTR(config_keys_, restore);
340
341 static struct configfs_attribute *kdump_config_keys_attrs[] = {
342 &config_keys_attr_restore,
343 NULL,
344 };
345
346 static const struct config_item_type kdump_config_keys_type = {
347 .ct_attrs = kdump_config_keys_attrs,
348 .ct_owner = THIS_MODULE,
349 };
350
351 static struct configfs_subsystem config_keys_subsys = {
352 .su_group = {
353 .cg_item = {
354 .ci_namebuf = "crash_dm_crypt_keys",
355 .ci_type = &config_keys_type,
356 },
357 },
358 };
359
build_keys_header(void)360 static int build_keys_header(void)
361 {
362 struct config_item *item = NULL;
363 struct config_key *key;
364 int i, r;
365
366 if (keys_header != NULL)
367 kvfree(keys_header);
368
369 keys_header = kzalloc(get_keys_header_size(key_count), GFP_KERNEL);
370 if (!keys_header)
371 return -ENOMEM;
372
373 keys_header->total_keys = key_count;
374
375 i = 0;
376 list_for_each_entry(item, &config_keys_subsys.su_group.cg_children,
377 ci_entry) {
378 if (item->ci_type != &config_key_type)
379 continue;
380
381 key = to_config_key(item);
382
383 if (!key->description) {
384 pr_warn("No key description for key %s\n", item->ci_name);
385 return -EINVAL;
386 }
387
388 strscpy(keys_header->keys[i].key_desc, key->description,
389 KEY_DESC_MAX_LEN);
390 r = read_key_from_user_keying(&keys_header->keys[i]);
391 if (r != 0) {
392 kexec_dprintk("Failed to read key %s\n",
393 keys_header->keys[i].key_desc);
394 return r;
395 }
396 i++;
397 kexec_dprintk("Found key: %s\n", item->ci_name);
398 }
399
400 return 0;
401 }
402
crash_load_dm_crypt_keys(struct kimage * image)403 int crash_load_dm_crypt_keys(struct kimage *image)
404 {
405 struct kexec_buf kbuf = {
406 .image = image,
407 .buf_min = 0,
408 .buf_max = ULONG_MAX,
409 .top_down = false,
410 .random = true,
411 };
412 int r;
413
414
415 if (key_count <= 0) {
416 kexec_dprintk("No dm-crypt keys\n");
417 return -ENOENT;
418 }
419
420 if (!is_dm_key_reused) {
421 image->dm_crypt_keys_addr = 0;
422 r = build_keys_header();
423 if (r)
424 return r;
425 }
426
427 kbuf.buffer = keys_header;
428 kbuf.bufsz = get_keys_header_size(key_count);
429
430 kbuf.memsz = kbuf.bufsz;
431 kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
432 kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
433 r = kexec_add_buffer(&kbuf);
434 if (r) {
435 kvfree((void *)kbuf.buffer);
436 return r;
437 }
438 image->dm_crypt_keys_addr = kbuf.mem;
439 image->dm_crypt_keys_sz = kbuf.bufsz;
440 kexec_dprintk(
441 "Loaded dm crypt keys to kexec_buffer bufsz=0x%lx memsz=0x%lx\n",
442 kbuf.bufsz, kbuf.memsz);
443
444 return r;
445 }
446
configfs_dmcrypt_keys_init(void)447 static int __init configfs_dmcrypt_keys_init(void)
448 {
449 int ret;
450
451 if (is_kdump_kernel()) {
452 config_keys_subsys.su_group.cg_item.ci_type =
453 &kdump_config_keys_type;
454 }
455
456 config_group_init(&config_keys_subsys.su_group);
457 mutex_init(&config_keys_subsys.su_mutex);
458 ret = configfs_register_subsystem(&config_keys_subsys);
459 if (ret) {
460 pr_err("Error %d while registering subsystem %s\n", ret,
461 config_keys_subsys.su_group.cg_item.ci_namebuf);
462 goto out_unregister;
463 }
464
465 return 0;
466
467 out_unregister:
468 configfs_unregister_subsystem(&config_keys_subsys);
469
470 return ret;
471 }
472
473 module_init(configfs_dmcrypt_keys_init);
474