From 072a3d0421259377e278fb787d1e4c5965b5b2d6 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Tue, 6 Oct 2020 00:10:24 +0530 Subject: nxp: cot using nxp internal and mbedtls Chain of trust(CoT) is enabled on NXP SoC in two ways: - Using MbedTLS, parsing X509 Certificates. - Using NXP internal method parsing CSF header Signed-off-by: Pankaj Gupta Change-Id: I78fb28516dfcfa667bebf8a1951ffb24bcab8de4 --- drivers/nxp/auth/csf_hdr_parser/cot.c | 276 ++++++++ drivers/nxp/auth/csf_hdr_parser/csf_hdr.h | 155 +++++ drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk | 64 ++ drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c | 347 +++++++++ drivers/nxp/auth/csf_hdr_parser/input_bl2_ch2 | 89 +++ drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3 | 65 ++ drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3_2 | 65 ++ drivers/nxp/auth/csf_hdr_parser/input_blx_ch2 | 30 + drivers/nxp/auth/csf_hdr_parser/input_blx_ch3 | 37 + drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3 | 43 ++ drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3_2 | 43 ++ drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c | 165 +++++ drivers/nxp/auth/tbbr/tbbr_cot.c | 812 ++++++++++++++++++++++ 13 files changed, 2191 insertions(+) create mode 100644 drivers/nxp/auth/csf_hdr_parser/cot.c create mode 100644 drivers/nxp/auth/csf_hdr_parser/csf_hdr.h create mode 100644 drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk create mode 100644 drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_bl2_ch2 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3_2 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_blx_ch2 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_blx_ch3 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3 create mode 100644 drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3_2 create mode 100644 drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c create mode 100644 drivers/nxp/auth/tbbr/tbbr_cot.c diff --git a/drivers/nxp/auth/csf_hdr_parser/cot.c b/drivers/nxp/auth/csf_hdr_parser/cot.c new file mode 100644 index 000000000..dbb1df3e4 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/cot.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#if USE_TBBR_DEFS +#include +#else +#include +#endif + + +static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +static auth_param_type_desc_t sig_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, 0); + +static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); + +/* + * TBBR Chain of trust definition + */ +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t scp_bl2_image = { + .img_id = SCP_BL2_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t fuse_prov_img = { + .img_id = FUSE_PROV_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t fuse_upgrade_img = { + .img_id = FUSE_UP_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_udimm_1d_img = { + .img_id = DDR_IMEM_UDIMM_1D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_udimm_2d_img = { + .img_id = DDR_IMEM_UDIMM_2D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_udimm_1d_img = { + .img_id = DDR_DMEM_UDIMM_1D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_udimm_2d_img = { + .img_id = DDR_DMEM_UDIMM_2D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_rdimm_1d_img = { + .img_id = DDR_IMEM_RDIMM_1D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_rdimm_2d_img = { + .img_id = DDR_IMEM_RDIMM_2D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_rdimm_1d_img = { + .img_id = DDR_DMEM_RDIMM_1D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_rdimm_2d_img = { + .img_id = DDR_DMEM_RDIMM_2D_IMAGE_ID, + .img_type = IMG_PLAT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &sig_hash + } + } + } +}; + +static const auth_img_desc_t * const cot_desc[] = { + [BL31_IMAGE_ID] = &bl31_image, + [SCP_BL2_IMAGE_ID] = &scp_bl2_image, + [BL32_IMAGE_ID] = &bl32_image, + [BL33_IMAGE_ID] = &bl33_image, + [FUSE_PROV_IMAGE_ID] = &fuse_prov_img, + [FUSE_UP_IMAGE_ID] = &fuse_upgrade_img, + [DDR_IMEM_UDIMM_1D_IMAGE_ID] = &ddr_imem_udimm_1d_img, + [DDR_IMEM_UDIMM_2D_IMAGE_ID] = &ddr_imem_udimm_2d_img, + [DDR_DMEM_UDIMM_1D_IMAGE_ID] = &ddr_dmem_udimm_1d_img, + [DDR_DMEM_UDIMM_2D_IMAGE_ID] = &ddr_dmem_udimm_2d_img, + [DDR_IMEM_RDIMM_1D_IMAGE_ID] = &ddr_imem_rdimm_1d_img, + [DDR_IMEM_RDIMM_2D_IMAGE_ID] = &ddr_imem_rdimm_2d_img, + [DDR_DMEM_RDIMM_1D_IMAGE_ID] = &ddr_dmem_rdimm_1d_img, + [DDR_DMEM_RDIMM_2D_IMAGE_ID] = &ddr_dmem_rdimm_2d_img, +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h new file mode 100644 index 000000000..c70b4838f --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.h @@ -0,0 +1,155 @@ +/* + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef _CSF_HDR_H_ +#define _CSF_HDR_H_ + +#include "caam.h" +#include "hash.h" +#include "rsa.h" + +/* Barker code size in bytes */ +#define CSF_BARKER_LEN 4 /* barker code length in ESBC uboot client */ + /* header */ + +#ifdef CSF_HDR_CH3 +struct csf_hdr { + uint8_t barker[CSF_BARKER_LEN]; /* 0x00 Barker code */ + uint32_t srk_tbl_off; /* 0x04 SRK Table Offset */ + + struct { + uint8_t num_srk; /* 0x08 No. of keys */ + uint8_t srk_sel; /* Key no. to be used */ + uint8_t reserve; /* 0x0a rseerved */ + } len_kr; + uint8_t ie_flag; + + uint32_t uid_flag; + + uint32_t psign; /* 0x10 signature offset */ + uint32_t sign_len; /* 0x14 length of signature */ + + union { + struct { + uint32_t sg_table_offset; /* 0x18 SG Table Offset */ + uint32_t sg_entries; /* 0x1c no of entries in SG */ + } sg_isbc; + uint64_t img_addr; /* 64 bit pointer to ESBC Image */ + }; + + union { + struct { + uint32_t img_size; /* ESBC client img size in bytes */ + uint32_t ie_key_sel; + } img; + uint64_t entry_point; /* 0x20-0x24 ESBC entry point */ + }; + + uint32_t fsl_uid_0; /* 0x28 Freescale unique id 0 */ + uint32_t fsl_uid_1; /* 0x2c Freescale unique id 1 */ + uint32_t oem_uid_0; /* 0x30 OEM unique id 0 */ + uint32_t oem_uid_1; /* 0x34 OEM unique id 1 */ + uint32_t oem_uid_2; /* 0x38 OEM unique id 2 */ + uint32_t oem_uid_3; /* 0x3c OEM unique id 3 */ + uint32_t oem_uid_4; /* 0x40 OEM unique id 4 */ + + uint32_t reserved[3]; /* 0x44 - 0x4f */ +}; + +/* Srk table and key revocation check */ +#define UNREVOCABLE_KEY 8 +#define REVOC_KEY_ALIGN 7 +#define MAX_KEY_ENTRIES 8 + +#else + +/* CSF header for Chassis 2 */ +struct csf_hdr { + uint8_t barker[CSF_BARKER_LEN]; /* barker code */ + union { + uint32_t pkey; /* public key offset */ + uint32_t srk_tbl_off; + }; + + union { + uint32_t key_len; /* pub key length in bytes */ + struct { + uint32_t srk_table_flag:8; + uint32_t srk_sel:8; + uint32_t num_srk:16; + } len_kr; + }; + + uint32_t psign; /* signature offset */ + uint32_t sign_len; /* length of the signature in bytes */ + + /* SG Table used by ISBC header */ + union { + struct { + uint32_t sg_table_offset; /* 0x14 SG Table Offset */ + uint32_t sg_entries; /* no of entries in SG table */ + } sg_isbc; + struct { + uint32_t reserved1; /* Reserved field */ + uint32_t img_size; /* ESBC img size in bytes */ + } img; + }; + + uint32_t entry_point; /* ESBC client entry point */ + uint32_t reserved2; /* Scatter gather flag */ + uint32_t uid_flag; + uint32_t fsl_uid_0; + uint32_t oem_uid_0; + uint32_t reserved3[2]; + uint32_t fsl_uid_1; + uint32_t oem_uid_1; + + /* The entries below aren't present in ISBC header */ + uint64_t img_addr; /* 64 bit pointer to ESBC Image */ + uint32_t ie_flag; + uint32_t ie_key_sel; +}; + +/* Srk table and key revocation check */ +#define UNREVOCABLE_KEY 4 +#define REVOC_KEY_ALIGN 3 +#define MAX_KEY_ENTRIES 4 + +#endif + +struct srk_table { + uint32_t key_len; + uint8_t pkey[2 * RSA_4K_KEY_SZ_BYTES]; +}; + +/* + * This struct contains the following fields + * length of the segment + * Destination Target ID + * source address + * destination address + */ +struct sg_table { + uint32_t len; /* Length of Image */ + uint32_t res1; + union { + uint64_t src_addr; /* SRC Address of Image */ + struct { + uint32_t src_addr; + uint32_t dst_addr; + } img; + }; +}; + +int validate_esbc_header(void *img_hdr, void **img_key, uint32_t *key_len, + void **img_sign, uint32_t *sign_len, + enum sig_alg *algo); + +int calc_img_hash(struct csf_hdr *hdr, void *img_addr, uint32_t img_size, + uint8_t *img_hash, uint32_t *hash_len); + +#endif diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk new file mode 100644 index 000000000..d518dbba9 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr.mk @@ -0,0 +1,64 @@ +# +# Copyright 2020 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# +# + +CSF_HDR_SOURCES := $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/csf_hdr_parser.c + +CSF_HDR_SOURCES += $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/plat_img_parser.c + +PLAT_INCLUDES += -I$(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/ + +$(eval $(call add_define, CSF_HEADER_PREPENDED)) + + +# Path to CST directory is required to generate the CSF header +# and prepend it to image before fip image gets generated +ifeq (${CST_DIR},) + $(error Error: CST_DIR not set) +endif + +# Rules are created for generating and appending CSF header to images before +# FIT image generation + +# CST_BL31 +define CST_BL31_RULE +$(1): $(2) + @echo " Generating CSF Header for $$@ $$<" + $(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \ + --app $(2) ${BL31_INPUT_FILE} +endef + +CST_BL31_SUFFIX := .cst + +# CST_BL32 +define CST_BL32_RULE +$(1): $(2) + @echo " Generating CSF Header for $$@ $$<" + $(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \ + --app $(2) ${BL32_INPUT_FILE} +endef + +CST_BL32_SUFFIX := .cst + +# CST_BL33 +define CST_BL33_RULE +$(1): $(2) + @echo " Generating CSF Header for $$@ $$<" + $(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \ + --app $(2) ${BL33_INPUT_FILE} +endef + +CST_BL33_SUFFIX := .cst + +# CST_SCP_BL2 +define CST_SCP_BL2_RULE +$(1): $(2) + @echo " Generating CSF Header for $$@ $$<" + $(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \ + --app $(2) ${FUSE_INPUT_FILE} +endef + +CST_SCP_BL2_SUFFIX := .cst diff --git a/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c b/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c new file mode 100644 index 000000000..ec0679a90 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/csf_hdr_parser.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Maximum OID string length ("a.b.c.d.e.f ...") */ +#define MAX_OID_STR_LEN 64 + +#define LIB_NAME "NXP CSFv2" + +#ifdef CSF_HDR_CH3 +/* Barker Code for LS Ch3 ESBC Header */ +static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 }; +#else +static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; +#endif + +#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * RSA_1K_KEY_SZ_BYTES) || \ + ((key_len) == 2 * RSA_2K_KEY_SZ_BYTES) || \ + ((key_len) == 2 * RSA_4K_KEY_SZ_BYTES)) + +/* Flag to indicate if values are there in rotpk_hash_table */ +bool rotpk_not_dpld = true; +uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES]; +uint32_t num_rotpk_hash_entries; + +/* + * This function deploys the hashes of the various platform keys in + * rotpk_hash_table. This is done in case of secure boot after comparison + * of table's hash with the hash in SFP fuses. This installation is done + * only in the first header parsing. + */ +static int deploy_rotpk_hash_table(void *srk_buffer, uint16_t num_srk) +{ + void *ctx; + int ret = 0; + int i, j = 0; + unsigned int digest_size = SHA256_BYTES; + enum hash_algo algo = SHA256; + uint8_t hash[SHA256_BYTES]; + uint32_t srk_hash[SHA256_BYTES/4] __aligned(CACHE_WRITEBACK_GRANULE); + struct srk_table *srktbl = (void *)srk_buffer; + struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(get_sfp_addr() + + SFP_FUSE_REGS_OFFSET); + + + if (num_srk > MAX_KEY_ENTRIES) + return -1; + + ret = hash_init(algo, &ctx); + if (ret) + return -1; + + /* Update hash with that of SRK table */ + ret = hash_update(algo, ctx, + (uint8_t *)((uint8_t *)srk_buffer), + num_srk * sizeof(struct srk_table)); + if (ret) + return -1; + + /* Copy hash at destination buffer */ + ret = hash_final(algo, ctx, hash, digest_size); + if (ret) + return -1; + + /* Add comparison of hash with SFP hash here */ + for (i = 0; i < SHA256_BYTES/4; i++) + srk_hash[i] = + mmio_read_32((uintptr_t)&sfp_ccsr_regs->srk_hash[i]); + + VERBOSE("SRK table HASH\n"); + for (i = 0; i < 8; i++) + VERBOSE("%x\n", *((uint32_t *)hash + i)); + + if (memcmp(hash, srk_hash, SHA256_BYTES) != 0) { + ERROR("Error in installing ROTPK table\n"); + ERROR("SRK hash doesn't match the fuse hash\n"); + return -1; + } + + /* Hash table already deployed */ + if (rotpk_not_dpld == false) + return 0; + + for (i = 0; i < num_srk; i++) { + ret = hash_init(algo, &ctx); + if (ret) + return -1; + + /* Update hash with that of SRK table */ + ret = hash_update(algo, ctx, srktbl[i].pkey, srktbl[i].key_len); + if (ret) + return -1; + + /* Copy hash at destination buffer */ + ret = hash_final(algo, ctx, rotpk_hash_table[i], digest_size); + if (ret) + return -1; + + VERBOSE("Table key %d HASH\n", i); + for (j = 0; j < 8; j++) + VERBOSE("%x\n", *((uint32_t *)rotpk_hash_table[i] + j)); + } + rotpk_not_dpld = false; + num_rotpk_hash_entries = num_srk; + + return 0; +} + +/* + * Calculate hash of ESBC hdr and ESBC. This function calculates the + * single hash of ESBC header and ESBC image + */ +int calc_img_hash(struct csf_hdr *hdr, + void *img_addr, uint32_t img_size, + uint8_t *img_hash, uint32_t *hash_len) +{ + void *ctx; + int ret = 0; + unsigned int digest_size = SHA256_BYTES; + enum hash_algo algo = SHA256; + + ret = hash_init(algo, &ctx); + /* Copy hash at destination buffer */ + if (ret) + return -1; + + /* Update hash for CSF Header */ + ret = hash_update(algo, ctx, + (uint8_t *)hdr, sizeof(struct csf_hdr)); + if (ret) + return -1; + + /* Update hash with that of SRK table */ + ret = hash_update(algo, ctx, + (uint8_t *)((uint8_t *)hdr + hdr->srk_tbl_off), + hdr->len_kr.num_srk * sizeof(struct srk_table)); + if (ret) + return -1; + + /* Update hash for actual Image */ + ret = hash_update(algo, ctx, (uint8_t *)(img_addr), img_size); + if (ret) + return -1; + + /* Copy hash at destination buffer */ + ret = hash_final(algo, ctx, img_hash, digest_size); + if (ret) + return -1; + + *hash_len = digest_size; + + VERBOSE("IMG encoded HASH\n"); + for (int i = 0; i < 8; i++) + VERBOSE("%x\n", *((uint32_t *)img_hash + i)); + + return 0; +} + +/* This function checks if selected key is revoked or not.*/ +static uint32_t is_key_revoked(uint32_t keynum, uint32_t rev_flag) +{ + if (keynum == UNREVOCABLE_KEY) + return 0; + + if ((uint32_t)(1 << (REVOC_KEY_ALIGN - keynum)) & rev_flag) + return 1; + + return 0; +} + +/* Parse the header to extract the type of key, + * Check if key is not revoked + * and return the key , key length and key_type + */ +static uint32_t get_key(struct csf_hdr *hdr, uint8_t **key, uint32_t *len, + enum sig_alg *key_type) +{ + int i = 0; + uint32_t ret = 0; + uint32_t key_num, key_revoc_flag; + void *esbc = hdr; + struct srk_table *srktbl = (void *)((uint8_t *)esbc + hdr->srk_tbl_off); + bool sb; + uint32_t mode; + + /* We currently support only RSA keys and signature */ + *key_type = RSA; + + /* Check for number of SRK entries */ + if ((hdr->len_kr.num_srk == 0) || + (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) { + ERROR("Error in NUM entries in SRK Table\n"); + return -1; + } + + /* + * Check the key number field. It should be not greater than + * number of entreis in SRK table + */ + key_num = hdr->len_kr.srk_sel; + if (key_num == 0 || key_num > hdr->len_kr.num_srk) { + ERROR("Invalid Key number\n"); + return -1; + } + + /* Get revoc key from sfp */ + key_revoc_flag = get_key_revoc(); + + /* Check if selected key has been revoked */ + ret = is_key_revoked(key_num, key_revoc_flag); + if (ret) { + ERROR("Selected key has been revoked\n"); + return -1; + } + + /* Check for valid key length - allowed key sized 1k, 2k and 4K */ + for (i = 0; i < hdr->len_kr.num_srk; i++) { + if (!CHECK_KEY_LEN(srktbl[i].key_len)) { + ERROR("Invalid key length\n"); + return -1; + } + } + + /* We don't return error from here. While parsing we just try to + * install the srk table. Failure needs to be taken care of in + * case of secure boot. This failure will be handled at the time + * of rotpk comparison in plat_get_rotpk_info function + */ + sb = check_boot_mode_secure(&mode); + if (sb) { + ret = deploy_rotpk_hash_table(srktbl, hdr->len_kr.num_srk); + if (ret) { + ERROR("ROTPK FAILURE\n"); + /* For ITS =1 , return failure */ + if (mode) + return -1; + ERROR("SECURE BOOT DEV-ENV MODE:\n"); + ERROR("\tCHECK ROTPK !\n"); + ERROR("\tCONTINUING ON FAILURE...\n"); + } + } + + /* Return the length of the selected key */ + *len = srktbl[key_num - 1].key_len; + + /* Point key to the selected key */ + *key = (uint8_t *)&(srktbl[key_num - 1].pkey); + + return 0; +} + +/* + * This function would parse the CSF header and do the following: + * 1. Basic integrity checks + * 2. Key checks and extract the key from SRK/IE Table + * 3. Key hash comparison with SRKH in fuses in case of SRK Table + * 4. OEM/UID checks - To be added + * 5. Hash calculation for various components used in signature + * 6. Signature integrity checks + * return -> 0 on success, -1 on failure + */ +int validate_esbc_header(void *img_hdr, void **img_key, uint32_t *key_len, + void **img_sign, uint32_t *sign_len, + enum sig_alg *algo) +{ + struct csf_hdr *hdr = img_hdr; + uint8_t *s; + uint32_t ret = 0; + void *esbc = (uint8_t *)(uintptr_t)img_hdr; + uint8_t *key; + uint32_t klen; + + /* check barker code */ + if (memcmp(hdr->barker, barker_code, CSF_BARKER_LEN)) { + ERROR("Wrong barker code in header\n"); + return -1; + } + + ret = get_key(hdr, &key, &klen, algo); + if (ret != 0) + return -1; + + /* check signaure */ + if (klen == 2 * hdr->sign_len) { + /* check signature length */ + if (!((hdr->sign_len == RSA_1K_KEY_SZ_BYTES) || + (hdr->sign_len == RSA_2K_KEY_SZ_BYTES) || + (hdr->sign_len == RSA_4K_KEY_SZ_BYTES))) { + ERROR("Wrong Signature length in header\n"); + return -1; + } + } else { + ERROR("RSA key length not twice the signature length\n"); + return -1; + } + + /* modulus most significant bit should be set */ + + if ((key[0] & 0x80) == 0) { + ERROR("RSA Public key MSB not set\n"); + return -1; + } + + /* modulus value should be odd */ + if ((key[klen / 2 - 1] & 0x1) == 0) { + ERROR("Public key Modulus in header not odd\n"); + return -1; + } + + /* Check signature value < modulus value */ + s = (uint8_t *)(esbc + hdr->psign); + + if (!(memcmp(s, key, hdr->sign_len) < 0)) { + ERROR("Signature not less than modulus"); + return -1; + } + + /* Populate the return addresses */ + *img_sign = (void *)(s); + + /* Save the length of signature */ + *sign_len = hdr->sign_len; + + *img_key = (uint8_t *)key; + + *key_len = klen; + + return ret; +} diff --git a/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch2 b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch2 new file mode 100644 index 000000000..bf8934bc9 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch2 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - 1010/1040/2041/3041/4080/5020/5040/9131/9132/9164/4240/C290/LS1 +PLATFORM=LS1043 +# ESBC Flag. Specify ESBC=0 to sign u-boot and ESBC=1 to sign ESBC images.(default is 0) +ESBC=0 +--------------------------------------------------- +# Entry Point/Image start address field in the header.[Mandatory] +# (default=ADDRESS of first file specified in images) +ENTRY_POINT=10000000 +--------------------------------------------------- +# Specify the file name of the keys separated by comma. +# The number of files and key select should lie between 1 and 4 for 1040 and C290. +# For rest of the platforms only one key is required and key select should not be provided. + +# USAGE (for 4080/5020/5040/3041/2041/1010/913x): PRI_KEY = +# USAGE (for 1040/C290/9164/4240/LS1): PRI_KEY = , , , + +# PRI_KEY (Default private key :srk.pri) - [Optional] +PRI_KEY=srk.pri +# PUB_KEY (Default public key :srk.pub) - [Optional] +PUB_KEY=srk.pub +# Please provide KEY_SELECT(between 1 to 4) (Required for 1040/C290/9164/4240/LS1 only) - [Optional] +KEY_SELECT= +--------------------------------------------------- +# Specify SG table address, only for (2041/3041/4080/5020/5040) with ESBC=0 - [Optional] +SG_TABLE_ADDR= +--------------------------------------------------- +# Specify the target where image will be loaded. (Default is NOR_16B) - [Optional] +# Only required for Non-PBL Devices (1010/1040/9131/9132i/C290) +# Select from - NOR_8B/NOR_16B/NAND_8B_512/NAND_8B_2K/NAND_8B_4K/NAND_16B_512/NAND_16B_2K/NAND_16B_4K/SD/MMC/SPI +IMAGE_TARGET= +--------------------------------------------------- +# Specify IMAGE, Max 8 images are possible. DST_ADDR is required only for Non-PBL Platform. [Mandatory] +# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR} +IMAGE_1={bl2.bin,10000000,ffffffff} +IMAGE_2={,,} +IMAGE_3={,,} +IMAGE_4={,,} +IMAGE_5={,,} +IMAGE_6={,,} +IMAGE_7={,,} +IMAGE_8={,,} +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +--------------------------------------------------- +# Specify the file names of csf header and sg table. (Default :hdr.out) [Optional] +OUTPUT_HDR_FILENAME=hdr_bl2.out + +# Specify the file names of hash file and sign file. +HASH_FILENAME=img_hash.out +INPUT_SIGN_FILENAME=sign.out + +# Specify the signature size.It is mandatory when neither public key nor private key is specified. +# Signature size would be [0x80 for 1k key, 0x100 for 2k key, and 0x200 for 4k key]. +SIGN_SIZE= +--------------------------------------------------- +# Specify the output file name of sg table. (Default :sg_table.out). [Optional] +# Please note that OUTPUT SG BIN is only required for 2041/3041/4080/5020/5040 when ESBC flag is not set. +OUTPUT_SG_BIN= +--------------------------------------------------- +# Following fields are Required for 4240/9164/1040/C290 only + +# Specify House keeping Area +# Required for 4240/9164/1040/C290 only when ESBC flag is not set. [Mandatory] +HK_AREA_POINTER= +HK_AREA_SIZE= +--------------------------------------------------- +# Following field Required for 4240/9164/1040/C290 only +# Specify Secondary Image Flag. (0 or 1) - [Optional] +# (Default is 0) +SEC_IMAGE=0 +# Specify Manufacturing Protection Flag. (0 or 1) - [Optional] +# Required only for LS1(Default is 0) +MP_FLAG=1 +--------------------------------------------------- diff --git a/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3 b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3 new file mode 100644 index 000000000..5fdad9c6e --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3 @@ -0,0 +1,65 @@ +/* + * Copyright 2018-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - +# TRUST 3.2: LX2160 +PLATFORM=LS2088 +--------------------------------------------------- +# Entry Point/Image start address field in the header.[Mandatory] +# (default=ADDRESS of first file specified in images) +# Address can be 64 bit +ENTRY_POINT=1800A000 +--------------------------------------------------- +# Specify the Key Information. +# PUB_KEY [Mandatory] Comma Separated List +# Usage: ..... +PUB_KEY=srk.pub +# KEY_SELECT [Mandatory] +# USAGE (for TRUST 3.x): (between 1 to 8) +KEY_SELECT=1 +# PRI_KEY [Mandatory] Single Key Used for Signing +# USAGE: +PRI_KEY=srk.pri +--------------------------------------------------- +# Specify IMAGE, Max 8 images are possible. +# DST_ADDR is required only for Non-PBL Platform. [Mandatory] +# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR} +# Address can be 64 bit +IMAGE_1={bl2.bin,1800A000,ffffffff} +IMAGE_2={,,} +IMAGE_3={,,} +IMAGE_4={,,} +IMAGE_5={,,} +IMAGE_6={,,} +IMAGE_7={,,} +IMAGE_8={,,} +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID_0=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +OEM_UID_2= +OEM_UID_3= +OEM_UID_4= +--------------------------------------------------- +# Specify the output file names [Optional]. +# Default Values chosen in Tool +OUTPUT_HDR_FILENAME=hdr_bl2.out +IMAGE_HASH_FILENAME= +RSA_SIGN_FILENAME= +--------------------------------------------------- +# Specify The Flags. (0 or 1) - [Optional] +MP_FLAG=0 +ISS_FLAG=1 +LW_FLAG=0 +--------------------------------------------------- +# Specify VERBOSE as 1, if you want to Display Header Information [Optional] +VERBOSE=1 diff --git a/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3_2 b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3_2 new file mode 100644 index 000000000..cc7c07c2e --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_bl2_ch3_2 @@ -0,0 +1,65 @@ +/* + * Copyright 2018-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - +# TRUST 3.2: LX2160 +PLATFORM=LX2160 +--------------------------------------------------- +# Entry Point/Image start address field in the header.[Mandatory] +# (default=ADDRESS of first file specified in images) +# Address can be 64 bit +ENTRY_POINT=1800D000 +--------------------------------------------------- +# Specify the Key Information. +# PUB_KEY [Mandatory] Comma Separated List +# Usage: ..... +PUB_KEY=srk.pub +# KEY_SELECT [Mandatory] +# USAGE (for TRUST 3.x): (between 1 to 8) +KEY_SELECT=1 +# PRI_KEY [Mandatory] Single Key Used for Signing +# USAGE: +PRI_KEY=srk.pri +--------------------------------------------------- +# Specify IMAGE, Max 8 images are possible. +# DST_ADDR is required only for Non-PBL Platform. [Mandatory] +# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR} +# Address can be 64 bit +IMAGE_1={bl2.bin,1800D000,ffffffff} +IMAGE_2={,,} +IMAGE_3={,,} +IMAGE_4={,,} +IMAGE_5={,,} +IMAGE_6={,,} +IMAGE_7={,,} +IMAGE_8={,,} +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID_0=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +OEM_UID_2= +OEM_UID_3= +OEM_UID_4= +--------------------------------------------------- +# Specify the output file names [Optional]. +# Default Values chosen in Tool +OUTPUT_HDR_FILENAME=hdr_bl2.out +IMAGE_HASH_FILENAME= +RSA_SIGN_FILENAME= +--------------------------------------------------- +# Specify The Flags. (0 or 1) - [Optional] +MP_FLAG=0 +ISS_FLAG=1 +LW_FLAG=0 +--------------------------------------------------- +# Specify VERBOSE as 1, if you want to Display Header Information [Optional] +VERBOSE=1 diff --git a/drivers/nxp/auth/csf_hdr_parser/input_blx_ch2 b/drivers/nxp/auth/csf_hdr_parser/input_blx_ch2 new file mode 100644 index 000000000..93b020be0 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_blx_ch2 @@ -0,0 +1,30 @@ +/* + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - 1010/1040/2041/3041/4080/5020/5040/9131/9132/9164/4240/C290/LS1 +PLATFORM=LS1043 +# ESBC Flag. Specify ESBC=0 to sign u-boot and ESBC=1 to sign ESBC images.(default is 0) +ESBC=1 +--------------------------------------------------- +# Specify the file name of the keys separated by comma. + +# PRI_KEY (Default private key :srk.pri) - [Optional] +PRI_KEY=srk.pri +# PUB_KEY (Default public key :srk.pub) - [Optional] +PUB_KEY=srk.pub +# Please provide KEY_SELECT(between 1 to 4) (Required for 1040/C290/9164/4240 only) - [Optional] +KEY_SELECT=1 +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +--------------------------------------------------- diff --git a/drivers/nxp/auth/csf_hdr_parser/input_blx_ch3 b/drivers/nxp/auth/csf_hdr_parser/input_blx_ch3 new file mode 100644 index 000000000..18e8e3b73 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_blx_ch3 @@ -0,0 +1,37 @@ +/* + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +ESBC=1 +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - +# TRUST 3.0: LS2085 +# TRUST 3.1: LS2088, LS1088 +PLATFORM=LS2088 +--------------------------------------------------- +# Specify the Key Information. +# PUB_KEY [Mandatory] Comma Separated List +# Usage: ..... +PUB_KEY=srk.pub +# KEY_SELECT [Mandatory] +# USAGE (for TRUST 3.x): (between 1 to 8) +KEY_SELECT=1 +# PRI_KEY [Mandatory] Single Key Used for Signing +# USAGE: +PRI_KEY=srk.pri + +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID_0=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +OEM_UID_2= +OEM_UID_3= +OEM_UID_4= +--------------------------------------------------- diff --git a/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3 b/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3 new file mode 100644 index 000000000..9111a2a29 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3 @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - +# TRUST 3.0: LS2085 +# TRUST 3.1: LS2088, LS1088 +PLATFORM=LS2088 +--------------------------------------------------- +# Specify the Key Information. +# PUB_KEY [Mandatory] Comma Separated List +# Usage: ..... +PUB_KEY=srk.pub +# KEY_SELECT [Mandatory] +# USAGE (for TRUST 3.x): (between 1 to 8) +KEY_SELECT=1 +# PRI_KEY [Mandatory] Single Key Used for Signing +# USAGE: +PRI_KEY=srk.pri +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID_0=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +OEM_UID_2= +OEM_UID_3= +OEM_UID_4= +--------------------------------------------------- +# Specify The Flags. (0 or 1) - [Optional] +MP_FLAG=0 +ISS_FLAG=1 +LW_FLAG=0 +--------------------------------------------------- +# Specify VERBOSE as 1, if you want to Display Header Information [Optional] +VERBOSE=1 +--------------------------------------------------- diff --git a/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3_2 b/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3_2 new file mode 100644 index 000000000..c2d7ce43e --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/input_pbi_ch3_2 @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +--------------------------------------------------- +# Specify the platform. [Mandatory] +# Choose Platform - +# TRUST 3.0: LS2085 +# TRUST 3.1: LS2088, LS1088 +PLATFORM=LX2160 +--------------------------------------------------- +# Specify the Key Information. +# PUB_KEY [Mandatory] Comma Separated List +# Usage: ..... +PUB_KEY=srk.pub +# KEY_SELECT [Mandatory] +# USAGE (for TRUST 3.x): (between 1 to 8) +KEY_SELECT=1 +# PRI_KEY [Mandatory] Single Key Used for Signing +# USAGE: +PRI_KEY=srk.pri +--------------------------------------------------- +# Specify OEM AND FSL ID to be populated in header. [Optional] +# e.g FSL_UID_0=11111111 +FSL_UID_0= +FSL_UID_1= +OEM_UID_0= +OEM_UID_1= +OEM_UID_2= +OEM_UID_3= +OEM_UID_4= +--------------------------------------------------- +# Specify The Flags. (0 or 1) - [Optional] +MP_FLAG=0 +ISS_FLAG=1 +LW_FLAG=0 +--------------------------------------------------- +# Specify VERBOSE as 1, if you want to Display Header Information [Optional] +VERBOSE=1 +--------------------------------------------------- diff --git a/drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c b/drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c new file mode 100644 index 000000000..f369094d7 --- /dev/null +++ b/drivers/nxp/auth/csf_hdr_parser/plat_img_parser.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. + * Copyright 2017-2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Temporary variables to speed up the authentication parameters search. These + * variables are assigned once during the integrity check and used any time an + * authentication parameter is requested, so we do not have to parse the image + * again. + */ + +/* Hash of Image + CSF Header + SRK table */ +uint8_t img_hash[SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE); +uint32_t hash_len; + +/* Key being used for authentication + * Points to the key in CSF header copied in DDR + * ESBC client key + */ +void *img_key; +uint32_t key_len; + +/* ESBC client signature */ +void *img_sign; +uint32_t sign_len; +enum sig_alg alg; + +/* Maximum OID string length ("a.b.c.d.e.f ...") */ +#define MAX_OID_STR_LEN 64 + +#define LIB_NAME "NXP CSFv2" + +/* + * Clear all static temporary variables. + */ +static void clear_temp_vars(void) +{ +#define ZERO_AND_CLEAN(x) \ + do { \ + zeromem(&x, sizeof(x)); \ + clean_dcache_range((uintptr_t)&x, sizeof(x)); \ + } while (0) + + ZERO_AND_CLEAN(img_key); + ZERO_AND_CLEAN(img_sign); + ZERO_AND_CLEAN(img_hash); + ZERO_AND_CLEAN(key_len); + ZERO_AND_CLEAN(hash_len); + ZERO_AND_CLEAN(sign_len); + +#undef ZERO_AND_CLEAN +} + +/* Exported functions */ + +static void init(void) +{ + clear_temp_vars(); +} + +/* + * This function would check the integrity of the CSF header + */ +static int check_integrity(void *img, unsigned int img_len) +{ + + int ret = 0; + /* + * Image is appended at an offset of 16K (IMG_OFFSET) to the header. + * So the size in header should be equal to img_len - IMG_OFFSET + */ + VERBOSE("Barker code is %x\n", *(unsigned int *)img); + ret = validate_esbc_header(img, &img_key, &key_len, &img_sign, + &sign_len, &alg); + if (ret < 0) { + ERROR("Header authentication failed\n"); + clear_temp_vars(); + return IMG_PARSER_ERR; + } + /* Calculate the hash of various components from the image */ + ret = calc_img_hash(img, (uint8_t *)img + CSF_HDR_SZ, + img_len - CSF_HDR_SZ, img_hash, &hash_len); + if (ret) { + ERROR("Issue in hash calculation %d\n", ret); + clear_temp_vars(); + return IMG_PARSER_ERR; + } + + return IMG_PARSER_OK; +} + +/* + * Extract an authentication parameter from CSF header + * + * CSF header has already been parsed and the required information like + * hash of data, signature, length stored in global variables has been + * extracted in chek_integrity function. This data + * is returned back to the caller. + */ +static int get_auth_param(const auth_param_type_desc_t *type_desc, + void *img, unsigned int img_len, + void **param, unsigned int *param_len) +{ + int rc = IMG_PARSER_OK; + + /* We do not use img because the check_integrity function has already + * extracted the relevant data ( pk, sig_alg, etc) + */ + + switch (type_desc->type) { + /* Hash will be returned for comparison with signature */ + case AUTH_PARAM_HASH: + *param = (void *)img_hash; + *param_len = (unsigned int)SHA256_BYTES; + break; + /* Return the public key used for signature extracted from the SRK table + * after checks with key revocation + */ + case AUTH_PARAM_PUB_KEY: + /* Get the subject public key */ + /* For a 1K key - the length would be 2k/8 = 0x100 bytes + * 2K RSA key - 0x200 , 4K RSA - 0x400 + */ + *param = img_key; + *param_len = (unsigned int)key_len; + break; + /* Call a function to tell if signature is RSA or ECDSA. ECDSA to be + * supported in later platforms like LX2 etc + */ + case AUTH_PARAM_SIG_ALG: + /* Algo will be signature - RSA or ECDSA on hash */ + *param = (void *)&alg; + *param_len = 4; + break; + /* Return the signature */ + case AUTH_PARAM_SIG: + *param = img_sign; + *param_len = (unsigned int)sign_len; + break; + case AUTH_PARAM_NV_CTR: + default: + rc = IMG_PARSER_ERR_NOT_FOUND; + break; + } + return rc; +} + +REGISTER_IMG_PARSER_LIB(IMG_PLAT, LIB_NAME, init, + check_integrity, get_auth_param); diff --git a/drivers/nxp/auth/tbbr/tbbr_cot.c b/drivers/nxp/auth/tbbr/tbbr_cot.c new file mode 100644 index 000000000..62faa841b --- /dev/null +++ b/drivers/nxp/auth/tbbr/tbbr_cot.c @@ -0,0 +1,812 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * Copyright 2020 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#if USE_TBBR_DEFS +#include +#else +#include +#endif + + +#if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256 +#define HASH_DER_LEN 51 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA384 +#define HASH_DER_LEN 67 +#elif TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA512 +#define HASH_DER_LEN 83 +#else +#error "Invalid value for TF_MBEDTLS_HASH_ALG_ID" +#endif + +/* + * The platform must allocate buffers to store the authentication parameters + * extracted from the certificates. In this case, because of the way the CoT is + * established, we can reuse some of the buffers on different stages + */ + +static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN]; + +static unsigned char soc_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN]; +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char non_trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; +static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN]; +static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; + +static unsigned char ddr_fw_content_pk_buf[PK_DER_LEN]; +static unsigned char ddr_imem_udimm_1d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_imem_udimm_2d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_dmem_udimm_1d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_dmem_udimm_2d_hash_buf[HASH_DER_LEN]; + +static unsigned char ddr_imem_rdimm_1d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_imem_rdimm_2d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_dmem_rdimm_1d_hash_buf[HASH_DER_LEN]; +static unsigned char ddr_dmem_rdimm_2d_hash_buf[HASH_DER_LEN]; + +/* + * Parameter type descriptors + */ +static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID); + +static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, 0); +static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG, 0); +static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_SIG_ALG, 0); +static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_RAW_DATA, 0); + + +static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); +static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID); +static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID); +static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID); +static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID); +static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID); +static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID); +static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID); + +static auth_param_type_desc_t ddr_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, DDR_FW_CONTENT_CERT_PK_OID); + +static auth_param_type_desc_t ddr_imem_udimm_1d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_IMEM_UDIMM_1D_HASH_OID); +static auth_param_type_desc_t ddr_imem_udimm_2d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_IMEM_UDIMM_2D_HASH_OID); +static auth_param_type_desc_t ddr_dmem_udimm_1d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_DMEM_UDIMM_1D_HASH_OID); +static auth_param_type_desc_t ddr_dmem_udimm_2d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_DMEM_UDIMM_2D_HASH_OID); + +static auth_param_type_desc_t ddr_imem_rdimm_1d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_IMEM_RDIMM_1D_HASH_OID); +static auth_param_type_desc_t ddr_imem_rdimm_2d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_IMEM_RDIMM_2D_HASH_OID); +static auth_param_type_desc_t ddr_dmem_rdimm_1d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_DMEM_RDIMM_1D_HASH_OID); +static auth_param_type_desc_t ddr_dmem_rdimm_2d_fw_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, DDR_DMEM_RDIMM_2D_HASH_OID); + + +/* + * Trusted key certificate + */ +static const auth_img_desc_t trusted_key_cert = { + .img_id = TRUSTED_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &trusted_world_pk, + .data = { + .ptr = (void *)trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + }, + [1] = { + .type_desc = &non_trusted_world_pk, + .data = { + .ptr = (void *)non_trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; + +/* + * SoC Firmware + */ +static const auth_img_desc_t soc_fw_key_cert = { + .img_id = SOC_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t soc_fw_content_cert = { + .img_id = SOC_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &soc_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &soc_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &soc_fw_hash, + .data = { + .ptr = (void *)soc_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &soc_fw_config_hash, + .data = { + .ptr = (void *)soc_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl31_image = { + .img_id = BL31_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_hash + } + } + } +}; +/* SOC FW Config */ +static const auth_img_desc_t soc_fw_config = { + .img_id = SOC_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &soc_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &soc_fw_config_hash + } + } + } +}; +/* + * Trusted OS Firmware + */ +static const auth_img_desc_t trusted_os_fw_key_cert = { + .img_id = TRUSTED_OS_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t trusted_os_fw_content_cert = { + .img_id = TRUSTED_OS_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_os_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &tos_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &tos_fw_hash, + .data = { + .ptr = (void *)tos_fw_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &tos_fw_extra1_hash, + .data = { + .ptr = (void *)tos_fw_extra1_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &tos_fw_extra2_hash, + .data = { + .ptr = (void *)tos_fw_extra2_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &tos_fw_config_hash, + .data = { + .ptr = (void *)tos_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl32_image = { + .img_id = BL32_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra1_image = { + .img_id = BL32_EXTRA1_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra1_hash + } + } + } +}; +static const auth_img_desc_t bl32_extra2_image = { + .img_id = BL32_EXTRA2_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_extra2_hash + } + } + } +}; +/* TOS FW Config */ +static const auth_img_desc_t tos_fw_config = { + .img_id = TOS_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &trusted_os_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &tos_fw_config_hash + } + } + } +}; +/* + * Non-Trusted Firmware + */ +static const auth_img_desc_t non_trusted_fw_key_cert = { + .img_id = NON_TRUSTED_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t non_trusted_fw_content_cert = { + .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &non_trusted_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &nt_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_world_bl_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &nt_fw_config_hash, + .data = { + .ptr = (void *)nt_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_world_bl_hash + } + } + } +}; +/* NT FW Config */ +static const auth_img_desc_t nt_fw_config = { + .img_id = NT_FW_CONFIG_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_fw_config_hash + } + } + } +}; +/* + * DDR Firmware + */ +static const auth_img_desc_t ddr_fw_key_cert = { + .img_id = DDR_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &ddr_fw_content_pk, + .data = { + .ptr = (void *)ddr_fw_content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t ddr_udimm_fw_content_cert = { + .img_id = DDR_UDIMM_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &ddr_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &ddr_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &ddr_imem_udimm_1d_fw_hash, + .data = { + .ptr = (void *)ddr_imem_udimm_1d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &ddr_imem_udimm_2d_fw_hash, + .data = { + .ptr = (void *)ddr_imem_udimm_2d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &ddr_dmem_udimm_1d_fw_hash, + .data = { + .ptr = (void *)ddr_dmem_udimm_1d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &ddr_dmem_udimm_2d_fw_hash, + .data = { + .ptr = (void *)ddr_dmem_udimm_2d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + } +}; + +static const auth_img_desc_t ddr_imem_udimm_1d_img = { + .img_id = DDR_IMEM_UDIMM_1D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_udimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_imem_udimm_1d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_udimm_2d_img = { + .img_id = DDR_IMEM_UDIMM_2D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_udimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_imem_udimm_2d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_udimm_1d_img = { + .img_id = DDR_DMEM_UDIMM_1D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_udimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_dmem_udimm_1d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_udimm_2d_img = { + .img_id = DDR_DMEM_UDIMM_2D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_udimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_dmem_udimm_2d_fw_hash + } + } + } +}; + +static const auth_img_desc_t ddr_rdimm_fw_content_cert = { + .img_id = DDR_RDIMM_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &ddr_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &ddr_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &ddr_imem_rdimm_1d_fw_hash, + .data = { + .ptr = (void *)ddr_imem_rdimm_1d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &ddr_imem_rdimm_2d_fw_hash, + .data = { + .ptr = (void *)ddr_imem_rdimm_2d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [2] = { + .type_desc = &ddr_dmem_rdimm_1d_fw_hash, + .data = { + .ptr = (void *)ddr_dmem_rdimm_1d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [3] = { + .type_desc = &ddr_dmem_rdimm_2d_fw_hash, + .data = { + .ptr = (void *)ddr_dmem_rdimm_2d_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + } +}; + +static const auth_img_desc_t ddr_imem_rdimm_1d_img = { + .img_id = DDR_IMEM_RDIMM_1D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_rdimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_imem_rdimm_1d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_imem_rdimm_2d_img = { + .img_id = DDR_IMEM_RDIMM_2D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_rdimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_imem_rdimm_2d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_rdimm_1d_img = { + .img_id = DDR_DMEM_RDIMM_1D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_rdimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_dmem_rdimm_1d_fw_hash + } + } + } +}; +static const auth_img_desc_t ddr_dmem_rdimm_2d_img = { + .img_id = DDR_DMEM_RDIMM_2D_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &ddr_rdimm_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &ddr_dmem_rdimm_2d_fw_hash + } + } + } +}; + +/* + * TBBR Chain of trust definition + */ + +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert, + [SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert, + [BL31_IMAGE_ID] = &bl31_image, + [SOC_FW_CONFIG_ID] = &soc_fw_config, + [TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert, + [BL32_IMAGE_ID] = &bl32_image, + [BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image, + [BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image, + [TOS_FW_CONFIG_ID] = &tos_fw_config, + [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, + [NT_FW_CONFIG_ID] = &nt_fw_config, + [DDR_FW_KEY_CERT_ID] = &ddr_fw_key_cert, + [DDR_UDIMM_FW_CONTENT_CERT_ID] = &ddr_udimm_fw_content_cert, + [DDR_RDIMM_FW_CONTENT_CERT_ID] = &ddr_rdimm_fw_content_cert, + [DDR_IMEM_UDIMM_1D_IMAGE_ID] = &ddr_imem_udimm_1d_img, + [DDR_IMEM_UDIMM_2D_IMAGE_ID] = &ddr_imem_udimm_2d_img, + [DDR_DMEM_UDIMM_1D_IMAGE_ID] = &ddr_dmem_udimm_1d_img, + [DDR_DMEM_UDIMM_2D_IMAGE_ID] = &ddr_dmem_udimm_2d_img, + [DDR_IMEM_RDIMM_1D_IMAGE_ID] = &ddr_imem_rdimm_1d_img, + [DDR_IMEM_RDIMM_2D_IMAGE_ID] = &ddr_imem_rdimm_2d_img, + [DDR_DMEM_RDIMM_1D_IMAGE_ID] = &ddr_dmem_rdimm_1d_img, + [DDR_DMEM_RDIMM_2D_IMAGE_ID] = &ddr_dmem_rdimm_2d_img, +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); -- cgit v1.2.3