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