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