From 63110a7734e6f22ae7c7cc06576c766ca7a7606a Mon Sep 17 00:00:00 2001 From: Claudio Carvalho Date: Sat, 9 Dec 2017 02:52:32 -0200 Subject: libstb: add support for ibm, secureboot-v2 ibm,secureboot-v2 changes: - The Container Verification Code is represented by the ibm,cvc node. - Each ibm,cvc child describes a CVC service. - hash-algo is superseded by hw-key-hash-size. Signed-off-by: Claudio Carvalho Signed-off-by: Stewart Smith --- libstb/cvc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libstb/secureboot.c | 16 ++++++++++++++++ libstb/secureboot.h | 1 + 3 files changed, 71 insertions(+) diff --git a/libstb/cvc.c b/libstb/cvc.c index fd1f607..4faeb96 100644 --- a/libstb/cvc.c +++ b/libstb/cvc.c @@ -134,6 +134,58 @@ static void cvc_service_register(uint32_t id, uint32_t offset, uint32_t version) name, service->addr, service->version); } +static int cvc_reserved_mem_init(struct dt_node *parent) { + struct dt_node *node, *service; + struct dt_node *reserved_mem; + struct dt_node *cvc_resv_mem = NULL; + uint32_t phandle; + uint64_t addr, size; + + reserved_mem = dt_find_by_path(dt_root, "/ibm,hostboot/reserved-memory"); + if (!reserved_mem) { + prlog(PR_ERR, "/ibm,hostboot/reserved-memory not found\n"); + return -1; + } + + /* + * The container verification code is stored in a hostboot reserved + * memory which is pointed by the property + * /ibm,secureboot/ibm,container-verification-code/memory-region + */ + dt_for_each_child(parent, node) { + if (dt_node_is_compatible(node, "ibm,container-verification-code")) { + phandle = dt_prop_get_u32(node, "memory-region"); + cvc_resv_mem = dt_find_by_phandle(reserved_mem, phandle); + break; + } + } + if (!cvc_resv_mem) { + prlog(PR_ERR, "CVC not found in /ibm,hostboot/reserved-memory\n"); + return -1; + } + addr = dt_get_address(cvc_resv_mem, 0, &size); + cvc_register(addr, addr + size-1); + + /* + * Each child of the CVC node describes a CVC service + */ + dt_for_each_child(node, service) { + uint32_t version, offset; + + version = dt_prop_get_u32(service, "version"); + offset = dt_prop_get_u32(service, "reg"); + + if (dt_node_is_compatible(service, "ibm,cvc-sha512")) + cvc_service_register(CVC_SHA512_SERVICE, offset, version); + else if (dt_node_is_compatible(service, "ibm,cvc-verify")) + cvc_service_register(CVC_VERIFY_SERVICE, offset, version); + else + prlog(PR_DEBUG, "unknown %s\n", service->name); + } + + return 0; +} + #define SECURE_ROM_MEMORY_SIZE (16 * 1024) #define SECURE_ROM_XSCOM_ADDRESS 0x02020017 @@ -198,6 +250,8 @@ int cvc_init(void) rc = cvc_secure_rom_init(); } else if (version == IBM_SECUREBOOT_SOFTROM) { softrom = true; + } else if (version == IBM_SECUREBOOT_V2) { + rc = cvc_reserved_mem_init(node); } else { prlog(PR_ERR, "%s FAILED. /ibm,secureboot not supported\n", __func__); diff --git a/libstb/secureboot.c b/libstb/secureboot.c index 953b123..f3a5db4 100644 --- a/libstb/secureboot.c +++ b/libstb/secureboot.c @@ -35,6 +35,7 @@ static struct { } secureboot_map[] = { { IBM_SECUREBOOT_V1, "ibm,secureboot-v1" }, { IBM_SECUREBOOT_SOFTROM, "ibm,secureboot-v1-softrom" }, + { IBM_SECUREBOOT_V2, "ibm,secureboot-v2" }, }; static void secureboot_enforce(void) @@ -130,6 +131,21 @@ void secureboot_init(void) secureboot_enforce(); } hw_key_hash_size = SHA512_DIGEST_LENGTH; + + } else if (version == IBM_SECUREBOOT_V2) { + + hw_key_hash_size = dt_prop_get_u32(node, "hw-key-hash-size"); + if (hw_key_hash_size == 0) { + prlog(PR_EMERG, "hw-key-hash-size=%zd too short\n", + hw_key_hash_size); + secureboot_enforce(); + } + if (hw_key_hash_size > SHA512_DIGEST_LENGTH) { + prlog(PR_EMERG, "hw-key-hash-size=%zd too big\n", + hw_key_hash_size); + secureboot_enforce(); + } + } else { prlog(PR_ERR, "%s FAILED. /ibm,secureboot not supported", __func__); diff --git a/libstb/secureboot.h b/libstb/secureboot.h index 8506ea0..b1cb29b 100644 --- a/libstb/secureboot.h +++ b/libstb/secureboot.h @@ -25,6 +25,7 @@ enum secureboot_version { IBM_SECUREBOOT_V1, IBM_SECUREBOOT_SOFTROM, + IBM_SECUREBOOT_V2, }; bool secureboot_is_compatible(struct dt_node *node, int *version, const char **compat); -- cgit v1.1