From 4f88695eff33ace9a14e64aa10a187ae1b440e4e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 27 Jan 2017 00:17:14 +0800 Subject: [PATCH] pseudo device id Most platforms have a per-device uinque ID available, but it is not publicly documented how to access it. That leads to a situation on, eg, Hikey where OP-TEE has no way to tell two Hikey's apart. For many situations, including OP-TEE's own "Secure Storage", this destroys security and other functionality. It's possible that the caller of OP-TEE, arm-trusted-firmware in aarch64 case has access to identifying unique tokens. In that case, it'd be nice if a-t-f could pass it into OP-TEE and if no access to the real SoC "OTP" per-device identifier, use this shorter unique token that has a very good chance of being unique between devices. This patch allows the caller of OP-TEE pass in a DTB, which may be vegstigal, to define the pseudo device ID on the DT path "/firmware/optee/pseudo-device-id". If the platform sets CFG_OTP_SUPPORT and CFG_OTP_SUPPORT_PSEUDO_ID, this pseudo ID will be used as if it was the Device unqiue ID. $(call force,CFG_DT,y) is also required to get the DT parsing. You would only enable this if you were using arm-trusted-firmware with the necessary patches to deliver the eMMC CID serial to OP-TEE OS at startup time via full or stub DTB. --- core/arch/arm/kernel/generic_boot.c | 50 +++++++++++++++++++++++++++++ core/arch/arm/plat-hikey/conf.mk | 4 +++ 2 files changed, 54 insertions(+) diff --git a/core/arch/arm/kernel/generic_boot.c b/core/arch/arm/kernel/generic_boot.c index 8bf0afc37fa..5d8ced37f30 100644 --- a/core/arch/arm/kernel/generic_boot.c +++ b/core/arch/arm/kernel/generic_boot.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,8 @@ */ #define PADDR_INVALID ULONG_MAX +uint32_t pseudo_device_id __early_bss; + #if defined(CFG_BOOT_SECONDARY_REQUEST) paddr_t ns_entry_addrs[CFG_TEE_CORE_NB_CORE] __early_bss; static uint32_t spin_table[CFG_TEE_CORE_NB_CORE] __early_bss; @@ -549,6 +552,20 @@ static int add_optee_res_mem_dt_node(void *fdt) return 0; } +static void read_optee_pseudo_device_node(void *fdt) +{ + int offs; + const uint32_t *p; + + offs = fdt_path_offset(fdt, "/firmware/optee"); + if (offs < 0) + return; + + p = fdt_getprop(fdt, offs, "pseudo-device-id", NULL); + + pseudo_device_id = *p; +} + static void init_fdt(unsigned long phys_fdt) { void *fdt; @@ -587,6 +604,8 @@ static void init_fdt(unsigned long phys_fdt) if (add_optee_res_mem_dt_node(fdt)) panic("Failed to add OP-TEE reserved memory DT node"); + read_optee_pseudo_device_node(fdt); + ret = fdt_pack(fdt); if (ret < 0) { EMSG("Failed to pack Device Tree at 0x%" PRIxPA ": error %d", @@ -709,3 +728,34 @@ paddr_t generic_boot_core_hpen(void) #endif } #endif + +#if defined (CFG_OTP_SUPPORT) && defined(CFG_OTP_SUPPORT_PSEUDO_ID) + +/* A-t-f read the 32-bit eMMC CID serial number. It's kinda- + * unique, so the absence of any other stable device-specific bits, + * we can use this to make pseudo device-specific ID tokens. + */ + +void tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) +{ + uint8_t *p = (uint8_t *)&pseudo_device_id; + size_t n; + + DMSG("%s: pseudo token 0x%x\n", __func__, pseudo_device_id); + + for (n = 0; n < sizeof(hwkey->data); n++) + hwkey->data[n] = p[n & 3] ^ 0xff; +} +int tee_otp_get_die_id(uint8_t *buffer, size_t len) +{ + uint8_t *p = (uint8_t *)&pseudo_device_id; + size_t n; + + EMSG("%s: pseudo token 0x%x\n", __func__, pseudo_device_id); + + for (n = 0; n < len; n++) + *buffer++ = p[n & 3]; + + return 0; +} +#endif diff --git a/core/arch/arm/plat-hikey/conf.mk b/core/arch/arm/plat-hikey/conf.mk index 8a8ef2ff28f..61a2dd00a5e 100644 --- a/core/arch/arm/plat-hikey/conf.mk +++ b/core/arch/arm/plat-hikey/conf.mk @@ -24,6 +24,10 @@ CFG_NUM_THREADS ?= 8 CFG_CRYPTO_WITH_CE ?= y CFG_WITH_STACK_CANARIES ?= y +CFG_OTP_SUPPORT ?= y +CFG_OTP_SUPPORT_PSEUDO_ID ?= y +$(call force,CFG_DT,y) + CFG_PL061 ?= y CFG_PL022 ?= y CFG_SPI ?= y