1cbabf03cSDov Murik // SPDX-License-Identifier: GPL-2.0
2cbabf03cSDov Murik /*
3cbabf03cSDov Murik * efi_secret module
4cbabf03cSDov Murik *
5cbabf03cSDov Murik * Copyright (C) 2022 IBM Corporation
6cbabf03cSDov Murik * Author: Dov Murik <dovmurik@linux.ibm.com>
7cbabf03cSDov Murik */
8cbabf03cSDov Murik
9cbabf03cSDov Murik /**
10cbabf03cSDov Murik * DOC: efi_secret: Allow reading EFI confidential computing (coco) secret area
11cbabf03cSDov Murik * via securityfs interface.
12cbabf03cSDov Murik *
13cbabf03cSDov Murik * When the module is loaded (and securityfs is mounted, typically under
14cbabf03cSDov Murik * /sys/kernel/security), a "secrets/coco" directory is created in securityfs.
15cbabf03cSDov Murik * In it, a file is created for each secret entry. The name of each such file
16cbabf03cSDov Murik * is the GUID of the secret entry, and its content is the secret data.
17cbabf03cSDov Murik */
18cbabf03cSDov Murik
19cbabf03cSDov Murik #include <linux/platform_device.h>
20cbabf03cSDov Murik #include <linux/seq_file.h>
21cbabf03cSDov Murik #include <linux/fs.h>
22cbabf03cSDov Murik #include <linux/kernel.h>
23cbabf03cSDov Murik #include <linux/init.h>
24cbabf03cSDov Murik #include <linux/module.h>
25cbabf03cSDov Murik #include <linux/io.h>
26cbabf03cSDov Murik #include <linux/security.h>
27cbabf03cSDov Murik #include <linux/efi.h>
28cbabf03cSDov Murik #include <linux/cacheflush.h>
29cbabf03cSDov Murik
30cbabf03cSDov Murik #define EFI_SECRET_NUM_FILES 64
31cbabf03cSDov Murik
32cbabf03cSDov Murik struct efi_secret {
33cbabf03cSDov Murik struct dentry *secrets_dir;
34cbabf03cSDov Murik struct dentry *fs_dir;
35cbabf03cSDov Murik struct dentry *fs_files[EFI_SECRET_NUM_FILES];
36cbabf03cSDov Murik void __iomem *secret_data;
37cbabf03cSDov Murik u64 secret_data_len;
38cbabf03cSDov Murik };
39cbabf03cSDov Murik
40cbabf03cSDov Murik /*
41cbabf03cSDov Murik * Structure of the EFI secret area
42cbabf03cSDov Murik *
43cbabf03cSDov Murik * Offset Length
44cbabf03cSDov Murik * (bytes) (bytes) Usage
45cbabf03cSDov Murik * ------- ------- -----
46cbabf03cSDov Murik * 0 16 Secret table header GUID (must be 1e74f542-71dd-4d66-963e-ef4287ff173b)
47cbabf03cSDov Murik * 16 4 Length of bytes of the entire secret area
48cbabf03cSDov Murik *
49cbabf03cSDov Murik * 20 16 First secret entry's GUID
50cbabf03cSDov Murik * 36 4 First secret entry's length in bytes (= 16 + 4 + x)
51cbabf03cSDov Murik * 40 x First secret entry's data
52cbabf03cSDov Murik *
53cbabf03cSDov Murik * 40+x 16 Second secret entry's GUID
54cbabf03cSDov Murik * 56+x 4 Second secret entry's length in bytes (= 16 + 4 + y)
55cbabf03cSDov Murik * 60+x y Second secret entry's data
56cbabf03cSDov Murik *
57cbabf03cSDov Murik * (... and so on for additional entries)
58cbabf03cSDov Murik *
59cbabf03cSDov Murik * The GUID of each secret entry designates the usage of the secret data.
60cbabf03cSDov Murik */
61cbabf03cSDov Murik
62cbabf03cSDov Murik /**
63cbabf03cSDov Murik * struct secret_header - Header of entire secret area; this should be followed
64cbabf03cSDov Murik * by instances of struct secret_entry.
65cbabf03cSDov Murik * @guid: Must be EFI_SECRET_TABLE_HEADER_GUID
66cbabf03cSDov Murik * @len: Length in bytes of entire secret area, including header
67cbabf03cSDov Murik */
68cbabf03cSDov Murik struct secret_header {
69cbabf03cSDov Murik efi_guid_t guid;
70cbabf03cSDov Murik u32 len;
71cbabf03cSDov Murik } __attribute((packed));
72cbabf03cSDov Murik
73cbabf03cSDov Murik /**
74cbabf03cSDov Murik * struct secret_entry - Holds one secret entry
75cbabf03cSDov Murik * @guid: Secret-specific GUID (or NULL_GUID if this secret entry was deleted)
76cbabf03cSDov Murik * @len: Length of secret entry, including its guid and len fields
77cbabf03cSDov Murik * @data: The secret data (full of zeros if this secret entry was deleted)
78cbabf03cSDov Murik */
79cbabf03cSDov Murik struct secret_entry {
80cbabf03cSDov Murik efi_guid_t guid;
81cbabf03cSDov Murik u32 len;
82cbabf03cSDov Murik u8 data[];
83cbabf03cSDov Murik } __attribute((packed));
84cbabf03cSDov Murik
secret_entry_data_len(struct secret_entry * e)85cbabf03cSDov Murik static size_t secret_entry_data_len(struct secret_entry *e)
86cbabf03cSDov Murik {
87cbabf03cSDov Murik return e->len - sizeof(*e);
88cbabf03cSDov Murik }
89cbabf03cSDov Murik
90cbabf03cSDov Murik static struct efi_secret the_efi_secret;
91cbabf03cSDov Murik
efi_secret_get(void)92cbabf03cSDov Murik static inline struct efi_secret *efi_secret_get(void)
93cbabf03cSDov Murik {
94cbabf03cSDov Murik return &the_efi_secret;
95cbabf03cSDov Murik }
96cbabf03cSDov Murik
efi_secret_bin_file_show(struct seq_file * file,void * data)97cbabf03cSDov Murik static int efi_secret_bin_file_show(struct seq_file *file, void *data)
98cbabf03cSDov Murik {
99cbabf03cSDov Murik struct secret_entry *e = file->private;
100cbabf03cSDov Murik
101cbabf03cSDov Murik if (e)
102cbabf03cSDov Murik seq_write(file, e->data, secret_entry_data_len(e));
103cbabf03cSDov Murik
104cbabf03cSDov Murik return 0;
105cbabf03cSDov Murik }
106cbabf03cSDov Murik DEFINE_SHOW_ATTRIBUTE(efi_secret_bin_file);
107cbabf03cSDov Murik
108cbabf03cSDov Murik /*
109cbabf03cSDov Murik * Overwrite memory content with zeroes, and ensure that dirty cache lines are
110cbabf03cSDov Murik * actually written back to memory, to clear out the secret.
111cbabf03cSDov Murik */
wipe_memory(void * addr,size_t size)112cbabf03cSDov Murik static void wipe_memory(void *addr, size_t size)
113cbabf03cSDov Murik {
114cbabf03cSDov Murik memzero_explicit(addr, size);
115cbabf03cSDov Murik #ifdef CONFIG_X86
116cbabf03cSDov Murik clflush_cache_range(addr, size);
117cbabf03cSDov Murik #endif
118cbabf03cSDov Murik }
119cbabf03cSDov Murik
efi_secret_unlink(struct inode * dir,struct dentry * dentry)120cbabf03cSDov Murik static int efi_secret_unlink(struct inode *dir, struct dentry *dentry)
121cbabf03cSDov Murik {
122cbabf03cSDov Murik struct efi_secret *s = efi_secret_get();
123cbabf03cSDov Murik struct inode *inode = d_inode(dentry);
124cbabf03cSDov Murik struct secret_entry *e = (struct secret_entry *)inode->i_private;
125cbabf03cSDov Murik int i;
126cbabf03cSDov Murik
127cbabf03cSDov Murik if (e) {
128cbabf03cSDov Murik /* Zero out the secret data */
129cbabf03cSDov Murik wipe_memory(e->data, secret_entry_data_len(e));
130cbabf03cSDov Murik e->guid = NULL_GUID;
131cbabf03cSDov Murik }
132cbabf03cSDov Murik
133cbabf03cSDov Murik inode->i_private = NULL;
134cbabf03cSDov Murik
135cbabf03cSDov Murik for (i = 0; i < EFI_SECRET_NUM_FILES; i++)
136cbabf03cSDov Murik if (s->fs_files[i] == dentry)
137cbabf03cSDov Murik s->fs_files[i] = NULL;
138cbabf03cSDov Murik
139cbabf03cSDov Murik /*
140cbabf03cSDov Murik * securityfs_remove tries to lock the directory's inode, but we reach
141cbabf03cSDov Murik * the unlink callback when it's already locked
142cbabf03cSDov Murik */
143cbabf03cSDov Murik inode_unlock(dir);
144cbabf03cSDov Murik securityfs_remove(dentry);
145cbabf03cSDov Murik inode_lock(dir);
146cbabf03cSDov Murik
147cbabf03cSDov Murik return 0;
148cbabf03cSDov Murik }
149cbabf03cSDov Murik
150cbabf03cSDov Murik static const struct inode_operations efi_secret_dir_inode_operations = {
151cbabf03cSDov Murik .lookup = simple_lookup,
152cbabf03cSDov Murik .unlink = efi_secret_unlink,
153cbabf03cSDov Murik };
154cbabf03cSDov Murik
efi_secret_map_area(struct platform_device * dev)155cbabf03cSDov Murik static int efi_secret_map_area(struct platform_device *dev)
156cbabf03cSDov Murik {
157cbabf03cSDov Murik int ret;
158cbabf03cSDov Murik struct efi_secret *s = efi_secret_get();
159cbabf03cSDov Murik struct linux_efi_coco_secret_area *secret_area;
160cbabf03cSDov Murik
161cbabf03cSDov Murik if (efi.coco_secret == EFI_INVALID_TABLE_ADDR) {
162cbabf03cSDov Murik dev_err(&dev->dev, "Secret area address is not available\n");
163cbabf03cSDov Murik return -EINVAL;
164cbabf03cSDov Murik }
165cbabf03cSDov Murik
166cbabf03cSDov Murik secret_area = memremap(efi.coco_secret, sizeof(*secret_area), MEMREMAP_WB);
167cbabf03cSDov Murik if (secret_area == NULL) {
168cbabf03cSDov Murik dev_err(&dev->dev, "Could not map secret area EFI config entry\n");
169cbabf03cSDov Murik return -ENOMEM;
170cbabf03cSDov Murik }
171cbabf03cSDov Murik if (!secret_area->base_pa || secret_area->size < sizeof(struct secret_header)) {
172cbabf03cSDov Murik dev_err(&dev->dev,
173cbabf03cSDov Murik "Invalid secret area memory location (base_pa=0x%llx size=0x%llx)\n",
174cbabf03cSDov Murik secret_area->base_pa, secret_area->size);
175cbabf03cSDov Murik ret = -EINVAL;
176cbabf03cSDov Murik goto unmap;
177cbabf03cSDov Murik }
178cbabf03cSDov Murik
179cbabf03cSDov Murik s->secret_data = ioremap_encrypted(secret_area->base_pa, secret_area->size);
180cbabf03cSDov Murik if (s->secret_data == NULL) {
181cbabf03cSDov Murik dev_err(&dev->dev, "Could not map secret area\n");
182cbabf03cSDov Murik ret = -ENOMEM;
183cbabf03cSDov Murik goto unmap;
184cbabf03cSDov Murik }
185cbabf03cSDov Murik
186cbabf03cSDov Murik s->secret_data_len = secret_area->size;
187cbabf03cSDov Murik ret = 0;
188cbabf03cSDov Murik
189cbabf03cSDov Murik unmap:
190cbabf03cSDov Murik memunmap(secret_area);
191cbabf03cSDov Murik return ret;
192cbabf03cSDov Murik }
193cbabf03cSDov Murik
efi_secret_securityfs_teardown(struct platform_device * dev)194cbabf03cSDov Murik static void efi_secret_securityfs_teardown(struct platform_device *dev)
195cbabf03cSDov Murik {
196cbabf03cSDov Murik struct efi_secret *s = efi_secret_get();
197cbabf03cSDov Murik int i;
198cbabf03cSDov Murik
199cbabf03cSDov Murik for (i = (EFI_SECRET_NUM_FILES - 1); i >= 0; i--) {
200cbabf03cSDov Murik securityfs_remove(s->fs_files[i]);
201cbabf03cSDov Murik s->fs_files[i] = NULL;
202cbabf03cSDov Murik }
203cbabf03cSDov Murik
204cbabf03cSDov Murik securityfs_remove(s->fs_dir);
205cbabf03cSDov Murik s->fs_dir = NULL;
206cbabf03cSDov Murik
207cbabf03cSDov Murik securityfs_remove(s->secrets_dir);
208cbabf03cSDov Murik s->secrets_dir = NULL;
209cbabf03cSDov Murik
210cbabf03cSDov Murik dev_dbg(&dev->dev, "Removed securityfs entries\n");
211cbabf03cSDov Murik }
212cbabf03cSDov Murik
efi_secret_securityfs_setup(struct platform_device * dev)213cbabf03cSDov Murik static int efi_secret_securityfs_setup(struct platform_device *dev)
214cbabf03cSDov Murik {
215cbabf03cSDov Murik struct efi_secret *s = efi_secret_get();
216cbabf03cSDov Murik int ret = 0, i = 0, bytes_left;
217cbabf03cSDov Murik unsigned char *ptr;
218cbabf03cSDov Murik struct secret_header *h;
219cbabf03cSDov Murik struct secret_entry *e;
220cbabf03cSDov Murik struct dentry *dent;
221cbabf03cSDov Murik char guid_str[EFI_VARIABLE_GUID_LEN + 1];
222cbabf03cSDov Murik
223cbabf03cSDov Murik ptr = (void __force *)s->secret_data;
224cbabf03cSDov Murik h = (struct secret_header *)ptr;
225cbabf03cSDov Murik if (efi_guidcmp(h->guid, EFI_SECRET_TABLE_HEADER_GUID)) {
226cbabf03cSDov Murik /*
227cbabf03cSDov Murik * This is not an error: it just means that EFI defines secret
228cbabf03cSDov Murik * area but it was not populated by the Guest Owner.
229cbabf03cSDov Murik */
230cbabf03cSDov Murik dev_dbg(&dev->dev, "EFI secret area does not start with correct GUID\n");
231cbabf03cSDov Murik return -ENODEV;
232cbabf03cSDov Murik }
233cbabf03cSDov Murik if (h->len < sizeof(*h)) {
234cbabf03cSDov Murik dev_err(&dev->dev, "EFI secret area reported length is too small\n");
235cbabf03cSDov Murik return -EINVAL;
236cbabf03cSDov Murik }
237cbabf03cSDov Murik if (h->len > s->secret_data_len) {
238cbabf03cSDov Murik dev_err(&dev->dev, "EFI secret area reported length is too big\n");
239cbabf03cSDov Murik return -EINVAL;
240cbabf03cSDov Murik }
241cbabf03cSDov Murik
242cbabf03cSDov Murik s->secrets_dir = NULL;
243cbabf03cSDov Murik s->fs_dir = NULL;
244cbabf03cSDov Murik memset(s->fs_files, 0, sizeof(s->fs_files));
245cbabf03cSDov Murik
246cbabf03cSDov Murik dent = securityfs_create_dir("secrets", NULL);
247cbabf03cSDov Murik if (IS_ERR(dent)) {
248cbabf03cSDov Murik dev_err(&dev->dev, "Error creating secrets securityfs directory entry err=%ld\n",
249cbabf03cSDov Murik PTR_ERR(dent));
250cbabf03cSDov Murik return PTR_ERR(dent);
251cbabf03cSDov Murik }
252cbabf03cSDov Murik s->secrets_dir = dent;
253cbabf03cSDov Murik
254cbabf03cSDov Murik dent = securityfs_create_dir("coco", s->secrets_dir);
255cbabf03cSDov Murik if (IS_ERR(dent)) {
256cbabf03cSDov Murik dev_err(&dev->dev, "Error creating coco securityfs directory entry err=%ld\n",
257cbabf03cSDov Murik PTR_ERR(dent));
258cbabf03cSDov Murik return PTR_ERR(dent);
259cbabf03cSDov Murik }
260cbabf03cSDov Murik d_inode(dent)->i_op = &efi_secret_dir_inode_operations;
261cbabf03cSDov Murik s->fs_dir = dent;
262cbabf03cSDov Murik
263cbabf03cSDov Murik bytes_left = h->len - sizeof(*h);
264cbabf03cSDov Murik ptr += sizeof(*h);
265cbabf03cSDov Murik while (bytes_left >= (int)sizeof(*e) && i < EFI_SECRET_NUM_FILES) {
266cbabf03cSDov Murik e = (struct secret_entry *)ptr;
267cbabf03cSDov Murik if (e->len < sizeof(*e) || e->len > (unsigned int)bytes_left) {
268cbabf03cSDov Murik dev_err(&dev->dev, "EFI secret area is corrupted\n");
269cbabf03cSDov Murik ret = -EINVAL;
270cbabf03cSDov Murik goto err_cleanup;
271cbabf03cSDov Murik }
272cbabf03cSDov Murik
273cbabf03cSDov Murik /* Skip deleted entries (which will have NULL_GUID) */
274cbabf03cSDov Murik if (efi_guidcmp(e->guid, NULL_GUID)) {
275cbabf03cSDov Murik efi_guid_to_str(&e->guid, guid_str);
276cbabf03cSDov Murik
277cbabf03cSDov Murik dent = securityfs_create_file(guid_str, 0440, s->fs_dir, (void *)e,
278cbabf03cSDov Murik &efi_secret_bin_file_fops);
279cbabf03cSDov Murik if (IS_ERR(dent)) {
280cbabf03cSDov Murik dev_err(&dev->dev, "Error creating efi_secret securityfs entry\n");
281cbabf03cSDov Murik ret = PTR_ERR(dent);
282cbabf03cSDov Murik goto err_cleanup;
283cbabf03cSDov Murik }
284cbabf03cSDov Murik
285cbabf03cSDov Murik s->fs_files[i++] = dent;
286cbabf03cSDov Murik }
287cbabf03cSDov Murik ptr += e->len;
288cbabf03cSDov Murik bytes_left -= e->len;
289cbabf03cSDov Murik }
290cbabf03cSDov Murik
291cbabf03cSDov Murik dev_info(&dev->dev, "Created %d entries in securityfs secrets/coco\n", i);
292cbabf03cSDov Murik return 0;
293cbabf03cSDov Murik
294cbabf03cSDov Murik err_cleanup:
295cbabf03cSDov Murik efi_secret_securityfs_teardown(dev);
296cbabf03cSDov Murik return ret;
297cbabf03cSDov Murik }
298cbabf03cSDov Murik
efi_secret_unmap_area(void)299cbabf03cSDov Murik static void efi_secret_unmap_area(void)
300cbabf03cSDov Murik {
301cbabf03cSDov Murik struct efi_secret *s = efi_secret_get();
302cbabf03cSDov Murik
303cbabf03cSDov Murik if (s->secret_data) {
304cbabf03cSDov Murik iounmap(s->secret_data);
305cbabf03cSDov Murik s->secret_data = NULL;
306cbabf03cSDov Murik s->secret_data_len = 0;
307cbabf03cSDov Murik }
308cbabf03cSDov Murik }
309cbabf03cSDov Murik
efi_secret_probe(struct platform_device * dev)310cbabf03cSDov Murik static int efi_secret_probe(struct platform_device *dev)
311cbabf03cSDov Murik {
312cbabf03cSDov Murik int ret;
313cbabf03cSDov Murik
314cbabf03cSDov Murik ret = efi_secret_map_area(dev);
315cbabf03cSDov Murik if (ret)
316cbabf03cSDov Murik return ret;
317cbabf03cSDov Murik
318cbabf03cSDov Murik ret = efi_secret_securityfs_setup(dev);
319cbabf03cSDov Murik if (ret)
320cbabf03cSDov Murik goto err_unmap;
321cbabf03cSDov Murik
322cbabf03cSDov Murik return ret;
323cbabf03cSDov Murik
324cbabf03cSDov Murik err_unmap:
325cbabf03cSDov Murik efi_secret_unmap_area();
326cbabf03cSDov Murik return ret;
327cbabf03cSDov Murik }
328cbabf03cSDov Murik
efi_secret_remove(struct platform_device * dev)329*021bc4b9SUwe Kleine-König static void efi_secret_remove(struct platform_device *dev)
330cbabf03cSDov Murik {
331cbabf03cSDov Murik efi_secret_securityfs_teardown(dev);
332cbabf03cSDov Murik efi_secret_unmap_area();
333cbabf03cSDov Murik }
334cbabf03cSDov Murik
335cbabf03cSDov Murik static struct platform_driver efi_secret_driver = {
336cbabf03cSDov Murik .probe = efi_secret_probe,
337*021bc4b9SUwe Kleine-König .remove_new = efi_secret_remove,
338cbabf03cSDov Murik .driver = {
339cbabf03cSDov Murik .name = "efi_secret",
340cbabf03cSDov Murik },
341cbabf03cSDov Murik };
342cbabf03cSDov Murik
343cbabf03cSDov Murik module_platform_driver(efi_secret_driver);
344cbabf03cSDov Murik
345cbabf03cSDov Murik MODULE_DESCRIPTION("Confidential computing EFI secret area access");
346cbabf03cSDov Murik MODULE_AUTHOR("IBM");
347cbabf03cSDov Murik MODULE_LICENSE("GPL");
348cbabf03cSDov Murik MODULE_ALIAS("platform:efi_secret");
349