15 #include "tfm_plat_defs.h"
16 #include "tfm_plat_device_id.h"
17 #include "tfm_plat_boot_seed.h"
18 #include "tfm_attest_hal.h"
21 #include "t_cose_common.h"
23 #include "tfm_plat_crypto_keys.h"
25 #define MAX_BOOT_STATUS 512
28 #define EAT_SW_COMPONENT_NESTED 1
29 #define EAT_SW_COMPONENT_NOT_NESTED 0
32 #ifdef SYMMETRIC_INITIAL_ATTESTATION
33 #define T_COSE_ALGORITHM T_COSE_ALGORITHM_HMAC256
35 #define T_COSE_ALGORITHM T_COSE_ALGORITHM_ES256
61 __attribute__ ((aligned(4)))
107 return error_mapping_to_psa_status_t(res);
148 static inline int32_t get_uint(
const void *int_ptr,
156 *value = (uint32_t)(*(uint8_t *)(int_ptr));
160 (void)
tfm_memcpy(&uint16, int_ptr,
sizeof(uint16));
161 *value = (uint32_t)uint16;
165 (void)
tfm_memcpy(value, int_ptr,
sizeof(uint32_t));
191 static int32_t attest_get_tlv_by_module(uint8_t module,
206 if (*tlv_ptr == NULL) {
208 tlv_curr = boot_data.
data;
220 while (tlv_curr < tlv_end) {
226 *tlv_len = tlv_entry.tlv_len;
248 static int32_t attest_get_tlv_by_id(uint8_t claim,
262 found = attest_get_tlv_by_module(module, &tlv_id,
270 if (claim == tlv_id) {
273 }
while (found == 1);
295 QCBOREncodeContext *cbor_encode_ctx = NULL;
296 UsefulBufC encoded = NULLUsefulBufC;
300 for (module = 0; module <
SW_MAX; ++module) {
307 found = attest_get_tlv_by_module(module, &tlv_id,
317 QCBOREncode_OpenArrayInMapN(cbor_encode_ctx,
323 QCBOREncode_AddEncoded(cbor_encode_ctx, encoded);
329 QCBOREncode_CloseArray(cbor_encode_ctx);
352 uint8_t boot_seed[BOOT_SEED_SIZE];
353 enum tfm_plat_err_t res;
354 struct q_useful_buf_c claim_value = {0};
356 uint8_t *tlv_ptr = NULL;
360 found = attest_get_tlv_by_id(
BOOT_SEED, &tlv_len, &tlv_ptr);
363 claim_value.len = tlv_len;
368 res = tfm_plat_get_boot_seed(
sizeof(boot_seed), boot_seed);
369 if (res != TFM_PLAT_ERR_SUCCESS) {
372 claim_value.ptr = boot_seed;
373 claim_value.len = BOOT_SEED_SIZE;
396 struct q_useful_buf_c claim_value;
422 uint8_t implementation_id[IMPLEMENTATION_ID_MAX_SIZE];
423 enum tfm_plat_err_t res_plat;
424 uint32_t size =
sizeof(implementation_id);
425 struct q_useful_buf_c claim_value;
427 res_plat = tfm_plat_get_implementation_id(&size, implementation_id);
428 if (res_plat != TFM_PLAT_ERR_SUCCESS) {
432 claim_value.ptr = implementation_id;
433 claim_value.len = size;
476 enum tfm_security_lifecycle_t security_lifecycle;
479 struct q_useful_buf_c claim_value = {0};
481 uint8_t *tlv_ptr = NULL;
490 claim_value.len = tlv_len;
491 res = get_uint(claim_value.ptr, claim_value.len, &slc_value);
495 security_lifecycle = (
enum tfm_security_lifecycle_t)slc_value;
500 security_lifecycle = tfm_attest_hal_get_security_lifecycle();
504 if (security_lifecycle > TFM_SLC_MAX_VALUE) {
510 (int64_t)security_lifecycle);
525 const struct q_useful_buf_c *challenge)
534 #ifdef INCLUDE_OPTIONAL_CLAIMS
549 service.ptr = tfm_attest_hal_get_verification_service(&size);
571 struct q_useful_buf_c profile;
574 profile.ptr = tfm_attest_hal_get_profile_definition(&size);
596 uint8_t hw_version[HW_VERSION_MAX_SIZE];
597 enum tfm_plat_err_t res_plat;
598 uint32_t size =
sizeof(hw_version);
599 struct q_useful_buf_c claim_value = {0};
601 uint8_t *tlv_ptr = NULL;
607 found = attest_get_tlv_by_id(
HW_VERSION, &tlv_len, &tlv_ptr);
610 claim_value.len = tlv_len;
615 res_plat = tfm_plat_get_hw_version(&size, hw_version);
616 if (res_plat != TFM_PLAT_ERR_SUCCESS) {
619 claim_value.ptr = hw_version;
620 claim_value.len = size;
641 static enum psa_attest_err_t attest_verify_challenge_size(
size_t challenge_size)
643 switch (challenge_size) {
654 #ifdef INCLUDE_TEST_CODE
670 static void attest_get_option_flags(
struct q_useful_buf_c *challenge,
671 uint32_t *option_flags,
674 uint32_t found_option_flags = 1;
675 uint32_t option_flags_size =
sizeof(uint32_t);
676 uint8_t *challenge_end;
677 uint8_t *challenge_data;
682 challenge_end = ((uint8_t *)challenge->ptr) + challenge->len;
683 challenge_data = ((uint8_t *)challenge->ptr) + option_flags_size;
686 while (challenge_data < challenge_end) {
687 if (*challenge_data++ != 0) {
688 found_option_flags = 0;
693 found_option_flags = 0;
696 if (found_option_flags) {
697 (void)
tfm_memcpy(option_flags, challenge->ptr, option_flags_size);
700 *key_select = *option_flags & 0x7;
721 attest_create_token(
struct q_useful_buf_c *challenge,
722 struct q_useful_buf *token,
723 struct q_useful_buf_c *completed_token)
728 int32_t key_select = 0;
729 uint32_t option_flags = 0;
736 #ifdef INCLUDE_TEST_CODE
737 attest_get_option_flags(challenge, &option_flags, &key_select);
750 attest_err = error_mapping_to_psa_attest_err_t(token_err);
754 attest_err = attest_add_challenge_claim(&attest_token_ctx,
762 attest_err = attest_add_boot_seed_claim(&attest_token_ctx);
767 attest_err = attest_add_instance_id_claim(&attest_token_ctx);
772 attest_err = attest_add_implementation_id_claim(&attest_token_ctx);
777 attest_err = attest_add_caller_id_claim(&attest_token_ctx);
782 attest_err = attest_add_security_lifecycle_claim(&attest_token_ctx);
787 attest_err = attest_add_all_sw_components(&attest_token_ctx);
792 #ifdef INCLUDE_OPTIONAL_CLAIMS
794 attest_err = attest_add_verification_service(&attest_token_ctx);
799 attest_err = attest_add_profile_definition(&attest_token_ctx);
804 attest_err = attest_add_hw_version_claim(&attest_token_ctx);
816 attest_err = error_mapping_to_psa_attest_err_t(token_err);
837 struct q_useful_buf_c challenge;
838 struct q_useful_buf token;
839 struct q_useful_buf_c completed_token;
841 challenge.ptr = in_vec[0].
base;
842 challenge.len = in_vec[0].
len;
843 token.ptr = out_vec[0].
base;
844 token.len = out_vec[0].
len;
846 attest_err = attest_verify_challenge_size(challenge.len);
851 if (token.len == 0) {
856 attest_err = attest_create_token(&challenge, &token, &completed_token);
861 out_vec[0].
base = (
void *)completed_token.ptr;
862 out_vec[0].
len = completed_token.len;
865 return error_mapping_to_psa_status_t(attest_err);
873 uint32_t challenge_size = *(uint32_t *)in_vec[0].base;
874 uint32_t *token_buf_size = (uint32_t *)out_vec[0].base;
875 struct q_useful_buf_c challenge;
876 struct q_useful_buf token;
877 struct q_useful_buf_c completed_token;
880 challenge.ptr = NULL;
881 challenge.
len = challenge_size;
885 token.len = INT32_MAX;
887 if (out_vec[0].len <
sizeof(uint32_t)) {
892 attest_err = attest_verify_challenge_size(challenge_size);
897 attest_err = attest_create_token(&challenge, &token, &completed_token);
902 *token_buf_size = completed_token.len;
905 return error_mapping_to_psa_status_t(attest_err);
908 #ifdef SYMMETRIC_INITIAL_ATTESTATION
926 struct q_useful_buf key_buffer;
933 if (num_invec != 0 || num_outvec != 3) {
938 key_buffer.ptr = out_vec[0].
base;
939 key_buffer.len = out_vec[0].
len;
941 if (out_vec[1].len !=
sizeof(curve_type) ||
942 out_vec[2].
len !=
sizeof(key_len)) {
954 if (key_buffer.len < key_len) {
959 (void)
tfm_memcpy(key_buffer.ptr, key_source, key_len);
963 *(
size_t *)out_vec[2].base = key_len;
966 return error_mapping_to_psa_status_t(attest_err);
enum attest_token_err_t attest_token_encode_finish(struct attest_token_encode_ctx *me, struct q_useful_buf_c *completed_token)
Finish the token, complete the signing and get the result.
Contains the received boot status information from bootloader.
enum psa_attest_err_t attest_register_initial_attestation_key()
Register the initial attestation private key to Crypto service. Loads the public key if the key has n...
#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE
psa_status_t initial_attest_get_token_size(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get the size of the initial attestation token.
Attestation Token Creation Interface.
#define PSA_ERROR_BUFFER_TOO_SMALL
#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS
void attest_token_encode_add_bstr(struct attest_token_encode_ctx *me, int32_t label, const struct q_useful_buf_c *value)
Add a binary string claim.
struct tfm_spm_service_t service[]
psa_attest_err_t
Initial attestation service error types.
enum attest_token_err_t attest_token_encode_start(struct attest_token_encode_ctx *me, uint32_t opt_flags, int32_t key_select, int32_t cose_alg_id, const struct q_useful_buf *out_buffer)
Initialize a token creation context.
enum psa_attest_err_t attest_unregister_initial_attestation_key()
Unregister the initial attestation private key from Crypto service to do not occupy key slot...
#define SHARED_DATA_ENTRY_HEADER_SIZE
void attest_token_encode_add_integer(struct attest_token_encode_ctx *me, int32_t label, int64_t value)
Add a 64-bit signed integer claim.
psa_status_t initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get the initial attestation public key.
#define NO_SW_COMPONENT_FIXED_VALUE
enum psa_attest_err_t attest_get_initial_attestation_public_key(uint8_t **public_key, size_t *public_key_len, psa_ecc_family_t *public_key_curve)
Get the public key derived from the initial attestation private key.
#define SHARED_DATA_TLV_INFO_MAGIC
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48
#define TOKEN_OPT_OMIT_CLAIMS
#define EAT_CBOR_ARM_LABEL_UEID
enum psa_attest_err_t attest_get_boot_data(uint8_t major_type, struct tfm_boot_data *boot_data, uint32_t len)
Copy the boot data (coming from boot loader) from shared memory area to service memory area...
struct shared_data_tlv_header header
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64
#define PSA_ERROR_GENERIC_ERROR
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32
#define PSA_ERROR_INVALID_ARGUMENT
void attest_token_encode_add_tstr(struct attest_token_encode_ctx *me, int32_t label, const struct q_useful_buf_c *value)
Add a text string claim.
#define EAT_CBOR_ARM_LABEL_CLIENT_ID
#define GET_IAS_MODULE(tlv_type)
Store the data for the runtime SW.
#define EAT_CBOR_ARM_LABEL_ORIGINATION
#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS
#define SECURITY_LIFECYCLE
#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID
enum psa_attest_err_t attest_get_caller_client_id(int32_t *caller_id)
Get the ID of the caller thread.
QCBOREncodeContext * attest_token_encode_borrow_cbor_cntxt(struct attest_token_encode_ctx *me)
Get a copy of the CBOR encoding context.
#define PSA_ERROR_NOT_SUPPORTED
__STATIC_INLINE void * tfm_memcpy(void *dest, const void *src, size_t num)
enum psa_attest_err_t attest_get_instance_id(struct q_useful_buf_c *id_buf)
Get the buffer of Instance ID data.
psa_status_t initial_attest_get_token(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get initial attestation token.
psa_status_t attest_init(void)
Initialise the initial attestation service during the TF-M boot up process.
#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION
int32_t psa_status_t
Function return status.
#define EAT_CBOR_ARM_LABEL_HW_VERSION
#define EAT_CBOR_ARM_LABEL_CHALLENGE
#define PSA_ERROR_SERVICE_FAILURE
#define GET_IAS_CLAIM(tlv_type)
#define EAT_CBOR_ARM_LABEL_BOOT_SEED