106 lines
2.9 KiB
Diff
106 lines
2.9 KiB
Diff
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;
|
|
}
|