arm-trusted-firmware/plat/arm/board/common/board_arm_trusted_boot.c

210 lines
5.3 KiB
C
Raw Normal View History

Add common ARM and CSS platform code This major change pulls out the common functionality from the FVP and Juno platform ports into the following categories: * (include/)plat/common. Common platform porting functionality that typically may be used by all platforms. * (include/)plat/arm/common. Common platform porting functionality that may be used by all ARM standard platforms. This includes all ARM development platforms like FVP and Juno but may also include non-ARM-owned platforms. * (include/)plat/arm/board/common. Common platform porting functionality for ARM development platforms at the board (off SoC) level. * (include/)plat/arm/css/common. Common platform porting functionality at the ARM Compute SubSystem (CSS) level. Juno is an example of a CSS-based platform. * (include/)plat/arm/soc/common. Common platform porting functionality at the ARM SoC level, which is not already defined at the ARM CSS level. No guarantees are made about the backward compatibility of functionality provided in (include/)plat/arm. Also remove any unnecessary variation between the ARM development platform ports, including: * Unify the way BL2 passes `bl31_params_t` to BL3-1. Use the Juno implementation, which copies the information from BL2 memory instead of expecting it to persist in shared memory. * Unify the TZC configuration. There is no need to add a region for SCP in Juno; it's enough to simply not allow any access to this reserved region. Also set region 0 to provide no access by default instead of assuming this is the case. * Unify the number of memory map regions required for ARM development platforms, although the actual ranges mapped for each platform may be different. For the FVP port, this reduces the mapped peripheral address space. These latter changes will only be observed when the platform ports are migrated to use the new common platform code in subsequent patches. Change-Id: Id9c269dd3dc6e74533d0e5116fdd826d53946dc8
2015-03-19 18:58:55 +00:00
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
Add common ARM and CSS platform code This major change pulls out the common functionality from the FVP and Juno platform ports into the following categories: * (include/)plat/common. Common platform porting functionality that typically may be used by all platforms. * (include/)plat/arm/common. Common platform porting functionality that may be used by all ARM standard platforms. This includes all ARM development platforms like FVP and Juno but may also include non-ARM-owned platforms. * (include/)plat/arm/board/common. Common platform porting functionality for ARM development platforms at the board (off SoC) level. * (include/)plat/arm/css/common. Common platform porting functionality at the ARM Compute SubSystem (CSS) level. Juno is an example of a CSS-based platform. * (include/)plat/arm/soc/common. Common platform porting functionality at the ARM SoC level, which is not already defined at the ARM CSS level. No guarantees are made about the backward compatibility of functionality provided in (include/)plat/arm. Also remove any unnecessary variation between the ARM development platform ports, including: * Unify the way BL2 passes `bl31_params_t` to BL3-1. Use the Juno implementation, which copies the information from BL2 memory instead of expecting it to persist in shared memory. * Unify the TZC configuration. There is no need to add a region for SCP in Juno; it's enough to simply not allow any access to this reserved region. Also set region 0 to provide no access by default instead of assuming this is the case. * Unify the number of memory map regions required for ARM development platforms, although the actual ranges mapped for each platform may be different. For the FVP port, this reduces the mapped peripheral address space. These latter changes will only be observed when the platform ports are migrated to use the new common platform code in subsequent patches. Change-Id: Id9c269dd3dc6e74533d0e5116fdd826d53946dc8
2015-03-19 18:58:55 +00:00
*
* SPDX-License-Identifier: BSD-3-Clause
Add common ARM and CSS platform code This major change pulls out the common functionality from the FVP and Juno platform ports into the following categories: * (include/)plat/common. Common platform porting functionality that typically may be used by all platforms. * (include/)plat/arm/common. Common platform porting functionality that may be used by all ARM standard platforms. This includes all ARM development platforms like FVP and Juno but may also include non-ARM-owned platforms. * (include/)plat/arm/board/common. Common platform porting functionality for ARM development platforms at the board (off SoC) level. * (include/)plat/arm/css/common. Common platform porting functionality at the ARM Compute SubSystem (CSS) level. Juno is an example of a CSS-based platform. * (include/)plat/arm/soc/common. Common platform porting functionality at the ARM SoC level, which is not already defined at the ARM CSS level. No guarantees are made about the backward compatibility of functionality provided in (include/)plat/arm. Also remove any unnecessary variation between the ARM development platform ports, including: * Unify the way BL2 passes `bl31_params_t` to BL3-1. Use the Juno implementation, which copies the information from BL2 memory instead of expecting it to persist in shared memory. * Unify the TZC configuration. There is no need to add a region for SCP in Juno; it's enough to simply not allow any access to this reserved region. Also set region 0 to provide no access by default instead of assuming this is the case. * Unify the number of memory map regions required for ARM development platforms, although the actual ranges mapped for each platform may be different. For the FVP port, this reduces the mapped peripheral address space. These latter changes will only be observed when the platform ports are migrated to use the new common platform code in subsequent patches. Change-Id: Id9c269dd3dc6e74533d0e5116fdd826d53946dc8
2015-03-19 18:58:55 +00:00
*/
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <common/debug.h>
#include <drivers/arm/cryptocell/cc_rotpk.h>
#include <drivers/delay_timer.h>
#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#if defined(ARM_COT_tbbr)
#include <tools_share/tbbr_oid.h>
#elif defined(ARM_COT_dualroot)
#include <tools_share/dualroot_oid.h>
#endif
#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
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 stored in dedicated registers.
*/
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, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
words = ARM_ROTPK_HASH_LEN >> 2;
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 & 0xFF);
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
*dst++ = (uint8_t)((tmp >> 16) & 0xFF);
*dst++ = (uint8_t)((tmp >> 24) & 0xFF);
}
*key_ptr = (void *)rotpk_hash_der;
*key_len = (unsigned int)sizeof(rotpk_hash_der);
*flags = ROTPK_IS_HASH;
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
/*
* Wrapper function for most Arm platforms to get ROTPK hash.
*/
static int 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 */
}
#if defined(ARM_COT_tbbr)
int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
unsigned int *key_len, unsigned int *flags)
{
return get_rotpk_info(key_ptr, key_len, flags);
}
#elif defined(ARM_COT_dualroot)
int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
/*
* Return the right root of trust key hash based on the cookie value:
* - NULL means the primary ROTPK.
* - Otherwise, interpret cookie as the OID of the certificate
* extension containing the key.
*/
if (cookie == NULL) {
return get_rotpk_info(key_ptr, key_len, flags);
} else if (strcmp(cookie, PROT_PK_OID) == 0) {
extern unsigned char arm_protpk_hash[];
extern unsigned char arm_protpk_hash_end[];
*key_ptr = arm_protpk_hash;
*key_len = arm_protpk_hash_end - arm_protpk_hash;
*flags = ROTPK_IS_HASH;
return 0;
} else {
/* Invalid key ID. */
return 1;
}
}
#endif
TBB: add non-volatile counter support This patch adds support for non-volatile counter authentication to the Authentication Module. This method consists of matching the counter values provided in the certificates with the ones stored in the platform. If the value from the certificate is lower than the platform, the boot process is aborted. This mechanism protects the system against rollback. The TBBR CoT has been updated to include this method as part of the authentication process. Two counters are used: one for the trusted world images and another for the non trusted world images. ** NEW PLATFORM APIs (mandatory when TBB is enabled) ** int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr); This API returns the non-volatile counter value stored in the platform. The cookie in the first argument may be used to select the counter in case the platform provides more than one (i.e. TBSA compliant platforms must provide trusted and non-trusted counters). This cookie is specified in the CoT. int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); This API sets a new counter value. The cookie may be used to select the counter to be updated. An implementation of these new APIs for ARM platforms is also provided. The values are obtained from the Trusted Non-Volatile Counters peripheral. The cookie is used to pass the extension OID. This OID may be interpreted by the platform to know which counter must return. On Juno, The trusted and non-trusted counter values have been tied to 31 and 223, respectively, and cannot be modified. ** IMPORTANT ** THIS PATCH BREAKS THE BUILD WHEN TRUSTED_BOARD_BOOT IS ENABLED. THE NEW PLATFORM APIs INTRODUCED IN THIS PATCH MUST BE IMPLEMENTED IN ORDER TO SUCCESSFULLY BUILD TF. Change-Id: Ic943b76b25f2a37f490eaaab6d87b4a8b3cbc89a
2016-01-22 11:05:57 +00:00
/*
* Return the non-volatile counter value stored in the platform. The cookie
* will contain the OID of the counter in the certificate.
*
* Return: 0 = success, Otherwise = error
*/
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
{
const char *oid;
uint32_t *nv_ctr_addr;
assert(cookie != NULL);
assert(nv_ctr != NULL);
oid = (const char *)cookie;
if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
} else {
return 1;
}
*nv_ctr = (unsigned int)(*nv_ctr_addr);
return 0;
}
/*
* Store a new non-volatile counter value. By default on ARM development
* platforms, the non-volatile counters are RO and cannot be modified. We expect
* the values in the certificates to always match the RO values so that this
* function is never called.
TBB: add non-volatile counter support This patch adds support for non-volatile counter authentication to the Authentication Module. This method consists of matching the counter values provided in the certificates with the ones stored in the platform. If the value from the certificate is lower than the platform, the boot process is aborted. This mechanism protects the system against rollback. The TBBR CoT has been updated to include this method as part of the authentication process. Two counters are used: one for the trusted world images and another for the non trusted world images. ** NEW PLATFORM APIs (mandatory when TBB is enabled) ** int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr); This API returns the non-volatile counter value stored in the platform. The cookie in the first argument may be used to select the counter in case the platform provides more than one (i.e. TBSA compliant platforms must provide trusted and non-trusted counters). This cookie is specified in the CoT. int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr); This API sets a new counter value. The cookie may be used to select the counter to be updated. An implementation of these new APIs for ARM platforms is also provided. The values are obtained from the Trusted Non-Volatile Counters peripheral. The cookie is used to pass the extension OID. This OID may be interpreted by the platform to know which counter must return. On Juno, The trusted and non-trusted counter values have been tied to 31 and 223, respectively, and cannot be modified. ** IMPORTANT ** THIS PATCH BREAKS THE BUILD WHEN TRUSTED_BOARD_BOOT IS ENABLED. THE NEW PLATFORM APIs INTRODUCED IN THIS PATCH MUST BE IMPLEMENTED IN ORDER TO SUCCESSFULLY BUILD TF. Change-Id: Ic943b76b25f2a37f490eaaab6d87b4a8b3cbc89a
2016-01-22 11:05:57 +00:00
*
* Return: 0 = success, Otherwise = error
*/
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}