Skip to content
Merged
2 changes: 1 addition & 1 deletion platform/ext/accelerator/cc312/otp_cc312.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ __PACKED_STRUCT plat_otp_layout_t {
uint8_t implementation_id[32];
uint8_t cert_ref[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];

uint8_t bl2_rotpk[MAX_IMAGE_NUM][PROV_ROTPK_DATA_SIZE];
uint8_t bl2_nv_counter[4][64];
Expand Down
2 changes: 1 addition & 1 deletion platform/ext/common/provisioning.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ __PACKED_STRUCT tfm_psa_rot_provisioning_data_t {
uint8_t implementation_id[32];
uint8_t cert_ref[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];

uint8_t entropy_seed[64];
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ __PACKED_STRUCT tfm_psa_rot_provisioning_data_t {
uint8_t implementation_id[32];
uint8_t cert_ref[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];

uint8_t entropy_seed[64];
};
Expand Down
27 changes: 9 additions & 18 deletions platform/ext/common/template/attest_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,18 @@ tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf)
return TFM_PLAT_ERR_SUCCESS;
}

enum tfm_plat_err_t
tfm_attest_hal_get_profile_definition(uint32_t *size, uint8_t *buf)
// cppcheck-suppress constParameter
enum tfm_plat_err_t tfm_attest_hal_get_profile_definition(uint32_t *size, uint8_t *buf)
{
enum tfm_plat_err_t err;
size_t otp_size;
size_t copy_size;

err = tfm_plat_otp_read(PLAT_OTP_ID_PROFILE_DEFINITION, *size, buf);
if(err != TFM_PLAT_ERR_SUCCESS) {
return err;
}

err = tfm_plat_otp_get_size(PLAT_OTP_ID_PROFILE_DEFINITION, &otp_size);
if(err != TFM_PLAT_ERR_SUCCESS) {
return err;
/* The templated implementation does not return the profile_definition
* from the OTP but it leaves to the Attestation service to determine
* it using build options directly in this case
*/
if (size == NULL || buf == NULL) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}

/* Actually copied data is always the smaller */
copy_size = (*size < otp_size) ? *size : otp_size;
/* String content */
*size = tfm_strnlen((char*)buf, copy_size);
*size = 0;

return TFM_PLAT_ERR_SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ __PACKED_STRUCT flash_otp_nv_counters_region_t {
uint8_t implementation_id[32];
uint8_t cert_ref[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];

#ifdef BL2
uint8_t bl2_rotpk_0[BL2_ROTPK_SIZE];
Expand Down
19 changes: 3 additions & 16 deletions platform/ext/target/arm/mps4/common/attest_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,11 @@ tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf)
enum tfm_plat_err_t
tfm_attest_hal_get_profile_definition(uint32_t *size, uint8_t *buf)
{
enum tfm_plat_err_t err;
size_t otp_size;
size_t copy_size;

err = tfm_plat_otp_read(PLAT_OTP_ID_PROFILE_DEFINITION, *size, buf);
if(err != TFM_PLAT_ERR_SUCCESS) {
return err;
}

err = tfm_plat_otp_get_size(PLAT_OTP_ID_PROFILE_DEFINITION, &otp_size);
if(err != TFM_PLAT_ERR_SUCCESS) {
return err;
if (size == NULL || buf == NULL) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}

/* Actually copied data is always the smaller */
copy_size = *size < otp_size ? *size : otp_size;
/* String content */
*size = tfm_strnlen((char*)buf, copy_size);
*size = 0;

return TFM_PLAT_ERR_SUCCESS;
}
Expand Down
2 changes: 1 addition & 1 deletion platform/ext/target/arm/mps4/common/otp_lcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ __PACKED_STRUCT plat_user_area_layout_t {
uint32_t iak_id[8];
uint32_t implementation_id[8];
uint32_t verification_service_url[8];
uint32_t profile_definition[12];
uint32_t profile_definition[8];

uint32_t secure_debug_pk[8];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct __attribute__((__packed__)) dm_provisioning_bundle {

uint8_t implementation_id[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];
uint8_t secure_debug_pk[32];
uint8_t boot_seed[32];
uint8_t cert_ref[32];
Expand Down
16 changes: 2 additions & 14 deletions platform/ext/target/arm/rse/common/attest_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,11 @@ tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf)
enum tfm_plat_err_t
tfm_attest_hal_get_profile_definition(uint32_t *size, uint8_t *buf)
{
#if ATTEST_TOKEN_PROFILE_ARM_CCA
const char profile [] = "tag:arm.com,2023:cca_platform#1.0.0";
#elif ATTEST_TOKEN_PROFILE_PSA_2_0_0
const char profile [] = "tag:psacertified.org,2023:psa#tfm";
#else
#ifdef TFM_PARTITION_INITIAL_ATTESTATION
#error "Attestation token profile is incorrect"
#endif
#endif

if (*size < sizeof(profile) - 1) {
if (size == NULL || buf == NULL) {
return TFM_PLAT_ERR_SYSTEM_ERR;
}

/* Not including the null-terminator. */
memcpy(buf, profile, sizeof(profile) - 1);
*size = sizeof(profile) - 1;
*size = 0;

return TFM_PLAT_ERR_SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023-2024, Arm Limited. All rights reserved.
* Copyright (c) 2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
Expand Down Expand Up @@ -34,7 +34,7 @@ __PACKED_STRUCT tfm_psa_rot_provisioning_data_t {
uint8_t implementation_id[32];
uint8_t cert_ref[32];
uint8_t verification_service_url[32];
uint8_t profile_definition[48];
uint8_t profile_definition[32];

uint8_t entropy_seed[64];
};
Expand Down
15 changes: 14 additions & 1 deletion platform/include/tfm_attest_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ enum tfm_security_lifecycle_t {
/**
* \def PROFILE_DEFINITION_MAX_SIZE
*
* \brief Maximum size of profile definition in bytes
* \brief Maximum size of profile definition in bytes. Note that the OTP
* layout might only store a reduced representation of the actual
* profile string that needs to be translated by interrogating the
* HAL of platform before generating the token
*/
#define PROFILE_DEFINITION_MAX_SIZE (48u)

Expand Down Expand Up @@ -88,6 +91,16 @@ tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf);
* \brief Retrieve the name of the profile definition document for initial
* attestation.
*
* \note It is allowed for this function to return an empty string, i.e.
* with the value of \p size equal to 0. In this case the Attestation
* service will determine the profile_definition string directly from
* the build options
*
* \note The profile_definition in OTP may contain either the full string
* associated with the profile or a reduced representation of it.
* The HAL function must be able to handle both cases and return the
* correct string, translating the reduced representation if necessary.
*
* This document describes the 'profile' of the initial attestation token,
* being a full description of the claims, their usage, verification and
* token signing.
Expand Down
35 changes: 31 additions & 4 deletions secure_fw/partitions/initial_attestation/attest_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@

#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))

#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))

#if ATTEST_TOKEN_PROFILE_PSA_IOT_1
#define ATTEST_TOKEN_PROFILE_DEFINITION_STRING "PSA_IOT_PROFILE_1"
#elif ATTEST_TOKEN_PROFILE_ARM_CCA
#define ATTEST_TOKEN_PROFILE_DEFINITION_STRING "tag:arm.com,2023:cca_platform#1.0.0"
#elif ATTEST_TOKEN_PROFILE_PSA_2_0_0
#define ATTEST_TOKEN_PROFILE_DEFINITION_STRING "tag:psacertified.org,2023:psa#tfm"
#else
#error "Attestation token profile is incorrect"
#endif

/*!
* \brief Static function to map return values between \ref psa_attest_err_t
* and \ref psa_status_t
Expand Down Expand Up @@ -234,18 +246,33 @@ attest_add_security_lifecycle_claim(struct attest_token_encode_ctx *token_ctx)
static enum psa_attest_err_t
attest_add_profile_definition(struct attest_token_encode_ctx *token_ctx)
{
static const char profile_definition[] = ATTEST_TOKEN_PROFILE_DEFINITION_STRING;
struct q_useful_buf_c profile;
uint8_t buf[PROFILE_DEFINITION_MAX_SIZE];
uint32_t size = sizeof(buf);
/* Make sure we pass a word aligned buffer as platforms might
* access OTP which has alignment requirements
*/
uint32_t buf[ALIGN_UP(PROFILE_DEFINITION_MAX_SIZE + 1, sizeof(uint32_t)) / sizeof(uint32_t)] = {0};
uint32_t size = sizeof(buf) - 1;
enum tfm_plat_err_t err;

err = tfm_attest_hal_get_profile_definition(&size, buf);
err = tfm_attest_hal_get_profile_definition(&size, (uint8_t *)buf);
if (err != TFM_PLAT_ERR_SUCCESS) {
return PSA_ATTEST_ERR_GENERAL;
}

profile.ptr = &buf;
profile.ptr = buf;
profile.len = size;

/* Check for mismatches between the value returned by HAL and Build options */
if (size == 0) {
LOG_INFFMT("[Attest] The platform did not return a profile_definition\r\n");
profile.ptr = profile_definition;
profile.len = sizeof(profile_definition) - 1;
} else if (size != (sizeof(profile_definition) - 1) || strncmp(profile_definition, (const char *)buf, size)) {
LOG_ERRFMT("[Attest] Using a mismatched profile_definition received from the HAL\r\n");
}

LOG_INFFMT("[Attest] Encoding profile_definition (size: %d): %s\r\n", profile.len, profile.ptr);
attest_token_encode_add_tstr(token_ctx,
IAT_PROFILE_DEFINITION,
&profile);
Expand Down