diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index 2025243..f5c8bc9 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -33,7 +33,7 @@ - ``GENERATE_COT=1`` In the case of Arm platforms, the location of the ROTPK hash must also be - specified at build time. Two locations are currently supported (see + specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted @@ -41,17 +41,16 @@ registers are read-only. On FVP Base and Cortex models, the registers are read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. - On both Juno and FVP models, the default value corresponds to an - ECDSA-SECP256R1 public key hash, whose private part is not currently - available. + On Juno board, the default value corresponds to an ECDSA-SECP256R1 public + key hash, whose private part is not currently available. - - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public RSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. - - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded - in the Arm platform port. The private/public ECDSA key pair may be - found in ``plat/arm/board/common/rotpk``. + - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in + plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation + of the new hash if ROT_KEY is specified. Example of command line using RSA development keys: @@ -108,7 +107,7 @@ -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* .. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git .. _mbed TLS Security Center: https://tls.mbed.org/security diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2f44fe8..13d7058 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -468,7 +468,8 @@ entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. - ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this + file that contains the ROT private key in PEM format and enforces public key + hash generation. If ``SAVE_KEYS=1``, this file name will be used to save the key. - ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the @@ -657,4 +658,4 @@ -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index d24ad23..a6f3796 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -57,8 +57,7 @@ ``ARM_ROTPK_LOCATION`` are: - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage - registers. The private key corresponding to this ROTPK hash is not - currently available. + registers. - ``devel_rsa`` : return a development public key hash embedded in the BL1 and BL2 binaries. This hash has been obtained from the RSA public key ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use @@ -70,6 +69,12 @@ use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY`` when creating the certificates. +- ``ARM_ROTPK_HASH``: used when ``ARM_ROTPK_LOCATION=devel_*``. Specifies the + location of the ROTPK hash. Not expected to be a build option. This defaults to + ``plat/arm/board/common/rotpk/*_sha256.bin`` depending on the specified algorithm. + Providing ``ROT_KEY`` enforces generation of the hash from the ``ROT_KEY`` and + overwrites the default hash file. + - ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options: - ``tsram`` : Trusted SRAM (default option when TBB is not enabled) @@ -111,4 +116,4 @@ -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 5bd53f3..c825bf4 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -18,6 +18,12 @@ * Definitions common to all ARM standard platforms *****************************************************************************/ +/* + * Root of trust key hash lengths + */ +#define ARM_ROTPK_HEADER_LEN 19 +#define ARM_ROTPK_HASH_LEN 32 + /* Special value used to verify platform parameters from BL2 to BL31 */ #define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 02feec7..32dc9f9 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,11 @@ #define STATE_SW_E_PARAM (-2) #define STATE_SW_E_DENIED (-3) +/* plat_get_rotpk_info() flags */ +#define ARM_ROTPK_REGS_ID 1 +#define ARM_ROTPK_DEVEL_RSA_ID 2 +#define ARM_ROTPK_DEVEL_ECDSA_ID 3 + /* IO storage utility functions */ void arm_io_setup(void); @@ -255,9 +260,17 @@ __dead2 void plat_arm_error_handler(int err); /* - * Optional function in ARM standard platforms + * Optional functions in ARM standard platforms */ void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames); +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags); +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags); #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932..3c19230 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,130 +8,61 @@ #include #include +#include +#include +#include #include +#include +#include #include -#include #include +#include -/* SHA256 algorithm */ -#define SHA256_BYTES 32 -/* ROTPK locations */ -#define ARM_ROTPK_REGS_ID 1 -#define ARM_ROTPK_DEVEL_RSA_ID 2 -#define ARM_ROTPK_DEVEL_ECDSA_ID 3 - -static const unsigned char rotpk_hash_hdr[] = \ - "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ - "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; -static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1; -static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES]; - -/* Use the cryptocell variants if Cryptocell is present */ #if !ARM_CRYPTOCELL_INTEG #if !ARM_ROTPK_LOCATION_ID #error "ARM_ROTPK_LOCATION_ID not defined" #endif +#endif /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \ - "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \ - "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \ - "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA"; -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) -static const unsigned char arm_devel_rotpk_hash[] = \ - "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \ - "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \ - "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \ - "\xA0\xB0\x20\x86\x4E\x6C\x07\x17"; -#endif +extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[]; + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; /* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } + * Return the ROTPK hash stored in dedicated registers. */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, +int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, unsigned int *flags) { uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; assert(key_ptr != NULL); assert(key_len != NULL); assert(flags != NULL); /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; -#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) - memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES); -#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) - uint32_t *src, tmp; - unsigned int words, i; + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; - /* - * Append the hash from Trusted Root-Key Storage registers. The hash has - * not been written linearly into the registers, so we have to do a bit - * of byte swapping: - * - * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C - * +---------------------------------------------------------------+ - * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | - * +---------------------------------------------------------------+ - * | ... ... | | ... ... | - * | +--------------------+ | +-------+ - * | | | | - * +----------------------------+ +----------------------------+ - * | | | | - * +-------+ | +--------------------+ | - * | | | | - * v v v v - * +---------------------------------------------------------------+ - * | | | - * +---------------------------------------------------------------+ - * 0 15 16 31 - * - * Additionally, we have to access the registers in 32-bit words - */ - words = SHA256_BYTES >> 3; + words = ARM_ROTPK_HASH_LEN >> 2; - /* Swap bytes 0-15 (first four registers) */ src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; for (i = 0 ; i < words ; i++) { tmp = src[words - 1 - i]; /* Words are read in little endian */ - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); - *dst++ = (uint8_t)((tmp >> 8) & 0xFF); *dst++ = (uint8_t)(tmp & 0xFF); - } - - /* Swap bytes 16-31 (last four registers) */ - src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2); - for (i = 0 ; i < words ; i++) { - tmp = src[words - 1 - i]; - *dst++ = (uint8_t)((tmp >> 24) & 0xFF); - *dst++ = (uint8_t)((tmp >> 16) & 0xFF); *dst++ = (uint8_t)((tmp >> 8) & 0xFF); - *dst++ = (uint8_t)(tmp & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); } -#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \ - || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */ *key_ptr = (void *)rotpk_hash_der; *key_len = (unsigned int)sizeof(rotpk_hash_der); @@ -139,6 +70,65 @@ return 0; } +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) +/* + * Return development ROTPK hash generated from ROT_KEY. + */ +int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = arm_rotpk_header; + *key_len = arm_rotpk_hash_end - arm_rotpk_header; + *flags = ROTPK_IS_HASH; + return 0; +} +#endif + +#if ARM_CRYPTOCELL_INTEG +/* + * Return ROTPK hash from CryptoCell. + */ +int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + unsigned char *dst; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + *key_ptr = rotpk_hash_der; + *key_len = sizeof(rotpk_hash_der); + return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags); +} +#endif + +/* + * Wraper function for most Arm platforms to get ROTPK hash. + */ +int arm_get_rotpk_info(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return arm_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} + /* * Return the non-volatile counter value stored in the platform. The cookie * will contain the OID of the counter in the certificate. @@ -179,37 +169,3 @@ { return 1; } -#else /* ARM_CRYPTOCELL_INTEG */ - -#include - -/* - * Return the ROTPK hash in the following ASN.1 structure in DER format: - * - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL - * } - * - * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING - * } - */ -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - unsigned int *flags) -{ - unsigned char *dst; - - assert(key_ptr != NULL); - assert(key_len != NULL); - assert(flags != NULL); - - /* Copy the DER header */ - memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); - dst = &rotpk_hash_der[rotpk_hash_hdr_len]; - *key_ptr = rotpk_hash_der; - *key_len = sizeof(rotpk_hash_der); - return cc_get_rotpk_hash(dst, SHA256_BYTES, flags); -} -#endif /* ARM_CRYPTOCELL_INTEG */ diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index b98dfd4..da63430 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -12,31 +12,60 @@ BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c ifneq (${TRUSTED_BOARD_BOOT},0) - ifneq (${ARM_CRYPTOCELL_INTEG}, 1) - # ROTPK hash location - ifeq (${ARM_ROTPK_LOCATION}, regs) - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) - KEY_ALG := rsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID - else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) - KEY_ALG := ecdsa - ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID - else - $(error "Unsupported ARM_ROTPK_LOCATION value") - endif - $(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) +ifneq (${ARM_CRYPTOCELL_INTEG}, 1) +# ROTPK hash location +ifeq (${ARM_ROTPK_LOCATION}, regs) + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID +else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa) + KEY_ALG := rsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa) + KEY_ALG := ecdsa + ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID + ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin +$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"')) +$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH) +$(warning Development keys support for FVP is deprecated. Use `regs` \ +option instead) +else + $(error "Unsupported ARM_ROTPK_LOCATION value") +endif - # Certificate NV-Counters. Use values corresponding to tied off values in - # ARM development platforms - TFW_NVCTR_VAL ?= 31 - NTFW_NVCTR_VAL ?= 223 - else - # Certificate NV-Counters when CryptoCell is integrated. For development - # platforms we set the counter to first valid value. - TFW_NVCTR_VAL ?= 0 - NTFW_NVCTR_VAL ?= 0 - endif - BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c - BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c +$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) + +# Force generation of the new hash if ROT_KEY is specified +ifdef ROT_KEY + HASH_PREREQUISITES = $(ROT_KEY) FORCE +FORCE: +else + HASH_PREREQUISITES = $(ROT_KEY) +endif + +$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES) +ifndef ROT_KEY + $(error Cannot generate hash: no ROT_KEY defined) +endif + openssl rsa -in $< -pubout -outform DER | openssl dgst \ + -sha256 -binary > $@ + +# Certificate NV-Counters. Use values corresponding to tied off values in +# ARM development platforms +TFW_NVCTR_VAL ?= 31 +NTFW_NVCTR_VAL ?= 223 +else +# Certificate NV-Counters when CryptoCell is integrated. For development +# platforms we set the counter to first valid value. +TFW_NVCTR_VAL ?= 0 +NTFW_NVCTR_VAL ?= 0 +endif +BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S +BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S + endif diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S new file mode 100644 index 0000000..80f2192 --- /dev/null +++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "plat/arm/common/arm_def.h" + + .global arm_rotpk_header + .global arm_rotpk_header_end + .section .rodata.arm_rotpk_hash, "a" + +arm_rotpk_header: + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +arm_rotpk_header_len: + +#ifdef ARM_ROTPK_HASH + .global arm_rotpk_hash_end + .incbin ARM_ROTPK_HASH +arm_rotpk_hash_end: +#endif + +.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header +.error "Invalid ROTPK header length." +.endif diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index dc50764..a09b80e 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,12 +9,31 @@ #include #include - +#include #include #include #include /* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} + +/* * Store a new non-volatile counter value. * * On some FVP versions, the non-volatile counters are read-only so this diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 97a326c..6fb34c4 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -139,7 +139,6 @@ plat/arm/board/fvp/fvp_bl1_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} @@ -158,7 +157,6 @@ plat/arm/board/fvp/fvp_bl2_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_trusted_boot.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${FVP_SECURITY_SOURCES} @@ -302,8 +300,10 @@ include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c +BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c # FVP being a development platform, enable capability to disable Authentication # dynamically if TRUSTED_BOARD_BOOT is set. -ifeq (${TRUSTED_BOARD_BOOT}, 1) - DYN_DISABLE_AUTH := 1 +DYN_DISABLE_AUTH := 1 endif diff --git a/plat/arm/board/juno/juno_trusted_boot.c b/plat/arm/board/juno/juno_trusted_boot.c new file mode 100644 index 0000000..25a7470 --- /dev/null +++ b/plat/arm/board/juno/juno_trusted_boot.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + +static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN]; + +extern unsigned char arm_rotpk_header[]; + +/* + * Return the ROTPK hash stored in the registers of Juno board. + */ +static int juno_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + uint8_t *dst; + uint32_t *src, tmp; + unsigned int words, i; + + assert(key_ptr != NULL); + assert(key_len != NULL); + assert(flags != NULL); + + /* Copy the DER header */ + memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN); + dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN]; + + + /* + * Append the hash from Trusted Root-Key Storage registers. The hash has + * not been written linearly into the registers, so we have to do a bit + * of byte swapping: + * + * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C + * +---------------------------------------------------------------+ + * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 | + * +---------------------------------------------------------------+ + * | ... ... | | ... ... | + * | +--------------------+ | +-------+ + * | | | | + * +----------------------------+ +----------------------------+ + * | | | | + * +-------+ | +--------------------+ | + * | | | | + * v v v v + * +---------------------------------------------------------------+ + * | | | + * +---------------------------------------------------------------+ + * 0 15 16 31 + * + * Additionally, we have to access the registers in 32-bit words + */ + words = ARM_ROTPK_HASH_LEN >> 3; + + /* Swap bytes 0-15 (first four registers) */ + src = (uint32_t *)TZ_PUB_KEY_HASH_BASE; + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + /* Words are read in little endian */ + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + /* Swap bytes 16-31 (last four registers) */ + src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + ARM_ROTPK_HASH_LEN / 2); + for (i = 0 ; i < words ; i++) { + tmp = src[words - 1 - i]; + *dst++ = (uint8_t)((tmp >> 24) & 0xFF); + *dst++ = (uint8_t)((tmp >> 16) & 0xFF); + *dst++ = (uint8_t)((tmp >> 8) & 0xFF); + *dst++ = (uint8_t)(tmp & 0xFF); + } + + *key_ptr = (void *)rotpk_hash_der; + *key_len = (unsigned int)sizeof(rotpk_hash_der); + *flags = ROTPK_IS_HASH; + return 0; +} + +#endif + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ +#if ARM_CRYPTOCELL_INTEG + return arm_get_rotpk_info_cc(key_ptr, key_len, flags); +#else + +#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \ + (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) + return arm_get_rotpk_info_dev(key_ptr, key_len, flags); +#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) + return juno_get_rotpk_info_regs(key_ptr, key_len, flags); +#else + return 1; +#endif + +#endif /* ARM_CRYPTOCELL_INTEG */ +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index bd6bae5..a85ad53 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -91,6 +91,11 @@ BL1_SOURCES += drivers/arm/css/sds/sds.c endif +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +BL2_SOURCES += plat/arm/board/juno/juno_trusted_boot.c +endif + endif ifneq (${RESET_TO_BL31},0) diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index 43c37ff..13a3de3 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -29,6 +29,11 @@ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/rde1edge/rde1edge_trusted_boot.c b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c new file mode 100644 index 0000000..c271f7f --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index ca1e95e..84a21b9 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -29,6 +29,11 @@ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c new file mode 100644 index 0000000..c271f7f --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index ce2717f..c6b2d41 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -29,6 +29,11 @@ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +BL2_SOURCES += ${SGI575_BASE}/sgi575_trusted_boot.c +endif + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb diff --git a/plat/arm/board/sgi575/sgi575_trusted_boot.c b/plat/arm/board/sgi575/sgi575_trusted_boot.c new file mode 100644 index 0000000..c271f7f --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +} diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk index 7a843c3..f096ca5 100644 --- a/plat/arm/board/sgm775/platform.mk +++ b/plat/arm/board/sgm775/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,3 +21,8 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c + +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +BL2_SOURCES += ${SGM775_BASE}/sgm775_trusted_boot.c +endif diff --git a/plat/arm/board/sgm775/sgm775_trusted_boot.c b/plat/arm/board/sgm775/sgm775_trusted_boot.c new file mode 100644 index 0000000..c271f7f --- /dev/null +++ b/plat/arm/board/sgm775/sgm775_trusted_boot.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(key_ptr, key_len, flags); +}