diff options
author | Julian Hall <julian.hall@arm.com> | 2021-05-13 15:30:39 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-07-05 12:43:49 +0200 |
commit | 700aa36408ceec03311bd7aa097c93d220371304 (patch) | |
tree | 8f27789bb08415199825541e94448c3ac83b2f4a | |
parent | 70be3f17bd00710dcab9fcba2fea2c23853c7c71 (diff) | |
download | trusted-services-700aa36408ceec03311bd7aa097c93d220371304.tar.gz |
Add attestation service provider and client
Adds the attestation service provider with a packed-c serializer. A
client that implements the PSA Attestation C API is also added. To
allow for service level testing in a PC environment, a standalone
service context has beed added for the attestation service.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I468e8be122472b5cfff4b9a56569a08b193a14e9
29 files changed, 1045 insertions, 41 deletions
diff --git a/components/service/attestation/client/psa/component.cmake b/components/service/attestation/client/psa/component.cmake new file mode 100644 index 00000000..046c0a53 --- /dev/null +++ b/components/service/attestation/client/psa/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}/iat_client.c" + ) diff --git a/components/service/attestation/client/psa/iat_client.c b/components/service/attestation/client/psa/iat_client.c new file mode 100644 index 00000000..5c88018f --- /dev/null +++ b/components/service/attestation/client/psa/iat_client.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stddef.h> +#include <string.h> +#include "iat_client.h" +#include <common/tlv/tlv.h> +#include <psa/initial_attestation.h> +#include <protocols/service/attestation/packed-c/get_token.h> +#include <protocols/service/attestation/packed-c/get_token_size.h> +#include <protocols/service/attestation/packed-c/opcodes.h> +#include <protocols/rpc/common/packed-c/status.h> + +/** + * @brief The singleton psa_iat_client instance + * + * The psa attestation C API assumes a single backend service provider. This + * structure defines the state used by the psa_iat_client that communicates + * with a remote provider using the provided rpc caller. + */ +static struct psa_iat_client +{ + struct rpc_caller *caller; + int rpc_status; +} instance; + + +psa_status_t psa_iat_client_init(struct rpc_caller *caller) +{ + instance.caller = caller; + instance.rpc_status = TS_RPC_CALL_ACCEPTED; + + return PSA_SUCCESS; +} + +void psa_iat_client_deinit(void) +{ + instance.caller = NULL; +} + +int psa_iat_client_rpc_status(void) +{ + return instance.rpc_status; +} + +psa_status_t psa_initial_attest_get_token( + const uint8_t *auth_challenge, size_t challenge_size, + uint8_t *token_buf, size_t token_buf_size, size_t *token_size) +{ + psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT; + size_t req_len = tlv_required_space(challenge_size); + + struct tlv_record challenge_record; + challenge_record.tag = TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE; + challenge_record.length = challenge_size; + challenge_record.value = auth_challenge; + + rpc_call_handle call_handle; + uint8_t *req_buf; + + *token_size = 0; + + call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + struct tlv_iterator req_iter; + + tlv_iterator_begin(&req_iter, req_buf, req_len); + tlv_encode(&req_iter, &challenge_record); + + instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle, + TS_ATTESTATION_OPCODE_GET_TOKEN, &opstatus, &resp_buf, &resp_len); + + if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + struct tlv_const_iterator resp_iter; + struct tlv_record decoded_record; + tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len); + + if (tlv_find_decode(&resp_iter, + TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN, &decoded_record)) { + + if (decoded_record.length <= token_buf_size) { + + memcpy(token_buf, decoded_record.value, decoded_record.length); + *token_size = decoded_record.length; + } + else { + /* Provided buffer is too small */ + psa_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Mandatory response parameter missing */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + } + + rpc_caller_end(instance.caller, call_handle); + } + + return psa_status; +} + +psa_status_t psa_initial_attest_get_token_size( + size_t challenge_size, size_t *token_size) +{ + psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT; + struct ts_attestation_get_token_size_in req_msg; + size_t req_len = sizeof(struct ts_attestation_get_token_size_in); + + *token_size = 0; /* For failure case */ + + req_msg.challenge_size = challenge_size; + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + struct tlv_iterator req_iter; + + memcpy(req_buf, &req_msg, req_len); + + instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle, + TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, &opstatus, &resp_buf, &resp_len); + + if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + if (resp_len >= sizeof(struct ts_attestation_get_token_size_out)) { + + struct ts_attestation_get_token_size_out resp_msg; + memcpy(&resp_msg, resp_buf, sizeof(struct ts_attestation_get_token_size_out)); + *token_size = resp_msg.token_size; + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + } + + rpc_caller_end(instance.caller, call_handle); + } + + return psa_status; +} diff --git a/components/service/attestation/client/psa/iat_client.h b/components/service/attestation/client/psa/iat_client.h new file mode 100644 index 00000000..7daeacf2 --- /dev/null +++ b/components/service/attestation/client/psa/iat_client.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PSA_IAT_CLIENT_H +#define PSA_IAT_CLIENT_H + +#include <psa/error.h> +#include <rpc_caller.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialises the singleton IAT client + * + * The IAT client provides an implementation of the PSA Attestation API. + * This API may be used by client applications to request attestion + * tokens. + * + * @param[in] rpc_caller RPC caller instance + * + * @return A status indicating the success/failure of the operation + */ +psa_status_t psa_iat_client_init(struct rpc_caller *caller); + +/** + * @brief De-initialises the singleton IAT client + * + */ +void psa_iat_client_deinit(void); + +/** + * @brief Return the most recent RPC status + * + * May be used to obtain information about an RPC error that resulted + * in an API operation failure + * + * @return Most recent RPC operation status + */ +int psa_iat_client_rpc_status(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_IAT_CLIENT_H */ diff --git a/components/service/attestation/include/component.cmake b/components/service/attestation/include/component.cmake new file mode 100644 index 00000000..00c61bda --- /dev/null +++ b/components/service/attestation/include/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_include_directories(${TGT} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}" + ) diff --git a/components/service/attestation/include/psa/initial_attestation.h b/components/service/attestation/include/psa/initial_attestation.h index bc630ee6..35a18d04 100644 --- a/components/service/attestation/include/psa/initial_attestation.h +++ b/components/service/attestation/include/psa/initial_attestation.h @@ -18,7 +18,6 @@ #include <limits.h> #include <stdint.h> #include <stddef.h> -#include "psa/crypto.h" #ifdef __cplusplus extern "C" { @@ -46,7 +45,7 @@ extern "C" { * attestation service. Used to configure buffers for services that verify the * produced tokens. */ -#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE (0x400) +#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE (4096) /** * The list of fixed claims in the initial attestation token is still evolving, @@ -201,26 +200,6 @@ psa_status_t psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size); -/** - * \brief Get the initial attestation public key. - * - * \param[out] public_key Pointer to the buffer where the public key - * will be stored. - * \param[in] key_buf_size Size of allocated buffer for key, in bytes. - * \param[out] public_key_len Size of public key in bytes. - * \param[out] public_key_curve Type of the elliptic curve which the key - * belongs to. - * - * \note Currently only the ECDSA P-256 over SHA-256 algorithm is supported. - * - * \return Returns error code as specified in \ref psa_status_t - */ -psa_status_t -tfm_initial_attest_get_public_key(uint8_t *public_key, - size_t public_key_buf_size, - size_t *public_key_len, - psa_ecc_family_t *elliptic_curve_type); - #ifdef __cplusplus } #endif diff --git a/components/service/attestation/key_mngr/attest_key_mngr.c b/components/service/attestation/key_mngr/attest_key_mngr.c index c871c829..a4d8ec0d 100644 --- a/components/service/attestation/key_mngr/attest_key_mngr.c +++ b/components/service/attestation/key_mngr/attest_key_mngr.c @@ -8,9 +8,6 @@ #include <psa/crypto.h> #include "attest_key_mngr.h" -/* todo - need strategy for assigning key IDs */ -#define IAK_KEY_ID 0x2000 - /** * The singleton attest_key_mngr instance. */ @@ -55,16 +52,20 @@ static psa_status_t generate_iak(psa_key_id_t key_id, psa_key_handle_t *iak_hand return status; } -void attest_key_mngr_init(void) +void attest_key_mngr_init(psa_key_id_t iak_id) { instance.is_iak_open = false; - instance.iak_id = IAK_KEY_ID; + instance.iak_id = iak_id; instance.iak_handle = -1; } void attest_key_mngr_deinit(void) { + if (instance.is_iak_open && !instance.iak_id) { + psa_destroy_key(instance.iak_handle); + instance.is_iak_open = false; + } } psa_status_t attest_key_mngr_get_iak_handle(psa_key_handle_t *iak_handle) @@ -73,20 +74,25 @@ psa_status_t attest_key_mngr_get_iak_handle(psa_key_handle_t *iak_handle) if (!instance.is_iak_open) { - status = psa_open_key(instance.iak_id, &instance.iak_handle); + if (instance.iak_id) { - if (status == PSA_ERROR_STORAGE_FAILURE) { - - /* Accommodate deployments with no persistent storage - * to support testing. In this case, a volatile key - * is generated, indicated by an invalid key id. + /* A valid key id has been specified so treat as a persistent key + * that will normally already exist. */ - instance.iak_id = 0; - } + status = psa_open_key(instance.iak_id, &instance.iak_handle); - if (status != PSA_SUCCESS) { + if (status != PSA_SUCCESS) { - /* First run and no key has been provisioned */ + /* First run and no key has been provisioned */ + status = generate_iak(instance.iak_id, &instance.iak_handle); + } + } + else { + + /* An invalid key id has been specified which indicates that a + * volatile key should be generated. This is option is intended + * for test purposes only. + */ status = generate_iak(instance.iak_id, &instance.iak_handle); } diff --git a/components/service/attestation/key_mngr/attest_key_mngr.h b/components/service/attestation/key_mngr/attest_key_mngr.h index 982c8410..eaf46fcd 100644 --- a/components/service/attestation/key_mngr/attest_key_mngr.h +++ b/components/service/attestation/key_mngr/attest_key_mngr.h @@ -9,6 +9,9 @@ #include <psa/crypto.h> +/* Key ID for a volatile IAK (for test) */ +#define ATTEST_KEY_MNGR_VOLATILE_IAK (0) + #ifdef __cplusplus extern "C" { #endif @@ -25,8 +28,15 @@ extern "C" { /** * \brief Initialize the attest_key_mngr + * + * Initializes the attest_key_mngr. The provided key id should + * be used as the identifier for the IAK. If a key ID of zero + * is passed, a volatile IAK will be generated. This is useful + * for test purposes. + * + * \param[in] iak_id The key id for the IAK */ -void attest_key_mngr_init(void); +void attest_key_mngr_init(psa_key_id_t iak_id); /** * \brief De-initialize the attest_key_mngr diff --git a/components/service/attestation/provider/attest_provider.c b/components/service/attestation/provider/attest_provider.c new file mode 100644 index 00000000..1e127176 --- /dev/null +++ b/components/service/attestation/provider/attest_provider.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <stdlib.h> +#include <string.h> +#include <protocols/service/attestation/packed-c/opcodes.h> +#include <protocols/rpc/common/packed-c/status.h> +#include <service/attestation/key_mngr/attest_key_mngr.h> +#include <service/attestation/reporter/attest_report.h> +#include <psa/initial_attestation.h> +#include "attest_provider.h" + +/* Service request handlers */ +static rpc_status_t get_token_handler(void *context, struct call_req* req); +static rpc_status_t get_token_size_handler(void *context, struct call_req* req); + +/* Handler mapping table for service */ +static const struct service_handler handler_table[] = { + {TS_ATTESTATION_OPCODE_GET_TOKEN, get_token_handler}, + {TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, get_token_size_handler} +}; + +struct rpc_interface *attest_provider_init(struct attest_provider *context, psa_key_id_t iak_id) +{ + struct rpc_interface *rpc_interface = NULL; + + if (context) { + + for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding) + context->serializers[encoding] = NULL; + + service_provider_init(&context->base_provider, context, + handler_table, sizeof(handler_table)/sizeof(struct service_handler)); + + attest_key_mngr_init(iak_id); + + rpc_interface = service_provider_get_rpc_interface(&context->base_provider); + } + + return rpc_interface; +} + +void attest_provider_deinit(struct attest_provider *context) +{ + (void)context; + attest_key_mngr_deinit(); +} + +void attest_provider_register_serializer(struct attest_provider *context, + unsigned int encoding, const struct attest_provider_serializer *serializer) +{ + if (encoding < TS_RPC_ENCODING_LIMIT) + context->serializers[encoding] = serializer; +} + +static const struct attest_provider_serializer *get_attest_serializer( + struct attest_provider *context, const struct call_req *req) +{ + const struct attest_provider_serializer *serializer = NULL; + unsigned int encoding = call_req_get_encoding(req); + + if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding]; + + return serializer; +} + +static rpc_status_t get_token_handler(void *context, struct call_req* req) +{ + struct attest_provider *this_instance = (struct attest_provider*)context; + rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED; + + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64]; + size_t challenge_len = sizeof(challenge); + + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req); + + if (serializer) + rpc_status = serializer->deserialize_get_token_req(req_buf, challenge, &challenge_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_key_handle_t iak_handle; + int opstatus = attest_key_mngr_get_iak_handle(&iak_handle); + + if (opstatus == PSA_SUCCESS) { + + const uint8_t *token = NULL; + size_t token_size = 0; + + opstatus = attest_report_create(iak_handle, + (int32_t)call_req_get_caller_id(req), + challenge, challenge_len, + &token, &token_size); + + if (opstatus == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_get_token_resp(resp_buf, token, token_size); + } + + attest_report_destroy(token); + } + + call_req_set_opstatus(req, opstatus); + } + + return rpc_status; +} + +static rpc_status_t get_token_size_handler(void *context, struct call_req* req) +{ + struct attest_provider *this_instance = (struct attest_provider*)context; + rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED; + + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64]; + size_t challenge_len = sizeof(challenge); + + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req); + + memset(challenge, 0, sizeof(challenge)); + + if (serializer) + rpc_status = serializer->deserialize_get_token_size_req(req_buf, &challenge_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_key_handle_t iak_handle; + int opstatus = attest_key_mngr_get_iak_handle(&iak_handle); + + if (opstatus == PSA_SUCCESS) { + + const uint8_t *token = NULL; + size_t token_size = 0; + + opstatus = attest_report_create(iak_handle, + (int32_t)call_req_get_caller_id(req), + challenge, challenge_len, + &token, &token_size); + + if (opstatus == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_get_token_size_resp(resp_buf, token_size); + } + + attest_report_destroy(token); + } + + call_req_set_opstatus(req, opstatus); + } + + return rpc_status; +} diff --git a/components/service/attestation/provider/attest_provider.h b/components/service/attestation/provider/attest_provider.h new file mode 100644 index 00000000..ed3b59a7 --- /dev/null +++ b/components/service/attestation/provider/attest_provider.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ATTEST_PROVIDER_H +#define ATTEST_PROVIDER_H + +#include <rpc/common/endpoint/rpc_interface.h> +#include <rpc_caller.h> +#include <service/common/provider/service_provider.h> +#include <service/attestation/provider/serializer/attest_provider_serializer.h> +#include <service/attestation/key_mngr/attest_key_mngr.h> +#include <protocols/rpc/common/packed-c/encoding.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The attest_provider is a service provider that implements an RPC interface + * for an instance of the attestation service. + */ +struct attest_provider +{ + struct service_provider base_provider; + const struct attest_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT]; +}; + +/** + * \brief Initialize an instance of the service provider + * + * Initializes a an attestation service provider. Returns an rpc_interface + * that should be associated with a suitable rpc endpoint. + * + * \param[in] context The instance to initialize + * \param[in] iak_id The key ID for the IAK + * + * \return An rpc_interface or NULL on failure + */ +struct rpc_interface *attest_provider_init(struct attest_provider *context, + psa_key_id_t iak_id); + +/** + * \brief Cleans up when the instance is no longer needed + * + * \param[in] context The instance to de-initialize + */ +void attest_provider_deinit(struct attest_provider *context); + +/** + * \brief Register a protocol serializer + * + * \param[in] context The instance + * \param[in] encoding Serialization encoding e.g. packed-c + * \param[in] serializer A concrete serializer + */ +void attest_provider_register_serializer(struct attest_provider *context, + unsigned int encoding, const struct attest_provider_serializer *serializer); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ATTEST_PROVIDER_H */ diff --git a/components/service/attestation/provider/component.cmake b/components/service/attestation/provider/component.cmake new file mode 100644 index 00000000..cd30f538 --- /dev/null +++ b/components/service/attestation/provider/component.cmake @@ -0,0 +1,13 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/attest_provider.c" + ) diff --git a/components/service/attestation/provider/serializer/attest_provider_serializer.h b/components/service/attestation/provider/serializer/attest_provider_serializer.h new file mode 100644 index 00000000..5334cba5 --- /dev/null +++ b/components/service/attestation/provider/serializer/attest_provider_serializer.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ATTEST_PROVIDER_SERIALIZER_H +#define ATTEST_PROVIDER_SERIALIZER_H + +#include <stddef.h> +#include <stdint.h> +#include <rpc/common/endpoint/rpc_interface.h> + +/* Provides a common interface for parameter serialization operations + * for the attestation service provider. Allows alternative serialization + * protocols to be used without hard-wiring a particular protocol + * into the service provider code. A concrete serializer must + * implement this interface. + */ +struct attest_provider_serializer { + + /* Operation: get_token */ + rpc_status_t (*deserialize_get_token_req)(const struct call_param_buf *req_buf, + uint8_t *auth_challenge, size_t *auth_challenge_len); + + rpc_status_t (*serialize_get_token_resp)(struct call_param_buf *resp_buf, + const uint8_t *token, + size_t token_size); + + /* Operation: get_token_size */ + rpc_status_t (*deserialize_get_token_size_req)(const struct call_param_buf *req_buf, + size_t *auth_challenge_len); + + rpc_status_t (*serialize_get_token_size_resp)(struct call_param_buf *resp_buf, + size_t token_size); +}; + +#endif /* ATTEST_PROVIDER_SERIALIZER_H */ diff --git a/components/service/attestation/provider/serializer/packed-c/component.cmake b/components/service/attestation/provider/serializer/packed-c/component.cmake new file mode 100644 index 00000000..7231a18e --- /dev/null +++ b/components/service/attestation/provider/serializer/packed-c/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}/packedc_attest_provider_serializer.c" + ) diff --git a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c new file mode 100644 index 00000000..c2e5d56f --- /dev/null +++ b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <string.h> +#include <common/tlv/tlv.h> +#include <protocols/rpc/common/packed-c/status.h> +#include <protocols/service/attestation/packed-c/get_token.h> +#include <protocols/service/attestation/packed-c/get_token_size.h> +#include "packedc_attest_provider_serializer.h" + + +/* Operation: get_token */ +static rpc_status_t deserialize_get_token_req(const struct call_param_buf *req_buf, + uint8_t *auth_challenge, size_t *auth_challenge_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + struct tlv_const_iterator req_iter; + struct tlv_record decoded_record; + + tlv_const_iterator_begin(&req_iter, (uint8_t*)req_buf->data, req_buf->data_len); + + if (tlv_find_decode(&req_iter, + TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE, &decoded_record)) { + + if (decoded_record.length <= *auth_challenge_len) { + + memcpy(auth_challenge, decoded_record.value, decoded_record.length); + *auth_challenge_len = decoded_record.length; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + return rpc_status; +} + +static rpc_status_t serialize_get_token_resp(struct call_param_buf *resp_buf, + const uint8_t *token, size_t token_size) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + struct tlv_iterator resp_iter; + + struct tlv_record token_record; + token_record.tag = TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN; + token_record.length = token_size; + token_record.value = token; + + tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size); + + if (tlv_encode(&resp_iter, &token_record)) { + + resp_buf->data_len = tlv_required_space(token_size); + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +/* Operation: get_token_size */ +static rpc_status_t deserialize_get_token_size_req(const struct call_param_buf *req_buf, + size_t *auth_challenge_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + struct ts_attestation_get_token_size_in recv_msg; + size_t expected_fixed_len = sizeof(struct ts_attestation_get_token_size_in); + + if (expected_fixed_len <= req_buf->data_len) { + + memcpy(&recv_msg, req_buf->data, expected_fixed_len); + *auth_challenge_len = recv_msg.challenge_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_get_token_size_resp(struct call_param_buf *resp_buf, + size_t token_size) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + struct ts_attestation_get_token_size_out resp_msg; + size_t fixed_len = sizeof(struct ts_attestation_get_token_size_out); + + resp_msg.token_size = token_size; + + if (fixed_len <= resp_buf->size) { + + memcpy(resp_buf->data, &resp_msg, fixed_len); + resp_buf->data_len = fixed_len; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +/* Singleton method to provide access to the serializer instance */ +const struct attest_provider_serializer *packedc_attest_provider_serializer_instance(void) +{ + static const struct attest_provider_serializer instance = { + deserialize_get_token_req, + serialize_get_token_resp, + deserialize_get_token_size_req, + serialize_get_token_size_resp + }; + + return &instance; +} diff --git a/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h new file mode 100644 index 00000000..b73adf8d --- /dev/null +++ b/components/service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PACKEDC_ATTEST_PROVIDER_SERIALIZER_H +#define PACKEDC_ATTEST_PROVIDER_SERIALIZER_H + +#include <service/attestation/provider/serializer/attest_provider_serializer.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Singleton method to provide access to the packed-c serializer + * for the attestation service provider. + */ +const struct attest_provider_serializer *packedc_attest_provider_serializer_instance(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PACKEDC_ATTEST_PROVIDER_SERIALIZER_H */ diff --git a/components/service/attestation/reporter/psa/psa_attest_report.c b/components/service/attestation/reporter/psa/psa_attest_report.c index 3228f1ca..1f4ed0ef 100644 --- a/components/service/attestation/reporter/psa/psa_attest_report.c +++ b/components/service/attestation/reporter/psa/psa_attest_report.c @@ -12,7 +12,9 @@ */ #include <stdlib.h> +#include <stdbool.h> #include <psa/error.h> +#include <psa/initial_attestation.h> #include <service/attestation/reporter/attest_report.h> #include <service/attestation/claims/claims_register.h> #include "eat_serializer.h" @@ -22,6 +24,7 @@ #define MAX_DEVICE_CLAIMS (50) #define MAX_SW_CLAIMS (50) +static bool validate_challenge(size_t len); 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); @@ -38,6 +41,8 @@ int attest_report_create(psa_key_handle_t key_handle, int32_t client_id, *report = NULL; *report_len = 0; + if (!validate_challenge(auth_challenge_len)) return PSA_ERROR_INVALID_ARGUMENT; + claim_vector_init(&device_claims, MAX_DEVICE_CLAIMS); claim_vector_init(&sw_claims, MAX_SW_CLAIMS); @@ -78,6 +83,15 @@ void attest_report_destroy(const uint8_t *report) free((void*)report); } +static bool validate_challenge(size_t len) +{ + /* Only allow specific challenge lengths */ + return + (len == PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32) || + (len == PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48) || + (len == PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64); +} + static void add_auth_challenge_claim(struct claim_vector *v, const uint8_t *data, size_t len) { struct claim claim; diff --git a/components/service/attestation/test/common/component.cmake b/components/service/attestation/test/common/component.cmake new file mode 100644 index 00000000..5985c766 --- /dev/null +++ b/components/service/attestation/test/common/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}/report_dump.cpp" + ) diff --git a/components/service/attestation/test/component/report_dump.cpp b/components/service/attestation/test/common/report_dump.cpp index 65f4a857..65f4a857 100644 --- a/components/service/attestation/test/component/report_dump.cpp +++ b/components/service/attestation/test/common/report_dump.cpp diff --git a/components/service/attestation/test/component/report_dump.h b/components/service/attestation/test/common/report_dump.h index 81becc56..81becc56 100644 --- a/components/service/attestation/test/component/report_dump.h +++ b/components/service/attestation/test/common/report_dump.h diff --git a/components/service/attestation/test/component/attestation_reporter_tests.cpp b/components/service/attestation/test/component/attestation_reporter_tests.cpp index 02b91ac5..c83dc3c1 100644 --- a/components/service/attestation/test/component/attestation_reporter_tests.cpp +++ b/components/service/attestation/test/component/attestation_reporter_tests.cpp @@ -13,10 +13,10 @@ #include <service/attestation/claims/sources/preloaded/preloaded_claim_source.h> #include <service/attestation/reporter/attest_report.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> #include <psa/crypto.h> -#include "report_dump.h" TEST_GROUP(AttestationReporterTests) { @@ -28,7 +28,7 @@ TEST_GROUP(AttestationReporterTests) report_len; psa_crypto_init(); - attest_key_mngr_init(); + attest_key_mngr_init(ATTEST_KEY_MNGR_VOLATILE_IAK); /* The set of registered claim_sources determines the content * of a generated attestation source. The set and type of diff --git a/components/service/attestation/test/component/component.cmake b/components/service/attestation/test/component/component.cmake index 9db9a97f..3bd7e56c 100644 --- a/components/service/attestation/test/component/component.cmake +++ b/components/service/attestation/test/component/component.cmake @@ -10,5 +10,4 @@ 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/service/attestation_service_tests.cpp b/components/service/attestation/test/service/attestation_service_tests.cpp new file mode 100644 index 00000000..9fe1f4d1 --- /dev/null +++ b/components/service/attestation/test/service/attestation_service_tests.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <limits.h> +#include <string.h> +#include <service/attestation/client/psa/iat_client.h> +#include <protocols/rpc/common/packed-c/encoding.h> +#include <service_locator.h> +#include <psa/initial_attestation.h> +#include <CppUTest/TestHarness.h> + +/* + * Service-level tests for the attestation service. + */ +TEST_GROUP(AttestationServiceTests) +{ + void setup() + { + struct rpc_caller *caller; + int status; + + m_rpc_session_handle = NULL; + m_attest_service_context = NULL; + + service_locator_init(); + + m_attest_service_context = + service_locator_query("sn:trustedfirmware.org:attestation:0", &status); + CHECK_TRUE(m_attest_service_context); + + m_rpc_session_handle = + service_context_open(m_attest_service_context, TS_RPC_ENCODING_PACKED_C, &caller); + CHECK_TRUE(m_rpc_session_handle); + + psa_iat_client_init(caller); + } + + void teardown() + { + psa_iat_client_deinit(); + + service_context_close(m_attest_service_context, m_rpc_session_handle); + m_rpc_session_handle = NULL; + + service_context_relinquish(m_attest_service_context); + m_attest_service_context = NULL; + } + + rpc_session_handle m_rpc_session_handle; + struct service_context *m_attest_service_context; +}; + +TEST(AttestationServiceTests, checkTokenSize) +{ + uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE]; + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64]; + + memset(challenge, 0x87, sizeof(challenge)); + + /* Check that the get_token_size operation returns the same size + * as theh get_token operation. + */ + psa_status_t status; + size_t reported_token_size = 0; + size_t actual_token_size = 0; + + status = psa_initial_attest_get_token_size( + sizeof(challenge), + &reported_token_size); + + LONGS_EQUAL(PSA_SUCCESS, status); + CHECK_TRUE(reported_token_size); + + status = psa_initial_attest_get_token( + challenge, sizeof(challenge), + token_buf, sizeof(token_buf), + &actual_token_size); + + LONGS_EQUAL(PSA_SUCCESS, status); + UNSIGNED_LONGS_EQUAL(reported_token_size, actual_token_size); +} + +TEST(AttestationServiceTests, invalidChallengeLen) +{ + uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE]; + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64]; + + memset(challenge, 0x87, sizeof(challenge)); + + /* Check that invalid challenge lengths are rejected cleanly */ + psa_status_t status; + size_t challenge_len; + size_t token_size = 0; + + /* Zero length challenge */ + challenge_len = 0; + status = psa_initial_attest_get_token_size( + challenge_len, + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + status = psa_initial_attest_get_token( + challenge, challenge_len, + token_buf, sizeof(token_buf), + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + /* Extra large challenge */ + challenge_len = UINT32_MAX; + status = psa_initial_attest_get_token_size( + challenge_len, + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + status = psa_initial_attest_get_token( + challenge, challenge_len, + token_buf, sizeof(token_buf), + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + /* Slightly large challenge */ + challenge_len = PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 + 1; + status = psa_initial_attest_get_token_size( + challenge_len, + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + status = psa_initial_attest_get_token( + challenge, challenge_len, + token_buf, sizeof(token_buf), + &token_size); + LONGS_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); +} + +TEST(AttestationServiceTests, repeatedOperation) +{ + uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE]; + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48]; + + memset(challenge, 0x61, sizeof(challenge)); + + /* Check reports can be requested repeatedly without + * resource exhausation due to a memory leak. + */ + for (int i = 0; i < 100; ++i) { + + psa_status_t status; + size_t reported_token_size = 0; + size_t actual_token_size = 0; + + status = psa_initial_attest_get_token_size( + sizeof(challenge), + &reported_token_size); + + LONGS_EQUAL(PSA_SUCCESS, status); + CHECK_TRUE(reported_token_size); + + status = psa_initial_attest_get_token( + challenge, sizeof(challenge), + token_buf, sizeof(token_buf), + &actual_token_size); + + LONGS_EQUAL(PSA_SUCCESS, status); + UNSIGNED_LONGS_EQUAL(reported_token_size, actual_token_size); + } +} diff --git a/components/service/attestation/test/service/component.cmake b/components/service/attestation/test/service/component.cmake new file mode 100644 index 00000000..a07e402b --- /dev/null +++ b/components/service/attestation/test/service/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}/attestation_service_tests.cpp" + ) diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.cpp b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp new file mode 100644 index 00000000..302a536d --- /dev/null +++ b/components/service/locator/standalone/services/attestation/attestation_service_context.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "attestation_service_context.h" +#include <service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.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> + +attestation_service_context::attestation_service_context(const char *sn) : + standalone_service_context(sn), + m_attest_provider(), + m_event_log_claim_source() +{ + +} + +attestation_service_context::~attestation_service_context() +{ + +} + +void attestation_service_context::do_init() +{ + struct claim_source *claim_source; + + /** + * Initialize and register claims sources to define the view of + * the device reflected by the attestation service. On a real + * device, the set of claim sources will be deployment specific + * to accommodate specific device architecture and product + * variations. + */ + claims_register_init(); + + /* Boot measurement source - uses mock event log */ + claim_source = event_log_claim_source_init(&m_event_log_claim_source, + mock_event_log_start(), mock_event_log_size()); + claims_register_add_claim_source(CLAIM_CATEGORY_BOOT_MEASUREMENT, claim_source); + + /* Initialize the attestation service provider */ + struct rpc_interface *attest_ep = + attest_provider_init(&m_attest_provider, ATTEST_KEY_MNGR_VOLATILE_IAK); + + attest_provider_register_serializer(&m_attest_provider, + TS_RPC_ENCODING_PACKED_C, packedc_attest_provider_serializer_instance()); + + standalone_service_context::set_rpc_interface(attest_ep); +} + +void attestation_service_context::do_deinit() +{ + attest_provider_deinit(&m_attest_provider); + claims_register_deinit(); +} diff --git a/components/service/locator/standalone/services/attestation/attestation_service_context.h b/components/service/locator/standalone/services/attestation/attestation_service_context.h new file mode 100644 index 00000000..ad8d0eea --- /dev/null +++ b/components/service/locator/standalone/services/attestation/attestation_service_context.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STANDALONE_ATTESTATION_SERVICE_CONTEXT_H +#define STANDALONE_ATTESTATION_SERVICE_CONTEXT_H + +#include <service/locator/standalone/standalone_service_context.h> +#include <rpc/direct/direct_caller.h> +#include <service/attestation/provider/attest_provider.h> +#include <service/attestation/claims/sources/event_log/event_log_claim_source.h> + + +class attestation_service_context : public standalone_service_context +{ +public: + attestation_service_context(const char *sn); + virtual ~attestation_service_context(); + +private: + + void do_init(); + void do_deinit(); + + struct attest_provider m_attest_provider; + struct event_log_claim_source m_event_log_claim_source; +}; + +#endif /* STANDALONE_ATTESTATION_SERVICE_CONTEXT_H */ diff --git a/components/service/locator/standalone/services/attestation/component.cmake b/components/service/locator/standalone/services/attestation/component.cmake new file mode 100644 index 00000000..41fc0317 --- /dev/null +++ b/components/service/locator/standalone/services/attestation/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}/attestation_service_context.cpp" + ) diff --git a/components/service/locator/standalone/standalone_env.cpp b/components/service/locator/standalone/standalone_env.cpp index 132b6d56..ab1a1be5 100644 --- a/components/service/locator/standalone/standalone_env.cpp +++ b/components/service/locator/standalone/standalone_env.cpp @@ -9,6 +9,7 @@ #include <service/locator/standalone/services/internal-trusted-storage/its_service_context.h> #include <service/locator/standalone/services/protected-storage/ps_service_context.h> #include <service/locator/standalone/services/test-runner/test_runner_service_context.h> +#include <service/locator/standalone/services/attestation/attestation_service_context.h> #include "standalone_location_strategy.h" #include "standalone_service_registry.h" @@ -26,5 +27,8 @@ void service_locator_envinit(void) static test_runner_service_context test_runner_context("sn:trustedfirmware.org:test-runner:0"); standalone_service_registry::instance()->regsiter_service_instance(&test_runner_context); + static attestation_service_context attestation_context("sn:trustedfirmware.org:attestation:0"); + standalone_service_registry::instance()->regsiter_service_instance(&attestation_context); + service_locator_register_strategy(standalone_location_strategy()); } diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake index 075538dd..bb52dd5c 100644 --- a/deployments/component-test/component-test.cmake +++ b/deployments/component-test/component-test.cmake @@ -41,6 +41,8 @@ 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/locator/standalone/services/attestation" + "components/service/attestation/include" "components/service/attestation/claims" "components/service/attestation/claims/sources/preloaded" "components/service/attestation/claims/sources/event_log" @@ -48,7 +50,12 @@ add_components( "components/service/attestation/claims/sources/event_log/test" "components/service/attestation/reporter/psa" "components/service/attestation/key_mngr" + "components/service/attestation/provider" + "components/service/attestation/provider/serializer/packed-c" + "components/service/attestation/client/psa" + "components/service/attestation/test/common" "components/service/attestation/test/component" + "components/service/attestation/test/service" "components/service/crypto/client/cpp" "components/service/crypto/client/cpp/protobuf" "components/service/crypto/client/cpp/packed-c" diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt index f6ac33d5..d1a96ae8 100644 --- a/deployments/libts/linux-pc/CMakeLists.txt +++ b/deployments/libts/linux-pc/CMakeLists.txt @@ -31,6 +31,7 @@ add_components( COMPONENTS "components/rpc/direct" "components/common/tlv" + "components/common/endian" "components/service/common/include" "components/service/common/serializer/protobuf" "components/service/common/provider" @@ -39,6 +40,16 @@ 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/locator/standalone/services/attestation" + "components/service/attestation/include" + "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/reporter/psa" + "components/service/attestation/key_mngr" + "components/service/attestation/provider" + "components/service/attestation/provider/serializer/packed-c" "components/service/crypto/provider/mbedcrypto" "components/service/crypto/provider/mbedcrypto/trng_adapter/linux" "components/service/crypto/provider/serializer/protobuf" @@ -80,6 +91,14 @@ protobuf_generate_all(TGT "ts" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protoco include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake) target_link_libraries(ts PRIVATE mbedcrypto) +# Qcbor +include(${TS_ROOT}/external/qcbor/qcbor.cmake) +target_link_libraries(ts PRIVATE qcbor) + +# t_cose +include(${TS_ROOT}/external/t_cose/t_cose.cmake) +target_link_libraries(ts PRIVATE t_cose) + #------------------------------------------------------------------------------- # Test executable (libts-test) for testing libts static library # diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt index 4a86c875..ac4c237d 100644 --- a/deployments/ts-service-test/linux-pc/CMakeLists.txt +++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt @@ -80,6 +80,9 @@ add_components( COMPONENTS "components/service/test_runner/client/cpp" "components/service/test_runner/test/service" + "components/service/attestation/include" + "components/service/attestation/client/psa" + "components/service/attestation/test/service" ) #------------------------------------------------------------------------------- |