Platform: Extend crypto key API with attestation key
Details:
- Add new functions to API to get the initial attestion key
or its size
- Add a new file, which contains an ECDSA P-256 key pair
in hard coded raw format (without any encoding)
- Add the orignal *.pem file, ASN.1 encoding
- Create dummy implementation per target to retrive the
hard coded key
Change-Id: Ie7dfac9d6df631f87c50f755cb80ffc7f00f5cbd
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index a515199..532c4d7 100644
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -123,6 +123,7 @@
if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
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}/target/mps2/an519/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index 3e7902a..3502a11 100644
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -124,6 +124,7 @@
if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
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}/target/mps2/an521/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/common/tfm_initial_attestation_key.pem b/platform/ext/common/tfm_initial_attestation_key.pem
new file mode 100644
index 0000000..f2c928e
--- /dev/null
+++ b/platform/ext/common/tfm_initial_attestation_key.pem
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgx0ZwvLfoWzgD77Qo
+lASS5z4/6dT3taitXkgMvby1VMKhRANCAATc8ND0vNXialTuNsrWYNKD0Sq8X3MH
+3lhonnfNYEUudYy621/p+JpxB+Wi6OpE7BsJt9oqGoKgJSpMHCbuHtfP
+-----END PRIVATE KEY-----
diff --git a/platform/ext/common/tfm_initial_attestation_key_material.c b/platform/ext/common/tfm_initial_attestation_key_material.c
new file mode 100644
index 0000000..b3ef451
--- /dev/null
+++ b/platform/ext/common/tfm_initial_attestation_key_material.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include "platform/include/tfm_plat_defs.h"
+#include "platform/include/tfm_plat_crypto_keys.h"
+
+/*
+ * This file contains the hard coded version of the ECDSA P-256 key pair in:
+ * platform/common/tfm_initial_attestation_key.pem
+ *
+ * This key is used to sign the initial attestation token.
+ * The key pair is stored in raw format, without any encoding(ASN.1, COSE).
+ *
+ * This ECDSA P-256 key is the construction of:
+ * - private key: 32 bytes
+ * - public key:
+ * - X-coordinate: 32 bytes
+ * - Y-coordinate: 32 bytes
+ *
+ * The hash of the raw public key (H(X || Y)) is also included, because it is
+ * used as an instance ID. It is a unique identifier of the device instance.
+ *
+ * Instance ID is mapped to:
+ * - UEID in the EAT token
+ *
+ * ####### DO NOT USE THIS KEY IN PRODUCTION #######
+ */
+
+/* Type of the EC curve which the key belongs to */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const enum ecc_curve_t initial_attestation_curve_type = P_256;
+
+/* Initial attestation private key in raw format, without any encoding.
+ * It belongs to the ECDSA P-256 curve.
+ * It MUST present on the device-
+ */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint8_t initial_attestation_private_key[] =
+{
+ 0xC7, 0x46, 0x70, 0xBC, 0xB7, 0xE8, 0x5B, 0x38,
+ 0x03, 0xEF, 0xB4, 0x28, 0x94, 0x04, 0x92, 0xE7,
+ 0x3E, 0x3F, 0xE9, 0xD4, 0xF7, 0xB5, 0xA8, 0xAD,
+ 0x5E, 0x48, 0x0C, 0xBD, 0xBC, 0xB5, 0x54, 0xC2
+};
+
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint32_t initial_attestation_private_key_size =
+ sizeof(initial_attestation_private_key);
+
+/* Initial attestation x-coordinate of the public key in raw format,
+ * without any encoding.
+ * It belongs to the ECDSA P-256 curve.
+ * It MIGHT be present on the device.
+ */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint8_t initial_attestation_public_x_key[] =
+{
+ 0xDC, 0xF0, 0xD0, 0xF4, 0xBC, 0xD5, 0xE2, 0x6A,
+ 0x54, 0xEE, 0x36, 0xCA, 0xD6, 0x60, 0xD2, 0x83,
+ 0xD1, 0x2A, 0xBC, 0x5F, 0x73, 0x07, 0xDE, 0x58,
+ 0x68, 0x9E, 0x77, 0xCD, 0x60, 0x45, 0x2E, 0x75,
+};
+
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint32_t initial_attestation_public_x_key_size =
+ sizeof(initial_attestation_public_x_key);
+
+/* Initial attestation y-coordinate of the public key in raw format,
+ * without any encoding.
+ * It belongs to the ECDSA P-256 curve.
+ * It MIGHT be present on the device.
+ */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint8_t initial_attestation_public_y_key[] =
+{
+ 0x8C, 0xBA, 0xDB, 0x5F, 0xE9, 0xF8, 0x9A, 0x71,
+ 0x07, 0xE5, 0xA2, 0xE8, 0xEA, 0x44, 0xEC, 0x1B,
+ 0x09, 0xB7, 0xDA, 0x2A, 0x1A, 0x82, 0xA0, 0x25,
+ 0x2A, 0x4C, 0x1C, 0x26, 0xEE, 0x1E, 0xD7, 0xCF,
+};
+
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint32_t initial_attestation_public_y_key_size =
+ sizeof(initial_attestation_public_y_key);
+
+/* Hash (SHA256) of initial attestation public key */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint8_t initial_attestation_raw_public_key_hash[] =
+{
+ 0xf4, 0x0c, 0x8f, 0xbf, 0x12, 0xdb, 0x78, 0x2a,
+ 0xfd, 0xf4, 0x75, 0x96, 0x6a, 0x06, 0x82, 0x36,
+ 0xe0, 0x32, 0xab, 0x80, 0xd1, 0xb7, 0xf1, 0xbc,
+ 0x9f, 0xe7, 0xd8, 0x7a, 0x88, 0xcb, 0x26, 0xd0,
+};
+
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_INITIAL_ATTESTATION")
+const uint32_t initial_attestation_raw_public_key_hash_size =
+ sizeof(initial_attestation_raw_public_key_hash);
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index 5f0e88a..daf11cd 100755
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -127,6 +127,7 @@
if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
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}/target/musca_a/dummy_crypto_keys.c")
endif()
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index 510e90f..63fc134 100755
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -123,6 +123,7 @@
if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
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}/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 3263b28..014b140 100644
--- a/platform/ext/target/mps2/an519/dummy_crypto_keys.c
+++ b/platform/ext/target/mps2/an519/dummy_crypto_keys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,16 @@
*/
#include "platform/include/tfm_plat_crypto_keys.h"
+#include <stddef.h>
+
+/* FIXME: Functions in this file should be implemented by platform vendor. For
+ * the security of the storage system, it is critical to use a hardware unique
+ * key. For the security of the attestation, it is critical to use a unique key
+ * pair and keep the private key is secret.
+ *
+ * AN519 does not have any available hardware unique key engine, so a
+ * software stub has been implemented in this case.
+ */
#define TFM_KEY_LEN_BYTES 16
@@ -22,29 +32,96 @@
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+extern const enum ecc_curve_t initial_attestation_curve_type;
+extern const uint8_t initial_attestation_private_key[];
+extern const uint32_t initial_attestation_private_key_size;
+extern const uint8_t initial_attestation_public_x_key[];
+extern const uint32_t initial_attestation_public_x_key_size;
+extern const uint8_t initial_attestation_public_y_key[];
+extern const uint32_t initial_attestation_public_y_key_size;
+
+/**
+ * \brief Copy the key to the destination buffer
+ *
+ * \param[out] p_dst Pointer to buffer where to store the key
+ * \param[in] p_src Pointer to the key
+ * \param[in] size Length of the key
+ */
+static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size)
+{
+ uint32_t i;
+
+ for (i = size; i > 0; i--) {
+ *p_dst = *p_src;
+ p_src++;
+ p_dst++;
+ }
+}
+
enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size)
{
- /* FIXME: this function should be implemented by platform vendor. For the
- * security of the storage system, it is critical to use a hardware unique
- * key.
- *
- * AN519 does not have any available hardware unique key engine, so a
- * software stub has been implemented in this case.
- */
- uint32_t i;
- uint8_t *p_dst = key;
- const uint8_t *p_huk = sample_tfm_key;
-
if(size > TFM_KEY_LEN_BYTES) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}
- for (i = size; i > 0; i--) {
- *p_dst = *p_huk;
- p_huk++;
- p_dst++;
- }
+ copy_key(key, sample_tfm_key, size);
return TFM_PLAT_ERR_SUCCESS;
}
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t *key_buf,
+ uint32_t size,
+ struct ecc_key_t *ecc_key,
+ enum ecc_curve_t *curve_type)
+{
+ uint8_t *key_dst;
+ const uint8_t *key_src;
+ uint32_t key_size;
+ uint32_t full_key_size = initial_attestation_private_key_size +
+ initial_attestation_public_x_key_size +
+ initial_attestation_public_y_key_size;
+
+ if (size < full_key_size) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Set the EC curve type which the key belongs to */
+ *curve_type = initial_attestation_curve_type;
+
+ /* Copy the private key to the buffer, it MUST be present */
+ key_dst = key_buf;
+ key_src = initial_attestation_private_key;
+ key_size = initial_attestation_private_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->priv_key = key_dst;
+ ecc_key->priv_key_size = key_size;
+
+ /* Copy the x-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_x_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_x_key;
+ key_size = initial_attestation_public_x_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->pubx_key = key_dst;
+ ecc_key->pubx_key_size = key_size;
+ } else {
+ ecc_key->pubx_key = NULL;
+ ecc_key->pubx_key_size = 0;
+ }
+
+ /* Copy the y-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_y_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_y_key;
+ key_size = initial_attestation_public_y_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->puby_key = key_dst;
+ ecc_key->puby_key_size = key_size;
+ } else {
+ ecc_key->puby_key = NULL;
+ ecc_key->puby_key_size = 0;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index 7bd8fbd..c01cd10 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -89,7 +89,7 @@
TFM_SP_INITIAL_ATTESTATION +0 ALIGN 32 {
*tfm_attest* (+RO)
- *(TFM_SP_INITIAL_ATTESTATION_PLATFORM_ATTR_FN)
+ *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
}
#ifdef TFM_PARTITION_TEST_CORE
diff --git a/platform/ext/target/mps2/an521/dummy_crypto_keys.c b/platform/ext/target/mps2/an521/dummy_crypto_keys.c
index 0d74ffd..a2c3459 100644
--- a/platform/ext/target/mps2/an521/dummy_crypto_keys.c
+++ b/platform/ext/target/mps2/an521/dummy_crypto_keys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,16 @@
*/
#include "platform/include/tfm_plat_crypto_keys.h"
+#include <stddef.h>
+
+/* FIXME: Functions in this file should be implemented by platform vendor. For
+ * the security of the storage system, it is critical to use a hardware unique
+ * key. For the security of the attestation, it is critical to use a unique key
+ * pair and keep the private key is secret.
+ *
+ * AN521 does not have any available hardware unique key engine, so a
+ * software stub has been implemented in this case.
+ */
#define TFM_KEY_LEN_BYTES 16
@@ -22,29 +32,96 @@
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+extern const enum ecc_curve_t initial_attestation_curve_type;
+extern const uint8_t initial_attestation_private_key[];
+extern const uint32_t initial_attestation_private_key_size;
+extern const uint8_t initial_attestation_public_x_key[];
+extern const uint32_t initial_attestation_public_x_key_size;
+extern const uint8_t initial_attestation_public_y_key[];
+extern const uint32_t initial_attestation_public_y_key_size;
+
+/**
+ * \brief Copy the key to the destination buffer
+ *
+ * \param[out] p_dst Pointer to buffer where to store the key
+ * \param[in] p_src Pointer to the key
+ * \param[in] size Length of the key
+ */
+static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size)
+{
+ uint32_t i;
+
+ for (i = size; i > 0; i--) {
+ *p_dst = *p_src;
+ p_src++;
+ p_dst++;
+ }
+}
+
enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size)
{
- /* FIXME: this function should be implemented by platform vendor. For the
- * security of the storage system, it is critical to use a hardware unique
- * key.
- *
- * AN521 does not have any available hardware unique key engine, so a
- * software stub has been implemented in this case.
- */
- uint32_t i;
- uint8_t *p_dst = key;
- const uint8_t *p_huk = sample_tfm_key;
-
if(size > TFM_KEY_LEN_BYTES) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}
- for (i = size; i > 0; i--) {
- *p_dst = *p_huk;
- p_huk++;
- p_dst++;
- }
+ copy_key(key, sample_tfm_key, size);
return TFM_PLAT_ERR_SUCCESS;
}
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t *key_buf,
+ uint32_t size,
+ struct ecc_key_t *ecc_key,
+ enum ecc_curve_t *curve_type)
+{
+ uint8_t *key_dst;
+ const uint8_t *key_src;
+ uint32_t key_size;
+ uint32_t full_key_size = initial_attestation_private_key_size +
+ initial_attestation_public_x_key_size +
+ initial_attestation_public_y_key_size;
+
+ if (size < full_key_size) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Set the EC curve type which the key belongs to */
+ *curve_type = initial_attestation_curve_type;
+
+ /* Copy the private key to the buffer, it MUST be present */
+ key_dst = key_buf;
+ key_src = initial_attestation_private_key;
+ key_size = initial_attestation_private_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->priv_key = key_dst;
+ ecc_key->priv_key_size = key_size;
+
+ /* Copy the x-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_x_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_x_key;
+ key_size = initial_attestation_public_x_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->pubx_key = key_dst;
+ ecc_key->pubx_key_size = key_size;
+ } else {
+ ecc_key->pubx_key = NULL;
+ ecc_key->pubx_key_size = 0;
+ }
+
+ /* Copy the y-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_y_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_y_key;
+ key_size = initial_attestation_public_y_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->puby_key = key_dst;
+ ecc_key->puby_key_size = key_size;
+ } else {
+ ecc_key->puby_key = NULL;
+ ecc_key->puby_key_size = 0;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
diff --git a/platform/ext/target/musca_a/dummy_crypto_keys.c b/platform/ext/target/musca_a/dummy_crypto_keys.c
index dafb837..7ce5c8d 100644
--- a/platform/ext/target/musca_a/dummy_crypto_keys.c
+++ b/platform/ext/target/musca_a/dummy_crypto_keys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,16 @@
*/
#include "platform/include/tfm_plat_crypto_keys.h"
+#include <stddef.h>
+
+/* FIXME: Functions in this file should be implemented by platform vendor. For
+ * the security of the storage system, it is critical to use a hardware unique
+ * key. For the security of the attestation, it is critical to use a unique key
+ * pair and keep the private key is secret.
+ *
+ * Musca A does not have any available hardware unique key engine, so a
+ * software stub has been implemented in this case.
+ */
#define TFM_KEY_LEN_BYTES 16
@@ -22,29 +32,96 @@
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+extern const enum ecc_curve_t initial_attestation_curve_type;
+extern const uint8_t initial_attestation_private_key[];
+extern const uint32_t initial_attestation_private_key_size;
+extern const uint8_t initial_attestation_public_x_key[];
+extern const uint32_t initial_attestation_public_x_key_size;
+extern const uint8_t initial_attestation_public_y_key[];
+extern const uint32_t initial_attestation_public_y_key_size;
+
+/**
+ * \brief Copy the key to the destination buffer
+ *
+ * \param[out] p_dst Pointer to buffer where to store the key
+ * \param[in] p_src Pointer to the key
+ * \param[in] size Length of the key
+ */
+static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size)
+{
+ uint32_t i;
+
+ for (i = size; i > 0; i--) {
+ *p_dst = *p_src;
+ p_src++;
+ p_dst++;
+ }
+}
+
enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size)
{
- /* FIXME: this function should be implemented by platform vendor. For the
- * security of the storage system, it is critical to use a hardware unique
- * key.
- *
- * Musca A does not have any available hardware unique key engine, so a
- * software stub has been implemented in this case.
- */
- uint32_t i;
- uint8_t *p_dst = key;
- const uint8_t *p_huk = sample_tfm_key;
-
if(size > TFM_KEY_LEN_BYTES) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}
- for (i = size; i > 0; i--) {
- *p_dst = *p_huk;
- p_huk++;
- p_dst++;
- }
+ copy_key(key, sample_tfm_key, size);
return TFM_PLAT_ERR_SUCCESS;
}
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t *key_buf,
+ uint32_t size,
+ struct ecc_key_t *ecc_key,
+ enum ecc_curve_t *curve_type)
+{
+ uint8_t *key_dst;
+ const uint8_t *key_src;
+ uint32_t key_size;
+ uint32_t full_key_size = initial_attestation_private_key_size +
+ initial_attestation_public_x_key_size +
+ initial_attestation_public_y_key_size;
+
+ if (size < full_key_size) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Set the EC curve type which the key belongs to */
+ *curve_type = initial_attestation_curve_type;
+
+ /* Copy the private key to the buffer, it MUST be present */
+ key_dst = key_buf;
+ key_src = initial_attestation_private_key;
+ key_size = initial_attestation_private_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->priv_key = key_dst;
+ ecc_key->priv_key_size = key_size;
+
+ /* Copy the x-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_x_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_x_key;
+ key_size = initial_attestation_public_x_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->pubx_key = key_dst;
+ ecc_key->pubx_key_size = key_size;
+ } else {
+ ecc_key->pubx_key = NULL;
+ ecc_key->pubx_key_size = 0;
+ }
+
+ /* Copy the y-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_y_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_y_key;
+ key_size = initial_attestation_public_y_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->puby_key = key_dst;
+ ecc_key->puby_key_size = key_size;
+ } else {
+ ecc_key->puby_key = NULL;
+ ecc_key->puby_key_size = 0;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
diff --git a/platform/ext/target/musca_b1/dummy_crypto_keys.c b/platform/ext/target/musca_b1/dummy_crypto_keys.c
index 2ce83a6..1db8646 100644
--- a/platform/ext/target/musca_b1/dummy_crypto_keys.c
+++ b/platform/ext/target/musca_b1/dummy_crypto_keys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,13 @@
*/
#include "platform/include/tfm_plat_crypto_keys.h"
+#include <stddef.h>
+
+/* FIXME: Functions in this file should be implemented by platform vendor. For
+ * the security of the storage system, it is critical to use a hardware unique
+ * key. For the security of the attestation, it is critical to use a unique key
+ * pair and keep the private key is secret.
+ */
#define TFM_KEY_LEN_BYTES 16
@@ -22,24 +29,95 @@
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
+extern const enum ecc_curve_t initial_attestation_curve_type;
+extern const uint8_t initial_attestation_private_key[];
+extern const uint32_t initial_attestation_private_key_size;
+extern const uint8_t initial_attestation_public_x_key[];
+extern const uint32_t initial_attestation_public_x_key_size;
+extern const uint8_t initial_attestation_public_y_key[];
+extern const uint32_t initial_attestation_public_y_key_size;
+
+/**
+ * \brief Copy the key to the destination buffer
+ *
+ * \param[out] p_dst Pointer to buffer where to store the key
+ * \param[in] p_src Pointer to the key
+ * \param[in] size Length of the key
+ */
+static inline void copy_key(uint8_t *p_dst, const uint8_t *p_src, size_t size)
+{
+ uint32_t i;
+
+ for (i = size; i > 0; i--) {
+ *p_dst = *p_src;
+ p_src++;
+ p_dst++;
+ }
+}
+
enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size)
{
- /* FIXME: this function should be implemented by platform vendor. For the
- * security of the storage system, it is critical to use a hardware unique
- * key.
- */
- uint32_t i;
- uint8_t *p_dst = key;
- const uint8_t *p_huk = sample_tfm_key;
-
if(size > TFM_KEY_LEN_BYTES) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}
- for (i = size; i > 0; i--) {
- *p_dst = *p_huk;
- p_huk++;
- p_dst++;
+ copy_key(key, sample_tfm_key, size);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t *key_buf,
+ uint32_t size,
+ struct ecc_key_t *ecc_key,
+ enum ecc_curve_t *curve_type)
+{
+ uint8_t *key_dst;
+ const uint8_t *key_src;
+ uint32_t key_size;
+ uint32_t full_key_size = initial_attestation_private_key_size +
+ initial_attestation_public_x_key_size +
+ initial_attestation_public_y_key_size;
+
+ if (size < full_key_size) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+
+ /* Set the EC curve type which the key belongs to */
+ *curve_type = initial_attestation_curve_type;
+
+ /* Copy the private key to the buffer, it MUST be present */
+ key_dst = key_buf;
+ key_src = initial_attestation_private_key;
+ key_size = initial_attestation_private_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->priv_key = key_dst;
+ ecc_key->priv_key_size = key_size;
+
+ /* Copy the x-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_x_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_x_key;
+ key_size = initial_attestation_public_x_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->pubx_key = key_dst;
+ ecc_key->pubx_key_size = key_size;
+ } else {
+ ecc_key->pubx_key = NULL;
+ ecc_key->pubx_key_size = 0;
+ }
+
+ /* Copy the y-coordinate of public key to the buffer, it MIGHT be present */
+ if (initial_attestation_public_y_key_size != 0) {
+ key_dst = key_dst + key_size;
+ key_src = initial_attestation_public_y_key;
+ key_size = initial_attestation_public_y_key_size;
+ copy_key(key_dst, key_src, key_size);
+ ecc_key->puby_key = key_dst;
+ ecc_key->puby_key_size = key_size;
+ } else {
+ ecc_key->puby_key = NULL;
+ ecc_key->puby_key_size = 0;
}
return TFM_PLAT_ERR_SUCCESS;
diff --git a/platform/include/tfm_plat_crypto_keys.h b/platform/include/tfm_plat_crypto_keys.h
index 9682cc9..386d61f 100644
--- a/platform/include/tfm_plat_crypto_keys.h
+++ b/platform/include/tfm_plat_crypto_keys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -20,6 +20,49 @@
#endif
/**
+ * Elliptic curve key type identifiers according to RFC8152 (COSE encoding)
+ * https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
+ */
+enum ecc_curve_t {
+ P_256 = 1, /* NIST P-256 also known as secp256r1 */
+ P_384 = 2, /* NIST P-384 also known as secp384r1 */
+ P_521 = 3, /* NIST P-521 also known as secp521r1 */
+ X25519 = 4, /* X25519 for use with ECDH only */
+ X448 = 5, /* X448 for use with ECDH only */
+ ED25519 = 6, /* Ed25519 for use with EdDSA only */
+ ED448 = 7, /* Ed448 for use with EdDSA only */
+};
+
+/**
+ * Structure definition to carry pointer and size information about an Elliptic
+ * curve key which is stored in a buffer(key_buf) in raw format (without
+ * encoding):
+ * - priv_key Base address of the private key in key_buf. It must be
+ * present on the device.
+ * - priv_key_size Size of the private key in bytes.
+ * - pubx_key Base address of x-coordinate of the public key in key_buf.
+ * It can be empty, because it can be recomputed based on
+ * private key.
+ * - pubx_key_size Length of x-coordinate of the public key in key_buf.
+ * It can be empty, because it can be recomputed based on
+ * private key.
+ * - puby_key Base address of y-coordinate of the public key in key_buf.
+ * It can be empty, because either it can be recomputed based
+ * on private key or some curve type works without it.
+ * - puby_key_size Length of y-coordinate of the public key in key_buf.
+ */
+struct ecc_key_t {
+ uint8_t *priv_key;
+ uint32_t priv_key_size;
+ uint8_t *pubx_key;
+ uint32_t pubx_key_size;
+ uint8_t *puby_key;
+ uint32_t puby_key_size;
+};
+
+#define ECC_P_256_KEY_SIZE (96u) /* 3 x 32 = 96 bytes priv + pub-x + pub-y */
+
+/**
* \brief Gets hardware unique key for encryption
*
* \param[out] key Buf to store the key in
@@ -29,6 +72,40 @@
*/
enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size);
+/**
+ * \brief Get the initial attestation key
+ *
+ * The device MUST contain an initial attestation key, which is used to sign the
+ * token. Initial attestation service supports elliptic curve signing
+ * algorithms. Device maker can decide whether store only the private key on the
+ * device or store both (public and private) key. Public key can be recomputed
+ * based on private key. Keys must be provided in raw format, just binary data
+ * without any encoding (DER, COSE). Caller provides a buffer to copy all the
+ * available key components to there. Key components must be copied after
+ * each other to the buffer. The base address and the length of each key
+ * component must be indicating in the corresponding field of ecc_key
+ * (\ref struct ecc_key_t).
+ * Curve_type indicates to which curve belongs the key.
+ *
+ *
+ * Keys must be provided in
+ *
+ * \param[in/out] key_buf Buffer to store the initial attestation key.
+ * \param[in] size Size of the buffer.
+ * \param[out] ecc_key A structure to carry pointer and size information
+ * about the initial attestation key, which is
+ * stored in key_buf.
+ * \param[out] curve_type The type of the EC curve, which the key belongs
+ * to according to \ref ecc_curve_t
+ *
+ * \return Returns error code specified in \ref tfm_plat_err_t
+ */
+enum tfm_plat_err_t
+tfm_plat_get_initial_attest_key(uint8_t *key_buf,
+ uint32_t size,
+ struct ecc_key_t *ecc_key,
+ enum ecc_curve_t *curve_type);
+
#ifdef __cplusplus
}
#endif