From: Ana Bobillo <[email protected]> The SDP gadget implements the serial download protocol of the i.MX boot ROM, but always reports SDP_SECURITY_OPEN in its HAB security report (report 3), also on a part whose secure boot is fused closed, where the ROM reports SDP_SECURITY_CLOSED.
Add sdp_is_closed(), a weak hook that says whether secure boot is enforced, false by default so that other platforms are unchanged, and implement it for i.MX: - HAB parts (i.MX6/7/7ULP/8M): imx_hab_is_enabled(), the secure boot fuse minus a field return; a fuse read error counts as closed; - ELE AHAB parts (i.MX8ULP/9): the OEM closed and OEM locked lifecycles, and on i.MX94/95/952 also OEM secure world closed, read from the same FSB register as ahab_status. The SECO AHAB parts (i.MX8QM/QXP) keep the weak default; none of their in-tree defconfigs enables SDP. Use it for the security report. The next patch makes the gadget refuse what the ROM refuses on a closed part. Signed-off-by: Ana Bobillo <[email protected]> --- arch/arm/mach-imx/ele_ahab.c | 13 +++++++++++++ arch/arm/mach-imx/hab.c | 7 +++++++ drivers/usb/gadget/f_sdp.c | 7 ++++++- include/sdp.h | 19 +++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/ele_ahab.c b/arch/arm/mach-imx/ele_ahab.c index e1284833ac5..abbaf70682d 100644 --- a/arch/arm/mach-imx/ele_ahab.c +++ b/arch/arm/mach-imx/ele_ahab.c @@ -14,6 +14,7 @@ #include <asm/arch/sys_proto.h> #include <console.h> #include <cpu_func.h> +#include <sdp.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; @@ -414,6 +415,8 @@ static int do_authenticate(struct cmd_tbl *cmdtp, int flag, int argc, #if IS_ENABLED(CONFIG_IMX95) || IS_ENABLED(CONFIG_IMX94) || IS_ENABLED(CONFIG_IMX952) #define FSB_LC_OFFSET 0x414 #define LC_OEM_OPEN 0x10 +/* OEM secure world closed, OEM closed, OEM locked */ +#define LC_OEM_CLOSED (0x20 | 0x40 | 0x80) static void display_life_cycle(u32 lc) { printf("Lifecycle: 0x%08X, ", lc); @@ -459,6 +462,8 @@ static void display_life_cycle(u32 lc) #else #define FSB_LC_OFFSET 0x41c #define LC_OEM_OPEN 0x8 +/* OEM closed, OEM locked */ +#define LC_OEM_CLOSED (0x20 | 0x100) static void display_life_cycle(u32 lc) { printf("Lifecycle: 0x%08X, ", lc); @@ -497,6 +502,14 @@ static void display_life_cycle(u32 lc) } #endif +/* Secure boot is enforced: the SDP gadget then behaves as the ROM's does */ +bool sdp_is_closed(void) +{ + u32 lc = readl(FSB_BASE_ADDR + FSB_LC_OFFSET) & 0x3ff; + + return lc & LC_OEM_CLOSED; +} + static int confirm_close(void) { puts("Warning: Please ensure your sample is in NXP closed state, " diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 35c497619d6..78c85081055 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -16,6 +16,7 @@ #include <asm/arch/sys_proto.h> #include <asm/mach-imx/hab.h> #include <linux/arm-smccc.h> +#include <sdp.h> DECLARE_GLOBAL_DATA_PTR; @@ -932,6 +933,12 @@ bool imx_hab_is_enabled(void) return is_enabled; } +/* Secure boot is enforced: the SDP gadget then behaves as the ROM's does */ +bool sdp_is_closed(void) +{ + return imx_hab_is_enabled(); +} + int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, uint32_t ivt_offset) { diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index aff69c3a138..8bd8f239766 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -288,6 +288,11 @@ static inline void *sdp_ptr(u32 val) return (void *)(uintptr_t)val; } +__weak bool sdp_is_closed(void) +{ + return false; +} + static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req) { struct f_sdp *sdp = req->context; @@ -801,7 +806,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, debug("Report 3: HAB security\n"); data[0] = 3; - status = SDP_SECURITY_OPEN; + status = sdp_is_closed() ? SDP_SECURITY_CLOSED : SDP_SECURITY_OPEN; memcpy(&data[1], &status, 4); sdp_func->in_req->length = 5; usb_ep_queue(sdp_func->in_ep, sdp_func->in_req, 0); diff --git a/include/sdp.h b/include/sdp.h index 0a97f28073a..829f20ab4ef 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -9,8 +9,27 @@ #ifndef __SDP_H_ #define __SDP_H_ +#include <linux/types.h> + +struct udevice; + int sdp_init(struct udevice *udc); +/** + * sdp_is_closed() - Tell whether secure boot is enforced on this part + * + * The SDP gadget emulates the i.MX boot ROM's serial download mode. On a + * part with secure boot fused (HAB closed, AHAB OEM closed), the ROM refuses + * the operations that would bypass the signature chain, and SDP has to do the + * same, or it is a way around secure boot on an otherwise locked device. + * + * The weak default says open; i.MX code overrides it per secure boot + * mechanism. + * + * Return: true if the part is closed, false otherwise + */ +bool sdp_is_closed(void); + #ifdef CONFIG_XPL_BUILD #include <spl.h>
