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