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