From 0e61017da84feac79856a44f7dcac9ce862c22ba Mon Sep 17 00:00:00 2001 From: Hector Palacios Date: Thu, 23 Mar 2023 14:12:34 +0100 Subject: [PATCH] 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 https://onedigi.atlassian.net/browse/DEL-8444 (cherry picked from commit 222a91f213e7d7e201f389fe3773f5f3f3a10c0a) --- ...d-HWID-from-nvmem-device-if-not-avai.patch | 105 ++++++++++++++++++ .../libubootenv/libubootenv_%.bbappend | 3 +- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 meta-digi-arm/recipes-bsp/libubootenv/libubootenv/0004-fall-back-to-read-HWID-from-nvmem-device-if-not-avai.patch diff --git a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv/0004-fall-back-to-read-HWID-from-nvmem-device-if-not-avai.patch b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv/0004-fall-back-to-read-HWID-from-nvmem-device-if-not-avai.patch new file mode 100644 index 000000000..08cb1ab43 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv/0004-fall-back-to-read-HWID-from-nvmem-device-if-not-avai.patch @@ -0,0 +1,105 @@ +From: Hector Palacios +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 + +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; + } diff --git a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend index 8076b29bd..5ee54cb84 100644 --- a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend +++ b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend @@ -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() {