diff options
author | Julian Hall <julian.hall@arm.com> | 2021-05-07 14:27:55 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-07-05 12:43:43 +0200 |
commit | 1d31302bc4a299648e331a024d24d524cc71e62a (patch) | |
tree | 7dcd974fcaa580f342641d7c5b07e4f3e9cbba38 | |
parent | 201ce4658f6e33f436b0f4a638de1be8f9dc8458 (diff) | |
download | trusted-services-1d31302bc4a299648e331a024d24d524cc71e62a.tar.gz |
Add attestation report creation
Adds components to create a cbor encoded attestion report using
claims gathered from registered claim sources. Tests added
that check the decoded cbor is as expected.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I8faddd6c5bea120745f85d70846725c5c51665b6
27 files changed, 1444 insertions, 191 deletions
diff --git a/components/service/attestation/claims/claim.h b/components/service/attestation/claims/claim.h index d36825d1f..1808f45b2 100644 --- a/components/service/attestation/claims/claim.h +++ b/components/service/attestation/claims/claim.h @@ -114,13 +114,47 @@ static inline void claim_collection_variant_create_iterator( } /** + * Claim category. Values may be combined in a bitmap + * to allow a set of categries to be expressed. + */ +enum claim_category +{ + CLAIM_CATEGORY_NONE = 0, + + /** + * A catagory of claim about the device instance. + */ + CLAIM_CATEGORY_DEVICE = (1U << 0), + + /** + * A catagory of claim based on a measurement during boot. + */ + CLAIM_CATEGORY_BOOT_MEASUREMENT = (1U << 1), + + /** + * A catagory of claim about an associated verifcation service. + */ + CLAIM_CATEGORY_VERIFICATION_SERVICE = (1U << 2) +}; + +/** * Claim subject identifier. Used for identifying what the claim relates * to. */ enum claim_subject_id { CLAIM_SUBJECT_ID_NONE = 0, - CLAIM_SUBJECT_ID_SW_COMPONENT, + CLAIM_SUBJECT_ID_AUTH_CHALLENGE, + CLAIM_SUBJECT_ID_INSTANCE_ID, + CLAIM_SUBJECT_ID_VERIFICATION_SERVICE_INDICATOR, + CLAIM_SUBJECT_ID_PROFILE_DEFINITION, + CLAIM_SUBJECT_ID_IMPLEMENTATION_ID, + CLAIM_SUBJECT_ID_CLIENT_ID, + CLAIM_SUBJECT_ID_LIFECYCLE_STATE, + CLAIM_SUBJECT_ID_HW_VERSION, + CLAIM_SUBJECT_ID_BOOT_SEED, + CLAIM_SUBJECT_ID_NO_SW_MEASUREMENTS, + CLAIM_SUBJECT_ID_SW_COMPONENT }; /** @@ -143,6 +177,7 @@ enum claim_variant_id */ struct claim { + enum claim_category category; enum claim_subject_id subject_id; enum claim_variant_id variant_id; diff --git a/components/service/attestation/claims/claim_source.h b/components/service/attestation/claims/claim_source.h index 5c28c47ca..381f2631e 100644 --- a/components/service/attestation/claims/claim_source.h +++ b/components/service/attestation/claims/claim_source.h @@ -7,6 +7,7 @@ #ifndef CLAIM_SOURCE_H #define CLAIM_SOURCE_H +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -24,7 +25,12 @@ struct claim_source bool (*get_claim)(void *context, struct claim *claim); void *context; - /* Generic claim source properties to be added */ + /** + * A bitmap of claim categories that this claim_source provides claims for. + * Claim categories are enumerated by enum claim_category. + */ + uint32_t category_map; + }; /** diff --git a/components/service/attestation/claims/claim_vector.c b/components/service/attestation/claims/claim_vector.c new file mode 100644 index 000000000..afa68b088 --- /dev/null +++ b/components/service/attestation/claims/claim_vector.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> +#include "claim_vector.h" + +void claim_vector_init(struct claim_vector *v, size_t limit) +{ + v->claims = malloc(sizeof(struct claim) * limit); + v->limit = (v->claims) ? limit : 0; + v->size = 0; +} + +void claim_vector_deinit(struct claim_vector *v) +{ + free(v->claims); + v->claims = NULL; + v->limit = 0; + v->size = 0; +} + +void claim_vector_push_back(struct claim_vector *v, const struct claim *claim) +{ + if (v->size < v->limit) { + + v->claims[v->size] = *claim; + ++v->size; + } +} + +size_t claim_vector_size(const struct claim_vector *v) +{ + return v->size; +} + +const struct claim *claim_vector_get_claim(const struct claim_vector *v, size_t index) +{ + const struct claim *claim = NULL; + if (index < v->size) claim = &v->claims[index]; + return claim; +} diff --git a/components/service/attestation/claims/claim_vector.h b/components/service/attestation/claims/claim_vector.h new file mode 100644 index 000000000..227ab981a --- /dev/null +++ b/components/service/attestation/claims/claim_vector.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CLAIM_VECTOR_H +#define CLAIM_VECTOR_H + +#include <stddef.h> +#include "claim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A claim_vector is a general purpose variable length array + * of claims. The maximum number of claims is specified + * when the claim_vector is initialized. Deinit must be + * called after use to free any allocated space. + */ +struct claim_vector +{ + size_t limit; + size_t size; + struct claim *claims; +}; + +/** + * \brief Initializes a claim_vector. + * + * Space is allocated for the specified limit but the vector is + * initially empty. + * + * \param[in] v This claim_vector + * \param[in] limit The maximum number of claims that can be held + */ +void claim_vector_init(struct claim_vector *v, size_t limit); + +/** + * \brief De-initializes a claim_vector. + * + * Frees any space allocated. Must be called when the claim_vector + * is finished with. + * + * \param[in] v This claim_vector + */ +void claim_vector_deinit(struct claim_vector *v); + +/** + * \brief Add a claim to the back of the vector + * + * \param[in] v This claim_vector + * \param[in] claim Claim to add to the vector + */ +void claim_vector_push_back(struct claim_vector *v, const struct claim *claim); + +/** + * \brief Returns the number of claims held + * + * \param[in] v This claim_vector + * + * \return Count of claims held + */ +size_t claim_vector_size(const struct claim_vector *v); + +/** + * \brief Returns a pointer to the claim at the specified index + * + * \param[in] v This claim_vector + * \param[in] index Index into vector + * + * \return Pointer to claim or NULL + */ +const struct claim *claim_vector_get_claim(const struct claim_vector *v, size_t index); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CLAIM_VECTOR_H */ diff --git a/components/service/attestation/claims/claims_register.c b/components/service/attestation/claims/claims_register.c new file mode 100644 index 000000000..76c09c857 --- /dev/null +++ b/components/service/attestation/claims/claims_register.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string.h> +#include "claims_register.h" + +/* Maximum registered claim_sources for a deployment */ +#define CLAIMS_REGISTER_MAX_CLAIM_SOURCES (20) + +/** + * The singleton claims_register instance. + */ +static struct claims_register +{ + size_t num_sources; + struct claim_source *sources[CLAIMS_REGISTER_MAX_CLAIM_SOURCES]; + +} instance; + +static void query_collection_by_category(struct claim *collection, + enum claim_category category, struct claim_vector *result); + + + +void claims_register_init(void) +{ + instance.num_sources = 0; + memset(instance.sources, 0, sizeof(instance.sources)); +} + +void claims_register_deinit(void) +{ + instance.num_sources = 0; +} + +void claims_register_add_claim_source(uint32_t category_map, + struct claim_source *source) +{ + if (instance.num_sources < CLAIMS_REGISTER_MAX_CLAIM_SOURCES) { + + source->category_map = category_map; + + instance.sources[instance.num_sources] = source; + ++instance.num_sources; + } +} + +void claims_register_query_by_category(enum claim_category category, + struct claim_vector *result) +{ + /* Iterate over all claim_sources and gather qualifying claims. + * A claim_source may source different categories of claim. e.g. + * an event log is a flexible logging mechanism that can hold + * arbitrary claims. + */ + for (size_t i = 0; i < instance.num_sources; ++i) { + + struct claim_source *source = instance.sources[i]; + + if (source->category_map & category) { + + struct claim claim; + + if (claim_source_get_claim(source, &claim)) { + + if (claim.variant_id == CLAIM_VARIANT_ID_COLLECTION) { + + query_collection_by_category(&claim, category, result); + } + else if (claim.category == category) { + + claim_vector_push_back(result, &claim); + } + } + } + } +} + +static void query_collection_by_category(struct claim *collection, + enum claim_category category, struct claim_vector *result) +{ + struct claim_iterator iter; + + claim_collection_variant_create_iterator(&collection->variant.collection, &iter); + + while (!iter.is_done(&iter)) { + + struct claim claim; + + iter.current(&iter, &claim); + + if (claim.category == category) { + + claim_vector_push_back(result, &claim); + } + + iter.next(&iter); + } +} diff --git a/components/service/attestation/claims/claims_register.h b/components/service/attestation/claims/claims_register.h new file mode 100644 index 000000000..99536332c --- /dev/null +++ b/components/service/attestation/claims/claims_register.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CLAIMS_REGISTER_H +#define CLAIMS_REGISTER_H + +#include <stdint.h> +#include "claim_vector.h" +#include "claim_source.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The claims_register is a singleton that provides a query + * method for obtaining claims about a device. The claims_register + * decouples a report generator from the details of where claims + * come from. A deployment specific set of claim_source objects + * are registered with the claims_register to actually gather claims. + */ + +/** + * \brief Initialize the singleton claims_register + * + */ +void claims_register_init(void); + +/** + * \brief De-initializes the claims_register. + * + */ +void claims_register_deinit(void); + +/** + * \brief Add a claim_source + * + * Because of diversity in where information about the security state of + * a device comes from, a set of deployment specific claim_sources are + * registered during service provider initialization. The bitmap + * of claim categories that can be sourced. + * + * \param[in] category_map The set of claim categries + * \param[in] source A concrete claim_source + */ +void claims_register_add_claim_source(uint32_t category_map, + struct claim_source *source); + +/** + * \brief Query for claims of a specific category + * + * Used by a report generator to obtain claims that correspond to + * a particular category. + * + * \param[in] category Claim category + * \param[out] result Qualifying claims are added the result claim_vector + */ +void claims_register_query_by_category(enum claim_category category, + struct claim_vector *result); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CLAIMS_REGISTER_H */ diff --git a/components/service/attestation/claims/component.cmake b/components/service/attestation/claims/component.cmake new file mode 100644 index 000000000..f367e894c --- /dev/null +++ b/components/service/attestation/claims/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}/claim_vector.c" + "${CMAKE_CURRENT_LIST_DIR}/claims_register.c" + ) 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 7abd02c5d..82603e4ef 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 @@ -145,6 +145,7 @@ static bool event_log_iterator_current(struct claim_iterator *iter, struct claim { case EV_POST_CODE: /* A measurement claim */ + claim->category = CLAIM_CATEGORY_BOOT_MEASUREMENT; claim->subject_id = CLAIM_SUBJECT_ID_SW_COMPONENT; claim->variant_id = CLAIM_VARIANT_ID_MEASUREMENT; tcg_event2_extract_digest(header, &claim->variant.measurement); @@ -154,6 +155,7 @@ static bool event_log_iterator_current(struct claim_iterator *iter, struct claim default: /* Unsupported event type */ + claim->category = CLAIM_CATEGORY_NONE; claim->subject_id = CLAIM_SUBJECT_ID_NONE; claim->variant_id = CLAIM_VARIANT_ID_UNSUPPORTED; break; diff --git a/components/service/attestation/claims/sources/event_log/event_log_claim_source.h b/components/service/attestation/claims/sources/event_log/event_log_claim_source.h index e3b428c46..8e8516672 100644 --- a/components/service/attestation/claims/sources/event_log/event_log_claim_source.h +++ b/components/service/attestation/claims/sources/event_log/event_log_claim_source.h @@ -33,7 +33,7 @@ struct event_log_claim_source * * \param[in] instance The event_log_claim_source instance to initialze * \param[in] event_log Pointer to the event log. - * \param[in] event_log_len Byte length of the event logf + * \param[in] event_log_len Byte length of the event log * * \return The initialize base claim_source structure */ diff --git a/components/service/attestation/claims/sources/event_log/mock/component.cmake b/components/service/attestation/claims/sources/event_log/mock/component.cmake new file mode 100644 index 000000000..1b9251693 --- /dev/null +++ b/components/service/attestation/claims/sources/event_log/mock/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}/mock_event_log.c" + ) diff --git a/components/service/attestation/claims/sources/event_log/mock/mock_event_log.c b/components/service/attestation/claims/sources/event_log/mock/mock_event_log.c new file mode 100644 index 000000000..3bd9e7501 --- /dev/null +++ b/components/service/attestation/claims/sources/event_log/mock/mock_event_log.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include "mock_event_log.h" + +/* Event log data captured from TF-A measured boot */ +static const uint8_t mock_event_log[] = {MOCK_EVENT_LOG_DATA}; + +/* Expected boot measurements for the mock event log*/ +static const struct mock_event_log_measurement expected_boot_measurement[] = +{ + {.id = "BL_2", + .digest = {0xa8,0x4f,0xb4,0x7b,0x54,0xd9,0x4b,0xab,0x49,0x73,0x63,0xf7,0x9b,0xfc,0x66,0xcb, + 0x85,0x12,0xab,0x18,0x6f,0x24,0x74,0x01,0x5d,0xcf,0x33,0xf3,0x80,0x9e,0x9b,0x20}}, + {.id = "BL_31", + .digest = {0x2f,0xd3,0x43,0x6c,0x6f,0xef,0x9b,0x11,0xc2,0x16,0xdd,0x1f,0x8b,0xdf,0x9b,0xa5, + 0x24,0x14,0xa5,0xc1,0x97,0x0c,0x3a,0x6c,0x78,0xbf,0xef,0x64,0x0f,0xc1,0x23,0xe1}}, + {.id = "HW_CONFIG", + .digest = {0xf3,0xde,0x4e,0x17,0xa1,0xa5,0xa7,0xfe,0xd9,0xd9,0xf4,0x16,0x3c,0x49,0x36,0x7e, + 0xae,0xf7,0x2f,0x2a,0xa8,0x87,0xe6,0xb6,0x22,0x89,0xcd,0x27,0xdc,0x1c,0x80,0x25}}, + {.id = "SOC_FW_CONFIG", + .digest = {0x4e,0xe4,0x8e,0x5a,0xe6,0x50,0xed,0xe0,0xb5,0xa3,0x54,0x8a,0x1f,0xd6,0x0e,0x8a, + 0xea,0x0e,0x71,0x75,0x0e,0xa4,0x3f,0x82,0x76,0xce,0xaf,0xcd,0x7c,0xb0,0x91,0xe0}}, + {.id = "BL_32", + .digest = {0x62,0x22,0x4f,0x0f,0xb0,0x5d,0xb4,0x77,0x1b,0x3f,0xa5,0x2e,0xab,0x76,0x1e,0x61, + 0x17,0xb8,0xc6,0x6e,0xac,0x8c,0xc8,0x4d,0x2e,0xb0,0x7d,0x70,0x08,0x60,0x4b,0x41}}, + {.id = "BL32_EXTRA1_IMAGE", + .digest = {0x39,0xd2,0xb8,0x5d,0x93,0x5d,0xf6,0xd8,0xf8,0xed,0x0c,0x1a,0x3a,0xe3,0xc8,0x90, + 0x72,0x19,0xf4,0x88,0x5c,0x79,0x15,0x05,0x7b,0xf0,0x76,0xdb,0xc1,0x4c,0x5d,0x77}}, + {.id = "BL_33", + .digest = {0xb5,0xd6,0x08,0x61,0xdd,0xfa,0x6d,0xda,0xa3,0xf7,0xa5,0xde,0xd6,0x8f,0x6f,0x39, + 0x25,0xb1,0x57,0xfa,0x3e,0xdb,0x46,0x42,0x58,0x24,0x8e,0x81,0x1c,0x45,0x5d,0x38}}, + {.id = "NT_FW_CONFIG", + .digest = {0x25,0x10,0x60,0x5d,0xd4,0xbc,0x9d,0x82,0x7a,0x16,0x9f,0x8a,0xcc,0x47,0x95,0xa6, + 0xfd,0xca,0xa0,0xc1,0x2b,0xc9,0x99,0x8f,0x51,0x20,0xff,0xc6,0xed,0x74,0x68,0x5a}} +}; + +const uint8_t *mock_event_log_start(void) +{ + return mock_event_log; +} + +size_t mock_event_log_size(void) +{ + return sizeof(mock_event_log); +} + +const struct mock_event_log_measurement *mock_event_Log_measurement(size_t i) +{ + const struct mock_event_log_measurement *measurement = NULL; + + if (i < mock_event_Log_measurement_count()) { + + measurement = &expected_boot_measurement[i]; + } + + return measurement; +} + +size_t mock_event_Log_measurement_count(void) +{ + return sizeof(expected_boot_measurement)/sizeof(struct mock_event_log_measurement); +} diff --git a/components/service/attestation/claims/sources/event_log/mock/mock_event_log.h b/components/service/attestation/claims/sources/event_log/mock/mock_event_log.h new file mode 100644 index 000000000..937093374 --- /dev/null +++ b/components/service/attestation/claims/sources/event_log/mock/mock_event_log.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOCK_EVENT_LOG_H +#define MOCK_EVENT_LOG_H + +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************************** + An event log captured from the TF-A measured boot + + The event log dump that corresponds to the data looks like this: + + NOTICE: TCG_EfiSpecIDEvent: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 3 + NOTICE: Digest : 00 + NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: : 00 00 00 + NOTICE: EventSize : 33 + NOTICE: Signature : Spec ID Event03 + NOTICE: PlatformClass : 0 + NOTICE: SpecVersion : 2.0.2 + NOTICE: UintnSize : 1 + NOTICE: NumberOfAlgorithms : 1 + NOTICE: DigestSizes : + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: DigestSize : 32 + NOTICE: VendorInfoSize : 0 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 3 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: EventSize : 17 + NOTICE: Signature : StartupLocality + NOTICE: StartupLocality : 0 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : a8 4f b4 7b 54 d9 4b ab 49 73 63 f7 9b fc 66 cb + NOTICE: : 85 12 ab 18 6f 24 74 01 5d cf 33 f3 80 9e 9b 20 + NOTICE: EventSize : 5 + NOTICE: Event : BL_2 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 2f d3 43 6c 6f ef 9b 11 c2 16 dd 1f 8b df 9b a5 + NOTICE: : 24 14 a5 c1 97 0c 3a 6c 78 bf ef 64 0f c1 23 e1 + NOTICE: EventSize : 6 + NOTICE: Event : BL_31 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : f3 de 4e 17 a1 a5 a7 fe d9 d9 f4 16 3c 49 36 7e + NOTICE: : ae f7 2f 2a a8 87 e6 b6 22 89 cd 27 dc 1c 80 25 + NOTICE: EventSize : 10 + NOTICE: Event : HW_CONFIG + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a + NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0 + NOTICE: EventSize : 14 + NOTICE: Event : SOC_FW_CONFIG + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 62 22 4f 0f b0 5d b4 77 1b 3f a5 2e ab 76 1e 61 + NOTICE: : 17 b8 c6 6e ac 8c c8 4d 2e b0 7d 70 08 60 4b 41 + NOTICE: EventSize : 6 + NOTICE: Event : BL_32 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 39 d2 b8 5d 93 5d f6 d8 f8 ed 0c 1a 3a e3 c8 90 + NOTICE: : 72 19 f4 88 5c 79 15 05 7b f0 76 db c1 4c 5d 77 + NOTICE: EventSize : 18 + NOTICE: Event : BL32_EXTRA1_IMAGE + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : b5 d6 08 61 dd fa 6d da a3 f7 a5 de d6 8f 6f 39 + NOTICE: : 25 b1 57 fa 3e db 46 42 58 24 8e 81 1c 45 5d 38 + NOTICE: EventSize : 6 + NOTICE: Event : BL_33 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6 + NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a + NOTICE: EventSize : 13 + NOTICE: Event : NT_FW_CONFIG + + ************************************************************************************/ +#define MOCK_EVENT_LOG_DATA \ + 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x00, \ + 0x53,0x70,0x65,0x63,0x20,0x49,0x44,0x20,0x45,0x76,0x65,0x6e,0x74,0x30,0x33,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x0b,0x00,0x20,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11, \ + 0x00,0x00,0x00,0x53,0x74,0x61,0x72,0x74,0x75,0x70,0x4c,0x6f,0x63,0x61,0x6c,0x69, \ + 0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, \ + 0x0b,0x00,0xa8,0x4f,0xb4,0x7b,0x54,0xd9,0x4b,0xab,0x49,0x73,0x63,0xf7,0x9b,0xfc, \ + 0x66,0xcb,0x85,0x12,0xab,0x18,0x6f,0x24,0x74,0x01,0x5d,0xcf,0x33,0xf3,0x80,0x9e, \ + 0x9b,0x20,0x05,0x00,0x00,0x00,0x42,0x4c,0x5f,0x32,0x00,0x00,0x00,0x00,0x00,0x01, \ + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x2f,0xd3,0x43,0x6c,0x6f,0xef,0x9b, \ + 0x11,0xc2,0x16,0xdd,0x1f,0x8b,0xdf,0x9b,0xa5,0x24,0x14,0xa5,0xc1,0x97,0x0c,0x3a, \ + 0x6c,0x78,0xbf,0xef,0x64,0x0f,0xc1,0x23,0xe1,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f, \ + 0x33,0x31,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b, \ + 0x00,0xf3,0xde,0x4e,0x17,0xa1,0xa5,0xa7,0xfe,0xd9,0xd9,0xf4,0x16,0x3c,0x49,0x36, \ + 0x7e,0xae,0xf7,0x2f,0x2a,0xa8,0x87,0xe6,0xb6,0x22,0x89,0xcd,0x27,0xdc,0x1c,0x80, \ + 0x25,0x0a,0x00,0x00,0x00,0x48,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00, \ + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x4e,0xe4,0x8e, \ + 0x5a,0xe6,0x50,0xed,0xe0,0xb5,0xa3,0x54,0x8a,0x1f,0xd6,0x0e,0x8a,0xea,0x0e,0x71, \ + 0x75,0x0e,0xa4,0x3f,0x82,0x76,0xce,0xaf,0xcd,0x7c,0xb0,0x91,0xe0,0x0e,0x00,0x00, \ + 0x00,0x53,0x4f,0x43,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00, \ + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x62,0x22,0x4f, \ + 0x0f,0xb0,0x5d,0xb4,0x77,0x1b,0x3f,0xa5,0x2e,0xab,0x76,0x1e,0x61,0x17,0xb8,0xc6, \ + 0x6e,0xac,0x8c,0xc8,0x4d,0x2e,0xb0,0x7d,0x70,0x08,0x60,0x4b,0x41,0x06,0x00,0x00, \ + 0x00,0x42,0x4c,0x5f,0x33,0x32,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01, \ + 0x00,0x00,0x00,0x0b,0x00,0x39,0xd2,0xb8,0x5d,0x93,0x5d,0xf6,0xd8,0xf8,0xed,0x0c, \ + 0x1a,0x3a,0xe3,0xc8,0x90,0x72,0x19,0xf4,0x88,0x5c,0x79,0x15,0x05,0x7b,0xf0,0x76, \ + 0xdb,0xc1,0x4c,0x5d,0x77,0x12,0x00,0x00,0x00,0x42,0x4c,0x33,0x32,0x5f,0x45,0x58, \ + 0x54,0x52,0x41,0x31,0x5f,0x49,0x4d,0x41,0x47,0x45,0x00,0x00,0x00,0x00,0x00,0x01, \ + 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0xb5,0xd6,0x08,0x61,0xdd,0xfa,0x6d, \ + 0xda,0xa3,0xf7,0xa5,0xde,0xd6,0x8f,0x6f,0x39,0x25,0xb1,0x57,0xfa,0x3e,0xdb,0x46, \ + 0x42,0x58,0x24,0x8e,0x81,0x1c,0x45,0x5d,0x38,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f, \ + 0x33,0x33,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b, \ + 0x00,0x25,0x10,0x60,0x5d,0xd4,0xbc,0x9d,0x82,0x7a,0x16,0x9f,0x8a,0xcc,0x47,0x95, \ + 0xa6,0xfd,0xca,0xa0,0xc1,0x2b,0xc9,0x99,0x8f,0x51,0x20,0xff,0xc6,0xed,0x74,0x68, \ + 0x5a,0x0d,0x00,0x00,0x00,0x4e,0x54,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49, \ + 0x47,0x00 + +/* Provides the expected values for a measurement */ +struct mock_event_log_measurement +{ + const char *id; + uint8_t digest[32]; +}; + +/** + * Returns the start address of the mock event log data + */ +const uint8_t *mock_event_log_start(void); + +/** + * Returns the length mock event log data + */ +size_t mock_event_log_size(void); + +/** + * Returns the expected measurement at the specified index. + */ +const struct mock_event_log_measurement *mock_event_Log_measurement(size_t i); + +/** + * Returns the expected number of measurements. + */ +size_t mock_event_Log_measurement_count(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MOCK_EVENT_LOG_H */ 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 b6733c713..c4865fc9f 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 @@ -6,191 +6,9 @@ #include <stdint.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 <CppUTest/TestHarness.h> -/*********************************************************************************** - An event log captured from the TF-A measured boot - - The event log dump that corresponds to the data looks like this: - - NOTICE: TCG_EfiSpecIDEvent: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 3 - NOTICE: Digest : 00 - NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - NOTICE: : 00 00 00 - NOTICE: EventSize : 33 - NOTICE: Signature : Spec ID Event03 - NOTICE: PlatformClass : 0 - NOTICE: SpecVersion : 2.0.2 - NOTICE: UintnSize : 1 - NOTICE: NumberOfAlgorithms : 1 - NOTICE: DigestSizes : - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: DigestSize : 32 - NOTICE: VendorInfoSize : 0 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 3 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - NOTICE: EventSize : 17 - NOTICE: Signature : StartupLocality - NOTICE: StartupLocality : 0 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : a8 4f b4 7b 54 d9 4b ab 49 73 63 f7 9b fc 66 cb - NOTICE: : 85 12 ab 18 6f 24 74 01 5d cf 33 f3 80 9e 9b 20 - NOTICE: EventSize : 5 - NOTICE: Event : BL_2 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 2f d3 43 6c 6f ef 9b 11 c2 16 dd 1f 8b df 9b a5 - NOTICE: : 24 14 a5 c1 97 0c 3a 6c 78 bf ef 64 0f c1 23 e1 - NOTICE: EventSize : 6 - NOTICE: Event : BL_31 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : f3 de 4e 17 a1 a5 a7 fe d9 d9 f4 16 3c 49 36 7e - NOTICE: : ae f7 2f 2a a8 87 e6 b6 22 89 cd 27 dc 1c 80 25 - NOTICE: EventSize : 10 - NOTICE: Event : HW_CONFIG - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a - NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0 - NOTICE: EventSize : 14 - NOTICE: Event : SOC_FW_CONFIG - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 62 22 4f 0f b0 5d b4 77 1b 3f a5 2e ab 76 1e 61 - NOTICE: : 17 b8 c6 6e ac 8c c8 4d 2e b0 7d 70 08 60 4b 41 - NOTICE: EventSize : 6 - NOTICE: Event : BL_32 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 39 d2 b8 5d 93 5d f6 d8 f8 ed 0c 1a 3a e3 c8 90 - NOTICE: : 72 19 f4 88 5c 79 15 05 7b f0 76 db c1 4c 5d 77 - NOTICE: EventSize : 18 - NOTICE: Event : BL32_EXTRA1_IMAGE - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : b5 d6 08 61 dd fa 6d da a3 f7 a5 de d6 8f 6f 39 - NOTICE: : 25 b1 57 fa 3e db 46 42 58 24 8e 81 1c 45 5d 38 - NOTICE: EventSize : 6 - NOTICE: Event : BL_33 - NOTICE: PCR_Event2: - NOTICE: PCRIndex : 0 - NOTICE: EventType : 1 - NOTICE: Digests Count : 1 - NOTICE: #0 AlgorithmId : SHA256 - NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6 - NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a - NOTICE: EventSize : 13 - NOTICE: Event : NT_FW_CONFIG - - ************************************************************************************/ -static const uint8_t tfa_measured_boot[] = -{ - 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x00, - 0x53,0x70,0x65,0x63,0x20,0x49,0x44,0x20,0x45,0x76,0x65,0x6e,0x74,0x30,0x33,0x00, - 0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x0b,0x00,0x20,0x00, - 0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11, - 0x00,0x00,0x00,0x53,0x74,0x61,0x72,0x74,0x75,0x70,0x4c,0x6f,0x63,0x61,0x6c,0x69, - 0x74,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00, - 0x0b,0x00,0xa8,0x4f,0xb4,0x7b,0x54,0xd9,0x4b,0xab,0x49,0x73,0x63,0xf7,0x9b,0xfc, - 0x66,0xcb,0x85,0x12,0xab,0x18,0x6f,0x24,0x74,0x01,0x5d,0xcf,0x33,0xf3,0x80,0x9e, - 0x9b,0x20,0x05,0x00,0x00,0x00,0x42,0x4c,0x5f,0x32,0x00,0x00,0x00,0x00,0x00,0x01, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x2f,0xd3,0x43,0x6c,0x6f,0xef,0x9b, - 0x11,0xc2,0x16,0xdd,0x1f,0x8b,0xdf,0x9b,0xa5,0x24,0x14,0xa5,0xc1,0x97,0x0c,0x3a, - 0x6c,0x78,0xbf,0xef,0x64,0x0f,0xc1,0x23,0xe1,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f, - 0x33,0x31,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b, - 0x00,0xf3,0xde,0x4e,0x17,0xa1,0xa5,0xa7,0xfe,0xd9,0xd9,0xf4,0x16,0x3c,0x49,0x36, - 0x7e,0xae,0xf7,0x2f,0x2a,0xa8,0x87,0xe6,0xb6,0x22,0x89,0xcd,0x27,0xdc,0x1c,0x80, - 0x25,0x0a,0x00,0x00,0x00,0x48,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x4e,0xe4,0x8e, - 0x5a,0xe6,0x50,0xed,0xe0,0xb5,0xa3,0x54,0x8a,0x1f,0xd6,0x0e,0x8a,0xea,0x0e,0x71, - 0x75,0x0e,0xa4,0x3f,0x82,0x76,0xce,0xaf,0xcd,0x7c,0xb0,0x91,0xe0,0x0e,0x00,0x00, - 0x00,0x53,0x4f,0x43,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49,0x47,0x00,0x00, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x62,0x22,0x4f, - 0x0f,0xb0,0x5d,0xb4,0x77,0x1b,0x3f,0xa5,0x2e,0xab,0x76,0x1e,0x61,0x17,0xb8,0xc6, - 0x6e,0xac,0x8c,0xc8,0x4d,0x2e,0xb0,0x7d,0x70,0x08,0x60,0x4b,0x41,0x06,0x00,0x00, - 0x00,0x42,0x4c,0x5f,0x33,0x32,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01, - 0x00,0x00,0x00,0x0b,0x00,0x39,0xd2,0xb8,0x5d,0x93,0x5d,0xf6,0xd8,0xf8,0xed,0x0c, - 0x1a,0x3a,0xe3,0xc8,0x90,0x72,0x19,0xf4,0x88,0x5c,0x79,0x15,0x05,0x7b,0xf0,0x76, - 0xdb,0xc1,0x4c,0x5d,0x77,0x12,0x00,0x00,0x00,0x42,0x4c,0x33,0x32,0x5f,0x45,0x58, - 0x54,0x52,0x41,0x31,0x5f,0x49,0x4d,0x41,0x47,0x45,0x00,0x00,0x00,0x00,0x00,0x01, - 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0xb5,0xd6,0x08,0x61,0xdd,0xfa,0x6d, - 0xda,0xa3,0xf7,0xa5,0xde,0xd6,0x8f,0x6f,0x39,0x25,0xb1,0x57,0xfa,0x3e,0xdb,0x46, - 0x42,0x58,0x24,0x8e,0x81,0x1c,0x45,0x5d,0x38,0x06,0x00,0x00,0x00,0x42,0x4c,0x5f, - 0x33,0x33,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0b, - 0x00,0x25,0x10,0x60,0x5d,0xd4,0xbc,0x9d,0x82,0x7a,0x16,0x9f,0x8a,0xcc,0x47,0x95, - 0xa6,0xfd,0xca,0xa0,0xc1,0x2b,0xc9,0x99,0x8f,0x51,0x20,0xff,0xc6,0xed,0x74,0x68, - 0x5a,0x0d,0x00,0x00,0x00,0x4e,0x54,0x5f,0x46,0x57,0x5f,0x43,0x4f,0x4e,0x46,0x49, - 0x47,0x00 -}; - -/* Expected boot measurements */ -static const struct -{ - const char *id; - uint8_t digest[32]; -} -expected_boot_measurement[] = -{ - {.id = "BL_2", - .digest = {0xa8,0x4f,0xb4,0x7b,0x54,0xd9,0x4b,0xab,0x49,0x73,0x63,0xf7,0x9b,0xfc,0x66,0xcb, - 0x85,0x12,0xab,0x18,0x6f,0x24,0x74,0x01,0x5d,0xcf,0x33,0xf3,0x80,0x9e,0x9b,0x20}}, - {.id = "BL_31", - .digest = {0x2f,0xd3,0x43,0x6c,0x6f,0xef,0x9b,0x11,0xc2,0x16,0xdd,0x1f,0x8b,0xdf,0x9b,0xa5, - 0x24,0x14,0xa5,0xc1,0x97,0x0c,0x3a,0x6c,0x78,0xbf,0xef,0x64,0x0f,0xc1,0x23,0xe1}}, - {.id = "HW_CONFIG", - .digest = {0xf3,0xde,0x4e,0x17,0xa1,0xa5,0xa7,0xfe,0xd9,0xd9,0xf4,0x16,0x3c,0x49,0x36,0x7e, - 0xae,0xf7,0x2f,0x2a,0xa8,0x87,0xe6,0xb6,0x22,0x89,0xcd,0x27,0xdc,0x1c,0x80,0x25}}, - {.id = "SOC_FW_CONFIG", - .digest = {0x4e,0xe4,0x8e,0x5a,0xe6,0x50,0xed,0xe0,0xb5,0xa3,0x54,0x8a,0x1f,0xd6,0x0e,0x8a, - 0xea,0x0e,0x71,0x75,0x0e,0xa4,0x3f,0x82,0x76,0xce,0xaf,0xcd,0x7c,0xb0,0x91,0xe0}}, - {.id = "BL_32", - .digest = {0x62,0x22,0x4f,0x0f,0xb0,0x5d,0xb4,0x77,0x1b,0x3f,0xa5,0x2e,0xab,0x76,0x1e,0x61, - 0x17,0xb8,0xc6,0x6e,0xac,0x8c,0xc8,0x4d,0x2e,0xb0,0x7d,0x70,0x08,0x60,0x4b,0x41}}, - {.id = "BL32_EXTRA1_IMAGE", - .digest = {0x39,0xd2,0xb8,0x5d,0x93,0x5d,0xf6,0xd8,0xf8,0xed,0x0c,0x1a,0x3a,0xe3,0xc8,0x90, - 0x72,0x19,0xf4,0x88,0x5c,0x79,0x15,0x05,0x7b,0xf0,0x76,0xdb,0xc1,0x4c,0x5d,0x77}}, - {.id = "BL_33", - .digest = {0xb5,0xd6,0x08,0x61,0xdd,0xfa,0x6d,0xda,0xa3,0xf7,0xa5,0xde,0xd6,0x8f,0x6f,0x39, - 0x25,0xb1,0x57,0xfa,0x3e,0xdb,0x46,0x42,0x58,0x24,0x8e,0x81,0x1c,0x45,0x5d,0x38}}, - {.id = "NT_FW_CONFIG", - .digest = {0x25,0x10,0x60,0x5d,0xd4,0xbc,0x9d,0x82,0x7a,0x16,0x9f,0x8a,0xcc,0x47,0x95,0xa6, - 0xfd,0xca,0xa0,0xc1,0x2b,0xc9,0x99,0x8f,0x51,0x20,0xff,0xc6,0xed,0x74,0x68,0x5a}} -}; - - TEST_GROUP(TcgEventLogTests) { @@ -203,7 +21,7 @@ TEST(TcgEventLogTests, interateBootMeasurements) struct claim_source *claim_source; claim_source = event_log_claim_source_init(&event_log_claim_source, - tfa_measured_boot, sizeof(tfa_measured_boot)); + mock_event_log_start(), mock_event_log_size()); CHECK_FALSE(claim_source == NULL); @@ -230,11 +48,16 @@ TEST(TcgEventLogTests, interateBootMeasurements) if (sw_component_claim.variant_id == CLAIM_VARIANT_ID_MEASUREMENT) { + CHECK_TRUE(measurement_count < mock_event_Log_measurement_count()); + + const struct mock_event_log_measurement *expected = + mock_event_Log_measurement(measurement_count); + /* Check extracted values are as expected */ - MEMCMP_EQUAL(expected_boot_measurement[measurement_count].id, + MEMCMP_EQUAL(expected->id, sw_component_claim.variant.measurement.id.bytes, sw_component_claim.variant.measurement.id.len); - MEMCMP_EQUAL(expected_boot_measurement[measurement_count].digest, + MEMCMP_EQUAL(expected->digest, sw_component_claim.variant.measurement.digest.bytes, sw_component_claim.variant.measurement.digest.len); diff --git a/components/service/attestation/claims/sources/preloaded/component.cmake b/components/service/attestation/claims/sources/preloaded/component.cmake new file mode 100644 index 000000000..5a289f2ee --- /dev/null +++ b/components/service/attestation/claims/sources/preloaded/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}/preloaded_claim_source.c" + ) diff --git a/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.c b/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.c new file mode 100644 index 000000000..dd612d69a --- /dev/null +++ b/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "preloaded_claim_source.h" + +static bool preloaded_claim_source_get_claim(void *context, struct claim *claim); +static void create_preloaded_iterator(const struct claim_collection_variant *variant, + struct claim_iterator *iter); + +static void preloaded_iterator_first(struct claim_iterator *iter); +static bool preloaded_iterator_next(struct claim_iterator *iter); +static bool preloaded_iterator_is_done(struct claim_iterator *iter); +static bool preloaded_iterator_current(struct claim_iterator *iter, struct claim *claim); + + +struct claim_source *preloaded_claim_source_init(struct preloaded_claim_source *instance, + const struct claim_vector *claims) +{ + instance->base.get_claim = preloaded_claim_source_get_claim; + instance->base.context = instance; + + instance->preloaded_claims = claims; + + return &instance->base; +} + +static bool preloaded_claim_source_get_claim(void *context, struct claim *claim) +{ + bool is_available = false; + struct preloaded_claim_source *instance = (struct preloaded_claim_source*)context; + + /* The claim returned from a preloaded_claim_source is always a claim collection, + * containing 0..* preloaded claims. + */ + if (instance->preloaded_claims) { + + claim->subject_id = CLAIM_SUBJECT_ID_NONE; + claim->variant_id = CLAIM_VARIANT_ID_COLLECTION; + claim->raw_data = NULL; + + claim->variant.collection.create_iterator = create_preloaded_iterator; + claim->variant.collection.begin_pos = &instance->preloaded_claims->claims[0]; + claim->variant.collection.end_pos = &instance->preloaded_claims->claims[instance->preloaded_claims->size]; + + is_available = true; + } + + return is_available; +} + +static void create_preloaded_iterator(const struct claim_collection_variant *variant, + struct claim_iterator *iter) +{ + /* Assign concrete methods */ + iter->first = preloaded_iterator_first; + iter->next = preloaded_iterator_next; + iter->is_done = preloaded_iterator_is_done; + iter->current = preloaded_iterator_current; + + /* Initialize to start of collection */ + iter->begin_pos = variant->begin_pos; + iter->end_pos = variant->end_pos; + iter->cur_pos = variant->begin_pos; +} + +static void preloaded_iterator_first(struct claim_iterator *iter) +{ + iter->cur_pos = iter->begin_pos; +} + +static bool preloaded_iterator_next(struct claim_iterator *iter) +{ + const uint8_t *pos = (const uint8_t*)iter->cur_pos; + pos += sizeof(struct claim); + iter->cur_pos = pos; + + return !preloaded_iterator_is_done(iter); +} + +static bool preloaded_iterator_is_done(struct claim_iterator *iter) +{ + return (iter->cur_pos >= iter->end_pos) || (iter->cur_pos < iter->begin_pos); +} + +static bool preloaded_iterator_current(struct claim_iterator *iter, struct claim *claim) +{ + bool success = false; + + if (!preloaded_iterator_is_done(iter)) { + + const struct claim *current_claim = (const struct claim*)iter->current; + *claim = *current_claim; + success = true; + } + + return success; +} diff --git a/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.h b/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.h new file mode 100644 index 000000000..83a218225 --- /dev/null +++ b/components/service/attestation/claims/sources/preloaded/preloaded_claim_source.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PRELOADED_CLAIM_SOURCE_H +#define PRELOADED_CLAIM_SOURCE_H + +#include <service/attestation/claims/claim.h> +#include <service/attestation/claims/claim_source.h> +#include <service/attestation/claims/claim_vector.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A claim source that sources claims that have been preloaded + * into a claim_vector. + */ +struct preloaded_claim_source +{ + struct claim_source base; + + const struct claim_vector *preloaded_claims; +}; + +/** + * \brief Initializes a preloaded_claim_source. + * + * \param[in] instance The preloaded_claim_source instance to initialze + * \param[in] claims claim_vector containing preloaded claims. + * + * \return The initialize base claim_source structure + */ +struct claim_source *preloaded_claim_source_init(struct preloaded_claim_source *instance, + const struct claim_vector *claims); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PRELOADED_CLAIM_SOURCE_H */ diff --git a/components/service/attestation/reporter/attestation_report.h b/components/service/attestation/reporter/attestation_report.h new file mode 100644 index 000000000..aa70b59e2 --- /dev/null +++ b/components/service/attestation/reporter/attestation_report.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ATTESTATION_REPORT_H +#define ATTESTATION_REPORT_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Creates an attestation report + * + * 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_reporter_destroy(). + * + * \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 + * \param[out] report The created report + * \param[out] report_len The length of the report + * + * \return Operation status + */ +int attestation_report_create(int32_t client_id, + const uint8_t *auth_challenge_data, size_t auth_challenge_len, + const uint8_t **report, size_t *report_len); + +/** + * \brief Destroys an attestation report + * + * Frees any resource associated with a created report + * + * \param[in] report The created report + */ +void attestation_report_destroy(const uint8_t *report); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ATTESTATION_REPORT_H */ diff --git a/components/service/attestation/reporter/psa/attestation_report.c b/components/service/attestation/reporter/psa/attestation_report.c new file mode 100644 index 000000000..87454a6e8 --- /dev/null +++ b/components/service/attestation/reporter/psa/attestation_report.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * An attestation reporter that creates PSA compliant attestation + * reports. The report content is specified by theh PSA Attestation + * specification. Reports are serialized usingg CBOR and signed using + * COSE. + */ + +#include <stdlib.h> +#include <psa/error.h> +#include <service/attestation/reporter/attestation_report.h> +#include <service/attestation/claims/claims_register.h> +#include "report_serializer.h" + +/* Local defines */ +#define MAX_DEVICE_CLAIMS (50) +#define MAX_SW_CLAIMS (50) + +static void add_auth_challenge_claim(struct claim_vector *v, const uint8_t *data, size_t len); +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, + const uint8_t *auth_challenge_data, size_t auth_challenge_len, + const uint8_t **report, size_t *report_len) +{ + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + struct claim_vector device_claims; + struct claim_vector sw_claims; + + *report = NULL; + *report_len = 0; + + claim_vector_init(&device_claims, MAX_DEVICE_CLAIMS); + claim_vector_init(&sw_claims, MAX_SW_CLAIMS); + + /* Add claims related to the requester */ + add_auth_challenge_claim(&device_claims, auth_challenge_data, auth_challenge_len); + add_client_id_claim(&device_claims, client_id); + + /* Collate all other claims to include in the report */ + claims_register_query_by_category(CLAIM_CATEGORY_DEVICE, &device_claims); + claims_register_query_by_category(CLAIM_CATEGORY_VERIFICATION_SERVICE, &device_claims); + claims_register_query_by_category(CLAIM_CATEGORY_BOOT_MEASUREMENT, &sw_claims); + + /* 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); + + claim_vector_deinit(&device_claims); + claim_vector_deinit(&sw_claims); + + return status; +} + +void attestation_report_destroy(const uint8_t *report) +{ + free((void*)report); +} + +static void add_auth_challenge_claim(struct claim_vector *v, const uint8_t *data, size_t len) +{ + struct claim claim; + + claim.subject_id = CLAIM_SUBJECT_ID_AUTH_CHALLENGE; + claim.variant_id = CLAIM_VARIANT_ID_BYTE_STRING; + claim.raw_data = NULL; + + claim.variant.byte_string.bytes = data; + claim.variant.byte_string.len = len; + + claim_vector_push_back(v, &claim); +} + +static void add_client_id_claim(struct claim_vector *v, int32_t client_id) +{ + struct claim claim; + + claim.subject_id = CLAIM_SUBJECT_ID_CLIENT_ID; + claim.variant_id = CLAIM_VARIANT_ID_INTEGER; + claim.raw_data = NULL; + + claim.variant.integer.value = client_id; + + claim_vector_push_back(v, &claim); +} + +static void add_no_sw_claim(struct claim_vector *v) +{ + struct claim claim; + + claim.subject_id = CLAIM_SUBJECT_ID_NO_SW_MEASUREMENTS; + claim.variant_id = CLAIM_VARIANT_ID_INTEGER; + claim.raw_data = NULL; + + claim.variant.integer.value = 1; + + claim_vector_push_back(v, &claim); +} diff --git a/components/service/attestation/reporter/psa/component.cmake b/components/service/attestation/reporter/psa/component.cmake new file mode 100644 index 000000000..26be202b1 --- /dev/null +++ b/components/service/attestation/reporter/psa/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}/attestation_report.c" + "${CMAKE_CURRENT_LIST_DIR}/report_serializer.c" + ) diff --git a/components/service/attestation/reporter/psa/report_serializer.c b/components/service/attestation/reporter/psa/report_serializer.c new file mode 100644 index 000000000..d66060e16 --- /dev/null +++ b/components/service/attestation/reporter/psa/report_serializer.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <qcbor/qcbor_encode.h> +#include <psa/error.h> +#include <protocols/service/attestation/packed-c/eat.h> +#include <service/attestation/claims/claim.h> +#include "report_serializer.h" + +static bool alloc_encode_buffer(const struct claim_vector *device_claims, + const struct claim_vector *sw_claims, UsefulBuf *encode_buffer); + +static void encode_claim(QCBOREncodeContext *encode_ctx, const struct claim *claim); +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, + const struct claim_vector *sw_claims, + const uint8_t **report, size_t *report_len) +{ + UsefulBuf encode_buffer; + + if (!alloc_encode_buffer(device_claims, sw_claims, &encode_buffer)) + return PSA_ERROR_INSUFFICIENT_MEMORY; + + QCBOREncodeContext encode_ctx; + QCBOREncode_Init(&encode_ctx, encode_buffer); + QCBOREncode_OpenMap(&encode_ctx); + + /* Encode all device claims */ + for (size_t i = 0; i < device_claims->size; ++i) { + + encode_claim(&encode_ctx, &device_claims->claims[i]); + } + + /* Add child array of sw claims if there are any */ + if (sw_claims->size) { + + QCBOREncode_OpenArrayInMapN(&encode_ctx, EAT_ARM_PSA_CLAIM_ID_SW_COMPONENTS); + + for (size_t i = 0; i < sw_claims->size; ++i) { + + encode_claim(&encode_ctx, &sw_claims->claims[i]); + } + + QCBOREncode_CloseArray(&encode_ctx); + } + + QCBOREncode_CloseMap(&encode_ctx); + + /* Finalize the encoding to create the CBOR serialized report */ + 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; + } + else { + + free(encode_buffer.ptr); + *report = NULL; + *report_len = 0; + } + + return qcbor_to_psa_status(qcbor_error); +} + +static bool alloc_encode_buffer(const struct claim_vector *device_claims, + const struct claim_vector *sw_claims, UsefulBuf *encode_buffer) +{ + // todo estimate required space + + encode_buffer->len = 4096; + encode_buffer->ptr = malloc(encode_buffer->len); + + return encode_buffer->ptr; +} + +static void encode_claim(QCBOREncodeContext *encode_ctx, const struct claim *claim) +{ + int label = eat_label(claim->subject_id); + + switch (claim->variant_id) + { + case CLAIM_VARIANT_ID_INTEGER: + { + QCBOREncode_AddInt64ToMapN(encode_ctx, label, claim->variant.integer.value); + break; + } + case CLAIM_VARIANT_ID_TEXT_STRING: + { + QCBOREncode_AddSZStringToMapN(encode_ctx, label, claim->variant.text_string.string); + break; + } + case CLAIM_VARIANT_ID_BYTE_STRING: + { + UsefulBufC byte_string; + byte_string.ptr = claim->variant.byte_string.bytes; + byte_string.len = claim->variant.byte_string.len; + QCBOREncode_AddBytesToMapN(encode_ctx, label, byte_string); + break; + } + case CLAIM_VARIANT_ID_MEASUREMENT: + { + 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); + byte_string.ptr = claim->variant.measurement.digest.bytes; + byte_string.len = claim->variant.measurement.digest.len; + QCBOREncode_AddBytesToMapN(encode_ctx, + EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_VALUE, byte_string); + QCBOREncode_CloseMap(encode_ctx); + break; + } + default: + break; + } +} + +static int eat_label(enum claim_subject_id subject_id) +{ + int label = 0; + + switch (subject_id) + { + case CLAIM_SUBJECT_ID_AUTH_CHALLENGE: + label = EAT_ARM_PSA_CLAIM_ID_CHALLENGE; + break; + case CLAIM_SUBJECT_ID_INSTANCE_ID: + label = EAT_ARM_PSA_CLAIM_ID_INSTANCE_ID; + break; + case CLAIM_SUBJECT_ID_VERIFICATION_SERVICE_INDICATOR: + label = EAT_ARM_PSA_CLAIM_ID_VERIFIER; + break; + case CLAIM_SUBJECT_ID_PROFILE_DEFINITION: + label = EAT_ARM_PSA_CLAIM_ID_PROFILE_DEFINITION; + break; + case CLAIM_SUBJECT_ID_IMPLEMENTATION_ID: + label = EAT_ARM_PSA_CLAIM_ID_IMPLEMENTATION_ID; + break; + case CLAIM_SUBJECT_ID_CLIENT_ID: + label = EAT_ARM_PSA_CLAIM_ID_CLIENT_ID; + break; + case CLAIM_SUBJECT_ID_LIFECYCLE_STATE: + label = EAT_ARM_PSA_CLAIM_ID_SECURITY_LIFECYCLE; + break; + case CLAIM_SUBJECT_ID_HW_VERSION: + label = EAT_ARM_PSA_CLAIM_ID_HW_VERSION; + break; + case CLAIM_SUBJECT_ID_BOOT_SEED: + label = EAT_ARM_PSA_CLAIM_ID_BOOT_SEED; + break; + case CLAIM_SUBJECT_ID_NO_SW_MEASUREMENTS: + label = EAT_ARM_PSA_CLAIM_ID_NO_SW_COMPONENTS; + break; + case CLAIM_SUBJECT_ID_SW_COMPONENT: + label = EAT_ARM_PSA_CLAIM_ID_SW_COMPONENTS; + break; + default: + break; + } + + return label; +} + +static int qcbor_to_psa_status(QCBORError qcbor_err) +{ + if (qcbor_err == QCBOR_SUCCESS) return PSA_SUCCESS; + if (qcbor_err == QCBOR_ERR_BUFFER_TOO_SMALL) return PSA_ERROR_BUFFER_TOO_SMALL; + + return PSA_ERROR_PROGRAMMER_ERROR; +} diff --git a/components/service/attestation/reporter/psa/report_serializer.h b/components/service/attestation/reporter/psa/report_serializer.h new file mode 100644 index 000000000..5da5a66fe --- /dev/null +++ b/components/service/attestation/reporter/psa/report_serializer.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PSA_REPORT_SERIALIZER_H +#define PSA_REPORT_SERIALIZER_H + +#include <stddef.h> +#include <stdint.h> +#include <service/attestation/claims/claim_vector.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Serialize the collated set of claims + * + * Serializes the claims into a CBOR document using PSA defined + * EAT custom claims to identify claim objects. + * + * \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 + * + * \return Operation status + */ +int serialize_report(const struct claim_vector *device_claims, + const struct claim_vector *sw_claims, + const uint8_t **report, size_t *report_len); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PSA_REPORT_SERIALIZER_H */ diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp new file mode 100644 index 000000000..71fc10d57 --- /dev/null +++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <psa/error.h> +#include <qcbor/qcbor_spiffy_decode.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 <protocols/service/attestation/packed-c/eat.h> +#include <CppUTest/TestHarness.h> +#include "report_dump.h" + +#include <stdio.h> + +TEST_GROUP(AttestationReporterTests) +{ + void setup() + { + struct claim_source *claim_source; + + report = NULL; + report_len; + + /* 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. + */ + claims_register_init(); + + /* Boot measurement source */ + claim_source = event_log_claim_source_init(&event_log_claim_source, + mock_event_log_start(), mock_event_log_size()); + claims_register_add_claim_source(CLAIM_CATEGORY_BOOT_MEASUREMENT, claim_source); + } + + void teardown() + { + attestation_report_destroy(report); + claims_register_deinit(); + } + + struct event_log_claim_source event_log_claim_source; + const uint8_t *report; + size_t report_len; +}; + +TEST(AttestationReporterTests, createReport) +{ + int status; + + /* Client inputs */ + int32_t client_id = 0x552791aa; + const uint8_t auth_challenge[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32 + }; + + /* Create a report */ + status = attestation_report_create(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); + CHECK_TRUE(report); + CHECK_TRUE(report_len); + + /* 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_EnterMap(&decode_ctx, NULL); + + /* Check client id */ + int64_t decoded_client_id = 0; + 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); + + /* Check the auth challenge */ + UsefulBufC auth_challenge_buf; + auth_challenge_buf.ptr = NULL; + auth_challenge_buf.len = 0; + QCBORDecode_GetByteStringInMapN(&decode_ctx, + EAT_ARM_PSA_CLAIM_ID_CHALLENGE, &auth_challenge_buf); + + UNSIGNED_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)); + + /* 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)); + 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)); + + /* Iterate over all array members */ + size_t sw_component_count = 0; + while (true) { + + QCBORDecode_EnterMap(&decode_ctx, NULL); + + if (QCBORDecode_GetAndResetError(&decode_ctx) == QCBOR_SUCCESS) { + + CHECK_TRUE(sw_component_count < mock_event_Log_measurement_count()); + + UsefulBufC property; + const struct mock_event_log_measurement *measurement = + mock_event_Log_measurement(sw_component_count); + + /* Check measurement id */ + QCBORDecode_GetByteStringInMapN(&decode_ctx, + EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_TYPE, &property); + UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx)); + CHECK_TRUE(property.ptr); + CHECK_TRUE(property.len); + MEMCMP_EQUAL(measurement->id, property.ptr, property.len); + + /* Check measurement digest */ + QCBORDecode_GetByteStringInMapN(&decode_ctx, + EAT_SW_COMPONENT_CLAIM_ID_MEASUREMENT_VALUE, &property); + UNSIGNED_LONGS_EQUAL(QCBOR_SUCCESS, QCBORDecode_GetError(&decode_ctx)); + CHECK_TRUE(property.ptr); + CHECK_TRUE(property.len); + MEMCMP_EQUAL(measurement->digest, property.ptr, property.len); + + QCBORDecode_ExitMap(&decode_ctx); + + ++sw_component_count; + } + else { + /* No more sw components */ + break; + } + } + + QCBORDecode_ExitArray(&decode_ctx); + UNSIGNED_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); +} diff --git a/components/service/attestation/test/component/component.cmake b/components/service/attestation/test/component/component.cmake new file mode 100644 index 000000000..9db9a97f1 --- /dev/null +++ b/components/service/attestation/test/component/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}/attestation_reporter_tests.cpp" + "${CMAKE_CURRENT_LIST_DIR}/report_dump.cpp" + ) diff --git a/components/service/attestation/test/component/report_dump.cpp b/components/service/attestation/test/component/report_dump.cpp new file mode 100644 index 000000000..65f4a8578 --- /dev/null +++ b/components/service/attestation/test/component/report_dump.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdio.h> +#include "report_dump.h" + +void report_dump(const uint8_t *report, size_t len) +{ + size_t bytes_in_row = 0; + size_t byte_count = 0; + + printf("\n*******report dump start (len: %ld)*******\n", len); + + while (byte_count < len) { + + printf("%02x", report[byte_count]); + + ++byte_count; + ++bytes_in_row; + + if (bytes_in_row < 16) { + + printf(" "); + } + else { + + bytes_in_row = 0; + printf("\n"); + } + } + + if (bytes_in_row) printf("\n"); + + printf("*******report dump end *******\n"); +} diff --git a/components/service/attestation/test/component/report_dump.h b/components/service/attestation/test/component/report_dump.h new file mode 100644 index 000000000..81becc564 --- /dev/null +++ b/components/service/attestation/test/component/report_dump.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef REPORT_DUMP_H +#define REPORT_DUMP_H + +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Dump a serialized report as an array of hex bytes. Bytes are + * 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); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* REPORT_DUMP_H */ diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake index 30ab1990a..e73153805 100644 --- a/deployments/component-test/component-test.cmake +++ b/deployments/component-test/component-test.cmake @@ -41,8 +41,13 @@ add_components( "components/service/locator/standalone/services/internal-trusted-storage" "components/service/locator/standalone/services/protected-storage" "components/service/locator/standalone/services/test-runner" + "components/service/attestation/claims" + "components/service/attestation/claims/sources/preloaded" "components/service/attestation/claims/sources/event_log" + "components/service/attestation/claims/sources/event_log/mock" "components/service/attestation/claims/sources/event_log/test" + "components/service/attestation/reporter/psa" + "components/service/attestation/test/component" "components/service/crypto/client/cpp" "components/service/crypto/client/cpp/protobuf" "components/service/crypto/client/cpp/packed-c" diff --git a/protocols/service/attestation/packed-c/eat.h b/protocols/service/attestation/packed-c/eat.h index a5ed31255..980190ddb 100644 --- a/protocols/service/attestation/packed-c/eat.h +++ b/protocols/service/attestation/packed-c/eat.h @@ -30,8 +30,8 @@ extern "C" { #define EAT_ARM_PSA_CLAIM_ID_SW_COMPONENTS (EAT_ARM_PSA_CLAIM_ID_BASE - 6) #define EAT_ARM_PSA_CLAIM_ID_NO_SW_COMPONENTS (EAT_ARM_PSA_CLAIM_ID_BASE - 7) #define EAT_ARM_PSA_CLAIM_ID_CHALLENGE (EAT_ARM_PSA_CLAIM_ID_BASE - 8) -#define EAT_ARM_PSA_CLAIM_ID_UEID (EAT_ARM_PSA_CLAIM_ID_BASE - 9) -#define EAT_ARM_PSA_CLAIM_ID_ORIGINATION (EAT_ARM_PSA_CLAIM_ID_BASE - 10) +#define EAT_ARM_PSA_CLAIM_ID_INSTANCE_ID (EAT_ARM_PSA_CLAIM_ID_BASE - 9) +#define EAT_ARM_PSA_CLAIM_ID_VERIFIER (EAT_ARM_PSA_CLAIM_ID_BASE - 10) /** * SW component EAT claim IDs |