aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXu Yong <yong.xu@arm.com>2019-11-01 14:28:34 +0800
committerDavid Vincze <david.vincze@arm.com>2019-11-29 16:35:34 +0100
commit9830d482a4c7d39dc6836c9dc3df23ce826d18ca (patch)
tree9703974782b661fe808be7fc28ec7123924ca718
parent2e297a51136c3d44ad3e76d5c95957d0661496eb (diff)
downloadtrusted-firmware-m-9830d482a4c7d39dc6836c9dc3df23ce826d18ca.tar.gz
Platform: Generate attestation key and program it to OTP on Musca-B1
Attestation key is stored in OTP at offset 0x30 words. The number of zero bits in attestation key is stored in OTP at offset 0x2F words. Default attestation key is generated based on ECC secp256r1 curve. Change-Id: If384f334f95bfcf0a8290d9a98a1dcc4cac3f670 Signed-off-by: Xu Yong <yong.xu@arm.com>
-rw-r--r--bl2/ext/mcuboot/include/config-boot.h4
-rw-r--r--platform/ext/common/cc312/BuildCC312.cmake2
-rw-r--r--platform/ext/common/cc312/cc312_provisioning.c146
-rw-r--r--platform/ext/common/cc312/crypto_hw.h6
-rw-r--r--platform/ext/musca_b1.cmake2
5 files changed, 160 insertions, 0 deletions
diff --git a/bl2/ext/mcuboot/include/config-boot.h b/bl2/ext/mcuboot/include/config-boot.h
index 71667eba2f..352c1172a1 100644
--- a/bl2/ext/mcuboot/include/config-boot.h
+++ b/bl2/ext/mcuboot/include/config-boot.h
@@ -68,6 +68,10 @@
#define MBEDTLS_CIPHER_C
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#endif /* CRYPTO_HW_ACCELERATOR_OTP_PROVISIONING */
#ifdef CRYPTO_HW_ACCELERATOR
diff --git a/platform/ext/common/cc312/BuildCC312.cmake b/platform/ext/common/cc312/BuildCC312.cmake
index 9bb963e452..6107abcc42 100644
--- a/platform/ext/common/cc312/BuildCC312.cmake
+++ b/platform/ext/common/cc312/BuildCC312.cmake
@@ -81,10 +81,12 @@ string(APPEND CC312_C_FLAGS " -I ${CC312_INSTALL_DIR}/include")
string(APPEND MBEDCRYPTO_C_FLAGS " -I ${PLATFORM_DIR}/common/cc312")
string(APPEND MBEDCRYPTO_C_FLAGS " -DMBEDTLS_ECDH_LEGACY_CONTEXT")
+string(APPEND MBEDCRYPTO_C_FLAGS " -DCC_IOT")
string(APPEND CC312_C_FLAGS " -DMBEDTLS_CONFIG_FILE=\'\\\\\\\"${MBEDTLS_CONFIG_FILE}\\\\\\\"\'")
string(APPEND CC312_C_FLAGS " -I ${MBEDTLS_CONFIG_PATH}")
string(APPEND CC312_C_FLAGS " -I ${PLATFORM_DIR}/common/cc312")
+string(APPEND CC312_C_FLAGS " -DCC_IOT")
if (MBEDCRYPTO_DEBUG)
if (${COMPILER} STREQUAL "GNUARM")
diff --git a/platform/ext/common/cc312/cc312_provisioning.c b/platform/ext/common/cc312/cc312_provisioning.c
index 24cf8a80bc..ae01e89c0d 100644
--- a/platform/ext/common/cc312/cc312_provisioning.c
+++ b/platform/ext/common/cc312/cc312_provisioning.c
@@ -15,7 +15,13 @@
#include "cc_dmpu.h"
#include "cc_pal_types.h"
#include "dx_reg_base_host.h"
+#include "mbedtls/ecdsa.h"
+#include "cc_rnd_common.h"
+#include "cmpu_derivation.h"
+#include "cmpu_llf_rnd.h"
#include "mbedtls_cc_mng_int.h"
+#include "cc_prod_error.h"
+#include "prod_util.h"
extern uint8_t rotpk_hash_0[];
extern uint8_t rotpk_hash_1[];
@@ -27,6 +33,139 @@ extern uint8_t rotpk_hash_1[];
__attribute__((aligned(CC_32BIT_WORD_SIZE)))
static uint8_t provisioning_mem_buf[PROVISIONING_MEM_BUF_LEN];
+/*
+ * Extract private key
+ */
+static int extract_private_key(mbedtls_ecdsa_context *key, uint8_t *buf)
+{
+ size_t len;
+
+ len = mbedtls_mpi_size(&key->d);
+ if (mbedtls_mpi_write_binary(&key->d, buf, len) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Generate ECC P256 keypair
+ */
+static int cc312_generate_ecc_p256_keypair(void *rng_state, uint8_t *output,
+ size_t len)
+{
+ uint32_t error = 0;
+ uint32_t *pEntrSrc;
+ uint32_t sourceSize;
+ uint8_t pKey[32] = { 0 };
+ uint8_t pIv[16] = { 0 };
+ uint32_t *pRndWorkBuff = (uint32_t *)provisioning_mem_buf;
+
+ error = CC_PROD_LLF_RND_GetTrngSource((uint32_t **)&pEntrSrc,
+ &sourceSize,
+ pRndWorkBuff);
+ if (error != CC_OK) {
+ return error;
+ }
+
+ error = CC_PROD_Derivation_Instantiate(pEntrSrc,
+ sourceSize,
+ pKey,
+ pIv);
+ if (error != CC_OK) {
+ return error;
+ }
+
+ if (len <= 32) {
+ memcpy(output, pKey, len);
+ } else if (len > 32 && len <= 48) {
+ memcpy(output, pKey, 32);
+ memcpy(output + 32, pIv, len - 32);
+ } else {
+ memcpy(output, pKey, 32);
+ memcpy(output + 32, pIv, 16);
+ memset(output + 48, 0, len - 48);
+ }
+
+ return 0;
+}
+
+static int cc312_generate_attestation_key(mbedtls_ecp_group_id curve_type,
+ uint8_t *private_key)
+{
+ int rc;
+ mbedtls_ecdsa_context ecdsa;
+
+ if (!private_key || curve_type == MBEDTLS_ECP_DP_NONE) {
+ return -1;
+ }
+
+ mbedtls_ecdsa_init(&ecdsa);
+
+ rc = mbedtls_ecdsa_genkey(&ecdsa, curve_type,
+ cc312_generate_ecc_p256_keypair, NULL);
+ if (rc) {
+ goto exit;
+ }
+
+ rc = extract_private_key(&ecdsa, private_key);
+ if (rc) {
+ goto exit;
+ }
+
+ rc = 0;
+
+exit:
+ mbedtls_ecdsa_free(&ecdsa);
+
+ return rc;
+}
+
+static int cc312_program_attestation_private_key(
+ mbedtls_ecp_group_id curve_type)
+{
+ uint32_t private_key[8];
+ uint32_t error;
+ uint32_t zero_count;
+ int ret;
+
+ /* Check if the attestation key area has been programmed */
+ CC_PROD_OTP_READ(zero_count, CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET);
+ if (zero_count) {
+ return -1;
+ }
+
+ ret = cc312_generate_attestation_key(curve_type,
+ (uint8_t *)private_key);
+ if (ret) {
+ return -1;
+ }
+
+ /* Program private key to OTP */
+ CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_ATTESTATION_KEY_OFFSET,
+ private_key,
+ CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS,
+ error);
+ if (error != CC_OK) {
+ return -1;
+ }
+
+ CC_PROD_GetZeroCount(private_key,
+ CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS,
+ &zero_count);
+ /* Program the number of zero bits in the private key. This is used to
+ * detect whether the private key is overwritten or tampered.
+ */
+ CC_PROD_OTP_WRITE_VERIFY_WORD(CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET,
+ zero_count,
+ error);
+ if (error != CC_OK) {
+ return -1;
+ }
+
+ return 0;
+}
+
static int cc312_cmpu_provision(void)
{
int rc;
@@ -105,13 +244,20 @@ int crypto_hw_accelerator_otp_provisioning(void)
return rc;
}
+ /* First cycle - program the attestation key and HUK */
if (lcs == CC_MNG_LCS_CM) {
+ rc = cc312_program_attestation_private_key(MBEDTLS_ECP_DP_SECP256R1);
+ if (rc) {
+ return rc;
+ }
+ printf("First cycle: Attestation key is provisioned successfully\r\n");
rc = cc312_cmpu_provision();
if (rc) {
return rc;
}
printf("First cycle: HUK is provisioned successfully\r\n");
printf("Please reset the board to program ROTPK\r\n");
+ /* Second cycle - program the ROTPK */
} else if (lcs == CC_MNG_LCS_DM) {
rc = cc312_dmpu_provision();
if (rc) {
diff --git a/platform/ext/common/cc312/crypto_hw.h b/platform/ext/common/cc312/crypto_hw.h
index aaa0aa8133..d3c513dbd5 100644
--- a/platform/ext/common/cc312/crypto_hw.h
+++ b/platform/ext/common/cc312/crypto_hw.h
@@ -22,6 +22,11 @@ extern "C" {
#define TFM_CRYPTO_ENGINE_BUF_SIZE (0x4000) /* 16KB for EC signing in attest */
#endif
+/* Offsets are specified in 32-bit words */
+#define CC_OTP_ATTESTATION_KEY_OFFSET (0x30UL)
+#define CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS (8)
+#define CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET (0x2FUL)
+
/**
* \brief Initialize the CC312 crypto accelerator
*
@@ -62,6 +67,7 @@ int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
* The following keys will be provisioned:
* - Hardware Unique Key (HUK)
* - Hash of ROTPK
+ * - Attestation private key
*
* \return 0 on success, non-zero otherwise
*/
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index 3b7e56fc16..dc385f166e 100644
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -232,6 +232,8 @@ if (CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "PROVISIONING")
add_definitions("-DCC_IOT")
embedded_include_directories(PATH "${CC312_SOURCE_DIR}/shared/hw/include/musca_b1" ABSOLUTE)
+ embedded_include_directories(PATH "${CMAKE_CURRENT_BINARY_DIR}/services/crypto/cryptocell/install/include" ABSOLUTE)
+ embedded_include_directories(PATH "${PLATFORM_DIR}/common/cc312/" ABSOLUTE)
elseif (CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "ENABLED")
set(CRYPTO_HW_ACCELERATOR ON)