aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hall <julian.hall@arm.com>2021-05-12 14:43:19 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-07-05 12:43:47 +0200
commit70be3f17bd00710dcab9fcba2fea2c23853c7c71 (patch)
tree7f67b7f69d43dbc3c5f596c610dbe212e08d5e87
parent827d4474a109ee1a72173c5bfdf039fb361667f1 (diff)
downloadtrusted-services-70be3f17bd00710dcab9fcba2fea2c23853c7c71.tar.gz
Add attestation key management
Adds component to manage access and creation of the IAK. Allows for factory provisioned and generate-on-first-run strategies. Extended the attestation reporter tests to use the key manager to allow the signed report to be verified. Signed-off-by: Julian Hall <julian.hall@arm.com> Change-Id: I01e126a8a18a7b3d24a0b322885aa9e558070250
-rw-r--r--components/service/attestation/key_mngr/attest_key_mngr.c112
-rw-r--r--components/service/attestation/key_mngr/attest_key_mngr.h60
-rw-r--r--components/service/attestation/key_mngr/component.cmake13
-rw-r--r--components/service/attestation/reporter/attest_report.h (renamed from components/service/attestation/reporter/attestation_report.h)16
-rw-r--r--components/service/attestation/reporter/psa/component.cmake5
-rw-r--r--components/service/attestation/reporter/psa/eat_serializer.c (renamed from components/service/attestation/reporter/psa/report_serializer.c)16
-rw-r--r--components/service/attestation/reporter/psa/eat_serializer.h (renamed from components/service/attestation/reporter/psa/report_serializer.h)17
-rw-r--r--components/service/attestation/reporter/psa/eat_signer.c81
-rw-r--r--components/service/attestation/reporter/psa/eat_signer.h38
-rw-r--r--components/service/attestation/reporter/psa/psa_attest_report.c (renamed from components/service/attestation/reporter/psa/attestation_report.c)24
-rw-r--r--components/service/attestation/test/component/attestation_reporter_tests.cpp64
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.cpp52
-rw-r--r--components/service/crypto/test/service/crypto_service_scenarios.h1
-rw-r--r--components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp5
-rw-r--r--deployments/component-test/component-test.cmake1
15 files changed, 454 insertions, 51 deletions
diff --git a/components/service/attestation/key_mngr/attest_key_mngr.c b/components/service/attestation/key_mngr/attest_key_mngr.c
new file mode 100644
index 0000000..c871c82
--- /dev/null
+++ b/components/service/attestation/key_mngr/attest_key_mngr.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <psa/crypto.h>
+#include "attest_key_mngr.h"
+
+/* todo - need strategy for assigning key IDs */
+#define IAK_KEY_ID 0x2000
+
+/**
+ * The singleton attest_key_mngr instance.
+ */
+static struct attest_key_mngr
+{
+ bool is_iak_open;
+ psa_key_id_t iak_id;
+ psa_key_handle_t iak_handle;
+} instance;
+
+/**
+ * \brief Generates the IAK
+ *
+ * If an IAK hasn't been provisioned during manufacture, there is the
+ * option to generate a persistent IAK on first run.
+ *
+ * \param[in] key_id The IAK key id or zero for volatile key
+ * \param[out] iak_handle The returned key handle
+ *
+ * \return Status
+ */
+static psa_status_t generate_iak(psa_key_id_t key_id, psa_key_handle_t *iak_handle)
+{
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ if (key_id)
+ psa_set_key_id(&attributes, key_id);
+ else
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+
+ psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1));
+ psa_set_key_bits(&attributes, 256);
+
+ status = psa_generate_key(&attributes, iak_handle);
+
+ psa_reset_key_attributes(&attributes);
+
+ return status;
+}
+
+void attest_key_mngr_init(void)
+{
+ instance.is_iak_open = false;
+ instance.iak_id = IAK_KEY_ID;
+ instance.iak_handle = -1;
+}
+
+void attest_key_mngr_deinit(void)
+{
+
+}
+
+psa_status_t attest_key_mngr_get_iak_handle(psa_key_handle_t *iak_handle)
+{
+ psa_status_t status = PSA_SUCCESS;
+
+ if (!instance.is_iak_open) {
+
+ status = psa_open_key(instance.iak_id, &instance.iak_handle);
+
+ if (status == PSA_ERROR_STORAGE_FAILURE) {
+
+ /* Accommodate deployments with no persistent storage
+ * to support testing. In this case, a volatile key
+ * is generated, indicated by an invalid key id.
+ */
+ instance.iak_id = 0;
+ }
+
+ if (status != PSA_SUCCESS) {
+
+ /* First run and no key has been provisioned */
+ status = generate_iak(instance.iak_id, &instance.iak_handle);
+ }
+
+ instance.is_iak_open = (status == PSA_SUCCESS);
+ }
+
+ *iak_handle = instance.iak_handle;
+ return status;
+}
+
+psa_status_t attest_key_mngr_export_iak_public_key(uint8_t *data,
+ size_t data_size, size_t *data_length)
+{
+ psa_key_handle_t handle;
+ psa_status_t status = attest_key_mngr_get_iak_handle(&handle);
+
+ if (status == PSA_SUCCESS) {
+
+ status = psa_export_public_key(handle, data, data_size, data_length);
+ }
+
+ return status;
+}
diff --git a/components/service/attestation/key_mngr/attest_key_mngr.h b/components/service/attestation/key_mngr/attest_key_mngr.h
new file mode 100644
index 0000000..982c841
--- /dev/null
+++ b/components/service/attestation/key_mngr/attest_key_mngr.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ATTEST_KEY_MNGR_H
+#define ATTEST_KEY_MNGR_H
+
+#include <psa/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The attestation key manager manages creation and access
+ * to the IAK. In real device deployments, the IAK will
+ * either be provisioned during manufacture or generated
+ * on first run. To accommodate both sceanrios and to support
+ * testing without a persistent key store, the IAK is
+ * genarated automatically if the corresponding persistent
+ * key doesn't exist.
+ */
+
+/**
+ * \brief Initialize the attest_key_mngr
+ */
+void attest_key_mngr_init(void);
+
+/**
+ * \brief De-initialize the attest_key_mngr
+ */
+void attest_key_mngr_deinit(void);
+
+/**
+ * \brief Get the IAK key handle
+ *
+ * \param[out] iak_handle The returned key handle
+ * \return Status
+ */
+psa_status_t attest_key_mngr_get_iak_handle(psa_key_handle_t *iak_handle);
+
+/**
+ * \brief Export the IAK public key
+ *
+ * \param[out] data Buffer for key data
+ * \param[in] data_size Size of buffer
+ * \param[out] data_length Length in bytes of key
+ *
+ * \return Status
+ */
+psa_status_t attest_key_mngr_export_iak_public_key(uint8_t *data,
+ size_t data_size, size_t *data_length);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* ATTEST_KEY_MNGR_H */
diff --git a/components/service/attestation/key_mngr/component.cmake b/components/service/attestation/key_mngr/component.cmake
new file mode 100644
index 0000000..722d4f5
--- /dev/null
+++ b/components/service/attestation/key_mngr/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/attest_key_mngr.c"
+ )
diff --git a/components/service/attestation/reporter/attestation_report.h b/components/service/attestation/reporter/attest_report.h
index 3b51af2..f5c6fb0 100644
--- a/components/service/attestation/reporter/attestation_report.h
+++ b/components/service/attestation/reporter/attest_report.h
@@ -4,12 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef ATTESTATION_REPORT_H
-#define ATTESTATION_REPORT_H
+#ifndef ATTEST_REPORT_H
+#define ATTEST_REPORT_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#include <psa/crypto.h>
#ifdef __cplusplus
extern "C" {
@@ -20,9 +21,10 @@ extern "C" {
*
* Using the view of the security state of the device provided by
* the claims_register, a signed attestation report is created. On
- * success, a buffer is allocated for the serialized report. The buffer
- * must be freed by calling attestation_report_destroy().
+ * success, a buffer is allocated for the signed report. The buffer
+ * must be freed by calling attest_report_destroy().
*
+ * \param[in] key_handle Signing key handle
* \param[in] client_id The requesting client id
* \param[in] auth_challenge_data The auth challenge from the requester
* \param[in] auth_challenge_len The auth challenge from the requester
@@ -31,7 +33,7 @@ extern "C" {
*
* \return Operation status
*/
-int attestation_report_create(int32_t client_id,
+int attest_report_create(psa_key_handle_t key_handle, int32_t client_id,
const uint8_t *auth_challenge_data, size_t auth_challenge_len,
const uint8_t **report, size_t *report_len);
@@ -42,11 +44,11 @@ int attestation_report_create(int32_t client_id,
*
* \param[in] report The created report
*/
-void attestation_report_destroy(const uint8_t *report);
+void attest_report_destroy(const uint8_t *report);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif /* ATTESTATION_REPORT_H */
+#endif /* ATTEST_REPORT_H */
diff --git a/components/service/attestation/reporter/psa/component.cmake b/components/service/attestation/reporter/psa/component.cmake
index 26be202..084c00f 100644
--- a/components/service/attestation/reporter/psa/component.cmake
+++ b/components/service/attestation/reporter/psa/component.cmake
@@ -9,6 +9,7 @@ if (NOT DEFINED TGT)
endif()
target_sources(${TGT} PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}/attestation_report.c"
- "${CMAKE_CURRENT_LIST_DIR}/report_serializer.c"
+ "${CMAKE_CURRENT_LIST_DIR}/psa_attest_report.c"
+ "${CMAKE_CURRENT_LIST_DIR}/eat_serializer.c"
+ "${CMAKE_CURRENT_LIST_DIR}/eat_signer.c"
)
diff --git a/components/service/attestation/reporter/psa/report_serializer.c b/components/service/attestation/reporter/psa/eat_serializer.c
index d66060e..88b595d 100644
--- a/components/service/attestation/reporter/psa/report_serializer.c
+++ b/components/service/attestation/reporter/psa/eat_serializer.c
@@ -11,7 +11,7 @@
#include <psa/error.h>
#include <protocols/service/attestation/packed-c/eat.h>
#include <service/attestation/claims/claim.h>
-#include "report_serializer.h"
+#include "eat_serializer.h"
static bool alloc_encode_buffer(const struct claim_vector *device_claims,
const struct claim_vector *sw_claims, UsefulBuf *encode_buffer);
@@ -20,9 +20,9 @@ static void encode_claim(QCBOREncodeContext *encode_ctx, const struct claim *cla
static int eat_label(enum claim_subject_id subject_id);
static int qcbor_to_psa_status(QCBORError qcbor_err);
-int serialize_report(const struct claim_vector *device_claims,
+int eat_serialize(const struct claim_vector *device_claims,
const struct claim_vector *sw_claims,
- const uint8_t **report, size_t *report_len)
+ const uint8_t **token, size_t *token_len)
{
UsefulBuf encode_buffer;
@@ -54,21 +54,21 @@ int serialize_report(const struct claim_vector *device_claims,
QCBOREncode_CloseMap(&encode_ctx);
- /* Finalize the encoding to create the CBOR serialized report */
+ /* Finalize the encoding to create the CBOR serialized token */
UsefulBufC encoded_cbor;
QCBORError qcbor_error;
qcbor_error = QCBOREncode_Finish(&encode_ctx, &encoded_cbor);
if (qcbor_error == QCBOR_SUCCESS) {
- *report = encoded_cbor.ptr;
- *report_len = encoded_cbor.len;
+ *token = encoded_cbor.ptr;
+ *token_len = encoded_cbor.len;
}
else {
free(encode_buffer.ptr);
- *report = NULL;
- *report_len = 0;
+ *token = NULL;
+ *token_len = 0;
}
return qcbor_to_psa_status(qcbor_error);
diff --git a/components/service/attestation/reporter/psa/report_serializer.h b/components/service/attestation/reporter/psa/eat_serializer.h
index 5da5a66..9744bc6 100644
--- a/components/service/attestation/reporter/psa/report_serializer.h
+++ b/components/service/attestation/reporter/psa/eat_serializer.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef PSA_REPORT_SERIALIZER_H
-#define PSA_REPORT_SERIALIZER_H
+#ifndef PSA_EAT_SERIALIZER_H
+#define PSA_EAT_SERIALIZER_H
#include <stddef.h>
#include <stdint.h>
@@ -19,22 +19,23 @@ extern "C" {
* \brief Serialize the collated set of claims
*
* Serializes the claims into a CBOR document using PSA defined
- * EAT custom claims to identify claim objects.
+ * EAT custom claims to identify claim objects. The output
+ * token is encoded as cbor but is not signed.
*
* \param[in] device_claims Collated device claims
* \param[in] sw_claims Collated software claims
- * \param[out] report The serialized report
- * \param[out] report_len The length of the report
+ * \param[out] token The serialized token
+ * \param[out] token_len The length of the token
*
* \return Operation status
*/
-int serialize_report(const struct claim_vector *device_claims,
+int eat_serialize(const struct claim_vector *device_claims,
const struct claim_vector *sw_claims,
- const uint8_t **report, size_t *report_len);
+ const uint8_t **token, size_t *token_len);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif /* PSA_REPORT_SERIALIZER_H */
+#endif /* PSA_EAT_SERIALIZER_H */
diff --git a/components/service/attestation/reporter/psa/eat_signer.c b/components/service/attestation/reporter/psa/eat_signer.c
new file mode 100644
index 0000000..08756e7
--- /dev/null
+++ b/components/service/attestation/reporter/psa/eat_signer.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <t_cose/t_cose_sign1_sign.h>
+#include <psa/error.h>
+#include "eat_signer.h"
+
+static bool alloc_output_buf(struct q_useful_buf *buf, size_t input_len);
+static int t_cose_to_psa_status(enum t_cose_err_t t_cose_status);
+
+int eat_sign(psa_key_handle_t key_handle,
+ const uint8_t *unsigned_token, size_t unsigned_token_len,
+ const uint8_t **signed_token, size_t *signed_token_len)
+{
+ struct t_cose_key signing_key;
+ struct t_cose_sign1_sign_ctx sign_ctx;
+ enum t_cose_err_t sign_status;
+ struct q_useful_buf_c input_buf;
+ struct q_useful_buf output_buf;
+ struct q_useful_buf_c result_buf;
+
+ /* Prepare input and output buffers for signing operation */
+ input_buf.ptr = unsigned_token;
+ input_buf.len = unsigned_token_len;
+ result_buf.ptr = NULL;
+ result_buf.len = 0;
+ if (!alloc_output_buf(&output_buf, unsigned_token_len))
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+
+ /* Initialize signing context */
+ signing_key.k.key_handle = key_handle;
+ signing_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
+ t_cose_sign1_sign_init(&sign_ctx, 0, T_COSE_ALGORITHM_ES256);
+ t_cose_sign1_set_signing_key(&sign_ctx, signing_key, NULL_Q_USEFUL_BUF_C);
+
+ /* Sign */
+ sign_status = t_cose_sign1_sign(&sign_ctx, input_buf, output_buf, &result_buf);
+
+ if (sign_status == T_COSE_SUCCESS) {
+
+ /* Note that result_buf points into output_buf with len
+ * corresponding to the signed token length.
+ */
+ *signed_token = result_buf.ptr;
+ *signed_token_len = result_buf.len;
+ }
+ else {
+
+ free((void*)output_buf.ptr);
+ *signed_token = NULL;
+ *signed_token_len = 0;
+ }
+
+ return t_cose_to_psa_status(sign_status);
+}
+
+static bool alloc_output_buf(struct q_useful_buf *buf, size_t input_len)
+{
+ size_t required_space = input_len + 300; /* todo figure out correct overhead */
+ uint8_t *space = malloc(required_space);
+
+ if (space) {
+ buf->ptr = space;
+ buf->len = required_space;
+ }
+
+ return space;
+}
+
+static int t_cose_to_psa_status(enum t_cose_err_t t_cose_status)
+{
+ if (t_cose_status == T_COSE_SUCCESS) return PSA_SUCCESS;
+ if (t_cose_status == T_COSE_ERR_TOO_SMALL) return PSA_ERROR_BUFFER_TOO_SMALL;
+
+ return PSA_ERROR_PROGRAMMER_ERROR;
+}
diff --git a/components/service/attestation/reporter/psa/eat_signer.h b/components/service/attestation/reporter/psa/eat_signer.h
new file mode 100644
index 0000000..421cbc2
--- /dev/null
+++ b/components/service/attestation/reporter/psa/eat_signer.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_EAT_SIGNER_H
+#define PSA_EAT_SIGNER_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <psa/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Sign the serialized EAT token
+ *
+ * \param[in] key_handle Signing key handle
+ * \param[in] unsigned_token The token to sign
+ * \param[in] unsigned_token_len The token to sign
+ * \param[out] signed_token The signed token
+ * \param[out] signed_token_len The length of the signed token
+ *
+ * \return Operation status
+ */
+int eat_sign(psa_key_handle_t key_handle,
+ const uint8_t *unsigned_token, size_t unsigned_token_len,
+ const uint8_t **signed_token, size_t *signed_token_len);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PSA_EAT_SIGNER_H */
diff --git a/components/service/attestation/reporter/psa/attestation_report.c b/components/service/attestation/reporter/psa/psa_attest_report.c
index ed34307..3228f1c 100644
--- a/components/service/attestation/reporter/psa/attestation_report.c
+++ b/components/service/attestation/reporter/psa/psa_attest_report.c
@@ -13,9 +13,10 @@
#include <stdlib.h>
#include <psa/error.h>
-#include <service/attestation/reporter/attestation_report.h>
+#include <service/attestation/reporter/attest_report.h>
#include <service/attestation/claims/claims_register.h>
-#include "report_serializer.h"
+#include "eat_serializer.h"
+#include "eat_signer.h"
/* Local defines */
#define MAX_DEVICE_CLAIMS (50)
@@ -26,7 +27,7 @@ static void add_client_id_claim(struct claim_vector *v, int32_t client_id);
static void add_no_sw_claim(struct claim_vector *v);
-int attestation_report_create(int32_t client_id,
+int attest_report_create(psa_key_handle_t key_handle, int32_t client_id,
const uint8_t *auth_challenge_data, size_t auth_challenge_len,
const uint8_t **report, size_t *report_len)
{
@@ -52,16 +53,27 @@ int attestation_report_create(int32_t client_id,
/* And if there aren't any sw claims, indicate in report */
if (!sw_claims.size) add_no_sw_claim(&device_claims);
- /* Serialize the collated claims to create the final report */
- status = serialize_report(&device_claims, &sw_claims, report, report_len);
+ /* Serialize and sign the collated claims to create the final EAT token */
+ const uint8_t *unsigned_token = NULL;
+ size_t unsigned_token_len = 0;
+ status = eat_serialize(&device_claims, &sw_claims,
+ &unsigned_token, &unsigned_token_len);
+ if (status == PSA_SUCCESS) {
+ status = eat_sign(key_handle,
+ unsigned_token, unsigned_token_len,
+ report, report_len);
+ }
+
+ /* Free resource used */
+ free((void*)unsigned_token);
claim_vector_deinit(&device_claims);
claim_vector_deinit(&sw_claims);
return status;
}
-void attestation_report_destroy(const uint8_t *report)
+void attest_report_destroy(const uint8_t *report)
{
free((void*)report);
}
diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp
index 71fc10d..02b91ac 100644
--- a/components/service/attestation/test/component/attestation_reporter_tests.cpp
+++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp
@@ -6,17 +6,18 @@
#include <psa/error.h>
#include <qcbor/qcbor_spiffy_decode.h>
+#include <t_cose/t_cose_sign1_verify.h>
#include <service/attestation/claims/claims_register.h>
#include <service/attestation/claims/sources/event_log/event_log_claim_source.h>
#include <service/attestation/claims/sources/event_log/mock/mock_event_log.h>
#include <service/attestation/claims/sources/preloaded/preloaded_claim_source.h>
-#include <service/attestation/reporter/attestation_report.h>
+#include <service/attestation/reporter/attest_report.h>
+#include <service/attestation/key_mngr/attest_key_mngr.h>
#include <protocols/service/attestation/packed-c/eat.h>
#include <CppUTest/TestHarness.h>
+#include <psa/crypto.h>
#include "report_dump.h"
-#include <stdio.h>
-
TEST_GROUP(AttestationReporterTests)
{
void setup()
@@ -26,6 +27,9 @@ TEST_GROUP(AttestationReporterTests)
report = NULL;
report_len;
+ psa_crypto_init();
+ attest_key_mngr_init();
+
/* The set of registered claim_sources determines the content
* of a generated attestation source. The set and type of
* claim_sources registered will be deployment specific.
@@ -40,8 +44,9 @@ TEST_GROUP(AttestationReporterTests)
void teardown()
{
- attestation_report_destroy(report);
+ attest_report_destroy(report);
claims_register_deinit();
+ attest_key_mngr_deinit();
}
struct event_log_claim_source event_log_claim_source;
@@ -60,26 +65,45 @@ TEST(AttestationReporterTests, createReport)
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
};
+ /* Retrieve the IAK handle */
+ psa_key_handle_t iak_handle;
+ status = attest_key_mngr_get_iak_handle(&iak_handle);
+ LONGS_EQUAL(PSA_SUCCESS, status);
+
/* Create a report */
- status = attestation_report_create(client_id,
+ status = attest_report_create(iak_handle, client_id,
auth_challenge, sizeof(auth_challenge),
&report, &report_len);
/* Expect the operation to succeed and a non-zero length
* report created.
*/
- UNSIGNED_LONGS_EQUAL(PSA_SUCCESS, status);
+ LONGS_EQUAL(PSA_SUCCESS, status);
CHECK_TRUE(report);
CHECK_TRUE(report_len);
+ /* Verify the signature */
+ struct t_cose_sign1_verify_ctx verify_ctx;
+ struct t_cose_key key_pair;
+
+ key_pair.k.key_handle = iak_handle;
+ key_pair.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
+ UsefulBufC signed_cose;
+ UsefulBufC report_body;
+
+ signed_cose.ptr = report;
+ signed_cose.len = report_len;
+
+ t_cose_sign1_verify_init(&verify_ctx, 0);
+ t_cose_sign1_set_verification_key(&verify_ctx, key_pair);
+
+ status = t_cose_sign1_verify(&verify_ctx, signed_cose, &report_body, NULL);
+ LONGS_EQUAL(T_COSE_SUCCESS, status);
+
/* Check the report contents */
QCBORDecodeContext decode_ctx;
- UsefulBufC report_buf;
-
- report_buf.ptr = report;
- report_buf.len = report_len;
- QCBORDecode_Init(&decode_ctx, report_buf, QCBOR_DECODE_MODE_NORMAL);
+ QCBORDecode_Init(&decode_ctx, report_body, QCBOR_DECODE_MODE_NORMAL);
QCBORDecode_EnterMap(&decode_ctx, NULL);
/* Check client id */
@@ -87,8 +111,8 @@ TEST(AttestationReporterTests, createReport)
QCBORDecode_GetInt64InMapN(&decode_ctx,
EAT_ARM_PSA_CLAIM_ID_CLIENT_ID, &decoded_client_id);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
- UNSIGNED_LONGS_EQUAL(client_id, decoded_client_id);
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(client_id, decoded_client_id);
/* Check the auth challenge */
UsefulBufC auth_challenge_buf;
@@ -97,7 +121,7 @@ TEST(AttestationReporterTests, createReport)
QCBORDecode_GetByteStringInMapN(&decode_ctx,
EAT_ARM_PSA_CLAIM_ID_CHALLENGE, &auth_challenge_buf);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
CHECK_TRUE(auth_challenge_buf.ptr);
UNSIGNED_LONGS_EQUAL(sizeof(auth_challenge), auth_challenge_buf.len);
MEMCMP_EQUAL(auth_challenge, auth_challenge_buf.ptr, sizeof(auth_challenge));
@@ -105,12 +129,12 @@ TEST(AttestationReporterTests, createReport)
/* Shouldn't expect to see the 'NO_SW_COMPONENTS' claim */
int64_t no_sw = 0;
QCBORDecode_GetInt64InMapN(&decode_ctx, EAT_ARM_PSA_CLAIM_ID_NO_SW_COMPONENTS, &no_sw);
- UNSIGNED_LONGS_EQUAL(QCBOR_ERR_LABEL_NOT_FOUND, QCBORDecode_GetAndResetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_ERR_LABEL_NOT_FOUND, QCBORDecode_GetAndResetError(&decode_ctx));
CHECK_FALSE(no_sw);
/* Check the sw components */
QCBORDecode_EnterArrayFromMapN(&decode_ctx, EAT_ARM_PSA_CLAIM_ID_SW_COMPONENTS);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
/* Iterate over all array members */
size_t sw_component_count = 0;
@@ -129,7 +153,7 @@ TEST(AttestationReporterTests, createReport)
/* Check measurement id */
QCBORDecode_GetByteStringInMapN(&decode_ctx,
EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE, &property);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
CHECK_TRUE(property.ptr);
CHECK_TRUE(property.len);
MEMCMP_EQUAL(measurement->id, property.ptr, property.len);
@@ -137,7 +161,7 @@ TEST(AttestationReporterTests, createReport)
/* Check measurement digest */
QCBORDecode_GetByteStringInMapN(&decode_ctx,
EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_VALUE, &property);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
CHECK_TRUE(property.ptr);
CHECK_TRUE(property.len);
MEMCMP_EQUAL(measurement->digest, property.ptr, property.len);
@@ -153,10 +177,10 @@ TEST(AttestationReporterTests, createReport)
}
QCBORDecode_ExitArray(&decode_ctx);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
+ LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
QCBORError qcbor_error;
QCBORDecode_ExitMap(&decode_ctx);
qcbor_error = QCBORDecode_Finish(&decode_ctx);
- UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, qcbor_error);
+ LONGS_EQUAL(QCBOR_SUCCESS, qcbor_error);
}
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.cpp b/components/service/crypto/test/service/crypto_service_scenarios.cpp
index e20b6be..7056b4a 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.cpp
+++ b/components/service/crypto/test/service/crypto_service_scenarios.cpp
@@ -215,6 +215,58 @@ void crypto_service_scenarios::signAndVerifyHash()
CHECK_EQUAL(PSA_SUCCESS, status);
}
+void crypto_service_scenarios::signAndVerifyEat()
+{
+ /* Sign and verify a hash using EAT key type and algorithm */
+ psa_status_t status;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id;
+
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+
+ psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
+ psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1));
+ psa_set_key_bits(&attributes, 256);
+
+ /* Generate a key */
+ status = m_crypto_client->generate_key(&attributes, &key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ psa_reset_key_attributes(&attributes);
+
+ /* Sign a hash */
+ uint8_t hash[64];
+ uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
+ size_t signature_length;
+
+ memset(hash, 0x71, sizeof(hash));
+
+ status = m_crypto_client->sign_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, sizeof(signature), &signature_length);
+
+ CHECK_EQUAL(PSA_SUCCESS, status);
+ CHECK(signature_length > 0);
+
+ /* Verify the signature */
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+
+ /* Change the hash and expect verify to fail */
+ hash[0] = 0x72;
+ status = m_crypto_client->verify_hash(key_id,
+ PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash),
+ signature, signature_length);
+ CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
+
+ /* Remove the key */
+ status = m_crypto_client->destroy_key(key_id);
+ CHECK_EQUAL(PSA_SUCCESS, status);
+}
+
void crypto_service_scenarios::asymEncryptDecrypt()
{
psa_status_t status;
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.h b/components/service/crypto/test/service/crypto_service_scenarios.h
index 0e996aa..648baae 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.h
+++ b/components/service/crypto/test/service/crypto_service_scenarios.h
@@ -21,6 +21,7 @@ public:
void asymEncryptDecrypt();
void asymEncryptDecryptWithSalt();
void signAndVerifyHash();
+ void signAndVerifyEat();
void exportAndImportKeyPair();
void exportPublicKey();
void generatePersistentKeys();
diff --git a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
index 5a620b4..9ceb0d5 100644
--- a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -77,6 +77,11 @@ TEST(CryptoServicePackedcTests, signAndVerifyHash)
m_scenarios->signAndVerifyHash();
}
+TEST(CryptoServicePackedcTests, signAndVerifyEat)
+{
+ m_scenarios->signAndVerifyEat();
+}
+
TEST(CryptoServicePackedcTests, asymEncryptDecrypt)
{
m_scenarios->asymEncryptDecrypt();
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 8f5610b..075538d 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -47,6 +47,7 @@ add_components(
"components/service/attestation/claims/sources/event_log/mock"
"components/service/attestation/claims/sources/event_log/test"
"components/service/attestation/reporter/psa"
+ "components/service/attestation/key_mngr"
"components/service/attestation/test/component"
"components/service/crypto/client/cpp"
"components/service/crypto/client/cpp/protobuf"