summaryrefslogtreecommitdiffstats
path: root/common/efi
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2021-11-22 09:47:16 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2021-11-25 08:43:59 +0100
commit92fe157a8b5eeeb1baa7204a3245770df6131f02 (patch)
treeb6a4f6eca2ba5553c05ea975d18f7510a789f803 /common/efi
parent09e48b3d17468d15e89f023c5086f0d9425a3003 (diff)
downloadbarebox-92fe157a8b5eeeb1baa7204a3245770df6131f02.tar.gz
barebox-92fe157a8b5eeeb1baa7204a3245770df6131f02.tar.xz
efi: centralize efivarfs_parse_filename
Turning an EFI varfs filename into its components will be useful for the EFI loader as well, so factor that out. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20211122084732.2597109-15-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/efi')
-rw-r--r--common/efi/Makefile2
-rw-r--r--common/efi/efivar-filename.c116
2 files changed, 117 insertions, 1 deletions
diff --git a/common/efi/Makefile b/common/efi/Makefile
index ed110f5a68..a7cebde4f1 100644
--- a/common/efi/Makefile
+++ b/common/efi/Makefile
@@ -3,4 +3,4 @@
obj-$(CONFIG_EFI_BOOTUP) += payload/
obj-$(CONFIG_EFI_GUID) += guid.o
obj-$(CONFIG_EFI_DEVICEPATH) += devicepath.o
-obj-y += errno.o
+obj-y += errno.o efivar-filename.o
diff --git a/common/efi/efivar-filename.c b/common/efi/efivar-filename.c
new file mode 100644
index 0000000000..51d0130fa7
--- /dev/null
+++ b/common/efi/efivar-filename.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/ctype.h>
+#include <string.h>
+#include <efi/efi-util.h>
+
+static int char_to_nibble(char c)
+{
+ int ret = tolower(c);
+
+ return ret <= '9' ? ret - '0' : ret - 'a' + 10;
+}
+
+static int read_byte_str(const char *str, u8 *out)
+{
+ if (!isxdigit(*str) || !isxdigit(*(str + 1)))
+ return -EINVAL;
+
+ *out = (char_to_nibble(*str) << 4) | char_to_nibble(*(str + 1));
+
+ return 0;
+}
+
+static int efi_guid_parse(const char *str, efi_guid_t *guid)
+{
+ int i, ret;
+ u8 idx[] = { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ for (i = 0; i < 16; i++) {
+ ret = read_byte_str(str, &guid->b[idx[i]]);
+ if (ret)
+ return ret;
+ str += 2;
+
+ switch (i) {
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ if (*str != '-')
+ return -EINVAL;
+ str++;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int __efivarfs_parse_filename(const char *filename, efi_guid_t *vendor,
+ s16 *name, size_t *namelen)
+{
+ int len, ret;
+ const char *guidstr;
+ int i;
+
+ len = strlen(filename);
+
+ if (len < sizeof("-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"))
+ return -EINVAL;
+
+ guidstr = filename + len - sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
+ if (*guidstr != '-' || guidstr == filename)
+ return -EINVAL;
+
+ guidstr++;
+
+ ret = efi_guid_parse(guidstr, vendor);
+ if (ret)
+ return ret;
+
+ if (guidstr - filename > *namelen)
+ ret = -EFBIG;
+
+ *namelen = guidstr - filename;
+
+ if (ret)
+ return ret;
+
+ for (i = 0; i < *namelen - 1; i++)
+ name[i] = filename[i];
+
+ name[i] = L'\0';
+
+ return 0;
+}
+
+int efivarfs_parse_filename(const char *filename, efi_guid_t *vendor,
+ s16 **name)
+{
+ int ret;
+ s16 *varname;
+ size_t namelen = 0;
+ int i;
+
+ if (*filename == '/')
+ filename++;
+
+ ret = __efivarfs_parse_filename(filename, vendor, NULL, &namelen);
+ if (ret != -EFBIG)
+ return ret;
+
+ varname = xzalloc(namelen * sizeof(s16));
+
+ for (i = 0; i < namelen - 1; i++)
+ varname[i] = filename[i];
+
+ varname[i] = L'\0';
+
+ *name = varname;
+
+ return 0;
+}
+
+