Platform: Implement API to get ROTPK
PSA Trusted Boot and Firmware Update specification requires
the support of at least one immutable root of trust public key
(ROTPK) for firmware verification. This key is provisioned to
the SoC during manufacturing. This API makes possible to
the bootloader to get the hash of ROTPK in order to validate the
public key which is present in the image manifest.
This is a dummy implementation not suitable for use in production!
Change-Id: Ibf4d3d376f9e6fceaaabc9a1f11a46ef20f07a16
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index 8f09654..46f5607 100644
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -40,6 +40,14 @@
if (${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "RAM_LOADING")
message(FATAL_ERROR "ERROR: RAM_LOADING upgrade strategy is not supported on target '${TARGET_PLATFORM}'.")
endif()
+ #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/tfm_rotpk.c
+ # instead independently loaded from secure code as a blob.
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048)
+ endif()
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072)
+ endif()
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/cmsis" ABSOLUTE)
@@ -136,6 +144,7 @@
message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!")
elseif(BUILD_TARGET_HARDWARE_KEYS)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_initial_attestation_key_material.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c")
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an519/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index 8b1f4ea..630eca2 100644
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -41,6 +41,14 @@
if (${MCUBOOT_UPGRADE_STRATEGY} STREQUAL "RAM_LOADING")
message(FATAL_ERROR "ERROR: RAM_LOADING upgrade strategy is not supported on target '${TARGET_PLATFORM}'.")
endif()
+ #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/tfm_rotpk.c
+ # instead independently loaded from secure code as a blob.
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048)
+ endif()
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072)
+ endif()
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/cmsis" ABSOLUTE)
@@ -137,6 +145,7 @@
message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!")
elseif(BUILD_TARGET_HARDWARE_KEYS)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_initial_attestation_key_material.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c")
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an521/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/Mps3AN524.cmake b/platform/ext/Mps3AN524.cmake
index 3e57cc9..687d2a4 100644
--- a/platform/ext/Mps3AN524.cmake
+++ b/platform/ext/Mps3AN524.cmake
@@ -49,6 +49,15 @@
message(WARNING "NO_SWAP upgrade strategy is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
mcuboot_override_upgrade_strategy("NO_SWAP")
endif()
+
+ #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/tfm_rotpk.c
+ # instead independently loaded from secure code as a blob.
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048)
+ endif()
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072)
+ endif()
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/cmsis" ABSOLUTE)
@@ -142,6 +151,7 @@
message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!")
elseif(BUILD_TARGET_HARDWARE_KEYS)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_initial_attestation_key_material.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c")
list(APPEND ALL_SRC_C "${AN524_DIR}/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/common/tfm_rotpk.c b/platform/ext/common/tfm_rotpk.c
new file mode 100644
index 0000000..ca97d5a
--- /dev/null
+++ b/platform/ext/common/tfm_rotpk.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include "platform/include/tfm_plat_crypto_keys.h"
+/**
+ * \file tfm_rotpk.c
+ *
+ * This file contains the hash value (SHA256) of the public parts of the
+ * firmware signing keys in bl2/ext/mcuboot folder (*.pem files).
+ * This simulates when the hash of the Root of Trust Public Key is programmed
+ * to an immutable device memory to be able to validate the image verification
+ * key.
+ *
+ * \note These key-hash values must be provisioned to the SoC during the
+ * production, independently from firmware binaries. This solution
+ * (hard-coded key-hash values in firmware) is not suited for use in
+ * production!
+ */
+
+#if defined(BL2)
+#if (MCUBOOT_SIGN_RSA_LEN == 2048)
+/* Hash of public key: bl2/ext/mcuboot/root-rsa-2048.pem */
+uint8_t rotpk_hash_0[ROTPK_HASH_LEN] = {
+ 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)
+/* Hash of public key: bl2/ext/mcuboot/root-rsa-3072.pem */
+uint8_t rotpk_hash_0[ROTPK_HASH_LEN] = {
+ 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
+
+const struct tfm_plat_rotpk_t device_rotpk[] = {
+ {
+ .key_hash = rotpk_hash_0,
+ .hash_len = ROTPK_HASH_LEN,
+ },
+};
+
+const uint32_t rotpk_key_cnt = 1;
+#endif /* BL2 */
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index a93297e..b850ccb9 100644
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -133,6 +133,7 @@
message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!")
elseif(BUILD_TARGET_HARDWARE_KEYS)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_initial_attestation_key_material.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c")
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_a/dummy_crypto_keys.c")
endif()
@@ -189,6 +190,15 @@
if (BL2)
set(BL2_LINKER_CONFIG ${BL2_SCATTER_FILE_NAME})
+
+ #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/tfm_rotpk.c
+ # instead independently loaded from secure code as a blob.
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048)
+ endif()
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072)
+ endif()
endif()
if (NOT DEFINED BUILD_BOOT_SEED)
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index 3133189..f869d9b 100644
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -41,6 +41,15 @@
message(WARNING "NO_SWAP upgrade strategy is mandatory on target '${TARGET_PLATFORM}'. Your choice was overriden.")
mcuboot_override_upgrade_strategy("NO_SWAP")
endif()
+
+ #FixMe: MCUBOOT_SIGN_RSA_LEN can be removed when ROTPK won't be hard coded in platform/ext/common/tfm_rotpk.c
+ # instead independently loaded from secure code as a blob.
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-2048")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=2048)
+ endif()
+ if (${MCUBOOT_SIGNATURE_TYPE} STREQUAL "RSA-3072")
+ add_definitions(-DMCUBOOT_SIGN_RSA_LEN=3072)
+ endif()
endif()
embedded_include_directories(PATH "${PLATFORM_DIR}/cmsis" ABSOLUTE)
@@ -143,6 +152,7 @@
message(FATAL_ERROR "Configuration variable BUILD_TARGET_HARDWARE_KEYS (true|false) is undefined!")
elseif (BUILD_TARGET_HARDWARE_KEYS)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_initial_attestation_key_material.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/common/tfm_rotpk.c")
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_b1/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/target/mps2/an519/dummy_crypto_keys.c b/platform/ext/target/mps2/an519/dummy_crypto_keys.c
index 014b140..d7e862a 100644
--- a/platform/ext/target/mps2/an519/dummy_crypto_keys.c
+++ b/platform/ext/target/mps2/an519/dummy_crypto_keys.c
@@ -40,6 +40,9 @@
extern const uint8_t initial_attestation_public_y_key[];
extern const uint32_t initial_attestation_public_y_key_size;
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
/**
* \brief Copy the key to the destination buffer
*
@@ -125,3 +128,24 @@
return TFM_PLAT_ERR_SUCCESS;
}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+ uint8_t *rotpk_hash,
+ uint32_t *rotpk_hash_size)
+{
+ if(*rotpk_hash_size < ROTPK_HASH_LEN) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (image_id >= rotpk_key_cnt) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ *rotpk_hash_size = ROTPK_HASH_LEN;
+ copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#endif
diff --git a/platform/ext/target/mps2/an521/dummy_crypto_keys.c b/platform/ext/target/mps2/an521/dummy_crypto_keys.c
index a2c3459..d60d457 100644
--- a/platform/ext/target/mps2/an521/dummy_crypto_keys.c
+++ b/platform/ext/target/mps2/an521/dummy_crypto_keys.c
@@ -40,6 +40,9 @@
extern const uint8_t initial_attestation_public_y_key[];
extern const uint32_t initial_attestation_public_y_key_size;
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
/**
* \brief Copy the key to the destination buffer
*
@@ -125,3 +128,24 @@
return TFM_PLAT_ERR_SUCCESS;
}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+ uint8_t *rotpk_hash,
+ uint32_t *rotpk_hash_size)
+{
+ if(*rotpk_hash_size < ROTPK_HASH_LEN) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (image_id >= rotpk_key_cnt) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ *rotpk_hash_size = ROTPK_HASH_LEN;
+ copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#endif
diff --git a/platform/ext/target/mps3/an524/dummy_crypto_keys.c b/platform/ext/target/mps3/an524/dummy_crypto_keys.c
index 1db8646..93073c0 100644
--- a/platform/ext/target/mps3/an524/dummy_crypto_keys.c
+++ b/platform/ext/target/mps3/an524/dummy_crypto_keys.c
@@ -37,6 +37,9 @@
extern const uint8_t initial_attestation_public_y_key[];
extern const uint32_t initial_attestation_public_y_key_size;
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
/**
* \brief Copy the key to the destination buffer
*
@@ -122,3 +125,24 @@
return TFM_PLAT_ERR_SUCCESS;
}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+ uint8_t *rotpk_hash,
+ uint32_t *rotpk_hash_size)
+{
+ if(*rotpk_hash_size < ROTPK_HASH_LEN) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (image_id >= rotpk_key_cnt) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ *rotpk_hash_size = ROTPK_HASH_LEN;
+ copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#endif
diff --git a/platform/ext/target/musca_a/dummy_crypto_keys.c b/platform/ext/target/musca_a/dummy_crypto_keys.c
index 4932d8d..3721889 100644
--- a/platform/ext/target/musca_a/dummy_crypto_keys.c
+++ b/platform/ext/target/musca_a/dummy_crypto_keys.c
@@ -40,6 +40,9 @@
extern const uint8_t initial_attestation_public_y_key[];
extern const uint32_t initial_attestation_public_y_key_size;
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
/**
* \brief Copy the key to the destination buffer
*
@@ -125,3 +128,24 @@
return TFM_PLAT_ERR_SUCCESS;
}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+ uint8_t *rotpk_hash,
+ uint32_t *rotpk_hash_size)
+{
+ if(*rotpk_hash_size < ROTPK_HASH_LEN) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (image_id >= rotpk_key_cnt) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ *rotpk_hash_size = ROTPK_HASH_LEN;
+ copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#endif
diff --git a/platform/ext/target/musca_b1/dummy_crypto_keys.c b/platform/ext/target/musca_b1/dummy_crypto_keys.c
index 1db8646..93073c0 100644
--- a/platform/ext/target/musca_b1/dummy_crypto_keys.c
+++ b/platform/ext/target/musca_b1/dummy_crypto_keys.c
@@ -37,6 +37,9 @@
extern const uint8_t initial_attestation_public_y_key[];
extern const uint32_t initial_attestation_public_y_key_size;
+extern const struct tfm_plat_rotpk_t device_rotpk[];
+extern const uint32_t rotpk_key_cnt;
+
/**
* \brief Copy the key to the destination buffer
*
@@ -122,3 +125,24 @@
return TFM_PLAT_ERR_SUCCESS;
}
+
+#ifdef BL2
+enum tfm_plat_err_t
+tfm_plat_get_rotpk_hash(uint8_t image_id,
+ uint8_t *rotpk_hash,
+ uint32_t *rotpk_hash_size)
+{
+ if(*rotpk_hash_size < ROTPK_HASH_LEN) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ if (image_id >= rotpk_key_cnt) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ *rotpk_hash_size = ROTPK_HASH_LEN;
+ copy_key(rotpk_hash, device_rotpk[image_id].key_hash, *rotpk_hash_size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+#endif
diff --git a/platform/include/tfm_plat_crypto_keys.h b/platform/include/tfm_plat_crypto_keys.h
index 01d2746..59b438b 100644
--- a/platform/include/tfm_plat_crypto_keys.h
+++ b/platform/include/tfm_plat_crypto_keys.h
@@ -62,6 +62,20 @@
#define ECC_P_256_KEY_SIZE (96u) /* 3 x 32 = 96 bytes priv + pub-x + pub-y */
+#define ROTPK_HASH_LEN (32u) /* SHA256 */
+
+/**
+ * Structure to store the hard-coded (embedded in secure firmware) hash of ROTPK
+ * for firmware authentication.
+ *
+ * \note Just temporary solution, hard-coded key-hash values in firmware is not
+ * suited for use in production!
+ */
+struct tfm_plat_rotpk_t {
+ const uint8_t *key_hash;
+ const uint8_t hash_len;
+};
+
/**
* \brief Gets hardware unique key for encryption
*