CC312: Enable BL1 rotpk for non-default BL1s

Change-Id: I457ed4437081d2f21fb1feff58236b30450c3eea
Signed-off-by: Raef Coles <raef.coles@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
This commit is contained in:
Raef Coles 2022-04-19 15:13:00 +01:00 committed by Satish Kumar
parent fbbcbc20c8
commit d32f6bf6f1
5 changed files with 191 additions and 31 deletions

View File

@ -54,7 +54,7 @@ else() #The default backend is IPC
endif()
# Load bl1 config
if (BL1)
if (BL1 AND PLATFORM_DEFAULT_BL1)
include(${CMAKE_SOURCE_DIR}/bl1/config/bl1_config_default.cmake)
endif()

View File

@ -203,12 +203,14 @@ __PACKED_STRUCT plat_otp_layout_t {
uint16_t iak_type_zero_bits;
uint16_t iak_id_zero_bits;
uint16_t bl2_rotpk_zero_bits[3];
#ifdef BL1
uint16_t bl1_rotpk_0_zero_bits;
#ifdef PLATFORM_DEFAULT_BL1
uint16_t bl2_encryption_key_zero_bits;
uint16_t bl1_2_image_hash_zero_bits;
uint16_t bl2_image_hash_zero_bits;
uint16_t bl1_rotpk_0_zero_bits;
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
uint16_t secure_debug_pk_zero_bits;
};
@ -225,16 +227,17 @@ __PACKED_STRUCT plat_otp_layout_t {
uint8_t bl2_rotpk[3][32];
uint8_t bl2_nv_counter[3][64];
#ifdef BL1
uint8_t bl1_rotpk_0[32];
uint8_t bl1_nv_counter[16];
#ifdef PLATFORM_DEFAULT_BL1
uint8_t bl2_encryption_key[32];
uint8_t bl1_2_image_hash[32];
uint8_t bl2_image_hash[32];
uint8_t bl1_rotpk_0[32];
uint8_t bl1_nv_counter[16];
uint8_t bl1_2_image[BL1_2_CODE_SIZE];
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
uint8_t secure_debug_pk[32];
};
@ -519,6 +522,13 @@ static enum tfm_plat_err_t check_keys_for_tampering(void)
}
#endif
err = verify_zero_bits_count(otp->bl1_rotpk_0,
sizeof(otp->bl1_rotpk_0),
(uint8_t*)&otp->bl1_rotpk_0_zero_bits);
if (err != TFM_PLAT_ERR_SUCCESS) {
return err;
}
#ifdef PLATFORM_DEFAULT_BL1
err = verify_zero_bits_count(otp->bl2_encryption_key,
sizeof(otp->bl2_encryption_key),
@ -541,12 +551,6 @@ static enum tfm_plat_err_t check_keys_for_tampering(void)
return err;
}
err = verify_zero_bits_count(otp->bl1_rotpk_0,
sizeof(otp->bl1_rotpk_0),
(uint8_t*)&otp->bl1_rotpk_0_zero_bits);
if (err != TFM_PLAT_ERR_SUCCESS) {
return err;
}
#endif /* PLATFORM_DEFAULT_BL1 */
#endif /* BL1 */
@ -692,6 +696,12 @@ enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
sizeof(otp->bl2_nv_counter[2]), out_len, out);
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
return otp_read(otp->bl1_rotpk_0,
sizeof(otp->bl1_rotpk_0), out_len, out);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return otp_read(otp->bl1_nv_counter,
sizeof(otp->bl1_nv_counter), out_len, out);
#ifdef PLATFORM_DEFAULT_BL1
case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
return otp_read(otp->bl2_encryption_key,
@ -702,12 +712,6 @@ enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
case PLAT_OTP_ID_BL2_IMAGE_HASH:
return otp_read(otp->bl2_image_hash,
sizeof(otp->bl2_image_hash), out_len, out);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return otp_read(otp->bl1_nv_counter,
sizeof(otp->bl1_nv_counter), out_len, out);
case PLAT_OTP_ID_BL1_ROTPK_0:
return otp_read(otp->bl1_rotpk_0,
sizeof(otp->bl1_rotpk_0), out_len, out);
case PLAT_OTP_ID_BL1_2_IMAGE:
return otp_read(otp->bl1_2_image,
sizeof(otp->bl1_2_image), out_len, out);
@ -903,6 +907,12 @@ enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
sizeof(otp->bl2_nv_counter[2]), in_len, in, NULL);
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
return otp_write(otp->bl1_rotpk_0, sizeof(otp->bl1_rotpk_0), in_len, in,
(uint8_t*)&otp->bl1_rotpk_0_zero_bits);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return otp_write(otp->bl1_nv_counter,
sizeof(otp->bl1_nv_counter), in_len, in, NULL);
#ifdef PLATFORM_DEFAULT_BL1
case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
return otp_write(otp->bl2_encryption_key,
@ -916,12 +926,6 @@ enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
return otp_write(otp->bl2_image_hash,
sizeof(otp->bl2_image_hash), in_len, in,
(uint8_t*)&otp->bl2_image_hash_zero_bits);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return otp_write(otp->bl1_nv_counter,
sizeof(otp->bl1_nv_counter), in_len, in, NULL);
case PLAT_OTP_ID_BL1_ROTPK_0:
return otp_write(otp->bl1_rotpk_0, sizeof(otp->bl1_rotpk_0), in_len, in,
(uint8_t*)&otp->bl1_rotpk_0_zero_bits);
case PLAT_OTP_ID_BL1_2_IMAGE:
return otp_write(otp->bl1_2_image,
sizeof(otp->bl1_2_image), in_len, in, NULL);
@ -1007,6 +1011,12 @@ enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
break;
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
*size = sizeof(otp->bl1_rotpk_0);
break;
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
*size = sizeof(otp->bl1_nv_counter);
break;
#ifdef PLATFORM_DEFAULT_BL1
case PLAT_OTP_ID_KEY_BL2_ENCRYPTION:
*size = sizeof(otp->bl2_encryption_key);
@ -1017,12 +1027,6 @@ enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
case PLAT_OTP_ID_BL2_IMAGE_HASH:
*size = sizeof(otp->bl2_image_hash);
break;
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
*size = sizeof(otp->bl1_nv_counter);
break;
case PLAT_OTP_ID_BL1_ROTPK_0:
*size = sizeof(otp->bl1_rotpk_0);
break;
case PLAT_OTP_ID_BL1_2_IMAGE:
*size = sizeof(otp->bl1_2_image);
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -90,6 +90,14 @@ enum tfm_plat_err_t tfm_plat_otp_read(enum tfm_otp_element_id_t id,
return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_2), out_len, out);
#endif /* BL2 */
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_rotpk_0), out_len, out);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_nv_counter_0), out_len, out);
#endif /* BL1 */
case PLAT_OTP_ID_ENTROPY_SEED:
return write_to_output(id, offsetof(struct flash_otp_nv_counters_region_t, entropy_seed), out_len, out);
@ -185,6 +193,14 @@ enum tfm_plat_err_t tfm_plat_otp_write(enum tfm_otp_element_id_t id,
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, bl2_nv_counter_2), in_len, in);
#endif /* Bl2 */
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_rotpk_0), in_len, in);
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, bl1_nv_counter_0), in_len, in);
#endif /* BL1 */
case PLAT_OTP_ID_ENTROPY_SEED:
return read_from_input(id, offsetof(struct flash_otp_nv_counters_region_t, entropy_seed), in_len, in);
@ -267,6 +283,16 @@ enum tfm_plat_err_t tfm_plat_otp_get_size(enum tfm_otp_element_id_t id,
break;
#endif /* BL2 */
#ifdef BL1
case PLAT_OTP_ID_BL1_ROTPK_0:
*size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_rotpk_0);
break;
case PLAT_OTP_ID_NV_COUNTER_BL1_0:
*size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->bl1_nv_counter_0);
break;
#endif /* BL1 */
case PLAT_OTP_ID_ENTROPY_SEED:
*size = sizeof(((struct flash_otp_nv_counters_region_t*)0)->entropy_seed);
break;

View File

@ -116,7 +116,7 @@ set(BL2_SOURCE ${CMAKE_SOURCE_DIR}/bl2)
target_sources(bl1_main
PRIVATE
${BL2_SOURCE}/src/flash_map.c
${BL2_SOURCE}/src/provisioning.c
./provisioning.c
)
target_include_directories(bl1_main

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "tfm_plat_provisioning.h"
#include "cmsis_compiler.h"
#include "tfm_plat_otp.h"
#include "tfm_attest_hal.h"
#include "psa/crypto.h"
#include "bootutil/bootutil_log.h"
#include <string.h>
#define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
__PACKED_STRUCT bl1_assembly_and_test_provisioning_data_t {
uint32_t magic;
uint8_t bl1_rotpk_0[32];
};
#ifdef TFM_DUMMY_PROVISIONING
static const struct bl1_assembly_and_test_provisioning_data_t bl1_assembly_and_test_prov_data = {
ASSEMBLY_AND_TEST_PROV_DATA_MAGIC,
#if (MCUBOOT_SIGN_RSA_LEN == 2048)
/* bl1 rotpk 0 */
{
0xfc, 0x57, 0x01, 0xdc, 0x61, 0x35, 0xe1, 0x32,
0x38, 0x47, 0xbd, 0xc4, 0x0f, 0x04, 0xd2, 0xe5,
0xbe, 0xe5, 0x83, 0x3b, 0x23, 0xc2, 0x9f, 0x93,
0x59, 0x3d, 0x00, 0x01, 0x8c, 0xfa, 0x99, 0x94,
},
#elif (MCUBOOT_SIGN_RSA_LEN == 3072)
/* bl1 rotpk 0 */
{
0xbf, 0xe6, 0xd8, 0x6f, 0x88, 0x26, 0xf4, 0xff,
0x97, 0xfb, 0x96, 0xc4, 0xe6, 0xfb, 0xc4, 0x99,
0x3e, 0x46, 0x19, 0xfc, 0x56, 0x5d, 0xa2, 0x6a,
0xdf, 0x34, 0xc3, 0x29, 0x48, 0x9a, 0xdc, 0x38,
},
#else
#error "No public key available for given signing algorithm."
#endif /* MCUBOOT_SIGN_RSA_LEN */
};
#else
static const struct bl1_assembly_and_test_provisioning_data_t bl1_assembly_and_test_prov_data;
#endif /* TFM_DUMMY_PROVISIONING */
void tfm_plat_provisioning_check_for_dummy_keys(void)
{
uint64_t iak_start;
tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
if(iak_start == 0xA4906F6DB254B4A9) {
BOOT_LOG_WRN("%s%s%s%s",
"\033[1;31m",
"This device was provisioned with dummy keys. ",
"This device is \033[1;1mNOT SECURE",
"\033[0m");
}
memset(&iak_start, 0, sizeof(iak_start));
}
int tfm_plat_provisioning_is_required(void)
{
enum tfm_plat_err_t err;
enum plat_otp_lcs_t lcs;
err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
if (err != TFM_PLAT_ERR_SUCCESS) {
return err;
}
return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
|| lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
}
enum tfm_plat_err_t provision_assembly_and_test(void)
{
enum tfm_plat_err_t err;
err = tfm_plat_otp_write(PLAT_OTP_ID_BL1_ROTPK_0,
sizeof(bl1_assembly_and_test_prov_data.bl1_rotpk_0),
bl1_assembly_and_test_prov_data.bl1_rotpk_0);
if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
return err;
}
return err;
}
enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
{
enum tfm_plat_err_t err;
enum plat_otp_lcs_t lcs;
err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
if (err != TFM_PLAT_ERR_SUCCESS) {
return err;
}
BOOT_LOG_INF("Beginning BL1 provisioning");
#ifdef TFM_DUMMY_PROVISIONING
BOOT_LOG_WRN("%s%s%s%s",
"\033[1;31m",
"TFM_DUMMY_PROVISIONING is not suitable for production! ",
"This device is \033[1;1mNOT SECURE",
"\033[0m");
#endif /* TFM_DUMMY_PROVISIONING */
if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
if (bl1_assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
BOOT_LOG_ERR("No valid ASSEMBLY_AND_TEST provisioning data found");
return TFM_PLAT_ERR_INVALID_INPUT;
}
err = provision_assembly_and_test();
if (err != TFM_PLAT_ERR_SUCCESS) {
return err;
}
}
return TFM_PLAT_ERR_SUCCESS;
}