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