Merge git://git.denx.de/u-boot-usb
[oweals/u-boot.git] / lib / efi_loader / efi_variable.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * UEFI runtime variable services
4  *
5  * Copyright (c) 2017 Rob Clark
6  */
7
8 #include <common.h>
9 #include <efi_loader.h>
10 #include <env_internal.h>
11 #include <hexdump.h>
12 #include <malloc.h>
13 #include <rtc.h>
14 #include <search.h>
15 #include <crypto/pkcs7_parser.h>
16 #include <linux/compat.h>
17 #include <u-boot/crc.h>
18
19 enum efi_secure_mode {
20         EFI_MODE_SETUP,
21         EFI_MODE_USER,
22         EFI_MODE_AUDIT,
23         EFI_MODE_DEPLOYED,
24 };
25
26 const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
27 static bool efi_secure_boot;
28 static int efi_secure_mode;
29 static u8 efi_vendor_keys;
30
31 #define READ_ONLY BIT(31)
32
33 /*
34  * Mapping between EFI variables and u-boot variables:
35  *
36  *   efi_$guid_$varname = {attributes}(type)value
37  *
38  * For example:
39  *
40  *   efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported=
41  *      "{ro,boot,run}(blob)0000000000000000"
42  *   efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder=
43  *      "(blob)00010000"
44  *
45  * The attributes are a comma separated list of these possible
46  * attributes:
47  *
48  *   + ro   - read-only
49  *   + boot - boot-services access
50  *   + run  - runtime access
51  *
52  * NOTE: with current implementation, no variables are available after
53  * ExitBootServices, and all are persisted (if possible).
54  *
55  * If not specified, the attributes default to "{boot}".
56  *
57  * The required type is one of:
58  *
59  *   + utf8 - raw utf8 string
60  *   + blob - arbitrary length hex string
61  *
62  * Maybe a utf16 type would be useful to for a string value to be auto
63  * converted to utf16?
64  */
65
66 #define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_"))
67
68 /**
69  * efi_to_native() - convert the UEFI variable name and vendor GUID to U-Boot
70  *                   variable name
71  *
72  * The U-Boot variable name is a concatenation of prefix 'efi', the hexstring
73  * encoded vendor GUID, and the UTF-8 encoded UEFI variable name separated by
74  * underscores, e.g. 'efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder'.
75  *
76  * @native:             pointer to pointer to U-Boot variable name
77  * @variable_name:      UEFI variable name
78  * @vendor:             vendor GUID
79  * Return:              status code
80  */
81 static efi_status_t efi_to_native(char **native, const u16 *variable_name,
82                                   const efi_guid_t *vendor)
83 {
84         size_t len;
85         char *pos;
86
87         len = PREFIX_LEN + utf16_utf8_strlen(variable_name) + 1;
88         *native = malloc(len);
89         if (!*native)
90                 return EFI_OUT_OF_RESOURCES;
91
92         pos = *native;
93         pos += sprintf(pos, "efi_%pUl_", vendor);
94         utf16_utf8_strcpy(&pos, variable_name);
95
96         return EFI_SUCCESS;
97 }
98
99 /**
100  * prefix() - skip over prefix
101  *
102  * Skip over a prefix string.
103  *
104  * @str:        string with prefix
105  * @prefix:     prefix string
106  * Return:      string without prefix, or NULL if prefix not found
107  */
108 static const char *prefix(const char *str, const char *prefix)
109 {
110         size_t n = strlen(prefix);
111         if (!strncmp(prefix, str, n))
112                 return str + n;
113         return NULL;
114 }
115
116 /**
117  * parse_attr() - decode attributes part of variable value
118  *
119  * Convert the string encoded attributes of a UEFI variable to a bit mask.
120  * TODO: Several attributes are not supported.
121  *
122  * @str:        value of U-Boot variable
123  * @attrp:      pointer to UEFI attributes
124  * @timep:      pointer to time attribute
125  * Return:      pointer to remainder of U-Boot variable value
126  */
127 static const char *parse_attr(const char *str, u32 *attrp, u64 *timep)
128 {
129         u32 attr = 0;
130         char sep = '{';
131
132         if (*str != '{') {
133                 *attrp = EFI_VARIABLE_BOOTSERVICE_ACCESS;
134                 return str;
135         }
136
137         while (*str == sep) {
138                 const char *s;
139
140                 str++;
141
142                 if ((s = prefix(str, "ro"))) {
143                         attr |= READ_ONLY;
144                 } else if ((s = prefix(str, "nv"))) {
145                         attr |= EFI_VARIABLE_NON_VOLATILE;
146                 } else if ((s = prefix(str, "boot"))) {
147                         attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
148                 } else if ((s = prefix(str, "run"))) {
149                         attr |= EFI_VARIABLE_RUNTIME_ACCESS;
150                 } else if ((s = prefix(str, "time="))) {
151                         attr |= EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
152                         hex2bin((u8 *)timep, s, sizeof(*timep));
153                         s += sizeof(*timep) * 2;
154                 } else if (*str == '}') {
155                         break;
156                 } else {
157                         printf("invalid attribute: %s\n", str);
158                         break;
159                 }
160
161                 str = s;
162                 sep = ',';
163         }
164
165         str++;
166
167         *attrp = attr;
168
169         return str;
170 }
171
172 static efi_status_t efi_set_variable_common(u16 *variable_name,
173                                             const efi_guid_t *vendor,
174                                             u32 attributes,
175                                             efi_uintn_t data_size,
176                                             const void *data,
177                                             bool ro_check);
178
179 /**
180  * efi_set_secure_state - modify secure boot state variables
181  * @sec_boot:           value of SecureBoot
182  * @setup_mode:         value of SetupMode
183  * @audit_mode:         value of AuditMode
184  * @deployed_mode:      value of DeployedMode
185  *
186  * Modify secure boot stat-related variables as indicated.
187  *
188  * Return:              status code
189  */
190 static efi_status_t efi_set_secure_state(int sec_boot, int setup_mode,
191                                          int audit_mode, int deployed_mode)
192 {
193         u32 attributes;
194         efi_status_t ret;
195
196         attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
197                      EFI_VARIABLE_RUNTIME_ACCESS |
198                      READ_ONLY;
199         ret = efi_set_variable_common(L"SecureBoot", &efi_global_variable_guid,
200                                       attributes, sizeof(sec_boot), &sec_boot,
201                                       false);
202         if (ret != EFI_SUCCESS)
203                 goto err;
204
205         ret = efi_set_variable_common(L"SetupMode", &efi_global_variable_guid,
206                                       attributes, sizeof(setup_mode),
207                                       &setup_mode, false);
208         if (ret != EFI_SUCCESS)
209                 goto err;
210
211         ret = efi_set_variable_common(L"AuditMode", &efi_global_variable_guid,
212                                       attributes, sizeof(audit_mode),
213                                       &audit_mode, false);
214         if (ret != EFI_SUCCESS)
215                 goto err;
216
217         ret = efi_set_variable_common(L"DeployedMode",
218                                       &efi_global_variable_guid, attributes,
219                                       sizeof(deployed_mode), &deployed_mode,
220                                       false);
221 err:
222         return ret;
223 }
224
225 /**
226  * efi_transfer_secure_state - handle a secure boot state transition
227  * @mode:       new state
228  *
229  * Depending on @mode, secure boot related variables are updated.
230  * Those variables are *read-only* for users, efi_set_variable_common()
231  * is called here.
232  *
233  * Return:      status code
234  */
235 static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode)
236 {
237         efi_status_t ret;
238
239         debug("Switching secure state from %d to %d\n", efi_secure_mode, mode);
240
241         if (mode == EFI_MODE_DEPLOYED) {
242                 ret = efi_set_secure_state(1, 0, 0, 1);
243                 if (ret != EFI_SUCCESS)
244                         goto err;
245
246                 efi_secure_boot = true;
247         } else if (mode == EFI_MODE_AUDIT) {
248                 ret = efi_set_variable_common(L"PK", &efi_global_variable_guid,
249                                               EFI_VARIABLE_BOOTSERVICE_ACCESS |
250                                               EFI_VARIABLE_RUNTIME_ACCESS,
251                                               0, NULL, false);
252                 if (ret != EFI_SUCCESS)
253                         goto err;
254
255                 ret = efi_set_secure_state(0, 1, 1, 0);
256                 if (ret != EFI_SUCCESS)
257                         goto err;
258
259                 efi_secure_boot = true;
260         } else if (mode == EFI_MODE_USER) {
261                 ret = efi_set_secure_state(1, 0, 0, 0);
262                 if (ret != EFI_SUCCESS)
263                         goto err;
264
265                 efi_secure_boot = true;
266         } else if (mode == EFI_MODE_SETUP) {
267                 ret = efi_set_secure_state(0, 1, 0, 0);
268                 if (ret != EFI_SUCCESS)
269                         goto err;
270         } else {
271                 return EFI_INVALID_PARAMETER;
272         }
273
274         efi_secure_mode = mode;
275
276         return EFI_SUCCESS;
277
278 err:
279         /* TODO: What action should be taken here? */
280         printf("ERROR: Secure state transition failed\n");
281         return ret;
282 }
283
284 /**
285  * efi_init_secure_state - initialize secure boot state
286  *
287  * Return:      status code
288  */
289 static efi_status_t efi_init_secure_state(void)
290 {
291         enum efi_secure_mode mode;
292         efi_uintn_t size;
293         efi_status_t ret;
294
295         /*
296          * TODO:
297          * Since there is currently no "platform-specific" installation
298          * method of Platform Key, we can't say if VendorKeys is 0 or 1
299          * precisely.
300          */
301
302         size = 0;
303         ret = EFI_CALL(efi_get_variable(L"PK", &efi_global_variable_guid,
304                                         NULL, &size, NULL));
305         if (ret == EFI_BUFFER_TOO_SMALL) {
306                 if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
307                         mode = EFI_MODE_USER;
308                 else
309                         mode = EFI_MODE_SETUP;
310
311                 efi_vendor_keys = 0;
312         } else if (ret == EFI_NOT_FOUND) {
313                 mode = EFI_MODE_SETUP;
314                 efi_vendor_keys = 1;
315         } else {
316                 goto err;
317         }
318
319         ret = efi_transfer_secure_state(mode);
320         if (ret == EFI_SUCCESS)
321                 ret = efi_set_variable_common(L"VendorKeys",
322                                               &efi_global_variable_guid,
323                                               EFI_VARIABLE_BOOTSERVICE_ACCESS |
324                                               EFI_VARIABLE_RUNTIME_ACCESS |
325                                               READ_ONLY,
326                                               sizeof(efi_vendor_keys),
327                                               &efi_vendor_keys, false);
328
329 err:
330         return ret;
331 }
332
333 /**
334  * efi_secure_boot_enabled - return if secure boot is enabled or not
335  *
336  * Return:      true if enabled, false if disabled
337  */
338 bool efi_secure_boot_enabled(void)
339 {
340         return efi_secure_boot;
341 }
342
343 #ifdef CONFIG_EFI_SECURE_BOOT
344 static u8 pkcs7_hdr[] = {
345         /* SEQUENCE */
346         0x30, 0x82, 0x05, 0xc7,
347         /* OID: pkcs7-signedData */
348         0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
349         /* Context Structured? */
350         0xa0, 0x82, 0x05, 0xb8,
351 };
352
353 /**
354  * efi_variable_parse_signature - parse a signature in variable
355  * @buf:        Pointer to variable's value
356  * @buflen:     Length of @buf
357  *
358  * Parse a signature embedded in variable's value and instantiate
359  * a pkcs7_message structure. Since pkcs7_parse_message() accepts only
360  * pkcs7's signedData, some header needed be prepended for correctly
361  * parsing authentication data, particularly for variable's.
362  *
363  * Return:      Pointer to pkcs7_message structure on success, NULL on error
364  */
365 static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
366                                                           size_t buflen)
367 {
368         u8 *ebuf;
369         size_t ebuflen, len;
370         struct pkcs7_message *msg;
371
372         /*
373          * This is the best assumption to check if the binary is
374          * already in a form of pkcs7's signedData.
375          */
376         if (buflen > sizeof(pkcs7_hdr) &&
377             !memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) {
378                 msg = pkcs7_parse_message(buf, buflen);
379                 goto out;
380         }
381
382         /*
383          * Otherwise, we should add a dummy prefix sequence for pkcs7
384          * message parser to be able to process.
385          * NOTE: EDK2 also uses similar hack in WrapPkcs7Data()
386          * in CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
387          * TODO:
388          * The header should be composed in a more refined manner.
389          */
390         debug("Makeshift prefix added to authentication data\n");
391         ebuflen = sizeof(pkcs7_hdr) + buflen;
392         if (ebuflen <= 0x7f) {
393                 debug("Data is too short\n");
394                 return NULL;
395         }
396
397         ebuf = malloc(ebuflen);
398         if (!ebuf) {
399                 debug("Out of memory\n");
400                 return NULL;
401         }
402
403         memcpy(ebuf, pkcs7_hdr, sizeof(pkcs7_hdr));
404         memcpy(ebuf + sizeof(pkcs7_hdr), buf, buflen);
405         len = ebuflen - 4;
406         ebuf[2] = (len >> 8) & 0xff;
407         ebuf[3] = len & 0xff;
408         len = ebuflen - 0x13;
409         ebuf[0x11] = (len >> 8) & 0xff;
410         ebuf[0x12] = len & 0xff;
411
412         msg = pkcs7_parse_message(ebuf, ebuflen);
413
414         free(ebuf);
415
416 out:
417         if (IS_ERR(msg))
418                 return NULL;
419
420         return msg;
421 }
422
423 /**
424  * efi_variable_authenticate - authenticate a variable
425  * @variable:   Variable name in u16
426  * @vendor:     Guid of variable
427  * @data_size:  Size of @data
428  * @data:       Pointer to variable's value
429  * @given_attr: Attributes to be given at SetVariable()
430  * @env_attr:   Attributes that an existing variable holds
431  * @time:       signed time that an existing variable holds
432  *
433  * Called by efi_set_variable() to verify that the input is correct.
434  * Will replace the given data pointer with another that points to
435  * the actual data to store in the internal memory.
436  * On success, @data and @data_size will be replaced with variable's
437  * actual data, excluding authentication data, and its size, and variable's
438  * attributes and signed time will also be returned in @env_attr and @time,
439  * respectively.
440  *
441  * Return:      status code
442  */
443 static efi_status_t efi_variable_authenticate(u16 *variable,
444                                               const efi_guid_t *vendor,
445                                               efi_uintn_t *data_size,
446                                               const void **data, u32 given_attr,
447                                               u32 *env_attr, u64 *time)
448 {
449         const struct efi_variable_authentication_2 *auth;
450         struct efi_signature_store *truststore, *truststore2;
451         struct pkcs7_message *var_sig;
452         struct efi_image_regions *regs;
453         struct efi_time timestamp;
454         struct rtc_time tm;
455         u64 new_time;
456         efi_status_t ret;
457
458         var_sig = NULL;
459         truststore = NULL;
460         truststore2 = NULL;
461         regs = NULL;
462         ret = EFI_SECURITY_VIOLATION;
463
464         if (*data_size < sizeof(struct efi_variable_authentication_2))
465                 goto err;
466
467         /* authentication data */
468         auth = *data;
469         if (*data_size < (sizeof(auth->time_stamp)
470                                 + auth->auth_info.hdr.dwLength))
471                 goto err;
472
473         if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
474                 goto err;
475
476         *data += sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength;
477         *data_size -= (sizeof(auth->time_stamp)
478                                 + auth->auth_info.hdr.dwLength);
479
480         memcpy(&timestamp, &auth->time_stamp, sizeof(timestamp));
481         memset(&tm, 0, sizeof(tm));
482         tm.tm_year = timestamp.year;
483         tm.tm_mon = timestamp.month;
484         tm.tm_mday = timestamp.day;
485         tm.tm_hour = timestamp.hour;
486         tm.tm_min = timestamp.minute;
487         tm.tm_sec = timestamp.second;
488         new_time = rtc_mktime(&tm);
489
490         if (!efi_secure_boot_enabled()) {
491                 /* finished checking */
492                 *time = new_time;
493                 return EFI_SUCCESS;
494         }
495
496         if (new_time <= *time)
497                 goto err;
498
499         /* data to be digested */
500         regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 5, 1);
501         if (!regs)
502                 goto err;
503         regs->max = 5;
504         efi_image_region_add(regs, (uint8_t *)variable,
505                              (uint8_t *)variable
506                                 + u16_strlen(variable) * sizeof(u16), 1);
507         efi_image_region_add(regs, (uint8_t *)vendor,
508                              (uint8_t *)vendor + sizeof(*vendor), 1);
509         efi_image_region_add(regs, (uint8_t *)&given_attr,
510                              (uint8_t *)&given_attr + sizeof(given_attr), 1);
511         efi_image_region_add(regs, (uint8_t *)&timestamp,
512                              (uint8_t *)&timestamp + sizeof(timestamp), 1);
513         efi_image_region_add(regs, (uint8_t *)*data,
514                              (uint8_t *)*data + *data_size, 1);
515
516         /* variable's signature list */
517         if (auth->auth_info.hdr.dwLength < sizeof(auth->auth_info))
518                 goto err;
519         var_sig = efi_variable_parse_signature(auth->auth_info.cert_data,
520                                                auth->auth_info.hdr.dwLength
521                                                    - sizeof(auth->auth_info));
522         if (IS_ERR(var_sig)) {
523                 debug("Parsing variable's signature failed\n");
524                 var_sig = NULL;
525                 goto err;
526         }
527
528         /* signature database used for authentication */
529         if (u16_strcmp(variable, L"PK") == 0 ||
530             u16_strcmp(variable, L"KEK") == 0) {
531                 /* with PK */
532                 truststore = efi_sigstore_parse_sigdb(L"PK");
533                 if (!truststore)
534                         goto err;
535         } else if (u16_strcmp(variable, L"db") == 0 ||
536                    u16_strcmp(variable, L"dbx") == 0) {
537                 /* with PK and KEK */
538                 truststore = efi_sigstore_parse_sigdb(L"KEK");
539                 truststore2 = efi_sigstore_parse_sigdb(L"PK");
540
541                 if (!truststore) {
542                         if (!truststore2)
543                                 goto err;
544
545                         truststore = truststore2;
546                         truststore2 = NULL;
547                 }
548         } else {
549                 /* TODO: support private authenticated variables */
550                 goto err;
551         }
552
553         /* verify signature */
554         if (efi_signature_verify_with_sigdb(regs, var_sig, truststore, NULL)) {
555                 debug("Verified\n");
556         } else {
557                 if (truststore2 &&
558                     efi_signature_verify_with_sigdb(regs, var_sig,
559                                                     truststore2, NULL)) {
560                         debug("Verified\n");
561                 } else {
562                         debug("Verifying variable's signature failed\n");
563                         goto err;
564                 }
565         }
566
567         /* finished checking */
568         *time = rtc_mktime(&tm);
569         ret = EFI_SUCCESS;
570
571 err:
572         efi_sigstore_free(truststore);
573         efi_sigstore_free(truststore2);
574         pkcs7_free_message(var_sig);
575         free(regs);
576
577         return ret;
578 }
579 #else
580 static efi_status_t efi_variable_authenticate(u16 *variable,
581                                               const efi_guid_t *vendor,
582                                               efi_uintn_t *data_size,
583                                               const void **data, u32 given_attr,
584                                               u32 *env_attr, u64 *time)
585 {
586         return EFI_SUCCESS;
587 }
588 #endif /* CONFIG_EFI_SECURE_BOOT */
589
590 static
591 efi_status_t EFIAPI efi_get_variable_common(u16 *variable_name,
592                                             const efi_guid_t *vendor,
593                                             u32 *attributes,
594                                             efi_uintn_t *data_size, void *data)
595 {
596         char *native_name;
597         efi_status_t ret;
598         unsigned long in_size;
599         const char *val = NULL, *s;
600         u64 time = 0;
601         u32 attr;
602
603         if (!variable_name || !vendor || !data_size)
604                 return EFI_EXIT(EFI_INVALID_PARAMETER);
605
606         ret = efi_to_native(&native_name, variable_name, vendor);
607         if (ret)
608                 return ret;
609
610         EFI_PRINT("get '%s'\n", native_name);
611
612         val = env_get(native_name);
613         free(native_name);
614         if (!val)
615                 return EFI_NOT_FOUND;
616
617         val = parse_attr(val, &attr, &time);
618
619         in_size = *data_size;
620
621         if ((s = prefix(val, "(blob)"))) {
622                 size_t len = strlen(s);
623
624                 /* number of hexadecimal digits must be even */
625                 if (len & 1)
626                         return EFI_DEVICE_ERROR;
627
628                 /* two characters per byte: */
629                 len /= 2;
630                 *data_size = len;
631
632                 if (in_size < len) {
633                         ret = EFI_BUFFER_TOO_SMALL;
634                         goto out;
635                 }
636
637                 if (!data) {
638                         debug("Variable with no data shouldn't exist.\n");
639                         return EFI_INVALID_PARAMETER;
640                 }
641
642                 if (hex2bin(data, s, len))
643                         return EFI_DEVICE_ERROR;
644
645                 EFI_PRINT("got value: \"%s\"\n", s);
646         } else if ((s = prefix(val, "(utf8)"))) {
647                 unsigned len = strlen(s) + 1;
648
649                 *data_size = len;
650
651                 if (in_size < len) {
652                         ret = EFI_BUFFER_TOO_SMALL;
653                         goto out;
654                 }
655
656                 if (!data) {
657                         debug("Variable with no data shouldn't exist.\n");
658                         return EFI_INVALID_PARAMETER;
659                 }
660
661                 memcpy(data, s, len);
662                 ((char *)data)[len] = '\0';
663
664                 EFI_PRINT("got value: \"%s\"\n", (char *)data);
665         } else {
666                 EFI_PRINT("invalid value: '%s'\n", val);
667                 return EFI_DEVICE_ERROR;
668         }
669
670 out:
671         if (attributes)
672                 *attributes = attr & EFI_VARIABLE_MASK;
673
674         return ret;
675 }
676
677 /**
678  * efi_efi_get_variable() - retrieve value of a UEFI variable
679  *
680  * This function implements the GetVariable runtime service.
681  *
682  * See the Unified Extensible Firmware Interface (UEFI) specification for
683  * details.
684  *
685  * @variable_name:      name of the variable
686  * @vendor:             vendor GUID
687  * @attributes:         attributes of the variable
688  * @data_size:          size of the buffer to which the variable value is copied
689  * @data:               buffer to which the variable value is copied
690  * Return:              status code
691  */
692 efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
693                                      const efi_guid_t *vendor, u32 *attributes,
694                                      efi_uintn_t *data_size, void *data)
695 {
696         efi_status_t ret;
697
698         EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes,
699                   data_size, data);
700
701         ret = efi_get_variable_common(variable_name, vendor, attributes,
702                                       data_size, data);
703         return EFI_EXIT(ret);
704 }
705
706 static char *efi_variables_list;
707 static char *efi_cur_variable;
708
709 /**
710  * parse_uboot_variable() - parse a u-boot variable and get uefi-related
711  *                          information
712  * @variable:           whole data of u-boot variable (ie. name=value)
713  * @variable_name_size: size of variable_name buffer in byte
714  * @variable_name:      name of uefi variable in u16, null-terminated
715  * @vendor:             vendor's guid
716  * @attributes:         attributes
717  *
718  * A uefi variable is encoded into a u-boot variable as described above.
719  * This function parses such a u-boot variable and retrieve uefi-related
720  * information into respective parameters. In return, variable_name_size
721  * is the size of variable name including NULL.
722  *
723  * Return:              EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when
724  *                      the entire variable list has been returned,
725  *                      otherwise non-zero status code
726  */
727 static efi_status_t parse_uboot_variable(char *variable,
728                                          efi_uintn_t *variable_name_size,
729                                          u16 *variable_name,
730                                          const efi_guid_t *vendor,
731                                          u32 *attributes)
732 {
733         char *guid, *name, *end, c;
734         size_t name_len;
735         efi_uintn_t old_variable_name_size;
736         u64 time;
737         u16 *p;
738
739         guid = strchr(variable, '_');
740         if (!guid)
741                 return EFI_INVALID_PARAMETER;
742         guid++;
743         name = strchr(guid, '_');
744         if (!name)
745                 return EFI_INVALID_PARAMETER;
746         name++;
747         end = strchr(name, '=');
748         if (!end)
749                 return EFI_INVALID_PARAMETER;
750
751         name_len = end - name;
752         old_variable_name_size = *variable_name_size;
753         *variable_name_size = sizeof(u16) * (name_len + 1);
754         if (old_variable_name_size < *variable_name_size)
755                 return EFI_BUFFER_TOO_SMALL;
756
757         end++; /* point to value */
758
759         /* variable name */
760         p = variable_name;
761         utf8_utf16_strncpy(&p, name, name_len);
762         variable_name[name_len] = 0;
763
764         /* guid */
765         c = *(name - 1);
766         *(name - 1) = '\0'; /* guid need be null-terminated here */
767         uuid_str_to_bin(guid, (unsigned char *)vendor, UUID_STR_FORMAT_GUID);
768         *(name - 1) = c;
769
770         /* attributes */
771         parse_attr(end, attributes, &time);
772
773         return EFI_SUCCESS;
774 }
775
776 /**
777  * efi_get_next_variable_name() - enumerate the current variable names
778  *
779  * @variable_name_size: size of variable_name buffer in byte
780  * @variable_name:      name of uefi variable's name in u16
781  * @vendor:             vendor's guid
782  *
783  * This function implements the GetNextVariableName service.
784  *
785  * See the Unified Extensible Firmware Interface (UEFI) specification for
786  * details.
787  *
788  * Return: status code
789  */
790 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
791                                                u16 *variable_name,
792                                                efi_guid_t *vendor)
793 {
794         char *native_name, *variable;
795         ssize_t name_len, list_len;
796         char regex[256];
797         char * const regexlist[] = {regex};
798         u32 attributes;
799         int i;
800         efi_status_t ret;
801
802         EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
803
804         if (!variable_name_size || !variable_name || !vendor)
805                 return EFI_EXIT(EFI_INVALID_PARAMETER);
806
807         if (variable_name[0]) {
808                 /* check null-terminated string */
809                 for (i = 0; i < *variable_name_size; i++)
810                         if (!variable_name[i])
811                                 break;
812                 if (i >= *variable_name_size)
813                         return EFI_EXIT(EFI_INVALID_PARAMETER);
814
815                 /* search for the last-returned variable */
816                 ret = efi_to_native(&native_name, variable_name, vendor);
817                 if (ret)
818                         return EFI_EXIT(ret);
819
820                 name_len = strlen(native_name);
821                 for (variable = efi_variables_list; variable && *variable;) {
822                         if (!strncmp(variable, native_name, name_len) &&
823                             variable[name_len] == '=')
824                                 break;
825
826                         variable = strchr(variable, '\n');
827                         if (variable)
828                                 variable++;
829                 }
830
831                 free(native_name);
832                 if (!(variable && *variable))
833                         return EFI_EXIT(EFI_INVALID_PARAMETER);
834
835                 /* next variable */
836                 variable = strchr(variable, '\n');
837                 if (variable)
838                         variable++;
839                 if (!(variable && *variable))
840                         return EFI_EXIT(EFI_NOT_FOUND);
841         } else {
842                 /*
843                  *new search: free a list used in the previous search
844                  */
845                 free(efi_variables_list);
846                 efi_variables_list = NULL;
847                 efi_cur_variable = NULL;
848
849                 snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*");
850                 list_len = hexport_r(&env_htab, '\n',
851                                      H_MATCH_REGEX | H_MATCH_KEY,
852                                      &efi_variables_list, 0, 1, regexlist);
853
854                 if (list_len <= 1)
855                         return EFI_EXIT(EFI_NOT_FOUND);
856
857                 variable = efi_variables_list;
858         }
859
860         ret = parse_uboot_variable(variable, variable_name_size, variable_name,
861                                    vendor, &attributes);
862
863         return EFI_EXIT(ret);
864 }
865
866 static efi_status_t efi_set_variable_common(u16 *variable_name,
867                                             const efi_guid_t *vendor,
868                                             u32 attributes,
869                                             efi_uintn_t data_size,
870                                             const void *data,
871                                             bool ro_check)
872 {
873         char *native_name = NULL, *old_data = NULL, *val = NULL, *s;
874         efi_uintn_t old_size;
875         bool append, delete;
876         u64 time = 0;
877         u32 attr;
878         efi_status_t ret = EFI_SUCCESS;
879
880         debug("%s: set '%s'\n", __func__, native_name);
881
882         if (!variable_name || !*variable_name || !vendor ||
883             ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
884              !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) {
885                 ret = EFI_INVALID_PARAMETER;
886                 goto err;
887         }
888
889         ret = efi_to_native(&native_name, variable_name, vendor);
890         if (ret)
891                 goto err;
892
893         /* check if a variable exists */
894         old_size = 0;
895         attr = 0;
896         ret = EFI_CALL(efi_get_variable(variable_name, vendor, &attr,
897                                         &old_size, NULL));
898         append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
899         attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
900         delete = !append && (!data_size || !attributes);
901
902         /* check attributes */
903         if (old_size) {
904                 if (ro_check && (attr & READ_ONLY)) {
905                         ret = EFI_WRITE_PROTECTED;
906                         goto err;
907                 }
908
909                 /* attributes won't be changed */
910                 if (!delete &&
911                     ((ro_check && attr != attributes) ||
912                      (!ro_check && ((attr & ~(u32)READ_ONLY)
913                                     != (attributes & ~(u32)READ_ONLY))))) {
914                         ret = EFI_INVALID_PARAMETER;
915                         goto err;
916                 }
917         } else {
918                 if (delete || append) {
919                         /*
920                          * Trying to delete or to update a non-existent
921                          * variable.
922                          */
923                         ret = EFI_NOT_FOUND;
924                         goto err;
925                 }
926         }
927
928         if (((!u16_strcmp(variable_name, L"PK") ||
929               !u16_strcmp(variable_name, L"KEK")) &&
930                 !guidcmp(vendor, &efi_global_variable_guid)) ||
931             ((!u16_strcmp(variable_name, L"db") ||
932               !u16_strcmp(variable_name, L"dbx")) &&
933                 !guidcmp(vendor, &efi_guid_image_security_database))) {
934                 /* authentication is mandatory */
935                 if (!(attributes &
936                       EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
937                         debug("%ls: AUTHENTICATED_WRITE_ACCESS required\n",
938                               variable_name);
939                         ret = EFI_INVALID_PARAMETER;
940                         goto err;
941                 }
942         }
943
944         /* authenticate a variable */
945         if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) {
946                 if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
947                         ret = EFI_INVALID_PARAMETER;
948                         goto err;
949                 }
950                 if (attributes &
951                     EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
952                         ret = efi_variable_authenticate(variable_name, vendor,
953                                                         &data_size, &data,
954                                                         attributes, &attr,
955                                                         &time);
956                         if (ret != EFI_SUCCESS)
957                                 goto err;
958
959                         /* last chance to check for delete */
960                         if (!data_size)
961                                 delete = true;
962                 }
963         } else {
964                 if (attributes &
965                     (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
966                      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
967                         debug("Secure boot is not configured\n");
968                         ret = EFI_INVALID_PARAMETER;
969                         goto err;
970                 }
971         }
972
973         /* delete a variable */
974         if (delete) {
975                 /* !old_size case has been handled before */
976                 val = NULL;
977                 ret = EFI_SUCCESS;
978                 goto out;
979         }
980
981         if (append) {
982                 old_data = malloc(old_size);
983                 if (!old_data) {
984                         return EFI_OUT_OF_RESOURCES;
985                         goto err;
986                 }
987                 ret = EFI_CALL(efi_get_variable(variable_name, vendor,
988                                                 &attr, &old_size, old_data));
989                 if (ret != EFI_SUCCESS)
990                         goto err;
991         } else {
992                 old_size = 0;
993         }
994
995         val = malloc(2 * old_size + 2 * data_size
996                      + strlen("{ro,run,boot,nv,time=0123456701234567}(blob)")
997                      + 1);
998         if (!val) {
999                 ret = EFI_OUT_OF_RESOURCES;
1000                 goto err;
1001         }
1002
1003         s = val;
1004
1005         /*
1006          * store attributes
1007          */
1008         attributes &= (READ_ONLY |
1009                        EFI_VARIABLE_NON_VOLATILE |
1010                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
1011                        EFI_VARIABLE_RUNTIME_ACCESS |
1012                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
1013         s += sprintf(s, "{");
1014         while (attributes) {
1015                 attr = 1 << (ffs(attributes) - 1);
1016
1017                 if (attr == READ_ONLY) {
1018                         s += sprintf(s, "ro");
1019                 } else if (attr == EFI_VARIABLE_NON_VOLATILE) {
1020                         s += sprintf(s, "nv");
1021                 } else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) {
1022                         s += sprintf(s, "boot");
1023                 } else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) {
1024                         s += sprintf(s, "run");
1025                 } else if (attr ==
1026                            EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
1027                         s += sprintf(s, "time=");
1028                         s = bin2hex(s, (u8 *)&time, sizeof(time));
1029                 }
1030
1031                 attributes &= ~attr;
1032                 if (attributes)
1033                         s += sprintf(s, ",");
1034         }
1035         s += sprintf(s, "}");
1036         s += sprintf(s, "(blob)");
1037
1038         /* store payload: */
1039         if (append)
1040                 s = bin2hex(s, old_data, old_size);
1041         s = bin2hex(s, data, data_size);
1042         *s = '\0';
1043
1044         EFI_PRINT("setting: %s=%s\n", native_name, val);
1045
1046 out:
1047         if (env_set(native_name, val)) {
1048                 ret = EFI_DEVICE_ERROR;
1049         } else {
1050                 bool vendor_keys_modified = false;
1051
1052                 if ((u16_strcmp(variable_name, L"PK") == 0 &&
1053                      guidcmp(vendor, &efi_global_variable_guid) == 0)) {
1054                         ret = efi_transfer_secure_state(
1055                                         (delete ? EFI_MODE_SETUP :
1056                                                   EFI_MODE_USER));
1057                         if (ret != EFI_SUCCESS)
1058                                 goto err;
1059
1060                         if (efi_secure_mode != EFI_MODE_SETUP)
1061                                 vendor_keys_modified = true;
1062                 } else if ((u16_strcmp(variable_name, L"KEK") == 0 &&
1063                      guidcmp(vendor, &efi_global_variable_guid) == 0)) {
1064                         if (efi_secure_mode != EFI_MODE_SETUP)
1065                                 vendor_keys_modified = true;
1066                 }
1067
1068                 /* update VendorKeys */
1069                 if (vendor_keys_modified & efi_vendor_keys) {
1070                         efi_vendor_keys = 0;
1071                         ret = efi_set_variable_common(
1072                                                 L"VendorKeys",
1073                                                 &efi_global_variable_guid,
1074                                                 EFI_VARIABLE_BOOTSERVICE_ACCESS
1075                                                  | EFI_VARIABLE_RUNTIME_ACCESS
1076                                                  | READ_ONLY,
1077                                                 sizeof(efi_vendor_keys),
1078                                                 &efi_vendor_keys,
1079                                                 false);
1080                 } else {
1081                         ret = EFI_SUCCESS;
1082                 }
1083         }
1084
1085 err:
1086         free(native_name);
1087         free(old_data);
1088         free(val);
1089
1090         return ret;
1091 }
1092
1093 /**
1094  * efi_set_variable() - set value of a UEFI variable
1095  *
1096  * This function implements the SetVariable runtime service.
1097  *
1098  * See the Unified Extensible Firmware Interface (UEFI) specification for
1099  * details.
1100  *
1101  * @variable_name:      name of the variable
1102  * @vendor:             vendor GUID
1103  * @attributes:         attributes of the variable
1104  * @data_size:          size of the buffer with the variable value
1105  * @data:               buffer with the variable value
1106  * Return:              status code
1107  */
1108 efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
1109                                      const efi_guid_t *vendor, u32 attributes,
1110                                      efi_uintn_t data_size, const void *data)
1111 {
1112         EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
1113                   data_size, data);
1114
1115         /* READ_ONLY bit is not part of API */
1116         attributes &= ~(u32)READ_ONLY;
1117
1118         return EFI_EXIT(efi_set_variable_common(variable_name, vendor,
1119                                                 attributes, data_size, data,
1120                                                 true));
1121 }
1122
1123 /**
1124  * efi_query_variable_info() - get information about EFI variables
1125  *
1126  * This function implements the QueryVariableInfo() runtime service.
1127  *
1128  * See the Unified Extensible Firmware Interface (UEFI) specification for
1129  * details.
1130  *
1131  * @attributes:                         bitmask to select variables to be
1132  *                                      queried
1133  * @maximum_variable_storage_size:      maximum size of storage area for the
1134  *                                      selected variable types
1135  * @remaining_variable_storage_size:    remaining size of storage are for the
1136  *                                      selected variable types
1137  * @maximum_variable_size:              maximum size of a variable of the
1138  *                                      selected type
1139  * Returns:                             status code
1140  */
1141 efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
1142                         u32 attributes,
1143                         u64 *maximum_variable_storage_size,
1144                         u64 *remaining_variable_storage_size,
1145                         u64 *maximum_variable_size)
1146 {
1147         return EFI_UNSUPPORTED;
1148 }
1149
1150 /**
1151  * efi_get_variable_runtime() - runtime implementation of GetVariable()
1152  *
1153  * @variable_name:      name of the variable
1154  * @vendor:             vendor GUID
1155  * @attributes:         attributes of the variable
1156  * @data_size:          size of the buffer to which the variable value is copied
1157  * @data:               buffer to which the variable value is copied
1158  * Return:              status code
1159  */
1160 static efi_status_t __efi_runtime EFIAPI
1161 efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
1162                          u32 *attributes, efi_uintn_t *data_size, void *data)
1163 {
1164         return EFI_UNSUPPORTED;
1165 }
1166
1167 /**
1168  * efi_get_next_variable_name_runtime() - runtime implementation of
1169  *                                        GetNextVariable()
1170  *
1171  * @variable_name_size: size of variable_name buffer in byte
1172  * @variable_name:      name of uefi variable's name in u16
1173  * @vendor:             vendor's guid
1174  * Return: status code
1175  */
1176 static efi_status_t __efi_runtime EFIAPI
1177 efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
1178                                    u16 *variable_name, efi_guid_t *vendor)
1179 {
1180         return EFI_UNSUPPORTED;
1181 }
1182
1183 /**
1184  * efi_set_variable_runtime() - runtime implementation of SetVariable()
1185  *
1186  * @variable_name:      name of the variable
1187  * @vendor:             vendor GUID
1188  * @attributes:         attributes of the variable
1189  * @data_size:          size of the buffer with the variable value
1190  * @data:               buffer with the variable value
1191  * Return:              status code
1192  */
1193 static efi_status_t __efi_runtime EFIAPI
1194 efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
1195                          u32 attributes, efi_uintn_t data_size,
1196                          const void *data)
1197 {
1198         return EFI_UNSUPPORTED;
1199 }
1200
1201 /**
1202  * efi_variables_boot_exit_notify() - notify ExitBootServices() is called
1203  */
1204 void efi_variables_boot_exit_notify(void)
1205 {
1206         efi_runtime_services.get_variable = efi_get_variable_runtime;
1207         efi_runtime_services.get_next_variable_name =
1208                                 efi_get_next_variable_name_runtime;
1209         efi_runtime_services.set_variable = efi_set_variable_runtime;
1210         efi_update_table_header_crc32(&efi_runtime_services.hdr);
1211 }
1212
1213 /**
1214  * efi_init_variables() - initialize variable services
1215  *
1216  * Return:      status code
1217  */
1218 efi_status_t efi_init_variables(void)
1219 {
1220         efi_status_t ret;
1221
1222         ret = efi_init_secure_state();
1223
1224         return ret;
1225 }