libubootenv: add fall-back function to read HWID from nvmem

The HWID is populated on the device tree by the boot loader.
This can be used as a key modifier when encrypting the U-Boot
environment. Some old U-Boot versions however, did not populate
the HWID on the device tree. When updating firmware from an
old version to a new one, the library may not be able to read
the HWID from the DT and then be unable to unencrypt the
environment.

This patch implements a fall-back function to read the HWID
directly from the nvmem node (sysfs). Implementation has been
done for ccimx6 family only, where this case of old U-Boot
can happen.

Signed-off-by: Hector Palacios <hector.palacios@digi.com>

https://onedigi.atlassian.net/browse/DEL-8444
(cherry picked from commit 222a91f213)
This commit is contained in:
Hector Palacios 2023-03-23 14:12:34 +01:00 committed by Mike Engel
parent 8718734b46
commit 0e61017da8
2 changed files with 107 additions and 1 deletions

View File

@ -0,0 +1,105 @@
From: Hector Palacios <hector.palacios@digi.com>
Date: Mon, 3 Apr 2023 18:21:07 +0200
Subject: [PATCH] fall back to read HWID from nvmem device if not available on
DT
Old U-Boot versions don't populate the HWID on the device tree. This may
be used as a key modifier for TrustFence encryption and, if not available
on the DT, newer firmware may be unable to unencrypt the U-Boot
environment.
This patch implements a fall-back function to query the HWID directly from
the nvmem device node if it cannot locate it at the DT.
This is only implemented for ccimx6 family, which may be in the case of
having an old U-Boot.
Signed-off-by: Hector Palacios <hector.palacios@digi.com>
https://onedigi.atlassian.net/browse/DEL-8444
---
src/uboot_env.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/src/uboot_env.c b/src/uboot_env.c
index 539e22f9a8ac..86f9b9ebfec2 100644
--- a/src/uboot_env.c
+++ b/src/uboot_env.c
@@ -945,6 +945,32 @@ static int is_env_encrypted(void)
return access(dt_prop, F_OK) != -1;
}
+/* Function that checks if machine is compatible (on the DT) */
+static bool machine_is_compatible(char *machine)
+{
+ int fd, nchars, len = 0;
+ int ret = false;
+ char str[256];
+ char *p = str;
+
+ fd = open("/proc/device-tree/compatible", O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ nchars = read(fd, str, 255);
+ while (len < nchars) {
+ if (!strcmp(p, machine)) {
+ ret = true;
+ break;
+ }
+ len += strlen(p) + 1;
+ p += strlen(p) + 1;
+ }
+
+ close(fd);
+ return ret;
+}
+
#define MAX_HWID_WORDS 4
static int env_caam_get_keymod(unsigned char output[16])
{
@@ -953,12 +979,11 @@ static int env_caam_get_keymod(unsigned char output[16])
int fd;
uint32_t ocotp_hwid[MAX_HWID_WORDS];
char dt_prop[32];
+ char buf[sizeof(uint32_t)];
for (i = 0; i < MAX_HWID_WORDS; i++) {
sprintf(dt_prop, "/proc/device-tree/digi,hwid_%d", i);
if (access(dt_prop, F_OK) != -1) {
- char buf[sizeof(uint32_t)];
-
fd = open(dt_prop, O_RDONLY);
if (fd < 0)
return fd;
@@ -969,6 +994,31 @@ static int env_caam_get_keymod(unsigned char output[16])
}
ocotp_hwid[i] = ntohl(*(uint32_t *)buf);
close(fd);
+ } else if (machine_is_compatible("digi,ccimx6ul") ||
+ machine_is_compatible("digi,ccimx6")) {
+ /*
+ * If HWID not available on the DT (old U-Boot version),
+ * fall back to read it directly from the nvmem device.
+ */
+ int hwid_offset = 136; /* (Bank * 8 + Word) * 4 */
+
+ /* HWID for CC6 family only has two words */
+ if (i == 2)
+ break;
+
+ fd = open("/sys/bus/nvmem/devices/imx-ocotp0/nvmem",
+ O_RDONLY);
+ if (fd < 0)
+ return fd;
+ len = lseek(fd, hwid_offset + i * 4, SEEK_SET);
+
+ len = read(fd, buf, sizeof(unsigned int));
+ if (len < 0) {
+ close(fd);
+ return -1;
+ }
+ ocotp_hwid[i] = *(unsigned int *)buf;
+ close(fd);
} else {
break;
}

View File

@ -1,4 +1,4 @@
# Copyright (C) 2021, Digi International Inc.
# Copyright (C) 2021-2023 Digi International Inc.
FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
@ -18,6 +18,7 @@ SRC_URI += " \
file://0001-Implement-support-for-environment-encryption-by-CAAM.patch \
file://0002-Implement-U-Boot-environment-access-functions.patch \
file://0003-tools-env-add-support-to-set-dynamic-location-of-env.patch \
file://0004-fall-back-to-read-HWID-from-nvmem-device-if-not-avai.patch \
"
do_install:append() {