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