aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hall <julian.hall@arm.com>2021-05-26 15:33:06 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-07-05 12:47:41 +0200
commit4834e6323a9ae2106ea80331b851194a3f7c5c81 (patch)
treef0bd2088ad2cb411aa956702b72e4fce635ad0db
parentcaa4af8770a5a9ac889ab143d8aadc9527a7d2ee (diff)
downloadtrusted-services-4834e6323a9ae2106ea80331b851194a3f7c5c81.tar.gz
Add demo app for attestation service
Adds the platform_inspect deployment that builds a user-space app that retrieves an attestation token, verifies it and pretty prints the result. The platform_inspect app may be extended to inspect other aspects of the device firmware e.g. a list of TS service providers. Signed-off-by: Julian Hall <julian.hall@arm.com> Change-Id: I98efd0313f15fdfd50d92716341165afdb1f0ff5
-rw-r--r--components/app/platform-inspect/attest_report_fetcher.cpp181
-rw-r--r--components/app/platform-inspect/attest_report_fetcher.h24
-rw-r--r--components/app/platform-inspect/component.cmake14
-rw-r--r--components/app/platform-inspect/platform_inspect.cpp38
-rw-r--r--components/common/cbor_dump/cbor_dump.c205
-rw-r--r--components/common/cbor_dump/cbor_dump.h48
-rw-r--r--components/common/cbor_dump/component.cmake (renamed from components/service/attestation/test/common/component.cmake)2
-rw-r--r--components/service/attestation/claims/claim.h2
-rw-r--r--components/service/attestation/claims/sources/event_log/event_log_claim_source.c6
-rw-r--r--components/service/attestation/claims/sources/event_log/test/tcg_event_log_test.cpp5
-rw-r--r--components/service/attestation/reporter/dump/pretty/component.cmake13
-rw-r--r--components/service/attestation/reporter/dump/pretty/pretty_report_dump.c34
-rw-r--r--components/service/attestation/reporter/dump/pretty/pretty_report_dump.h27
-rw-r--r--components/service/attestation/reporter/dump/raw/component.cmake13
-rw-r--r--components/service/attestation/reporter/dump/raw/raw_report_dump.cpp (renamed from components/service/attestation/test/common/report_dump.cpp)4
-rw-r--r--components/service/attestation/reporter/dump/raw/raw_report_dump.h (renamed from components/service/attestation/test/common/report_dump.h)8
-rw-r--r--components/service/attestation/reporter/psa/eat_serializer.c8
-rw-r--r--components/service/attestation/test/component/attestation_reporter_tests.cpp4
-rw-r--r--deployments/component-test/component-test.cmake2
-rw-r--r--deployments/platform-inspect/arm-linux/CMakeLists.txt45
-rw-r--r--deployments/platform-inspect/linux-pc/CMakeLists.txt24
-rw-r--r--deployments/platform-inspect/platform-inspect.cmake69
-rw-r--r--tools/b-test/test_data.yaml10
23 files changed, 764 insertions, 22 deletions
diff --git a/components/app/platform-inspect/attest_report_fetcher.cpp b/components/app/platform-inspect/attest_report_fetcher.cpp
new file mode 100644
index 0000000..a600ca4
--- /dev/null
+++ b/components/app/platform-inspect/attest_report_fetcher.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstring>
+#include <string>
+#include <vector>
+#include <service/attestation/client/psa/iat_client.h>
+#include <service/attestation/client/provision/attest_provision_client.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service_locator.h>
+#include <psa/crypto.h>
+#include <psa/initial_attestation.h>
+#include <provision/attest_provision.h>
+#include <qcbor/qcbor_spiffy_decode.h>
+#include <t_cose/t_cose_sign1_verify.h>
+
+#define IAK_KEY_BITS (256)
+
+static bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg);
+static bool fetch_iak_public_key(psa_key_handle_t &iak_handle, std::string &error_msg);
+static bool verify_token(std::vector<uint8_t> &report, const uint8_t *token, size_t token_len,
+ psa_key_handle_t iak_handle, std::string &error_msg);
+
+bool fetch_attest_report(std::vector<uint8_t> &report, std::string &error_msg)
+{
+ bool success = false;
+ rpc_session_handle rpc_session_handle = NULL;
+ struct service_context *attest_service_context = NULL;
+ int status;
+
+ attest_service_context =
+ service_locator_query("sn:trustedfirmware.org:attestation:0", &status);
+
+ if (attest_service_context) {
+
+ struct rpc_caller *caller = NULL;
+ rpc_session_handle =
+ service_context_open(attest_service_context, TS_RPC_ENCODING_PACKED_C, &caller);
+
+ if (rpc_session_handle) {
+
+ psa_iat_client_init(caller);
+ attest_provision_client_init(caller);
+
+ success = fetch_and_verify(report, error_msg);
+ }
+ else {
+
+ error_msg = "Failed to open RPC session";
+ }
+ }
+ else {
+
+ error_msg = "Failed to discover attestation service provider";
+ }
+
+ /* Clean-up context */
+ psa_iat_client_deinit();
+ attest_provision_client_deinit();
+ service_context_close(attest_service_context, rpc_session_handle);
+ service_context_relinquish(attest_service_context);
+
+ return success;
+}
+
+static bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg)
+{
+ bool success = false;
+ uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE];
+ uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32];
+ psa_key_handle_t iak_handle;
+ int status;
+
+ if (!fetch_iak_public_key(iak_handle, error_msg)) {
+
+ return false;
+ }
+
+ status = psa_generate_random(challenge, sizeof(challenge));
+
+ if (status != PSA_SUCCESS) {
+
+ error_msg = "Failed to generate challenge";
+ return false;
+ }
+
+ size_t token_size;
+
+ status =
+ psa_initial_attest_get_token(challenge, sizeof(challenge),
+ token_buf, sizeof(token_buf), &token_size);
+
+ if (status == PSA_SUCCESS) {
+
+ success = verify_token(report, token_buf, token_size, iak_handle, error_msg);
+ }
+ else {
+
+ error_msg = "Failed to fetch attestation token";
+ }
+
+ return success;
+}
+
+static bool fetch_iak_public_key(psa_key_handle_t &iak_handle, std::string &error_msg)
+{
+ size_t iak_pub_key_len = 0;
+ uint8_t iak_pub_key_buf[PSA_KEY_EXPORT_MAX_SIZE(
+ PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
+ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1)),
+ IAK_KEY_BITS)];
+
+ int status = attest_provision_export_iak_public_key(iak_pub_key_buf,
+ sizeof(iak_pub_key_buf), &iak_pub_key_len);
+
+ if (status == PSA_SUCCESS) {
+
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+ psa_set_key_usage_flags(&attributes, 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_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1));
+ psa_set_key_bits(&attributes, IAK_KEY_BITS);
+
+ status = psa_import_key(&attributes, iak_pub_key_buf, iak_pub_key_len, &iak_handle);
+
+ if (status != PSA_SUCCESS) {
+
+ printf("psa_import_key status: %d\n", status);
+ error_msg = "Failed to set-up IAK for verify";
+ }
+
+ psa_reset_key_attributes(&attributes);
+ }
+ else {
+
+ error_msg = "Failed to export IAK public key";
+ }
+
+ return (status == PSA_SUCCESS);
+}
+
+static bool verify_token(std::vector<uint8_t> &report, const uint8_t *token, size_t token_len,
+ psa_key_handle_t iak_handle, std::string &error_msg)
+{
+ 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 = token;
+ signed_cose.len = token_len;
+
+ report_body.ptr = NULL;
+ report_body.len = 0;
+
+ t_cose_sign1_verify_init(&verify_ctx, 0);
+ t_cose_sign1_set_verification_key(&verify_ctx, key_pair);
+
+ int status = t_cose_sign1_verify(&verify_ctx, signed_cose, &report_body, NULL);
+
+ if (status == T_COSE_SUCCESS) {
+
+ report.resize(report_body.len);
+ memcpy(report.data(), report_body.ptr, report_body.len);
+ }
+ else {
+
+ error_msg = "Attestation token failed to verify";
+ }
+
+ return (status == T_COSE_SUCCESS);
+}
diff --git a/components/app/platform-inspect/attest_report_fetcher.h b/components/app/platform-inspect/attest_report_fetcher.h
new file mode 100644
index 0000000..75d171b
--- /dev/null
+++ b/components/app/platform-inspect/attest_report_fetcher.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ATTEST_REPORT_FETCHER_H
+#define ATTEST_REPORT_FETCHER_H
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+/** \brief Fetch and verify an attestaton report
+ *
+ * \param[out] report The CBOR encoded report
+ * \param[out] error_msg Error message on failure
+ *
+ * \return Returns true if fetch successful
+ */
+bool fetch_attest_report(std::vector<uint8_t> &report, std::string &error_msg);
+
+
+#endif /* ATTEST_REPORT_FETCHER_H */
diff --git a/components/app/platform-inspect/component.cmake b/components/app/platform-inspect/component.cmake
new file mode 100644
index 0000000..07200a9
--- /dev/null
+++ b/components/app/platform-inspect/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# 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}/platform_inspect.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/attest_report_fetcher.cpp"
+ )
diff --git a/components/app/platform-inspect/platform_inspect.cpp b/components/app/platform-inspect/platform_inspect.cpp
new file mode 100644
index 0000000..fd0e05b
--- /dev/null
+++ b/components/app/platform-inspect/platform_inspect.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cstdint>
+#include <cstdio>
+#include <string>
+#include <vector>
+#include <psa/crypto.h>
+#include <service_locator.h>
+#include <service/attestation/reporter/dump/raw/raw_report_dump.h>
+#include <service/attestation/reporter/dump/pretty/pretty_report_dump.h>
+#include "attest_report_fetcher.h"
+
+int main(int argc, char *argv[])
+{
+ int rval = -1;
+
+ psa_crypto_init();
+ service_locator_init();
+
+ /* Fetch platform info */
+ std::string error_msg;
+ std::vector<uint8_t> attest_report;
+
+ if (fetch_attest_report(attest_report, error_msg)) {
+
+ rval = pretty_report_dump(attest_report.data(), attest_report.size());
+ }
+ else {
+
+ printf("%s\n", error_msg.c_str());
+ }
+
+ return rval;
+}
diff --git a/components/common/cbor_dump/cbor_dump.c b/components/common/cbor_dump/cbor_dump.c
new file mode 100644
index 0000000..e711d21
--- /dev/null
+++ b/components/common/cbor_dump/cbor_dump.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <qcbor/qcbor_decode.h>
+#include "cbor_dump.h"
+
+/* Dump context structure */
+struct dump_context
+{
+ FILE *outfile;
+ unsigned int initial_indent;
+ const char *root_label;
+ const struct cbor_dictionary_entry *dictionary;
+ unsigned int dictionary_len;
+};
+
+static int dump_next_item(QCBORDecodeContext *decode_ctx, struct dump_context *dump_ctx);
+static void dump_indent(struct dump_context *dump_ctx, const QCBORItem *item);
+static void dump_label(struct dump_context *dump_ctx, const QCBORItem *item);
+static void dump_value_separator(struct dump_context *dump_ctx, const QCBORItem *item);
+static void dump_value(struct dump_context *dump_ctx, const QCBORItem *item);
+static void dump_text_string(struct dump_context *dump_ctx, const uint8_t *data, size_t len);
+static void dump_byte_string(struct dump_context *dump_ctx, const uint8_t *data, size_t len);
+static const char *dictionary_lookup(struct dump_context *dump_ctx, int64_t id);
+
+int cbor_dump(FILE *file,
+ const uint8_t *cbor, size_t cbor_len,
+ unsigned int indent, const char *root_label,
+ const struct cbor_dictionary_entry *dictionary, unsigned int dictionary_len)
+{
+ int status = -1;
+ UsefulBufC cbor_buf;
+ UsefulBuf mem_pool;
+ uint8_t mem_pool_space[cbor_len + QCBOR_DECODE_MIN_MEM_POOL_SIZE];
+
+ cbor_buf.ptr = cbor;
+ cbor_buf.len = cbor_len;
+
+ mem_pool.ptr = mem_pool_space;
+ mem_pool.len = sizeof(mem_pool_space);
+
+ QCBORDecodeContext decode_ctx;
+
+ QCBORDecode_Init(&decode_ctx, cbor_buf, QCBOR_DECODE_MODE_NORMAL);
+ status = QCBORDecode_SetMemPool(&decode_ctx, mem_pool, true);
+
+ if (status == QCBOR_SUCCESS) {
+
+ struct dump_context dump_ctx;
+
+ dump_ctx.outfile = file;
+ dump_ctx.initial_indent = indent;
+ dump_ctx.root_label = root_label;
+ dump_ctx.dictionary = dictionary;
+ dump_ctx.dictionary_len = dictionary_len;
+
+ while ((status = dump_next_item(&decode_ctx, &dump_ctx)) == QCBOR_SUCCESS);
+
+ // Hitting the end of data is not an error.
+ if (status == QCBOR_ERR_NO_MORE_ITEMS)
+ status=QCBOR_SUCCESS;
+ }
+
+ return status;
+}
+
+static int dump_next_item(QCBORDecodeContext *decode_ctx, struct dump_context *dump_ctx)
+{
+ int status = -1;
+ QCBORItem item;
+
+ status = QCBORDecode_GetNext(decode_ctx, &item);
+
+ if (status == QCBOR_SUCCESS) {
+
+ dump_indent(dump_ctx, &item);
+ dump_label(dump_ctx, &item);
+ dump_value_separator(dump_ctx, &item);
+ dump_value(dump_ctx, &item);
+ }
+
+ return status;
+}
+
+static void dump_indent(struct dump_context *dump_ctx, const QCBORItem *item)
+{
+ unsigned int num_tabs = dump_ctx->initial_indent + item->uNestingLevel;
+
+ for (unsigned int i = 0; i < num_tabs; ++i) {
+
+ fprintf(dump_ctx->outfile, " ");
+ }
+}
+
+static void dump_label(struct dump_context *dump_ctx, const QCBORItem *item)
+{
+ switch (item->uLabelType)
+ {
+ case QCBOR_TYPE_INT64:
+ case QCBOR_TYPE_UINT64:
+ {
+ const char *label_string = dictionary_lookup(dump_ctx, item->label.int64);
+ if (label_string)
+ fprintf(dump_ctx->outfile, "%s:", label_string);
+ else
+ fprintf(dump_ctx->outfile, "%ld:", item->label.int64);
+ break;
+ }
+ case QCBOR_TYPE_TEXT_STRING:
+ fprintf(dump_ctx->outfile, "%s:", (const char*)item->label.string.ptr);
+ break;
+ case QCBOR_TYPE_NONE:
+ if (item->uNestingLevel == 0 && dump_ctx->root_label) {
+ fprintf(dump_ctx->outfile, "%s:", dump_ctx->root_label);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void dump_value_separator(struct dump_context *dump_ctx, const QCBORItem *item)
+{
+ if ((item->uDataType == QCBOR_TYPE_ARRAY) ||
+ (item->uDataType == QCBOR_TYPE_MAP)) {
+
+ fprintf(dump_ctx->outfile, "\n");
+ }
+ else {
+
+ fprintf(dump_ctx->outfile, "\t");
+ }
+
+}
+
+static void dump_value(struct dump_context *dump_ctx, const QCBORItem *item)
+{
+ if (item->uDataType == QCBOR_TYPE_TEXT_STRING) {
+
+ dump_text_string(dump_ctx, (const char*)item->val.string.ptr, item->val.string.len);
+ fprintf(dump_ctx->outfile, "\n");
+ }
+ else if (item->uDataType == QCBOR_TYPE_BYTE_STRING) {
+
+ dump_byte_string(dump_ctx, (const char*)item->val.string.ptr, item->val.string.len);
+ fprintf(dump_ctx->outfile, "\n");
+ }
+ else if (item->uDataType == QCBOR_TYPE_INT64) {
+
+ fprintf(dump_ctx->outfile, "%ld\n", item->val.int64);
+ }
+ else if (item->uDataType == QCBOR_TYPE_UINT64) {
+
+ fprintf(dump_ctx->outfile, "%lu\n", item->val.uint64);
+ }
+ else if ((item->uDataType != QCBOR_TYPE_NONE) &&
+ (item->uDataType != QCBOR_TYPE_ARRAY) &&
+ (item->uDataType != QCBOR_TYPE_MAP))
+ {
+
+ fprintf(dump_ctx->outfile, "value %d", item->uDataType);
+ }
+}
+
+static void dump_text_string(struct dump_context *dump_ctx, const uint8_t *data, size_t len)
+{
+ char text_buf[len + 1];
+
+ memcpy(text_buf, data, len);
+ text_buf[len] = '\0';
+
+ fprintf(dump_ctx->outfile, "%s", text_buf);
+}
+
+static void dump_byte_string(struct dump_context *dump_ctx, const uint8_t *data, size_t len)
+{
+ for (size_t i = 0; i < len; ++i) {
+
+ fprintf(dump_ctx->outfile, "%02x ", data[i]);
+ }
+}
+
+static const char *dictionary_lookup(struct dump_context *dump_ctx, int64_t id)
+{
+ const char *match = NULL;
+
+ if (dump_ctx->dictionary) {
+
+ for (size_t i = 0; i < dump_ctx->dictionary_len; ++i) {
+
+ if (dump_ctx->dictionary[i].id == id) {
+
+ match = dump_ctx->dictionary[i].string;
+ break;
+ }
+ }
+ }
+
+ return match;
+}
diff --git a/components/common/cbor_dump/cbor_dump.h b/components/common/cbor_dump/cbor_dump.h
new file mode 100644
index 0000000..a0d8f94
--- /dev/null
+++ b/components/common/cbor_dump/cbor_dump.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CBOR_DUMP_H
+#define CBOR_DUMP_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Dictionary entry for mapping a CBOR ID to a string.
+ */
+struct cbor_dictionary_entry
+{
+ int32_t id;
+ const char *string;
+};
+
+/**
+ * Dump decoded cbor to the specified file.
+ *
+ * \param[in] file Dump to this file
+ * \param[in] cbor Serialized cbor to decode
+ * \param[in] cbor_len Length of the cbor
+ * \param[in] indent Initial indentation of dump output
+ * \param[in] root_label Root label or NULL if none.
+ * \param[in] dictionary Dictionary of IDs to strings. NULL if none.
+ * \param[in] dictionary_len Number of entries in the dictionary.
+ */
+int cbor_dump(FILE *file,
+ const uint8_t *cbor, size_t cbor_len,
+ unsigned int indent, const char *root_label,
+ const struct cbor_dictionary_entry *dictionary, unsigned int dictionary_len);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CBOR_DUMP_H */
diff --git a/components/service/attestation/test/common/component.cmake b/components/common/cbor_dump/component.cmake
index 5985c76..02aef54 100644
--- a/components/service/attestation/test/common/component.cmake
+++ b/components/common/cbor_dump/component.cmake
@@ -9,5 +9,5 @@ if (NOT DEFINED TGT)
endif()
target_sources(${TGT} PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}/report_dump.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/cbor_dump.c"
)
diff --git a/components/service/attestation/claims/claim.h b/components/service/attestation/claims/claim.h
index 1808f45..94ff0ad 100644
--- a/components/service/attestation/claims/claim.h
+++ b/components/service/attestation/claims/claim.h
@@ -86,7 +86,7 @@ struct byte_string_claim_variant
*/
struct measurement_claim_variant
{
- struct byte_string_claim_variant id;
+ struct text_string_claim_variant id;
struct byte_string_claim_variant digest;
};
diff --git a/components/service/attestation/claims/sources/event_log/event_log_claim_source.c b/components/service/attestation/claims/sources/event_log/event_log_claim_source.c
index 82603e4..b7273ab 100644
--- a/components/service/attestation/claims/sources/event_log/event_log_claim_source.c
+++ b/components/service/attestation/claims/sources/event_log/event_log_claim_source.c
@@ -253,8 +253,7 @@ static void tcg_event2_extract_measurement_id(const void *event_data,
struct measurement_claim_variant *measurement,
const void *limit)
{
- measurement->id.len = 0;
- measurement->id.bytes = NULL;
+ measurement->id.string = NULL;
if (((const uint8_t*)limit - sizeof(event2_data_t)) >= (const uint8_t*)event_data) {
@@ -262,8 +261,7 @@ static void tcg_event2_extract_measurement_id(const void *event_data,
if (id_size) {
- measurement->id.len = id_size;
- measurement->id.bytes = (const uint8_t*)event_data + offsetof(event2_data_t, event);
+ measurement->id.string = (const uint8_t*)event_data + offsetof(event2_data_t, event);
}
}
}
diff --git a/components/service/attestation/claims/sources/event_log/test/tcg_event_log_test.cpp b/components/service/attestation/claims/sources/event_log/test/tcg_event_log_test.cpp
index c4865fc..f155fee 100644
--- a/components/service/attestation/claims/sources/event_log/test/tcg_event_log_test.cpp
+++ b/components/service/attestation/claims/sources/event_log/test/tcg_event_log_test.cpp
@@ -54,9 +54,8 @@ TEST(TcgEventLogTests, interateBootMeasurements)
mock_event_Log_measurement(measurement_count);
/* Check extracted values are as expected */
- MEMCMP_EQUAL(expected->id,
- sw_component_claim.variant.measurement.id.bytes,
- sw_component_claim.variant.measurement.id.len);
+ STRCMP_EQUAL(expected->id,
+ sw_component_claim.variant.measurement.id.string);
MEMCMP_EQUAL(expected->digest,
sw_component_claim.variant.measurement.digest.bytes,
sw_component_claim.variant.measurement.digest.len);
diff --git a/components/service/attestation/reporter/dump/pretty/component.cmake b/components/service/attestation/reporter/dump/pretty/component.cmake
new file mode 100644
index 0000000..fa6636b
--- /dev/null
+++ b/components/service/attestation/reporter/dump/pretty/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}/pretty_report_dump.c"
+ )
diff --git a/components/service/attestation/reporter/dump/pretty/pretty_report_dump.c b/components/service/attestation/reporter/dump/pretty/pretty_report_dump.c
new file mode 100644
index 0000000..4b57550
--- /dev/null
+++ b/components/service/attestation/reporter/dump/pretty/pretty_report_dump.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <common/cbor_dump/cbor_dump.h>
+#include <protocols/service/attestation/packed-c/eat.h>
+
+int pretty_report_dump(const uint8_t *report, size_t len)
+{
+ static const struct cbor_dictionary_entry eat_dictionary[] =
+ {
+ {EAT_ARM_PSA_CLAIM_ID_PROFILE_DEFINITION, "profile_definition"},
+ {EAT_ARM_PSA_CLAIM_ID_CLIENT_ID, "client_id"},
+ {EAT_ARM_PSA_CLAIM_ID_SECURITY_LIFECYCLE, "security_lifecycle"},
+ {EAT_ARM_PSA_CLAIM_ID_IMPLEMENTATION_ID, "implementation_id"},
+ {EAT_ARM_PSA_CLAIM_ID_BOOT_SEED, "boot_seed"},
+ {EAT_ARM_PSA_CLAIM_ID_HW_VERSION, "hw_version"},
+ {EAT_ARM_PSA_CLAIM_ID_SW_COMPONENTS, "sw_components"},
+ {EAT_ARM_PSA_CLAIM_ID_NO_SW_COMPONENTS, "no_sw_components"},
+ {EAT_ARM_PSA_CLAIM_ID_CHALLENGE, "challenge"},
+ {EAT_ARM_PSA_CLAIM_ID_INSTANCE_ID, "instance_id"},
+ {EAT_ARM_PSA_CLAIM_ID_VERIFIER, "verifier_id"},
+ {EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE, "type"},
+ {EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_VALUE, "digest"}
+ };
+
+ return cbor_dump(stdout, report, len,
+ 0, "attestation_report",
+ eat_dictionary, sizeof(eat_dictionary)/sizeof(struct cbor_dictionary_entry));
+}
diff --git a/components/service/attestation/reporter/dump/pretty/pretty_report_dump.h b/components/service/attestation/reporter/dump/pretty/pretty_report_dump.h
new file mode 100644
index 0000000..0d24b30
--- /dev/null
+++ b/components/service/attestation/reporter/dump/pretty/pretty_report_dump.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PRETTY_REPORT_DUMP_H
+#define PRETTY_REPORT_DUMP_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Pretty print an attestation report
+ */
+int pretty_report_dump(const uint8_t *report, size_t len);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PRETTY_REPORT_DUMP_H */
diff --git a/components/service/attestation/reporter/dump/raw/component.cmake b/components/service/attestation/reporter/dump/raw/component.cmake
new file mode 100644
index 0000000..55ae88a
--- /dev/null
+++ b/components/service/attestation/reporter/dump/raw/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}/raw_report_dump.cpp"
+ )
diff --git a/components/service/attestation/test/common/report_dump.cpp b/components/service/attestation/reporter/dump/raw/raw_report_dump.cpp
index 65f4a85..1ac0e59 100644
--- a/components/service/attestation/test/common/report_dump.cpp
+++ b/components/service/attestation/reporter/dump/raw/raw_report_dump.cpp
@@ -5,9 +5,9 @@
*/
#include <stdio.h>
-#include "report_dump.h"
+#include "raw_report_dump.h"
-void report_dump(const uint8_t *report, size_t len)
+void raw_report_dump(const uint8_t *report, size_t len)
{
size_t bytes_in_row = 0;
size_t byte_count = 0;
diff --git a/components/service/attestation/test/common/report_dump.h b/components/service/attestation/reporter/dump/raw/raw_report_dump.h
index 81becc5..aae3732 100644
--- a/components/service/attestation/test/common/report_dump.h
+++ b/components/service/attestation/reporter/dump/raw/raw_report_dump.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef REPORT_DUMP_H
-#define REPORT_DUMP_H
+#ifndef RAW_REPORT_DUMP_H
+#define RAW_REPORT_DUMP_H
#include <stddef.h>
#include <stdint.h>
@@ -19,11 +19,11 @@ extern "C" {
* output to stdout. This is useful for viewing the report contents
* using an external CBOR decoder.
*/
-void report_dump(const uint8_t *report, size_t len);
+void raw_report_dump(const uint8_t *report, size_t len);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif /* REPORT_DUMP_H */
+#endif /* RAW_REPORT_DUMP_H */
diff --git a/components/service/attestation/reporter/psa/eat_serializer.c b/components/service/attestation/reporter/psa/eat_serializer.c
index 88b595d..240c674 100644
--- a/components/service/attestation/reporter/psa/eat_serializer.c
+++ b/components/service/attestation/reporter/psa/eat_serializer.c
@@ -113,10 +113,10 @@ static void encode_claim(QCBOREncodeContext *encode_ctx, const struct claim *cla
{
UsefulBufC byte_string;
QCBOREncode_OpenMap(encode_ctx);
- byte_string.ptr = claim->variant.measurement.id.bytes;
- byte_string.len = claim->variant.measurement.id.len;
- QCBOREncode_AddBytesToMapN(encode_ctx,
- EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE, byte_string);
+ QCBOREncode_AddSZStringToMapN(encode_ctx,
+ EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE,
+ claim->variant.measurement.id.string);
+
byte_string.ptr = claim->variant.measurement.digest.bytes;
byte_string.len = claim->variant.measurement.digest.len;
QCBOREncode_AddBytesToMapN(encode_ctx,
diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp
index 984af99..d0d0948 100644
--- a/components/service/attestation/test/component/attestation_reporter_tests.cpp
+++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp
@@ -16,8 +16,8 @@
#include <service/attestation/claims/sources/null_lifecycle/null_lifecycle_claim_source.h>
#include <service/attestation/claims/sources/instance_id/instance_id_claim_source.h>
#include <service/attestation/reporter/attest_report.h>
+#include <service/attestation/reporter/dump/raw/raw_report_dump.h>
#include <service/attestation/key_mngr/attest_key_mngr.h>
-#include <service/attestation/test/common/report_dump.h>
#include <protocols/service/attestation/packed-c/eat.h>
#include <CppUTest/TestHarness.h>
@@ -200,7 +200,7 @@ TEST(AttestationReporterTests, createReport)
mock_event_Log_measurement(sw_component_count);
/* Check measurement id */
- QCBORDecode_GetByteStringInMapN(&decode_ctx,
+ QCBORDecode_GetTextStringInMapN(&decode_ctx,
EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE, &property);
LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx));
CHECK_TRUE(property.ptr);
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 2a8556a..6b2f9e5 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -51,12 +51,12 @@ 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/reporter/dump/raw"
"components/service/attestation/key_mngr"
"components/service/attestation/provider"
"components/service/attestation/provider/serializer/packed-c"
"components/service/attestation/client/psa"
"components/service/attestation/client/provision"
- "components/service/attestation/test/common"
"components/service/attestation/test/component"
"components/service/attestation/test/service"
"components/service/crypto/client/cpp"
diff --git a/deployments/platform-inspect/arm-linux/CMakeLists.txt b/deployments/platform-inspect/arm-linux/CMakeLists.txt
new file mode 100644
index 0000000..f4d02c0
--- /dev/null
+++ b/deployments/platform-inspect/arm-linux/CMakeLists.txt
@@ -0,0 +1,45 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.16)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# Required for use of stdout/stderr file pointers from the application.
+#
+#-------------------------------------------------------------------------------
+set(CMAKE_POSITION_INDEPENDENT_CODE True)
+
+#-------------------------------------------------------------------------------
+# The CMakeLists.txt for building the platform-inspect deployment for arm-linux
+#
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/arm-linux/env.cmake)
+project(trusted-services LANGUAGES CXX C)
+add_executable(platform-inspect)
+target_include_directories(platform-inspect PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+# Extend with components that are common across all deployments of
+# platform-inspect
+#
+#-------------------------------------------------------------------------------
+include(../platform-inspect.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# Define library options and dependencies.
+#
+#-------------------------------------------------------------------------------
+env_set_link_options(TGT platform-inspect)
+target_link_libraries(platform-inspect PRIVATE stdc++ gcc m)
+
+#-------------------------------------------------------------------------------
+# Linker option to enable repeated searches for undefined references.
+# Required to resolve dependencies between t_cose and qcbor libraries.
+#-------------------------------------------------------------------------------
+target_link_options(platform-inspect PRIVATE
+ -Wl,--start-group
+ )
diff --git a/deployments/platform-inspect/linux-pc/CMakeLists.txt b/deployments/platform-inspect/linux-pc/CMakeLists.txt
new file mode 100644
index 0000000..52a5834
--- /dev/null
+++ b/deployments/platform-inspect/linux-pc/CMakeLists.txt
@@ -0,0 +1,24 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.16)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+# The CMakeLists.txt for building the platform-inspect deployment for linux-pc
+#
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/linux-pc/env.cmake)
+project(trusted-services LANGUAGES CXX C)
+add_executable(platform-inspect)
+target_include_directories(platform-inspect PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+# Extend with components that are common across all deployments of
+# platform-inspect
+#
+#-------------------------------------------------------------------------------
+include(../platform-inspect.cmake REQUIRED)
diff --git a/deployments/platform-inspect/platform-inspect.cmake b/deployments/platform-inspect/platform-inspect.cmake
new file mode 100644
index 0000000..a8952f4
--- /dev/null
+++ b/deployments/platform-inspect/platform-inspect.cmake
@@ -0,0 +1,69 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# The base build file shared between deployments of 'platform-inspect' for
+# different environments.
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Use libts for locating and accessing trusted services. An appropriate version
+# of libts will be imported for the enviroment in which platform-inspect is
+# built.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(platform-inspect PRIVATE libts)
+
+#-------------------------------------------------------------------------------
+# Components that are common accross all deployments
+#
+#-------------------------------------------------------------------------------
+add_components(
+ TARGET "platform-inspect"
+ BASE_DIR ${TS_ROOT}
+ COMPONENTS
+ "components/app/platform-inspect"
+ "components/common/tlv"
+ "components/common/cbor_dump"
+ "components/service/common/include"
+ "components/service/attestation/include"
+ "components/service/attestation/client/psa"
+ "components/service/attestation/client/provision"
+ "components/service/attestation/reporter/dump/raw"
+ "components/service/attestation/reporter/dump/pretty"
+)
+
+#-------------------------------------------------------------------------------
+# Components used from external projects
+#
+#-------------------------------------------------------------------------------
+
+# Configuration for mbedcrypto
+set(MBEDTLS_USER_CONFIG_FILE
+ "${TS_ROOT}/components/service/crypto/client/cpp/config_mbedtls_user.h"
+ CACHE STRING "Configuration file for mbedcrypto")
+
+# Mbed TLS provides libmbedcrypto
+include(../../../external/MbedTLS/MbedTLS.cmake)
+target_link_libraries(platform-inspect PRIVATE mbedcrypto)
+
+# Qcbor
+include(${TS_ROOT}/external/qcbor/qcbor.cmake)
+target_link_libraries(platform-inspect PRIVATE qcbor)
+
+# t_cose
+include(${TS_ROOT}/external/t_cose/t_cose.cmake)
+target_link_libraries(platform-inspect PRIVATE t_cose)
+
+#-------------------------------------------------------------------------------
+# Define install content.
+#
+#-------------------------------------------------------------------------------
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
+endif()
+install(TARGETS platform-inspect RUNTIME DESTINATION ${TS_ENV}/bin)
diff --git a/tools/b-test/test_data.yaml b/tools/b-test/test_data.yaml
index 32c6337..3e7e36c 100644
--- a/tools/b-test/test_data.yaml
+++ b/tools/b-test/test_data.yaml
@@ -83,3 +83,13 @@ data:
params:
- "-GUnix Makefiles"
- "-DSP_DEV_KIT_DIR=$SP_DEV_KIT_DIR"
+ - name: "platform-inspect-arm-linux"
+ src: "$TS_ROOT/deployments/platform-inspect/arm-linux"
+ os_id : "GNU/Linux"
+ params:
+ - "-GUnix Makefiles"
+ - name: "platform-inspect-pc-linux"
+ src: "$TS_ROOT/deployments/platform-inspect/linux-pc"
+ os_id : "GNU/Linux"
+ params:
+ - "-GUnix Makefiles"