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