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:
parent
8718734b46
commit
0e61017da8
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (C) 2021, Digi International Inc.
|
# Copyright (C) 2021-2023 Digi International Inc.
|
||||||
|
|
||||||
FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
|
FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@ SRC_URI += " \
|
||||||
file://0001-Implement-support-for-environment-encryption-by-CAAM.patch \
|
file://0001-Implement-support-for-environment-encryption-by-CAAM.patch \
|
||||||
file://0002-Implement-U-Boot-environment-access-functions.patch \
|
file://0002-Implement-U-Boot-environment-access-functions.patch \
|
||||||
file://0003-tools-env-add-support-to-set-dynamic-location-of-env.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() {
|
do_install:append() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue