efi_loader: factor out the common code from efi_transfer_secure_state()
[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                                             bool is_non_volatile)
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_EXIT(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                         debug("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                         debug("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 static
688 efi_status_t EFIAPI efi_get_volatile_variable(u16 *variable_name,
689                                               const efi_guid_t *vendor,
690                                               u32 *attributes,
691                                               efi_uintn_t *data_size,
692                                               void *data)
693 {
694         return efi_get_variable_common(variable_name, vendor, attributes,
695                                        data_size, data, false);
696 }
697
698 efi_status_t EFIAPI efi_get_nonvolatile_variable(u16 *variable_name,
699                                                  const efi_guid_t *vendor,
700                                                  u32 *attributes,
701                                                  efi_uintn_t *data_size,
702                                                  void *data)
703 {
704         return efi_get_variable_common(variable_name, vendor, attributes,
705                                        data_size, data, true);
706 }
707
708 /**
709  * efi_efi_get_variable() - retrieve value of a UEFI variable
710  *
711  * This function implements the GetVariable runtime service.
712  *
713  * See the Unified Extensible Firmware Interface (UEFI) specification for
714  * details.
715  *
716  * @variable_name:      name of the variable
717  * @vendor:             vendor GUID
718  * @attributes:         attributes of the variable
719  * @data_size:          size of the buffer to which the variable value is copied
720  * @data:               buffer to which the variable value is copied
721  * Return:              status code
722  */
723 efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
724                                      const efi_guid_t *vendor, u32 *attributes,
725                                      efi_uintn_t *data_size, void *data)
726 {
727         efi_status_t ret;
728
729         EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes,
730                   data_size, data);
731
732         ret = efi_get_volatile_variable(variable_name, vendor, attributes,
733                                         data_size, data);
734         if (ret == EFI_NOT_FOUND)
735                 ret = efi_get_nonvolatile_variable(variable_name, vendor,
736                                                    attributes, data_size, data);
737
738         return EFI_EXIT(ret);
739 }
740
741 static char *efi_variables_list;
742 static char *efi_cur_variable;
743
744 /**
745  * parse_uboot_variable() - parse a u-boot variable and get uefi-related
746  *                          information
747  * @variable:           whole data of u-boot variable (ie. name=value)
748  * @variable_name_size: size of variable_name buffer in byte
749  * @variable_name:      name of uefi variable in u16, null-terminated
750  * @vendor:             vendor's guid
751  * @attributes:         attributes
752  *
753  * A uefi variable is encoded into a u-boot variable as described above.
754  * This function parses such a u-boot variable and retrieve uefi-related
755  * information into respective parameters. In return, variable_name_size
756  * is the size of variable name including NULL.
757  *
758  * Return:              EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when
759  *                      the entire variable list has been returned,
760  *                      otherwise non-zero status code
761  */
762 static efi_status_t parse_uboot_variable(char *variable,
763                                          efi_uintn_t *variable_name_size,
764                                          u16 *variable_name,
765                                          const efi_guid_t *vendor,
766                                          u32 *attributes)
767 {
768         char *guid, *name, *end, c;
769         size_t name_len;
770         efi_uintn_t old_variable_name_size;
771         u64 time;
772         u16 *p;
773
774         guid = strchr(variable, '_');
775         if (!guid)
776                 return EFI_INVALID_PARAMETER;
777         guid++;
778         name = strchr(guid, '_');
779         if (!name)
780                 return EFI_INVALID_PARAMETER;
781         name++;
782         end = strchr(name, '=');
783         if (!end)
784                 return EFI_INVALID_PARAMETER;
785
786         name_len = end - name;
787         old_variable_name_size = *variable_name_size;
788         *variable_name_size = sizeof(u16) * (name_len + 1);
789         if (old_variable_name_size < *variable_name_size)
790                 return EFI_BUFFER_TOO_SMALL;
791
792         end++; /* point to value */
793
794         /* variable name */
795         p = variable_name;
796         utf8_utf16_strncpy(&p, name, name_len);
797         variable_name[name_len] = 0;
798
799         /* guid */
800         c = *(name - 1);
801         *(name - 1) = '\0'; /* guid need be null-terminated here */
802         uuid_str_to_bin(guid, (unsigned char *)vendor, UUID_STR_FORMAT_GUID);
803         *(name - 1) = c;
804
805         /* attributes */
806         parse_attr(end, attributes, &time);
807
808         return EFI_SUCCESS;
809 }
810
811 /**
812  * efi_get_next_variable_name() - enumerate the current variable names
813  *
814  * @variable_name_size: size of variable_name buffer in byte
815  * @variable_name:      name of uefi variable's name in u16
816  * @vendor:             vendor's guid
817  *
818  * This function implements the GetNextVariableName service.
819  *
820  * See the Unified Extensible Firmware Interface (UEFI) specification for
821  * details.
822  *
823  * Return: status code
824  */
825 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
826                                                u16 *variable_name,
827                                                efi_guid_t *vendor)
828 {
829         char *native_name, *variable;
830         ssize_t name_len, list_len;
831         char regex[256];
832         char * const regexlist[] = {regex};
833         u32 attributes;
834         int i;
835         efi_status_t ret;
836
837         EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
838
839         if (!variable_name_size || !variable_name || !vendor)
840                 return EFI_EXIT(EFI_INVALID_PARAMETER);
841
842         if (variable_name[0]) {
843                 /* check null-terminated string */
844                 for (i = 0; i < *variable_name_size; i++)
845                         if (!variable_name[i])
846                                 break;
847                 if (i >= *variable_name_size)
848                         return EFI_EXIT(EFI_INVALID_PARAMETER);
849
850                 /* search for the last-returned variable */
851                 ret = efi_to_native(&native_name, variable_name, vendor);
852                 if (ret)
853                         return EFI_EXIT(ret);
854
855                 name_len = strlen(native_name);
856                 for (variable = efi_variables_list; variable && *variable;) {
857                         if (!strncmp(variable, native_name, name_len) &&
858                             variable[name_len] == '=')
859                                 break;
860
861                         variable = strchr(variable, '\n');
862                         if (variable)
863                                 variable++;
864                 }
865
866                 free(native_name);
867                 if (!(variable && *variable))
868                         return EFI_EXIT(EFI_INVALID_PARAMETER);
869
870                 /* next variable */
871                 variable = strchr(variable, '\n');
872                 if (variable)
873                         variable++;
874                 if (!(variable && *variable))
875                         return EFI_EXIT(EFI_NOT_FOUND);
876         } else {
877                 /*
878                  *new search: free a list used in the previous search
879                  */
880                 free(efi_variables_list);
881                 efi_variables_list = NULL;
882                 efi_cur_variable = NULL;
883
884                 snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*");
885                 list_len = hexport_r(&env_htab, '\n',
886                                      H_MATCH_REGEX | H_MATCH_KEY,
887                                      &efi_variables_list, 0, 1, regexlist);
888
889                 if (list_len <= 1)
890                         return EFI_EXIT(EFI_NOT_FOUND);
891
892                 variable = efi_variables_list;
893         }
894
895         ret = parse_uboot_variable(variable, variable_name_size, variable_name,
896                                    vendor, &attributes);
897
898         return EFI_EXIT(ret);
899 }
900
901 static
902 efi_status_t EFIAPI efi_set_variable_common(u16 *variable_name,
903                                             const efi_guid_t *vendor,
904                                             u32 attributes,
905                                             efi_uintn_t data_size,
906                                             const void *data,
907                                             bool ro_check,
908                                             bool is_non_volatile)
909 {
910         char *native_name = NULL, *old_data = NULL, *val = NULL, *s;
911         efi_uintn_t old_size;
912         bool append, delete;
913         u64 time = 0;
914         u32 attr;
915         efi_status_t ret = EFI_SUCCESS;
916
917         debug("%s: set '%s'\n", __func__, native_name);
918
919         if (!variable_name || !*variable_name || !vendor ||
920             ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
921              !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) {
922                 ret = EFI_INVALID_PARAMETER;
923                 goto err;
924         }
925
926         ret = efi_to_native(&native_name, variable_name, vendor);
927         if (ret)
928                 goto err;
929
930         /* check if a variable exists */
931         old_size = 0;
932         attr = 0;
933         ret = EFI_CALL(efi_get_variable(variable_name, vendor, &attr,
934                                         &old_size, NULL));
935         if (ret == EFI_BUFFER_TOO_SMALL) {
936                 if ((is_non_volatile && !(attr & EFI_VARIABLE_NON_VOLATILE)) ||
937                     (!is_non_volatile && (attr & EFI_VARIABLE_NON_VOLATILE))) {
938                         ret = EFI_INVALID_PARAMETER;
939                         goto err;
940                 }
941         }
942
943         append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
944         attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
945         delete = !append && (!data_size || !attributes);
946
947         /* check attributes */
948         if (old_size) {
949                 if (ro_check && (attr & READ_ONLY)) {
950                         ret = EFI_WRITE_PROTECTED;
951                         goto err;
952                 }
953
954                 /* attributes won't be changed */
955                 if (!delete &&
956                     ((ro_check && attr != attributes) ||
957                      (!ro_check && ((attr & ~(u32)READ_ONLY)
958                                     != (attributes & ~(u32)READ_ONLY))))) {
959                         ret = EFI_INVALID_PARAMETER;
960                         goto err;
961                 }
962         } else {
963                 if (delete || append) {
964                         /*
965                          * Trying to delete or to update a non-existent
966                          * variable.
967                          */
968                         ret = EFI_NOT_FOUND;
969                         goto err;
970                 }
971         }
972
973         if (((!u16_strcmp(variable_name, L"PK") ||
974               !u16_strcmp(variable_name, L"KEK")) &&
975                 !guidcmp(vendor, &efi_global_variable_guid)) ||
976             ((!u16_strcmp(variable_name, L"db") ||
977               !u16_strcmp(variable_name, L"dbx")) &&
978                 !guidcmp(vendor, &efi_guid_image_security_database))) {
979                 /* authentication is mandatory */
980                 if (!(attributes &
981                       EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
982                         debug("%ls: AUTHENTICATED_WRITE_ACCESS required\n",
983                               variable_name);
984                         ret = EFI_INVALID_PARAMETER;
985                         goto err;
986                 }
987         }
988
989         /* authenticate a variable */
990         if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) {
991                 if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
992                         ret = EFI_INVALID_PARAMETER;
993                         goto err;
994                 }
995                 if (attributes &
996                     EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
997                         ret = efi_variable_authenticate(variable_name, vendor,
998                                                         &data_size, &data,
999                                                         attributes, &attr,
1000                                                         &time);
1001                         if (ret != EFI_SUCCESS)
1002                                 goto err;
1003
1004                         /* last chance to check for delete */
1005                         if (!data_size)
1006                                 delete = true;
1007                 }
1008         } else {
1009                 if (attributes &
1010                     (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
1011                      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
1012                         debug("Secure boot is not configured\n");
1013                         ret = EFI_INVALID_PARAMETER;
1014                         goto err;
1015                 }
1016         }
1017
1018         /* delete a variable */
1019         if (delete) {
1020                 /* !old_size case has been handled before */
1021                 val = NULL;
1022                 ret = EFI_SUCCESS;
1023                 goto out;
1024         }
1025
1026         if (append) {
1027                 old_data = malloc(old_size);
1028                 if (!old_data) {
1029                         return EFI_OUT_OF_RESOURCES;
1030                         goto err;
1031                 }
1032                 ret = EFI_CALL(efi_get_variable(variable_name, vendor,
1033                                                 &attr, &old_size, old_data));
1034                 if (ret != EFI_SUCCESS)
1035                         goto err;
1036         } else {
1037                 old_size = 0;
1038         }
1039
1040         val = malloc(2 * old_size + 2 * data_size
1041                      + strlen("{ro,run,boot,nv,time=0123456701234567}(blob)")
1042                      + 1);
1043         if (!val) {
1044                 ret = EFI_OUT_OF_RESOURCES;
1045                 goto err;
1046         }
1047
1048         s = val;
1049
1050         /*
1051          * store attributes
1052          */
1053         attributes &= (READ_ONLY |
1054                        EFI_VARIABLE_NON_VOLATILE |
1055                        EFI_VARIABLE_BOOTSERVICE_ACCESS |
1056                        EFI_VARIABLE_RUNTIME_ACCESS |
1057                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
1058         s += sprintf(s, "{");
1059         while (attributes) {
1060                 attr = 1 << (ffs(attributes) - 1);
1061
1062                 if (attr == READ_ONLY) {
1063                         s += sprintf(s, "ro");
1064                 } else if (attr == EFI_VARIABLE_NON_VOLATILE) {
1065                         s += sprintf(s, "nv");
1066                 } else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) {
1067                         s += sprintf(s, "boot");
1068                 } else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) {
1069                         s += sprintf(s, "run");
1070                 } else if (attr ==
1071                            EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
1072                         s += sprintf(s, "time=");
1073                         s = bin2hex(s, (u8 *)&time, sizeof(time));
1074                 }
1075
1076                 attributes &= ~attr;
1077                 if (attributes)
1078                         s += sprintf(s, ",");
1079         }
1080         s += sprintf(s, "}");
1081         s += sprintf(s, "(blob)");
1082
1083         /* store payload: */
1084         if (append)
1085                 s = bin2hex(s, old_data, old_size);
1086         s = bin2hex(s, data, data_size);
1087         *s = '\0';
1088
1089         EFI_PRINT("setting: %s=%s\n", native_name, val);
1090
1091 out:
1092         if (env_set(native_name, val)) {
1093                 ret = EFI_DEVICE_ERROR;
1094         } else {
1095                 bool vendor_keys_modified = false;
1096
1097                 if ((u16_strcmp(variable_name, L"PK") == 0 &&
1098                      guidcmp(vendor, &efi_global_variable_guid) == 0)) {
1099                         ret = efi_transfer_secure_state(
1100                                         (delete ? EFI_MODE_SETUP :
1101                                                   EFI_MODE_USER));
1102                         if (ret != EFI_SUCCESS)
1103                                 goto err;
1104
1105                         if (efi_secure_mode != EFI_MODE_SETUP)
1106                                 vendor_keys_modified = true;
1107                 } else if ((u16_strcmp(variable_name, L"KEK") == 0 &&
1108                      guidcmp(vendor, &efi_global_variable_guid) == 0)) {
1109                         if (efi_secure_mode != EFI_MODE_SETUP)
1110                                 vendor_keys_modified = true;
1111                 }
1112
1113                 /* update VendorKeys */
1114                 if (vendor_keys_modified & efi_vendor_keys) {
1115                         efi_vendor_keys = 0;
1116                         ret = efi_set_variable_internal(
1117                                                 L"VendorKeys",
1118                                                 &efi_global_variable_guid,
1119                                                 EFI_VARIABLE_BOOTSERVICE_ACCESS
1120                                                  | EFI_VARIABLE_RUNTIME_ACCESS
1121                                                  | READ_ONLY,
1122                                                 sizeof(efi_vendor_keys),
1123                                                 &efi_vendor_keys,
1124                                                 false);
1125                 } else {
1126                         ret = EFI_SUCCESS;
1127                 }
1128         }
1129
1130 err:
1131         free(native_name);
1132         free(old_data);
1133         free(val);
1134
1135         return ret;
1136 }
1137
1138 static
1139 efi_status_t EFIAPI efi_set_volatile_variable(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         return efi_set_variable_common(variable_name, vendor, attributes,
1147                                        data_size, data, ro_check, false);
1148 }
1149
1150 efi_status_t EFIAPI efi_set_nonvolatile_variable(u16 *variable_name,
1151                                                  const efi_guid_t *vendor,
1152                                                  u32 attributes,
1153                                                  efi_uintn_t data_size,
1154                                                  const void *data,
1155                                                  bool ro_check)
1156 {
1157         efi_status_t ret;
1158
1159         ret = efi_set_variable_common(variable_name, vendor, attributes,
1160                                       data_size, data, ro_check, true);
1161
1162         return ret;
1163 }
1164
1165 static efi_status_t efi_set_variable_internal(u16 *variable_name,
1166                                               const efi_guid_t *vendor,
1167                                               u32 attributes,
1168                                               efi_uintn_t data_size,
1169                                               const void *data,
1170                                               bool ro_check)
1171 {
1172         efi_status_t ret;
1173
1174         if (attributes & EFI_VARIABLE_NON_VOLATILE)
1175                 ret = efi_set_nonvolatile_variable(variable_name, vendor,
1176                                                    attributes,
1177                                                    data_size, data, ro_check);
1178         else
1179                 ret = efi_set_volatile_variable(variable_name, vendor,
1180                                                 attributes, data_size, data,
1181                                                 ro_check);
1182
1183         return ret;
1184 }
1185
1186 /**
1187  * efi_set_variable() - set value of a UEFI variable
1188  *
1189  * This function implements the SetVariable runtime service.
1190  *
1191  * See the Unified Extensible Firmware Interface (UEFI) specification for
1192  * details.
1193  *
1194  * @variable_name:      name of the variable
1195  * @vendor:             vendor GUID
1196  * @attributes:         attributes of the variable
1197  * @data_size:          size of the buffer with the variable value
1198  * @data:               buffer with the variable value
1199  * Return:              status code
1200  */
1201 efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
1202                                      const efi_guid_t *vendor, u32 attributes,
1203                                      efi_uintn_t data_size, const void *data)
1204 {
1205         EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
1206                   data_size, data);
1207
1208         /* READ_ONLY bit is not part of API */
1209         attributes &= ~(u32)READ_ONLY;
1210
1211         return EFI_EXIT(efi_set_variable_internal(variable_name, vendor,
1212                                                   attributes, data_size, data,
1213                                                   true));
1214 }
1215
1216 /**
1217  * efi_query_variable_info() - get information about EFI variables
1218  *
1219  * This function implements the QueryVariableInfo() runtime service.
1220  *
1221  * See the Unified Extensible Firmware Interface (UEFI) specification for
1222  * details.
1223  *
1224  * @attributes:                         bitmask to select variables to be
1225  *                                      queried
1226  * @maximum_variable_storage_size:      maximum size of storage area for the
1227  *                                      selected variable types
1228  * @remaining_variable_storage_size:    remaining size of storage are for the
1229  *                                      selected variable types
1230  * @maximum_variable_size:              maximum size of a variable of the
1231  *                                      selected type
1232  * Returns:                             status code
1233  */
1234 efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
1235                         u32 attributes,
1236                         u64 *maximum_variable_storage_size,
1237                         u64 *remaining_variable_storage_size,
1238                         u64 *maximum_variable_size)
1239 {
1240         return EFI_UNSUPPORTED;
1241 }
1242
1243 /**
1244  * efi_get_variable_runtime() - runtime implementation of GetVariable()
1245  *
1246  * @variable_name:      name of the variable
1247  * @vendor:             vendor GUID
1248  * @attributes:         attributes of the variable
1249  * @data_size:          size of the buffer to which the variable value is copied
1250  * @data:               buffer to which the variable value is copied
1251  * Return:              status code
1252  */
1253 static efi_status_t __efi_runtime EFIAPI
1254 efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
1255                          u32 *attributes, efi_uintn_t *data_size, void *data)
1256 {
1257         return EFI_UNSUPPORTED;
1258 }
1259
1260 /**
1261  * efi_get_next_variable_name_runtime() - runtime implementation of
1262  *                                        GetNextVariable()
1263  *
1264  * @variable_name_size: size of variable_name buffer in byte
1265  * @variable_name:      name of uefi variable's name in u16
1266  * @vendor:             vendor's guid
1267  * Return: status code
1268  */
1269 static efi_status_t __efi_runtime EFIAPI
1270 efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
1271                                    u16 *variable_name, efi_guid_t *vendor)
1272 {
1273         return EFI_UNSUPPORTED;
1274 }
1275
1276 /**
1277  * efi_set_variable_runtime() - runtime implementation of SetVariable()
1278  *
1279  * @variable_name:      name of the variable
1280  * @vendor:             vendor GUID
1281  * @attributes:         attributes of the variable
1282  * @data_size:          size of the buffer with the variable value
1283  * @data:               buffer with the variable value
1284  * Return:              status code
1285  */
1286 static efi_status_t __efi_runtime EFIAPI
1287 efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
1288                          u32 attributes, efi_uintn_t data_size,
1289                          const void *data)
1290 {
1291         return EFI_UNSUPPORTED;
1292 }
1293
1294 /**
1295  * efi_variables_boot_exit_notify() - notify ExitBootServices() is called
1296  */
1297 void efi_variables_boot_exit_notify(void)
1298 {
1299         efi_runtime_services.get_variable = efi_get_variable_runtime;
1300         efi_runtime_services.get_next_variable_name =
1301                                 efi_get_next_variable_name_runtime;
1302         efi_runtime_services.set_variable = efi_set_variable_runtime;
1303         efi_update_table_header_crc32(&efi_runtime_services.hdr);
1304 }
1305
1306 /**
1307  * efi_init_variables() - initialize variable services
1308  *
1309  * Return:      status code
1310  */
1311 efi_status_t efi_init_variables(void)
1312 {
1313         efi_status_t ret;
1314
1315         ret = efi_init_secure_state();
1316
1317         return ret;
1318 }