efi_loader: use %pUs for printing GUIDs
[platform/kernel/u-boot.git] / lib / efi_loader / efi_var_common.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * UEFI runtime variable services
4  *
5  * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
6  * Copyright (c) 2020 Linaro Limited, Author: AKASHI Takahiro
7  */
8
9 #include <common.h>
10 #include <efi_loader.h>
11 #include <efi_variable.h>
12 #include <stdlib.h>
13
14 enum efi_secure_mode {
15         EFI_MODE_SETUP,
16         EFI_MODE_USER,
17         EFI_MODE_AUDIT,
18         EFI_MODE_DEPLOYED,
19 };
20
21 struct efi_auth_var_name_type {
22         const u16 *name;
23         const efi_guid_t *guid;
24         const enum efi_auth_var_type type;
25 };
26
27 const efi_guid_t efi_guid_image_security_database =
28                 EFI_IMAGE_SECURITY_DATABASE_GUID;
29
30 static const struct efi_auth_var_name_type name_type[] = {
31         {u"PK", &efi_global_variable_guid, EFI_AUTH_VAR_PK},
32         {u"KEK", &efi_global_variable_guid, EFI_AUTH_VAR_KEK},
33         {u"db",  &efi_guid_image_security_database, EFI_AUTH_VAR_DB},
34         {u"dbx",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBX},
35         {u"dbt",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBT},
36         {u"dbr",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBR},
37         {u"AuditMode", &efi_global_variable_guid, EFI_AUTH_MODE},
38         {u"DeployedMode", &efi_global_variable_guid, EFI_AUTH_MODE},
39 };
40
41 static bool efi_secure_boot;
42 static enum efi_secure_mode efi_secure_mode;
43
44 /**
45  * efi_efi_get_variable() - retrieve value of a UEFI variable
46  *
47  * This function implements the GetVariable runtime service.
48  *
49  * See the Unified Extensible Firmware Interface (UEFI) specification for
50  * details.
51  *
52  * @variable_name:      name of the variable
53  * @vendor:             vendor GUID
54  * @attributes:         attributes of the variable
55  * @data_size:          size of the buffer to which the variable value is copied
56  * @data:               buffer to which the variable value is copied
57  * Return:              status code
58  */
59 efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
60                                      const efi_guid_t *vendor, u32 *attributes,
61                                      efi_uintn_t *data_size, void *data)
62 {
63         efi_status_t ret;
64
65         EFI_ENTRY("\"%ls\" %pUs %p %p %p", variable_name, vendor, attributes,
66                   data_size, data);
67
68         ret = efi_get_variable_int(variable_name, vendor, attributes,
69                                    data_size, data, NULL);
70
71         /* Remove EFI_VARIABLE_READ_ONLY flag */
72         if (attributes)
73                 *attributes &= EFI_VARIABLE_MASK;
74
75         return EFI_EXIT(ret);
76 }
77
78 /**
79  * efi_set_variable() - set value of a UEFI variable
80  *
81  * This function implements the SetVariable runtime service.
82  *
83  * See the Unified Extensible Firmware Interface (UEFI) specification for
84  * details.
85  *
86  * @variable_name:      name of the variable
87  * @vendor:             vendor GUID
88  * @attributes:         attributes of the variable
89  * @data_size:          size of the buffer with the variable value
90  * @data:               buffer with the variable value
91  * Return:              status code
92  */
93 efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
94                                      const efi_guid_t *vendor, u32 attributes,
95                                      efi_uintn_t data_size, const void *data)
96 {
97         efi_status_t ret;
98
99         EFI_ENTRY("\"%ls\" %pUs %x %zu %p", variable_name, vendor, attributes,
100                   data_size, data);
101
102         /* Make sure that the EFI_VARIABLE_READ_ONLY flag is not set */
103         if (attributes & ~(u32)EFI_VARIABLE_MASK)
104                 ret = EFI_INVALID_PARAMETER;
105         else
106                 ret = efi_set_variable_int(variable_name, vendor, attributes,
107                                            data_size, data, true);
108
109         return EFI_EXIT(ret);
110 }
111
112 /**
113  * efi_get_next_variable_name() - enumerate the current variable names
114  *
115  * @variable_name_size: size of variable_name buffer in byte
116  * @variable_name:      name of uefi variable's name in u16
117  * @vendor:             vendor's guid
118  *
119  * See the Unified Extensible Firmware Interface (UEFI) specification for
120  * details.
121  *
122  * Return: status code
123  */
124 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
125                                                u16 *variable_name,
126                                                efi_guid_t *vendor)
127 {
128         efi_status_t ret;
129
130         EFI_ENTRY("%p \"%ls\" %pUs", variable_name_size, variable_name, vendor);
131
132         ret = efi_get_next_variable_name_int(variable_name_size, variable_name,
133                                              vendor);
134
135         return EFI_EXIT(ret);
136 }
137
138 /**
139  * efi_query_variable_info() - get information about EFI variables
140  *
141  * This function implements the QueryVariableInfo() runtime service.
142  *
143  * See the Unified Extensible Firmware Interface (UEFI) specification for
144  * details.
145  *
146  * @attributes:                         bitmask to select variables to be
147  *                                      queried
148  * @maximum_variable_storage_size:      maximum size of storage area for the
149  *                                      selected variable types
150  * @remaining_variable_storage_size:    remaining size of storage are for the
151  *                                      selected variable types
152  * @maximum_variable_size:              maximum size of a variable of the
153  *                                      selected type
154  * Returns:                             status code
155  */
156 efi_status_t EFIAPI efi_query_variable_info(
157                         u32 attributes, u64 *maximum_variable_storage_size,
158                         u64 *remaining_variable_storage_size,
159                         u64 *maximum_variable_size)
160 {
161         efi_status_t ret;
162
163         EFI_ENTRY("%x %p %p %p", attributes, maximum_variable_storage_size,
164                   remaining_variable_storage_size, maximum_variable_size);
165
166         if (!maximum_variable_storage_size ||
167             !remaining_variable_storage_size ||
168             !maximum_variable_size ||
169             !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))
170                 return EFI_EXIT(EFI_INVALID_PARAMETER);
171
172         if ((attributes & ~(u32)EFI_VARIABLE_MASK) ||
173             (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) ||
174             (attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) ||
175             (!IS_ENABLED(CONFIG_EFI_SECURE_BOOT) &&
176              (attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)))
177                 return EFI_EXIT(EFI_UNSUPPORTED);
178
179         ret = efi_query_variable_info_int(attributes,
180                                           maximum_variable_storage_size,
181                                           remaining_variable_storage_size,
182                                           maximum_variable_size);
183
184         return EFI_EXIT(ret);
185 }
186
187 efi_status_t __efi_runtime EFIAPI
188 efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *guid,
189                          u32 *attributes, efi_uintn_t *data_size, void *data)
190 {
191         efi_status_t ret;
192
193         ret = efi_get_variable_mem(variable_name, guid, attributes, data_size, data, NULL);
194
195         /* Remove EFI_VARIABLE_READ_ONLY flag */
196         if (attributes)
197                 *attributes &= EFI_VARIABLE_MASK;
198
199         return ret;
200 }
201
202 efi_status_t __efi_runtime EFIAPI
203 efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
204                                    u16 *variable_name, efi_guid_t *guid)
205 {
206         return efi_get_next_variable_name_mem(variable_name_size, variable_name, guid);
207 }
208
209 /**
210  * efi_set_secure_state - modify secure boot state variables
211  * @secure_boot:        value of SecureBoot
212  * @setup_mode:         value of SetupMode
213  * @audit_mode:         value of AuditMode
214  * @deployed_mode:      value of DeployedMode
215  *
216  * Modify secure boot status related variables as indicated.
217  *
218  * Return:              status code
219  */
220 static efi_status_t efi_set_secure_state(u8 secure_boot, u8 setup_mode,
221                                          u8 audit_mode, u8 deployed_mode)
222 {
223         efi_status_t ret;
224         const u32 attributes_ro = EFI_VARIABLE_BOOTSERVICE_ACCESS |
225                                   EFI_VARIABLE_RUNTIME_ACCESS |
226                                   EFI_VARIABLE_READ_ONLY;
227         const u32 attributes_rw = EFI_VARIABLE_BOOTSERVICE_ACCESS |
228                                   EFI_VARIABLE_RUNTIME_ACCESS;
229
230         efi_secure_boot = secure_boot;
231
232         ret = efi_set_variable_int(L"SecureBoot", &efi_global_variable_guid,
233                                    attributes_ro, sizeof(secure_boot),
234                                    &secure_boot, false);
235         if (ret != EFI_SUCCESS)
236                 goto err;
237
238         ret = efi_set_variable_int(L"SetupMode", &efi_global_variable_guid,
239                                    attributes_ro, sizeof(setup_mode),
240                                    &setup_mode, false);
241         if (ret != EFI_SUCCESS)
242                 goto err;
243
244         ret = efi_set_variable_int(L"AuditMode", &efi_global_variable_guid,
245                                    audit_mode || setup_mode ?
246                                    attributes_ro : attributes_rw,
247                                    sizeof(audit_mode), &audit_mode, false);
248         if (ret != EFI_SUCCESS)
249                 goto err;
250
251         ret = efi_set_variable_int(L"DeployedMode",
252                                    &efi_global_variable_guid,
253                                    audit_mode || deployed_mode || setup_mode ?
254                                    attributes_ro : attributes_rw,
255                                    sizeof(deployed_mode), &deployed_mode,
256                                    false);
257 err:
258         return ret;
259 }
260
261 /**
262  * efi_transfer_secure_state - handle a secure boot state transition
263  * @mode:       new state
264  *
265  * Depending on @mode, secure boot related variables are updated.
266  * Those variables are *read-only* for users, efi_set_variable_int()
267  * is called here.
268  *
269  * Return:      status code
270  */
271 static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode)
272 {
273         efi_status_t ret;
274
275         EFI_PRINT("Switching secure state from %d to %d\n", efi_secure_mode,
276                   mode);
277
278         if (mode == EFI_MODE_DEPLOYED) {
279                 ret = efi_set_secure_state(1, 0, 0, 1);
280                 if (ret != EFI_SUCCESS)
281                         goto err;
282         } else if (mode == EFI_MODE_AUDIT) {
283                 ret = efi_set_variable_int(L"PK", &efi_global_variable_guid,
284                                            EFI_VARIABLE_BOOTSERVICE_ACCESS |
285                                            EFI_VARIABLE_RUNTIME_ACCESS,
286                                            0, NULL, false);
287                 if (ret != EFI_SUCCESS)
288                         goto err;
289
290                 ret = efi_set_secure_state(0, 1, 1, 0);
291                 if (ret != EFI_SUCCESS)
292                         goto err;
293         } else if (mode == EFI_MODE_USER) {
294                 ret = efi_set_secure_state(1, 0, 0, 0);
295                 if (ret != EFI_SUCCESS)
296                         goto err;
297         } else if (mode == EFI_MODE_SETUP) {
298                 ret = efi_set_secure_state(0, 1, 0, 0);
299                 if (ret != EFI_SUCCESS)
300                         goto err;
301         } else {
302                 return EFI_INVALID_PARAMETER;
303         }
304
305         efi_secure_mode = mode;
306
307         return EFI_SUCCESS;
308
309 err:
310         /* TODO: What action should be taken here? */
311         printf("ERROR: Secure state transition failed\n");
312         return ret;
313 }
314
315 efi_status_t efi_init_secure_state(void)
316 {
317         enum efi_secure_mode mode;
318         u8 efi_vendor_keys = 0;
319         efi_uintn_t size;
320         efi_status_t ret;
321         u8 deployed_mode = 0;
322         u8 audit_mode = 0;
323         u8 setup_mode = 1;
324
325         if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) {
326                 size = sizeof(deployed_mode);
327                 ret = efi_get_variable_int(u"DeployedMode", &efi_global_variable_guid,
328                                            NULL, &size, &deployed_mode, NULL);
329                 size = sizeof(audit_mode);
330                 ret = efi_get_variable_int(u"AuditMode", &efi_global_variable_guid,
331                                            NULL, &size, &audit_mode, NULL);
332                 size = 0;
333                 ret = efi_get_variable_int(u"PK", &efi_global_variable_guid,
334                                            NULL, &size, NULL, NULL);
335                 if (ret == EFI_BUFFER_TOO_SMALL) {
336                         setup_mode = 0;
337                         audit_mode = 0;
338                 } else {
339                         setup_mode = 1;
340                         deployed_mode = 0;
341                 }
342         }
343         if (deployed_mode)
344                 mode = EFI_MODE_DEPLOYED;
345         else if (audit_mode)
346                 mode = EFI_MODE_AUDIT;
347         else if (setup_mode)
348                 mode = EFI_MODE_SETUP;
349         else
350                 mode = EFI_MODE_USER;
351
352         ret = efi_transfer_secure_state(mode);
353         if (ret != EFI_SUCCESS)
354                 return ret;
355
356         /* As we do not provide vendor keys this variable is always 0. */
357         ret = efi_set_variable_int(L"VendorKeys",
358                                    &efi_global_variable_guid,
359                                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
360                                    EFI_VARIABLE_RUNTIME_ACCESS |
361                                    EFI_VARIABLE_READ_ONLY,
362                                    sizeof(efi_vendor_keys),
363                                    &efi_vendor_keys, false);
364         return ret;
365 }
366
367 /**
368  * efi_secure_boot_enabled - return if secure boot is enabled or not
369  *
370  * Return:      true if enabled, false if disabled
371  */
372 bool efi_secure_boot_enabled(void)
373 {
374         return efi_secure_boot;
375 }
376
377 enum efi_auth_var_type efi_auth_var_get_type(const u16 *name,
378                                              const efi_guid_t *guid)
379 {
380         for (size_t i = 0; i < ARRAY_SIZE(name_type); ++i) {
381                 if (!u16_strcmp(name, name_type[i].name) &&
382                     !guidcmp(guid, name_type[i].guid))
383                         return name_type[i].type;
384         }
385         return EFI_AUTH_VAR_NONE;
386 }
387
388 const efi_guid_t *efi_auth_var_get_guid(const u16 *name)
389 {
390         for (size_t i = 0; i < ARRAY_SIZE(name_type); ++i) {
391                 if (!u16_strcmp(name, name_type[i].name))
392                         return name_type[i].guid;
393         }
394         return &efi_global_variable_guid;
395 }
396
397 /**
398  * efi_get_var() - read value of an EFI variable
399  *
400  * @name:       variable name
401  * @start:      vendor GUID
402  * @size:       size of allocated buffer
403  *
404  * Return:      buffer with variable data or NULL
405  */
406 void *efi_get_var(const u16 *name, const efi_guid_t *vendor, efi_uintn_t *size)
407 {
408         efi_status_t ret;
409         void *buf = NULL;
410
411         *size = 0;
412         ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL);
413         if (ret == EFI_BUFFER_TOO_SMALL) {
414                 buf = malloc(*size);
415                 if (!buf)
416                         return NULL;
417                 ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL);
418         }
419
420         if (ret != EFI_SUCCESS) {
421                 free(buf);
422                 *size = 0;
423                 return NULL;
424         }
425
426         return buf;
427 }