Merge changes from topic "DPE" into integration

* changes:
  feat(tc): group components into certificates
  feat(dice): add cert_id argument to dpe_derive_context()
  refactor(sds): modify log level for region validity
  feat(tc): add dummy TRNG support to be able to boot pVMs
  feat(tc): get the parent component provided DPE context_handle
  feat(tc): share DPE context handle with child component
  feat(tc): add DPE context handle node to device tree
  feat(tc): add DPE backend to the measured boot framework
  feat(auth): add explicit entries for key OIDs
  feat(dice): add DPE driver to measured boot
  feat(dice): add client API for DICE Protection Environment
  feat(dice): add QCBOR library as a dependency of DPE
  feat(dice): add typedefs from the Open DICE repo
  docs(changelog): add 'dice' scope
  refactor(tc): align image identifier string macros
  refactor(fvp): align image identifier string macros
  refactor(imx8m): align image identifier string macros
  refactor(qemu): align image identifier string macros
  fix(measured-boot): add missing image identifier string
  refactor(measured-boot): move metadata size macros to a common header
  refactor(measured-boot): move image identifier strings to a common header
This commit is contained in:
Manish V Badarkhe 2024-03-07 21:41:23 +01:00 committed by TrustedFirmware Code Review
commit e7d14fa83f
45 changed files with 2050 additions and 159 deletions

View file

@ -1145,6 +1145,7 @@ $(eval $(call assert_booleans,\
HARDEN_SLS \
HW_ASSISTED_COHERENCY \
MEASURED_BOOT \
DICE_PROTECTION_ENVIRONMENT \
DRTM_SUPPORT \
NS_TIMER_SWITCH \
OVERRIDE_LIBC \
@ -1312,6 +1313,7 @@ $(eval $(call add_defines,\
HW_ASSISTED_COHERENCY \
LOG_LEVEL \
MEASURED_BOOT \
DICE_PROTECTION_ENVIRONMENT \
DRTM_SUPPORT \
NS_TIMER_SWITCH \
PL011_GENERIC_UART \

View file

@ -804,6 +804,9 @@ subsections:
deprecated:
- lib/psa
- title: DICE Protection Environment
scope: dice
- title: Context Management
scope: context-mgmt

View file

@ -706,6 +706,13 @@ Common build options
This option defaults to 0.
- ``DICE_PROTECTION_ENVIRONMENT``: Boolean flag to specify the measured boot
backend when ``MEASURED_BOOT`` is enabled. The default value is ``0``. When
set to ``1`` then measurements and additional metadata collected during the
measured boot process are sent to the DICE Protection Environment for storage
and processing. A certificate chain, which represents the boot state of the
device, can be queried from the DPE.
- ``MARCH_DIRECTIVE``: used to pass a -march option from the platform build
options to the compiler. An example usage:

View file

@ -79,6 +79,10 @@ support:
- mbed TLS == 3.4.1 (tag: ``mbedtls-3.4.1``)
The following libraries are required for DICE Protection Environment support:
- QCBOR == 1.2 (tag: ``v1.2``)
These tools are optional:
- Device Tree Compiler (DTC) >= 1.4.7
@ -184,7 +188,7 @@ documentation, available `here <https://git-scm.com/docs/githooks>`_.
--------------
*Copyright (c) 2021-2023, Arm Limited. All rights reserved.*
*Copyright (c) 2021-2024, Arm Limited. All rights reserved.*
.. _Arm Developer website: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads
.. _Gerrit Code Review: https://www.gerritcodereview.com/

View file

@ -40,6 +40,9 @@ You can find additional definitions in the `Arm Glossary`_.
Common Vulnerabilities and Exposures. A CVE document is commonly used to
describe a publicly-known security vulnerability.
DICE
Device Identifier Composition Engine
DCE
DRTM Configuration Environment
@ -52,6 +55,9 @@ You can find additional definitions in the `Arm Glossary`_.
DRTM
Dynamic Root of Trust for Measurement
DPE
DICE Protection Environment
DS-5
Arm Development Studio 5

View file

@ -85,6 +85,17 @@ license text is included in those source files.
See the original `Linux MIT license`_.
- Some source files originating from the `Open Profile for DICE`_ project.
These files are licensed under the Apache License, Version 2.0, which is a
permissive license compatible with BSD-3-Clause. Any contributions to this
code must also be made under the terms of `Apache License 2.0`_.
These files are:
- ``include/lib/dice/dice.h``
.. _FreeBSD: http://www.freebsd.org
.. _Linux MIT license: https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/MIT
.. _SCC: http://www.simple-cc.org/
.. _Open Profile for DICE: https://pigweed.googlesource.com/open-dice/
.. _Apache License 2.0: https://www.apache.org/licenses/LICENSE-2.0.txt

View file

@ -250,7 +250,7 @@ int sds_init(unsigned int region_id)
uintptr_t sds_mem_base = sds_regions[region_id].base;
if (!IS_SDS_REGION_VALID(sds_mem_base)) {
WARN("SDS: No valid SDS Memory Region found\n");
VERBOSE("SDS: No valid SDS Memory Region found\n");
return SDS_ERR_FAIL;
}

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <psa/crypto_types.h>
#include <psa/crypto_values.h>
#include <common/debug.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/measured_boot/rss/dice_prot_env.h>
#include <lib/cassert.h>
#include <lib/psa/dice_protection_environment.h>
#include <platform_def.h>
#define DPE_ALG_SHA512 0
#define DPE_ALG_SHA384 1
#define DPE_ALG_SHA256 2
#if DPE_ALG_ID == DPE_ALG_SHA512
#define CRYPTO_MD_ID CRYPTO_MD_SHA512
#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512
#elif DPE_ALG_ID == DPE_ALG_SHA384
#define CRYPTO_MD_ID CRYPTO_MD_SHA384
#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384
#elif DPE_ALG_ID == DPE_ALG_SHA256
#define CRYPTO_MD_ID CRYPTO_MD_SHA256
#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256
#else
# error Invalid DPE hash algorithm.
#endif /* DPE_ALG_ID */
/* Ensure that computed hash values fits into the DiceInputValues structure */
CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
assert_digest_size_bigger_than_allocated_buffer);
static int initial_context_handle;
static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
DiceInputValues *dice_inputs)
{
/* Hash of the content certificate signing key (public part) */
memcpy(dice_inputs->authority_hash, metadata->signer_id,
DPE_DIGEST_SIZE);
/* SW type string identifier */
assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
dice_inputs->code_descriptor = metadata->sw_type;
dice_inputs->code_descriptor_size = metadata->sw_type_size;
}
void dpe_init(struct dpe_metadata *metadata)
{
assert(metadata != NULL);
/* Init the non-const members of the metadata structure */
while (metadata->id != DPE_INVALID_ID) {
/* Terminating 0 character is not needed due to CBOR encoding */
metadata->sw_type_size =
strlen((const char *)&metadata->sw_type);
metadata++;
}
plat_dpe_get_context_handle(&initial_context_handle);
}
int dpe_measure_and_record(struct dpe_metadata *metadata,
uintptr_t data_base, uint32_t data_size,
uint32_t data_id)
{
static int current_context_handle;
DiceInputValues dice_inputs = { 0 };
int new_parent_context_handle;
int new_context_handle;
dpe_error_t ret;
int rc;
assert(metadata != NULL);
/* Get the metadata associated with this image. */
while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
metadata++;
}
/* If image is not present in metadata array then skip */
if (metadata->id == DPE_INVALID_ID) {
return 0;
}
/* Calculate hash */
rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
(void *)data_base, data_size,
dice_inputs.code_hash);
if (rc != 0) {
return rc;
}
map_metadata_to_dice_inputs(metadata, &dice_inputs);
/* Only at the first call */
if (current_context_handle == 0) {
current_context_handle = initial_context_handle;
}
VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
ret = dpe_derive_context(current_context_handle,
metadata->cert_id,
metadata->retain_parent_context,
metadata->allow_new_context_to_derive,
metadata->create_certificate,
&dice_inputs,
0, /* target_locality */
false, /* return_certificate */
true, /* allow_new_context_to_export */
false, /* export_cdi */
&new_context_handle,
&new_parent_context_handle,
NULL, 0, NULL, /* new_certificate_* */
NULL, 0, NULL); /* exported_cdi_* */
if (ret == DPE_NO_ERROR) {
current_context_handle = new_parent_context_handle;
if (metadata->allow_new_context_to_derive == true) {
/* Share new_context_handle with child component:
* e.g: BL2, BL33.
*/
VERBOSE("Share new_context_handle with child: 0x%x\n",
new_context_handle);
plat_dpe_share_context_handle(&new_context_handle);
}
} else {
ERROR("dpe_derive_context failed: %d\n", ret);
}
return (ret == DPE_NO_ERROR) ? 0 : -1;
}
int dpe_set_signer_id(struct dpe_metadata *metadata,
const void *pk_oid,
const void *pk_ptr,
size_t pk_len)
{
unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
int rc;
bool hash_calc_done = false;
assert(metadata != NULL);
/*
* Do an exhaustive search over the platform metadata to find
* all images whose key OID matches the one passed in argument.
*
* Note that it is not an error if do not get any matches.
* The platform may decide not to measure all of the images
* in the system.
*/
while (metadata->id != DPE_INVALID_ID) {
/* Get the metadata associated with this key-oid */
if (metadata->pk_oid == pk_oid) {
if (hash_calc_done == false) {
/* Calculate public key hash */
rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
(void *)pk_ptr,
pk_len, hash_data);
if (rc != 0) {
return rc;
}
hash_calc_done = true;
}
/*
* Fill the signer-ID field with the newly/already
* computed hash of the public key and update its
* signer ID size field with compile-time decided
* digest size.
*/
(void)memcpy(metadata->signer_id,
hash_data,
DPE_DIGEST_SIZE);
metadata->signer_id_size = DPE_DIGEST_SIZE;
}
metadata++;
}
return 0;
}

View file

@ -0,0 +1,29 @@
#
# Copyright (c) 2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# Hash algorithm for DICE Protection Environment
# SHA-256 (or stronger) is required.
DPE_HASH_ALG := sha256
ifeq (${DPE_HASH_ALG}, sha512)
DPE_ALG_ID := DPE_ALG_SHA512
DPE_DIGEST_SIZE := 64U
else ifeq (${DPE_HASH_ALG}, sha384)
DPE_ALG_ID := DPE_ALG_SHA384
DPE_DIGEST_SIZE := 48U
else
DPE_ALG_ID := DPE_ALG_SHA256
DPE_DIGEST_SIZE := 32U
endif #DPE_HASH_ALG
# Set definitions for DICE Protection Environment
$(eval $(call add_defines,\
$(sort \
DPE_ALG_ID \
DPE_DIGEST_SIZE \
)))
DPE_SOURCES += drivers/measured_boot/rss/dice_prot_env.c

View file

@ -0,0 +1,23 @@
#
# Copyright (c) 2024, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# TF-A was tested with v1.2 version of QCBOR
ifeq (${QCBOR_DIR},)
$(error Error: QCBOR_DIR not set)
endif
QCBOR_SOURCES += ${QCBOR_DIR}/src/qcbor_encode.c \
${QCBOR_DIR}/src/qcbor_decode.c \
${QCBOR_DIR}/src/UsefulBuf.c
QCBOR_INCLUDES += ${QCBOR_DIR}/inc
# Floating point numbers are not used, so disable the support.
# This reduces the library size as well.
$(eval $(call add_define,QCBOR_DISABLE_FLOAT_HW_USE))
$(eval $(call add_define,USEFULBUF_DISABLE_ALL_FLOAT))
$(eval $(call add_define,QCBOR_DISABLE_PREFERRED_FLOAT))

View file

@ -128,7 +128,7 @@ int rss_mboot_set_signer_id(struct rss_mboot_metadata *metadata_ptr,
while (metadata_ptr->id != RSS_MBOOT_INVALID_ID) {
/* Get the metadata associated with this key-oid */
if (metadata_ptr->pk_oid == pk_oid) {
if (!hash_calc_done) {
if (hash_calc_done == false) {
/* Calculate public key hash */
rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
(void *)pk_ptr,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2022, Arm Limited. All rights reserved.
* Copyright (c) 2020-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -43,51 +43,6 @@
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
/*
* Each event log entry has some metadata (i.e. a string) that identifies
* what is measured.These macros define these strings.
* Note that these strings follow the standardization recommendations
* defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
* where applicable. They should not be changed in the code.
* Where the SBSG does not make recommendations, we are free to choose any
* naming convention.
* The key thing is to choose meaningful strings so that when the TPM event
* log is used in attestation, the different components can be identified.
*/
#define EVLOG_BL2_STRING "BL_2"
#define EVLOG_BL31_STRING "SECURE_RT_EL3"
#if defined(SPD_opteed)
#define EVLOG_BL32_STRING "SECURE_RT_EL1_OPTEE"
#elif defined(SPD_tspd)
#define EVLOG_BL32_STRING "SECURE_RT_EL1_TSPD"
#elif defined(SPD_tlkd)
#define EVLOG_BL32_STRING "SECURE_RT_EL1_TLKD"
#elif defined(SPD_trusty)
#define EVLOG_BL32_STRING "SECURE_RT_EL1_TRUSTY"
#else
#define EVLOG_BL32_STRING "SECURE_RT_EL1_UNKNOWN"
#endif
#define EVLOG_BL32_EXTRA1_STRING "SECURE_RT_EL1_OPTEE_EXTRA1"
#define EVLOG_BL32_EXTRA2_STRING "SECURE_RT_EL1_OPTEE_EXTRA2"
#define EVLOG_BL33_STRING "BL_33"
#define EVLOG_FW_CONFIG_STRING "FW_CONFIG"
#define EVLOG_HW_CONFIG_STRING "HW_CONFIG"
#define EVLOG_NT_FW_CONFIG_STRING "NT_FW_CONFIG"
#define EVLOG_SCP_BL2_STRING "SYS_CTRL_2"
#define EVLOG_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG"
#define EVLOG_STM32_STRING "STM32"
#define EVLOG_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
#define EVLOG_TOS_FW_CONFIG_STRING "TOS_FW_CONFIG"
#define EVLOG_RMM_STRING "RMM"
#define EVLOG_SP1_STRING "SP1"
#define EVLOG_SP2_STRING "SP2"
#define EVLOG_SP3_STRING "SP3"
#define EVLOG_SP4_STRING "SP4"
#define EVLOG_SP5_STRING "SP5"
#define EVLOG_SP6_STRING "SP6"
#define EVLOG_SP7_STRING "SP7"
#define EVLOG_SP8_STRING "SP8"
typedef struct {
unsigned int id;
const char *name;

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef METADATA_H
#define METADATA_H
/* Minimum measurement value size that can be requested to store */
#define MEASUREMENT_VALUE_MIN_SIZE 32U
/* Maximum measurement value size that can be requested to store */
#define MEASUREMENT_VALUE_MAX_SIZE 64U
/* Minimum signer id size that can be requested to store */
#define SIGNER_ID_MIN_SIZE MEASUREMENT_VALUE_MIN_SIZE
/* Maximum signer id size that can be requested to store */
#define SIGNER_ID_MAX_SIZE MEASUREMENT_VALUE_MAX_SIZE
/* The theoretical maximum image version is: "255.255.65535\0" */
#define VERSION_MAX_SIZE 14U
/* Example sw_type: "BL_2, BL_33, etc." */
#define SW_TYPE_MAX_SIZE 32U
/*
* Images, measured during the boot process, have some associated metadata.
* One of these types of metadata is the image identifier strings. These macros
* define these strings. They are used across the different measured boot
* backends.
* Note that these strings follow the standardization recommendations
* defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086),
* where applicable. They should not be changed in the code.
* Where the SBSG does not make recommendations, we are free to choose any
* naming convention.
* The key thing is to choose meaningful strings so that when the measured boot
* metadata is used in attestation, the different components can be identified.
*/
#define MBOOT_BL2_IMAGE_STRING "BL_2"
#define MBOOT_BL31_IMAGE_STRING "SECURE_RT_EL3"
#if defined(SPD_opteed)
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_OPTEE"
#elif defined(SPD_tspd)
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_TSPD"
#elif defined(SPD_tlkd)
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_TLKD"
#elif defined(SPD_trusty)
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_TRUSTY"
#elif defined(SPD_spmd)
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_SPMD"
#else
#define MBOOT_BL32_IMAGE_STRING "SECURE_RT_EL1_UNKNOWN"
#endif /* SPD_opteed */
#define MBOOT_BL32_EXTRA1_IMAGE_STRING "SECURE_RT_EL1_OPTEE_EXTRA1"
#define MBOOT_BL32_EXTRA2_IMAGE_STRING "SECURE_RT_EL1_OPTEE_EXTRA2"
#define MBOOT_BL33_IMAGE_STRING "BL_33"
#define MBOOT_FW_CONFIG_STRING "FW_CONFIG"
#define MBOOT_HW_CONFIG_STRING "HW_CONFIG"
#define MBOOT_NT_FW_CONFIG_STRING "NT_FW_CONFIG"
#define MBOOT_SCP_BL2_IMAGE_STRING "SYS_CTRL_2"
#define MBOOT_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG"
#define MBOOT_STM32_STRING "STM32"
#define MBOOT_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
#define MBOOT_TOS_FW_CONFIG_STRING "TOS_FW_CONFIG"
#define MBOOT_RMM_IMAGE_STRING "RMM"
#define MBOOT_SP1_STRING "SP1"
#define MBOOT_SP2_STRING "SP2"
#define MBOOT_SP3_STRING "SP3"
#define MBOOT_SP4_STRING "SP4"
#define MBOOT_SP5_STRING "SP5"
#define MBOOT_SP6_STRING "SP6"
#define MBOOT_SP7_STRING "SP7"
#define MBOOT_SP8_STRING "SP8"
#endif /* METADATA_H */

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef DICE_PROT_ENV_H
#define DICE_PROT_ENV_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <drivers/measured_boot/metadata.h>
#define DPE_INVALID_ID UINT32_MAX
struct dpe_metadata {
unsigned int id;
uint32_t cert_id;
uint8_t signer_id[SIGNER_ID_MAX_SIZE];
size_t signer_id_size;
uint8_t version[VERSION_MAX_SIZE];
size_t version_size;
uint8_t sw_type[SW_TYPE_MAX_SIZE];
size_t sw_type_size;
bool allow_new_context_to_derive;
bool retain_parent_context;
bool create_certificate;
void *pk_oid;
};
void dpe_init(struct dpe_metadata *metadata);
/* Returns 0 in case of success otherwise -1. */
int dpe_measure_and_record(struct dpe_metadata *metadata,
uintptr_t data_base, uint32_t data_size,
uint32_t data_id);
int dpe_set_signer_id(struct dpe_metadata *metadata,
const void *pk_oid, const void *pk_ptr, size_t pk_len);
/* Child components inherit their first valid context handle from their parents.
* How to share context handle is platform specific.
*/
void plat_dpe_share_context_handle(int *ctx_handle);
void plat_dpe_get_context_handle(int *ctx_handle);
#endif /* DICE_PROT_ENV_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -10,27 +10,10 @@
#include <stdint.h>
#include <common/debug.h>
#include <measured_boot.h>
#include <drivers/measured_boot/metadata.h>
#define RSS_MBOOT_INVALID_ID UINT32_MAX
/*
* Each boot measurement has some metadata (i.e. a string) that identifies
* what was measured and how. The sw_type field of the rss_mboot_metadata
* structure represents the role of the software component that was measured.
* The below macros define strings suitable for the sw_type.
* The key thing is to choose meaningful strings so that when the attestation
* token is verified, then the different components can be identified.
*/
#define RSS_MBOOT_BL2_STRING "BL_2"
#define RSS_MBOOT_BL31_STRING "SECURE_RT_EL3"
#define RSS_MBOOT_HW_CONFIG_STRING "HW_CONFIG"
#define RSS_MBOOT_FW_CONFIG_STRING "FW_CONFIG"
#define RSS_MBOOT_TB_FW_CONFIG_STRING "TB_FW_CONFIG"
#define RSS_MBOOT_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG"
#define RSS_MBOOT_RMM_STRING "RMM"
struct rss_mboot_metadata {
unsigned int id;
uint8_t slot;

166
include/lib/dice/dice.h Normal file
View file

@ -0,0 +1,166 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef DICE_DICE_H_
#define DICE_DICE_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DICE_CDI_SIZE 32
#define DICE_HASH_SIZE 64
#define DICE_HIDDEN_SIZE 64
#define DICE_INLINE_CONFIG_SIZE 64
#define DICE_PRIVATE_KEY_SEED_SIZE 32
#define DICE_ID_SIZE 20
typedef enum {
kDiceResultOk,
kDiceResultInvalidInput,
kDiceResultBufferTooSmall,
kDiceResultPlatformError,
} DiceResult;
typedef enum {
kDiceModeNotInitialized,
kDiceModeNormal,
kDiceModeDebug,
kDiceModeMaintenance,
} DiceMode;
typedef enum {
kDiceConfigTypeInline,
kDiceConfigTypeDescriptor,
} DiceConfigType;
// Contains a full set of input values describing the target program or system.
// See the Open Profile for DICE specification for a detailed explanation of
// these inputs.
//
// Fields:
// code_hash: A hash or similar representation of the target code.
// code_descriptor: An optional descriptor to be included in the certificate.
// This descriptor is opaque to the DICE flow and is included verbatim
// in the certificate with no validation. May be null.
// code_descriptor_size: The size in bytes of |code_descriptor|.
// config_type: Indicates how to interpret the remaining config-related
// fields. If the type is 'inline', then the 64 byte configuration input
// value must be provided in |config_value| and |config_descriptor| is
// ignored. If the type is 'descriptor', then |config_descriptor| is
// hashed to get the configuration input value and |config_value| is
// ignored.
// config_value: A 64-byte configuration input value when |config_type| is
// kDiceConfigTypeInline. Otherwise, this field is ignored.
// config_descriptor: A descriptor to be hashed for the configuration input
// value when |config_type| is kDiceConfigTypeDescriptor. Otherwise,
// this field is ignored and may be null.
// config_descriptor_size: The size in bytes of |config_descriptor|.
// authority_hash: A hash or similar representation of the authority used to
// verify the target code. If the code is not verified or the authority
// is implicit, for example hard coded as part of the code currently
// executing, then this value should be set to all zero bytes.
// authority_descriptor: An optional descriptor to be included in the
// certificate. This descriptor is opaque to the DICE flow and is
// included verbatim in the certificate with no validation. May be null.
// authority_descriptor_size: The size in bytes of |authority_descriptor|.
// mode: The current operating mode.
// hidden: Additional input which will not appear in certificates. If this is
// not used it should be set to all zero bytes.
typedef struct DiceInputValues_ {
uint8_t code_hash[DICE_HASH_SIZE];
const uint8_t* code_descriptor;
size_t code_descriptor_size;
DiceConfigType config_type;
uint8_t config_value[DICE_INLINE_CONFIG_SIZE];
const uint8_t* config_descriptor;
size_t config_descriptor_size;
uint8_t authority_hash[DICE_HASH_SIZE];
const uint8_t* authority_descriptor;
size_t authority_descriptor_size;
DiceMode mode;
uint8_t hidden[DICE_HIDDEN_SIZE];
} DiceInputValues;
// Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success
// populates |cdi_private_key_seed| and returns kDiceResultOk.
DiceResult DiceDeriveCdiPrivateKeySeed(
void* context, const uint8_t cdi_attest[DICE_CDI_SIZE],
uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]);
// Derives an |id| from a |cdi_public_key| value. Because public keys can vary
// in length depending on the algorithm, the |cdi_public_key_size| in bytes must
// be provided. When interpreted as an integer, |id| is big-endian. On success
// populates |id| and returns kDiceResultOk.
DiceResult DiceDeriveCdiCertificateId(void* context,
const uint8_t* cdi_public_key,
size_t cdi_public_key_size,
uint8_t id[DICE_ID_SIZE]);
// Executes the main DICE flow.
//
// Given a full set of input values and the current CDI values, computes the
// next CDI values and a matching certificate. See the Open Profile for DICE
// specification for a detailed explanation of this flow.
// In certain cases, the caller may not need to generate the CDI certificate.
// The caller should signal this by setting the certificate parameters to
// null/zero values appropriately.
//
// Parameters:
// context: Context provided by the caller that is opaque to this library
// but is passed through to the integration-provided operations in
// dice/ops.h. The value is, therefore, integration-specific and may be
// null.
// current_cdi_attest, current_cdi_seal: The current CDI values as produced
// by a previous DICE flow. If this is the first DICE flow in a system,
// the Unique Device Secret (UDS) should be used for both of these
// arguments.
// input_values: A set of input values describing the target program or
// system.
// next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed
// to by the |next_cdi_certificate| argument. This should be set to zero
// if next CDI certificate should not be computed.
// next_cdi_certificate: On success, will be populated with the generated
// certificate, up to |next_cdi_certificate_buffer_size| in size. If the
// certificate cannot fit in the buffer, |next_cdi_certificate_size| is
// populated with the required size and kDiceResultBufferTooSmall is
// returned. This should be set to NULL if next CDI certificate should
// not be computed.
// next_cdi_certificate_actual_size: On success, will be populated with the
// size, in bytes, of the certificate data written to
// |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will
// be populated with the required buffer size. This should be set to NULL
// if next CDI certificate should not be computed.
// next_cdi_attest: On success, will be populated with the next CDI value for
// attestation.
// next_cdi_seal: On success, will be populated with the next CDI value for
// sealing.
DiceResult DiceMainFlow(void* context,
const uint8_t current_cdi_attest[DICE_CDI_SIZE],
const uint8_t current_cdi_seal[DICE_CDI_SIZE],
const DiceInputValues* input_values,
size_t next_cdi_certificate_buffer_size,
uint8_t* next_cdi_certificate,
size_t* next_cdi_certificate_actual_size,
uint8_t next_cdi_attest[DICE_CDI_SIZE],
uint8_t next_cdi_seal[DICE_CDI_SIZE]);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // DICE_DICE_H_

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef DICE_PROTECTION_ENVIRONMENT_H
#define DICE_PROTECTION_ENVIRONMENT_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <dice.h>
/* Additional defines for max size limit. These limits are set by DPE in RSS. */
#define DICE_AUTHORITY_DESCRIPTOR_MAX_SIZE 64
#define DICE_CONFIG_DESCRIPTOR_MAX_SIZE 64
#define DICE_CODE_DESCRIPTOR_MAX_SIZE 32
typedef int32_t dpe_error_t;
#define DPE_NO_ERROR ((dpe_error_t)0)
#define DPE_INTERNAL_ERROR ((dpe_error_t)1)
#define DPE_INVALID_COMMAND ((dpe_error_t)2)
#define DPE_INVALID_ARGUMENT ((dpe_error_t)3)
#define DPE_ARGUMENT_NOT_SUPPORTED ((dpe_error_t)4)
#define DPE_SESSION_EXHAUSTED ((dpe_error_t)5)
/* Custom values in RSS based DPE implementation */
#define DPE_INSUFFICIENT_MEMORY ((dpe_error_t)128)
#define DPE_ERR_CBOR_FORMATTING ((dpe_error_t)129)
/**
* Client facing API. Parameters are according to the DPE spec version r0.9
*
* \brief Performs the DICE computation to derive a new context and optionally
* creates an intermediate certificate. Software component measurement
* must be provided in dice_inputs.
*
* \param[in] context_handle Input context handle for the DPE
* context.
* \param[in] cert_id Logical certificate id to which derived
* context belongs to.
* \param[in] retain_parent_context Flag to indicate whether to retain the
* parent context. True only if a client
* will call further DPE commands on the
* same context.
* \param[in] allow_new_context_to_derive Flag to indicate whether derived context
* can derive further. True only if the
* new context will load further components.
* \param[in] create_certificate Flag to indicate whether to create an
* intermediate certificate. True only if
* it is the last component in the layer.
* \param[in] dice_inputs DICE input values.
* \param[in] target_locality Identifies the locality to which the
* derived context will be bound. Could be
* MHU id.
* \param[in] return_certificate Indicates whether to return the generated
* certificate when create_certificate is true.
* \param[in] allow_new_context_to_export Indicates whether the DPE permits export of
* the CDI from the newly derived context.
* \param[in] export_cdi Indicates whether to export derived CDI.
* \param[out] new_context_handle New handle for the derived context.
* \param[out] new_parent_context_handle New handle for the parent context.
* \param[out] new_certificate_buf If create_certificate and return_certificate
* are both true, this argument holds the new
* certificate generated for the new context
* \param[in] new_certificate_buf_size Size of the allocated buffer for
* new certificate.
* \param[out] new_certificate_actual_size Actual size of the new certificate.
* \param[out] exported_cdi_buf If export_cdi is true, this is the
* exported CDI value.
* \param[in] exported_cdi_buf_size Size of the allocated buffer for
* exported cdi.
* \param[out] exported_cdi_actual_size Actual size of the exported cdi.
*
* \return Returns error code of type dpe_error_t
*/
dpe_error_t dpe_derive_context(int context_handle,
uint32_t cert_id,
bool retain_parent_context,
bool allow_new_context_to_derive,
bool create_certificate,
const DiceInputValues *dice_inputs,
int32_t target_locality,
bool return_certificate,
bool allow_new_context_to_export,
bool export_cdi,
int *new_context_handle,
int *new_parent_context_handle,
uint8_t *new_certificate_buf,
size_t new_certificate_buf_size,
size_t *new_certificate_actual_size,
uint8_t *exported_cdi_buf,
size_t exported_cdi_buf_size,
size_t *exported_cdi_actual_size);
#endif /* DICE_PROTECTION_ENVIRONMENT_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -14,21 +14,6 @@
#include "psa/error.h"
/* Minimum measurement value size that can be requested to store */
#define MEASUREMENT_VALUE_MIN_SIZE 32U
/* Maximum measurement value size that can be requested to store */
#define MEASUREMENT_VALUE_MAX_SIZE 64U
/* Minimum signer id size that can be requested to store */
#define SIGNER_ID_MIN_SIZE MEASUREMENT_VALUE_MIN_SIZE
/* Maximum signer id size that can be requested to store */
#define SIGNER_ID_MAX_SIZE MEASUREMENT_VALUE_MAX_SIZE
/* The theoretical maximum image version is: "255.255.65535\0" */
#define VERSION_MAX_SIZE 14U
/* Example sw_type: "BL_2, BL_33, etc." */
#define SW_TYPE_MAX_SIZE 20U
#define NUM_OF_MEASUREMENT_SLOTS 32U
/**
* Extends and stores a measurement to the requested slot.
*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023, Arm Limited. All rights reserved.
* Copyright (c) 2019-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -17,7 +17,10 @@
/******** PSA_SP_MEASURED_BOOT ********/
#define RSS_MEASURED_BOOT_HANDLE (0x40000110U)
/******** PSA_SP_DELAGATED_ATTESTATION ********/
/******** PSA_SP_DELEGATED_ATTESTATION ********/
#define RSS_DELEGATED_SERVICE_HANDLE (0x40000111U)
/******** PSA_SP_DICE_PROTECTION_ENVIRONMENT ********/
#define RSS_DPE_SERVICE_HANDLE (0x40000112U)
#endif /* PSA_MANIFEST_SID_H */

View file

@ -290,6 +290,12 @@ void arm_bl1_set_mbedtls_heap(void);
int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size);
#if MEASURED_BOOT
#if DICE_PROTECTION_ENVIRONMENT
int arm_set_nt_fw_info(int *ctx_handle);
int arm_set_tb_fw_info(int *ctx_handle);
int arm_get_tb_fw_info(int *ctx_handle);
#else
/* Specific to event log backend */
int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size);
int arm_set_nt_fw_info(
/*
@ -304,6 +310,7 @@ int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size,
size_t log_max_size);
int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
size_t *log_max_size);
#endif /* DICE_PROTECTION_ENVIRONMENT */
#endif /* MEASURED_BOOT */
/*

View file

@ -243,7 +243,7 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved);
int bl1_plat_handle_pre_image_load(unsigned int image_id);
int bl1_plat_handle_post_image_load(unsigned int image_id);
#if MEASURED_BOOT
#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
void bl1_plat_mboot_init(void);
void bl1_plat_mboot_finish(void);
#else
@ -253,7 +253,7 @@ static inline void bl1_plat_mboot_init(void)
static inline void bl1_plat_mboot_finish(void)
{
}
#endif /* MEASURED_BOOT */
#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT */
/*******************************************************************************
* Mandatory BL2 functions
@ -273,7 +273,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id);
/*******************************************************************************
* Optional BL2 functions (may be overridden)
******************************************************************************/
#if MEASURED_BOOT
#if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT)
void bl2_plat_mboot_init(void);
void bl2_plat_mboot_finish(void);
#else
@ -283,7 +283,7 @@ static inline void bl2_plat_mboot_init(void)
static inline void bl2_plat_mboot_finish(void)
{
}
#endif /* MEASURED_BOOT */
#endif /* MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENTs */
/*******************************************************************************
* Mandatory BL2 at EL3 functions: Must be implemented

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -170,6 +170,12 @@
#define SOC_FW_CONFIG_KEY_OID SOC_FW_CONTENT_CERT_PK_OID
#define HW_CONFIG_KEY_OID ZERO_OID
#define SCP_BL2_IMAGE_KEY_OID SCP_FW_CONTENT_CERT_PK_OID
#define BL32_IMAGE_KEY_OID TRUSTED_OS_FW_CONTENT_CERT_PK_OID
#define TOS_FW_CONFIG_KEY_OID TRUSTED_OS_FW_CONTENT_CERT_PK_OID
#define BL33_IMAGE_KEY_OID NON_TRUSTED_FW_CONTENT_CERT_PK_OID
#define NT_FW_CONFIG_KEY_OID NON_TRUSTED_FW_CONTENT_CERT_PK_OID
#ifdef PLAT_DEF_OID
#include <platform_oid.h>
#endif

View file

@ -0,0 +1,370 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <qcbor/qcbor_decode.h>
#include <qcbor/qcbor_encode.h>
#include <qcbor/qcbor_spiffy_decode.h>
#include <common/debug.h>
#include <dice.h>
#include <dice_protection_environment.h>
#include <psa/client.h>
#include <psa_manifest/sid.h>
enum dpe_command_id_t {
/* Standard commands */
DPE_GET_PROFILE = 1,
DPE_OPEN_SESSION = 2,
DPE_CLOSE_SESSION = 3,
DPE_SYNC_SESSION = 4,
DPE_EXPORT_SESSION = 5,
DPE_IMPORT_SESSION = 6,
DPE_INITIALIZE_CONTEXT = 7,
DPE_DERIVE_CONTEXT = 8,
DPE_CERTIFY_KEY = 9,
DPE_SIGN = 10,
DPE_SEAL = 11,
DPE_UNSEAL = 12,
DPE_DERIVE_SEALING_PUBLIC_KEY = 13,
DPE_ROTATE_CONTEXT_HANDLE = 14,
DPE_DESTROY_CONTEXT = 15,
};
enum dice_input_labels_t {
DICE_CODE_HASH = 1,
DICE_CODE_DESCRIPTOR = 2,
DICE_CONFIG_TYPE = 3,
DICE_CONFIG_VALUE = 4,
DICE_CONFIG_DESCRIPTOR = 5,
DICE_AUTHORITY_HASH = 6,
DICE_AUTHORITY_DESCRIPTOR = 7,
DICE_MODE = 8,
DICE_HIDDEN = 9,
};
enum dpe_derive_context_input_labels_t {
DPE_DERIVE_CONTEXT_CONTEXT_HANDLE = 1,
DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT = 2,
DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE = 3,
DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE = 4,
DPE_DERIVE_CONTEXT_NEW_SESSION_INITIATOR_HANDSHAKE = 5,
DPE_DERIVE_CONTEXT_INPUT_DATA = 6,
DPE_DERIVE_CONTEXT_INTERNAL_INPUTS = 7,
DPE_DERIVE_CONTEXT_TARGET_LOCALITY = 8,
DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE = 9,
DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT = 10,
DPE_DERIVE_CONTEXT_EXPORT_CDI = 11,
/* enum values 256 and onwards are reserved for custom arguments */
DPE_DERIVE_CONTEXT_CERT_ID = 256,
};
enum dpe_derive_context_output_labels_t {
DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE = 1,
DPE_DERIVE_CONTEXT_NEW_SESSION_RESPONDER_HANDSHAKE = 2,
DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE = 3,
DPE_DERIVE_CONTEXT_NEW_CERTIFICATE = 4,
DPE_DERIVE_CONTEXT_EXPORTED_CDI = 5,
};
struct derive_context_input_t {
int context_handle;
uint32_t cert_id;
bool retain_parent_context;
bool allow_new_context_to_derive;
bool create_certificate;
const DiceInputValues *dice_inputs;
int32_t target_locality;
bool return_certificate;
bool allow_new_context_to_export;
bool export_cdi;
};
struct derive_context_output_t {
int new_context_handle;
int new_parent_context_handle;
const uint8_t *new_certificate;
size_t new_certificate_size;
const uint8_t *exported_cdi;
size_t exported_cdi_size;
};
static void encode_dice_inputs(QCBOREncodeContext *encode_ctx,
const DiceInputValues *input)
{
/* Wrap the DICE inputs into a byte string */
QCBOREncode_BstrWrapInMapN(encode_ctx, DPE_DERIVE_CONTEXT_INPUT_DATA);
/* Inside the byte string the DICE inputs are encoded as a map */
QCBOREncode_OpenMap(encode_ctx);
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_HASH,
(UsefulBufC) { input->code_hash,
sizeof(input->code_hash) });
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CODE_DESCRIPTOR,
(UsefulBufC) { input->code_descriptor,
input->code_descriptor_size });
QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_CONFIG_TYPE,
input->config_type);
if (input->config_type == kDiceConfigTypeInline) {
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_VALUE,
(UsefulBufC) { input->config_value,
sizeof(input->config_value) });
} else {
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_CONFIG_DESCRIPTOR,
(UsefulBufC) { input->config_descriptor,
input->config_descriptor_size });
}
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_HASH,
(UsefulBufC) { input->authority_hash,
sizeof(input->authority_hash) });
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_AUTHORITY_DESCRIPTOR,
(UsefulBufC) { input->authority_descriptor,
input->authority_descriptor_size });
QCBOREncode_AddInt64ToMapN(encode_ctx, DICE_MODE, input->mode);
QCBOREncode_AddBytesToMapN(encode_ctx, DICE_HIDDEN,
(UsefulBufC) { input->hidden,
sizeof(input->hidden) });
QCBOREncode_CloseMap(encode_ctx);
QCBOREncode_CloseBstrWrap2(encode_ctx, true, NULL);
}
static QCBORError encode_derive_context(const struct derive_context_input_t *args,
UsefulBuf buf,
UsefulBufC *encoded_buf)
{
QCBOREncodeContext encode_ctx;
QCBOREncode_Init(&encode_ctx, buf);
QCBOREncode_OpenArray(&encode_ctx);
QCBOREncode_AddUInt64(&encode_ctx, DPE_DERIVE_CONTEXT);
/* Encode DeriveContext command */
QCBOREncode_OpenMap(&encode_ctx);
QCBOREncode_AddBytesToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_CONTEXT_HANDLE,
(UsefulBufC) { &args->context_handle,
sizeof(args->context_handle) });
QCBOREncode_AddUInt64ToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_CERT_ID,
args->cert_id);
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
args->retain_parent_context);
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
args->allow_new_context_to_derive);
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
args->create_certificate);
encode_dice_inputs(&encode_ctx, args->dice_inputs);
QCBOREncode_AddBytesToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_TARGET_LOCALITY,
(UsefulBufC) { &args->target_locality,
sizeof(args->target_locality) });
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
args->return_certificate);
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
args->allow_new_context_to_export);
QCBOREncode_AddBoolToMapN(&encode_ctx,
DPE_DERIVE_CONTEXT_EXPORT_CDI,
args->export_cdi);
QCBOREncode_CloseMap(&encode_ctx);
QCBOREncode_CloseArray(&encode_ctx);
return QCBOREncode_Finish(&encode_ctx, encoded_buf);
}
static QCBORError decode_derive_context_response(UsefulBufC encoded_buf,
struct derive_context_output_t *args,
dpe_error_t *dpe_err)
{
QCBORDecodeContext decode_ctx;
UsefulBufC out;
int64_t response_dpe_err;
QCBORDecode_Init(&decode_ctx, encoded_buf, QCBOR_DECODE_MODE_NORMAL);
QCBORDecode_EnterArray(&decode_ctx, NULL);
/* Get the error code from the response. DPE returns int32_t */
QCBORDecode_GetInt64(&decode_ctx, &response_dpe_err);
*dpe_err = (dpe_error_t)response_dpe_err;
/* Decode DeriveContext response if successful */
if (*dpe_err == DPE_NO_ERROR) {
QCBORDecode_EnterMap(&decode_ctx, NULL);
QCBORDecode_GetByteStringInMapN(&decode_ctx,
DPE_DERIVE_CONTEXT_NEW_CONTEXT_HANDLE,
&out);
if (out.len != sizeof(args->new_context_handle)) {
return QCBORDecode_Finish(&decode_ctx);
}
memcpy(&args->new_context_handle, out.ptr, out.len);
QCBORDecode_GetByteStringInMapN(&decode_ctx,
DPE_DERIVE_CONTEXT_PARENT_CONTEXT_HANDLE,
&out);
if (out.len != sizeof(args->new_parent_context_handle)) {
return QCBORDecode_Finish(&decode_ctx);
}
memcpy(&args->new_parent_context_handle, out.ptr, out.len);
QCBORDecode_GetByteStringInMapN(&decode_ctx,
DPE_DERIVE_CONTEXT_NEW_CERTIFICATE,
&out);
args->new_certificate = out.ptr;
args->new_certificate_size = out.len;
QCBORDecode_GetByteStringInMapN(&decode_ctx,
DPE_DERIVE_CONTEXT_EXPORTED_CDI,
&out);
args->exported_cdi = out.ptr;
args->exported_cdi_size = out.len;
QCBORDecode_ExitMap(&decode_ctx);
}
QCBORDecode_ExitArray(&decode_ctx);
return QCBORDecode_Finish(&decode_ctx);
}
static int32_t dpe_client_call(const char *cmd_input, size_t cmd_input_size,
char *cmd_output, size_t *cmd_output_size)
{
int32_t err;
psa_invec in_vec[] = {
{ cmd_input, cmd_input_size },
};
psa_outvec out_vec[] = {
{ cmd_output, *cmd_output_size },
};
err = psa_call(RSS_DPE_SERVICE_HANDLE, 0,
in_vec, IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
if (err == PSA_SUCCESS) {
*cmd_output_size = out_vec[0].len;
}
return err;
}
dpe_error_t dpe_derive_context(int context_handle,
uint32_t cert_id,
bool retain_parent_context,
bool allow_new_context_to_derive,
bool create_certificate,
const DiceInputValues *dice_inputs,
int32_t target_locality,
bool return_certificate,
bool allow_new_context_to_export,
bool export_cdi,
int *new_context_handle,
int *new_parent_context_handle,
uint8_t *new_certificate_buf,
size_t new_certificate_buf_size,
size_t *new_certificate_actual_size,
uint8_t *exported_cdi_buf,
size_t exported_cdi_buf_size,
size_t *exported_cdi_actual_size)
{
int32_t service_err;
dpe_error_t dpe_err;
QCBORError qcbor_err;
UsefulBufC encoded_buf;
UsefulBuf_MAKE_STACK_UB(cmd_buf, 612);
const struct derive_context_input_t in_args = {
context_handle,
cert_id,
retain_parent_context,
allow_new_context_to_derive,
create_certificate,
dice_inputs,
target_locality,
return_certificate,
allow_new_context_to_export,
export_cdi,
};
struct derive_context_output_t out_args;
/*
* Validate the output params here because they are not sent to the
* service. Input params are validated by the DPE service.
*/
if ((new_context_handle == NULL) ||
(retain_parent_context == true && new_parent_context_handle == NULL) ||
(return_certificate == true &&
(new_certificate_buf == NULL || new_certificate_actual_size == NULL)) ||
(export_cdi == true &&
(exported_cdi_buf == NULL || exported_cdi_actual_size == NULL))) {
return DPE_INVALID_ARGUMENT;
}
qcbor_err = encode_derive_context(&in_args, cmd_buf, &encoded_buf);
if (qcbor_err != QCBOR_SUCCESS) {
return DPE_INTERNAL_ERROR;
}
service_err = dpe_client_call(encoded_buf.ptr, encoded_buf.len,
cmd_buf.ptr, &cmd_buf.len);
if (service_err != 0) {
return DPE_INTERNAL_ERROR;
}
qcbor_err = decode_derive_context_response(UsefulBuf_Const(cmd_buf),
&out_args, &dpe_err);
if (qcbor_err != QCBOR_SUCCESS) {
return DPE_INTERNAL_ERROR;
} else if (dpe_err != DPE_NO_ERROR) {
return dpe_err;
}
/* Copy returned values into caller's memory */
*new_context_handle = out_args.new_context_handle;
if (retain_parent_context == true) {
*new_parent_context_handle = out_args.new_parent_context_handle;
}
if (return_certificate == true) {
if (out_args.new_certificate_size > new_certificate_buf_size) {
return DPE_INVALID_ARGUMENT;
}
memcpy(new_certificate_buf, out_args.new_certificate,
out_args.new_certificate_size);
*new_certificate_actual_size = out_args.new_certificate_size;
}
if (export_cdi == true) {
if (out_args.exported_cdi_size > exported_cdi_buf_size) {
return DPE_INVALID_ARGUMENT;
}
memcpy(exported_cdi_buf, out_args.exported_cdi,
out_args.exported_cdi_size);
*exported_cdi_actual_size = out_args.exported_cdi_size;
}
return DPE_NO_ERROR;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -8,6 +8,7 @@
#include <string.h>
#include <common/debug.h>
#include <drivers/measured_boot/metadata.h>
#include <measured_boot.h>
#include <psa/client.h>
#include <psa_manifest/sid.h>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@ -10,6 +10,8 @@
#include <stdint.h>
#include <drivers/measured_boot/metadata.h>
/* Measured boot message types that distinguish its services */
#define RSS_MEASURED_BOOT_READ 1001U
#define RSS_MEASURED_BOOT_EXTEND 1002U

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -176,6 +176,9 @@ endif
# Option to build TF with Measured Boot support
MEASURED_BOOT := 0
# Option to enable the DICE Protection Environmnet as a Measured Boot backend
DICE_PROTECTION_ENVIRONMENT :=0
# NS timer register save and restore
NS_TIMER_SWITCH := 0

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, Arm Limited. All rights reserved.
* Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,6 +7,7 @@
#include <stdint.h>
#include <drivers/measured_boot/event_log/event_log.h>
#include <drivers/measured_boot/metadata.h>
#include <plat/arm/common/plat_arm.h>
#include <tools_share/zero_oid.h>
@ -15,9 +16,9 @@ static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
/* FVP table with platform specific image IDs, names and PCRs */
const event_log_metadata_t fvp_event_log_metadata[] = {
{ FW_CONFIG_ID, EVLOG_FW_CONFIG_STRING, PCR_0 },
{ TB_FW_CONFIG_ID, EVLOG_TB_FW_CONFIG_STRING, PCR_0 },
{ BL2_IMAGE_ID, EVLOG_BL2_STRING, PCR_0 },
{ FW_CONFIG_ID, MBOOT_FW_CONFIG_STRING, PCR_0 },
{ TB_FW_CONFIG_ID, MBOOT_TB_FW_CONFIG_STRING, PCR_0 },
{ BL2_IMAGE_ID, MBOOT_BL2_IMAGE_STRING, PCR_0 },
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, Arm Limited. All rights reserved.
* Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,6 +8,7 @@
#include <common/tbbr/tbbr_img_def.h>
#include <drivers/measured_boot/event_log/event_log.h>
#include <drivers/measured_boot/metadata.h>
#if defined(ARM_COT_cca)
#include <tools_share/cca_oid.h>
#else
@ -28,27 +29,27 @@ static uint64_t event_log_base;
/* FVP table with platform specific image IDs, names and PCRs */
const event_log_metadata_t fvp_event_log_metadata[] = {
{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
{ RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0},
{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
{ RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0},
#if defined(SPD_spmd)
{ SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 },
{ SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 },
{ SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 },
{ SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 },
{ SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 },
{ SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 },
{ SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 },
{ SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 },
{ SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 },
{ SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 },
{ SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 },
{ SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 },
{ SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 },
{ SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 },
{ SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 },
{ SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 },
#endif
{ CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* DICE Protection Environment Client Config */
dice_protection_environment: context_handle {
compatible = "arm,dpe_ctx_handle";
dpe_ctx_handle = <0x0>;
};

View file

@ -30,5 +30,10 @@
max-size = <PLAT_HW_CONFIG_DTB_SIZE>;
id = <HW_CONFIG_ID>;
};
nt_fw-config {
load-address = <0x0 (PLAT_HW_CONFIG_DTB_BASE + PLAT_HW_CONFIG_DTB_SIZE)>;
max-size = <0x1000>;
id = <NT_FW_CONFIG_ID>;
};
};
};

View file

@ -0,0 +1,13 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/dts-v1/;
/ {
#if DICE_PROTECTION_ENVIRONMENT
#include "dice_prot_env.dtsi"
#endif
};

View file

@ -82,4 +82,7 @@
#endif
#endif /* ARM_BL2_SP_LIST_DTS */
};
#if DICE_PROTECTION_ENVIRONMENT
#include "dice_prot_env.dtsi"
#endif
};

View file

@ -32,6 +32,9 @@
* | DTB |
* | (32K) |
* 0x8000_8000 ------------------
* | NT_FW_CONFIG |
* | (4KB) |
* 0x8000_9000 ------------------
* | ... |
* 0xf8a0_0000 ------------------ TC_NS_FWU_BASE
* | FWU shmem |

View file

@ -137,14 +137,18 @@ BL31_SOURCES += ${FDT_WRAPPERS_SOURCES}
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${TC_BASE}/fdts/${PLAT}_fw_config.dts \
${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts
${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts \
${TC_BASE}/fdts/${PLAT}_nt_fw_config.dts
FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
FVP_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FW_CONFIG},--fw-config,${FW_CONFIG}))
# Add the TB_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config,${TB_FW_CONFIG}))
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config,${FVP_NT_FW_CONFIG}))
ifeq (${SPD},spmd)
ifeq ($(ARM_SPMC_MANIFEST_DTS),)
@ -170,27 +174,56 @@ $(eval $(call TOOL_ADD_PAYLOAD,${TC_HW_CONFIG},--hw-config,${TC_HW_CONFIG}))
# Include Measured Boot makefile before any Crypto library makefile.
# Crypto library makefile may need default definitions of Measured Boot build
# flags present in Measured Boot makefile.
$(info Including rss_comms.mk)
ifeq (${MEASURED_BOOT},1)
MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk
$(info Including ${MEASURED_BOOT_MK})
include ${MEASURED_BOOT_MK}
$(info Including rss_comms.mk)
include drivers/arm/rss/rss_comms.mk
$(info Including rss_comms.mk)
include drivers/arm/rss/rss_comms.mk
BL1_SOURCES += ${MEASURED_BOOT_SOURCES} \
BL1_SOURCES += ${RSS_COMMS_SOURCES}
BL2_SOURCES += ${RSS_COMMS_SOURCES}
PLAT_INCLUDES += -Iinclude/lib/psa
ifeq (${DICE_PROTECTION_ENVIRONMENT},1)
$(info Including qcbor.mk)
include drivers/measured_boot/rss/qcbor.mk
$(info Including dice_prot_env.mk)
include drivers/measured_boot/rss/dice_prot_env.mk
BL1_SOURCES += ${QCBOR_SOURCES} \
${DPE_SOURCES} \
plat/arm/board/tc/tc_common_dpe.c \
plat/arm/board/tc/tc_bl1_dpe.c \
lib/psa/dice_protection_environment.c \
drivers/arm/css/sds/sds.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c
BL2_SOURCES += ${QCBOR_SOURCES} \
${DPE_SOURCES} \
plat/arm/board/tc/tc_common_dpe.c \
plat/arm/board/tc/tc_bl2_dpe.c \
lib/psa/dice_protection_environment.c
PLAT_INCLUDES += -I${QCBOR_INCLUDES} \
-Iinclude/lib/dice
else
$(info Including rss_measured_boot.mk)
include drivers/measured_boot/rss/rss_measured_boot.mk
BL1_SOURCES += ${MEASURED_BOOT_SOURCES} \
plat/arm/board/tc/tc_common_measured_boot.c \
plat/arm/board/tc/tc_bl1_measured_boot.c \
lib/psa/measured_boot.c \
${RSS_COMMS_SOURCES}
lib/psa/measured_boot.c
BL2_SOURCES += ${MEASURED_BOOT_SOURCES} \
BL2_SOURCES += ${MEASURED_BOOT_SOURCES} \
plat/arm/board/tc/tc_common_measured_boot.c \
plat/arm/board/tc/tc_bl2_measured_boot.c \
lib/psa/measured_boot.c \
${RSS_COMMS_SOURCES}
PLAT_INCLUDES += -Iinclude/lib/psa
lib/psa/measured_boot.c
endif
endif
ifeq (${TRNG_SUPPORT},1)
BL31_SOURCES += plat/arm/board/tc/tc_trng.c
endif
ifneq (${PLATFORM_TEST},)

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <common/debug.h>
#include <drivers/arm/css/sds.h>
#include <drivers/arm/rss_comms.h>
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/measured_boot/metadata.h>
#include <drivers/measured_boot/rss/dice_prot_env.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <tools_share/zero_oid.h>
#include "tc_dpe_cert.h"
struct dpe_metadata tc_dpe_metadata[] = {
{
.id = FW_CONFIG_ID,
.cert_id = DPE_AP_FW_CERT_ID,
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_FW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = ZERO_OID },
{
.id = TB_FW_CONFIG_ID,
.cert_id = DPE_AP_FW_CERT_ID,
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_TB_FW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = ZERO_OID },
{
.id = BL2_IMAGE_ID,
.cert_id = DPE_AP_FW_CERT_ID,
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_BL2_IMAGE_STRING,
.allow_new_context_to_derive = true,
.retain_parent_context = false,
.create_certificate = false,
.pk_oid = ZERO_OID },
{
.id = DPE_INVALID_ID }
};
/* Effective timeout of 10000 ms */
#define RSS_DPE_BOOT_10US_RETRIES 1000000
#define TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID 0x0000000A
/* Context handle is meant to be used by BL2. Sharing it via TB_FW_CONFIG */
static int new_ctx_handle;
void plat_dpe_share_context_handle(int *ctx_handle)
{
new_ctx_handle = *ctx_handle;
}
void plat_dpe_get_context_handle(int *ctx_handle)
{
int retry = RSS_DPE_BOOT_10US_RETRIES;
int ret;
/* Initialize System level generic or SP804 timer */
generic_delay_timer_init();
/* Check the initialization of the Shared Data Storage area between RSS
* and AP. Since AP_BL1 is executed first then a bit later the RSS
* runtime, which initialize this area, therefore AP needs to check it
* in a loop until it gets written by RSS Secure Runtime.
*/
VERBOSE("Waiting for DPE service initialization in RSS Secure Runtime\n");
while (retry > 0) {
ret = sds_init(SDS_RSS_AP_REGION_ID);
if (ret != SDS_OK) {
udelay(10);
retry--;
} else {
break;
}
}
if (retry == 0) {
ERROR("DPE init timeout\n");
plat_panic_handler();
} else {
VERBOSE("DPE init succeeded in %dms.\n",
(RSS_DPE_BOOT_10US_RETRIES - retry) / 100);
}
/* TODO: call this in a loop to avoid reading unfinished data */
ret = sds_struct_read(SDS_RSS_AP_REGION_ID,
TC2_SDS_DPE_CTX_HANDLE_STRUCT_ID,
0,
ctx_handle,
sizeof(*ctx_handle),
SDS_ACCESS_MODE_NON_CACHED);
if (ret != SDS_OK) {
ERROR("Unable to get DPE context handle from SDS area\n");
plat_panic_handler();
}
VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
}
void bl1_plat_mboot_init(void)
{
/* Initialize the communication channel between AP and RSS */
(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
PLAT_RSS_AP_RCV_MHU_BASE);
dpe_init(tc_dpe_metadata);
}
void bl1_plat_mboot_finish(void)
{
int rc;
VERBOSE("Share DPE context handle with BL2: 0x%x\n", new_ctx_handle);
rc = arm_set_tb_fw_info(&new_ctx_handle);
if (rc != 0) {
ERROR("Unable to set DPE context handle in TB_FW_CONFIG\n");
/*
* It is a fatal error because on TC platform, BL2 software
* assumes that a valid DPE context_handle is passed through
* the DTB object by BL1.
*/
plat_panic_handler();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,8 +7,8 @@
#include <stdint.h>
#include <drivers/arm/rss_comms.h>
#include <drivers/measured_boot/metadata.h>
#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <lib/psa/measured_boot.h>
#include <tools_share/zero_oid.h>
#include <plat/arm/common/plat_arm.h>
@ -22,21 +22,21 @@ struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
.id = FW_CONFIG_ID,
.slot = U(6),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_FW_CONFIG_STRING,
.sw_type = MBOOT_FW_CONFIG_STRING,
.pk_oid = ZERO_OID,
.lock_measurement = true },
{
.id = TB_FW_CONFIG_ID,
.slot = U(7),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING,
.sw_type = MBOOT_TB_FW_CONFIG_STRING,
.pk_oid = ZERO_OID,
.lock_measurement = true },
{
.id = BL2_IMAGE_ID,
.slot = U(8),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_BL2_STRING,
.sw_type = MBOOT_BL2_IMAGE_STRING,
.pk_oid = ZERO_OID,
.lock_measurement = true },

View file

@ -0,0 +1,236 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <common/debug.h>
#include <drivers/arm/rss_comms.h>
#include <drivers/measured_boot/metadata.h>
#include <drivers/measured_boot/rss/dice_prot_env.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <tools_share/tbbr_oid.h>
#include "tc_dpe_cert.h"
/*
* The content and the values of this array depends on:
* - build config: Which components are loaded: SPMD, TOS, SPx, etc ?
* - boot order: the last element in a layer should be treated differently.
*/
/*
* TODO:
* - The content of the array must be tailored according to the build
* config (TOS, SPMD, etc). All loaded components (executables and
* config blobs) must be present in this array.
* - Current content is according to the Trusty build config.
*/
struct dpe_metadata tc_dpe_metadata[] = {
{
.id = BL31_IMAGE_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_BL31_IMAGE_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = BL31_IMAGE_KEY_OID },
{
.id = BL32_IMAGE_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_BL32_IMAGE_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = BL32_IMAGE_KEY_OID },
{
.id = BL33_IMAGE_ID,
.cert_id = DPE_HYPERVISOR_CERT_ID,
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_BL33_IMAGE_STRING,
.allow_new_context_to_derive = true,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = BL33_IMAGE_KEY_OID },
{
.id = HW_CONFIG_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_HW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = HW_CONFIG_KEY_OID },
{
.id = NT_FW_CONFIG_ID,
.cert_id = DPE_HYPERVISOR_CERT_ID,
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_NT_FW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NT_FW_CONFIG_KEY_OID },
{
.id = SCP_BL2_IMAGE_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SCP_BL2_IMAGE_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = SCP_BL2_IMAGE_KEY_OID },
{
.id = SOC_FW_CONFIG_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = SOC_FW_CONFIG_KEY_OID },
{
.id = TOS_FW_CONFIG_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_TOS_FW_CONFIG_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = TOS_FW_CONFIG_KEY_OID },
#if defined(SPD_spmd)
{
.id = SP_PKG1_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP1_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = true, /* With Trusty only one SP is loaded */
.pk_oid = NULL },
{
.id = SP_PKG2_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP2_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG3_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP3_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG4_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP4_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG5_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP5_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG6_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP6_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG7_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP7_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
{
.id = SP_PKG8_ID,
.cert_id = DPE_CERT_ID_SAME_AS_PARENT, /* AP_BL2: DPE_AP_FW_CERT_ID */
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = MBOOT_SP8_STRING,
.allow_new_context_to_derive = false,
.retain_parent_context = true,
.create_certificate = false,
.pk_oid = NULL },
#endif
{
.id = DPE_INVALID_ID }
};
/* Context handle is meant to be used by BL33. Sharing it via NT_FW_CONFIG */
static int new_ctx_handle;
void plat_dpe_share_context_handle(int *ctx_handle)
{
new_ctx_handle = *ctx_handle;
}
void plat_dpe_get_context_handle(int *ctx_handle)
{
int rc;
rc = arm_get_tb_fw_info(ctx_handle);
if (rc != 0) {
ERROR("Unable to get DPE context handle from TB_FW_CONFIG\n");
/*
* It is a fatal error because on FVP platform, BL2 software
* assumes that a valid DPE context_handle is passed through
* the DTB object by BL1.
*/
plat_panic_handler();
}
VERBOSE("Received DPE context handle: 0x%x\n", *ctx_handle);
}
void bl2_plat_mboot_init(void)
{
/* Initialize the communication channel between AP and RSS */
(void)rss_comms_init(PLAT_RSS_AP_SND_MHU_BASE,
PLAT_RSS_AP_RCV_MHU_BASE);
dpe_init(tc_dpe_metadata);
}
void bl2_plat_mboot_finish(void)
{
int rc;
VERBOSE("Share DPE context handle with BL33: 0x%x\n", new_ctx_handle);
rc = arm_set_nt_fw_info(&new_ctx_handle);
if (rc != 0) {
ERROR("Unable to set DPE context handle in NT_FW_CONFIG\n");
/*
* It is a fatal error because on TC platform, BL33 software
* assumes that a valid DPE context_handle is passed through
* the DTB object by BL2.
*/
plat_panic_handler();
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,8 +7,8 @@
#include <stdint.h>
#include <drivers/arm/rss_comms.h>
#include <drivers/measured_boot/metadata.h>
#include <drivers/measured_boot/rss/rss_measured_boot.h>
#include <lib/psa/measured_boot.h>
#include <tools_share/tbbr_oid.h>
#include <plat/common/common_def.h>
@ -22,21 +22,21 @@ struct rss_mboot_metadata tc_rss_mboot_metadata[] = {
.id = BL31_IMAGE_ID,
.slot = U(9),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_BL31_STRING,
.sw_type = MBOOT_BL31_IMAGE_STRING,
.pk_oid = BL31_IMAGE_KEY_OID,
.lock_measurement = true },
{
.id = HW_CONFIG_ID,
.slot = U(10),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_HW_CONFIG_STRING,
.sw_type = MBOOT_HW_CONFIG_STRING,
.pk_oid = HW_CONFIG_KEY_OID,
.lock_measurement = true },
{
.id = SOC_FW_CONFIG_ID,
.slot = U(11),
.signer_id_size = SIGNER_ID_MIN_SIZE,
.sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING,
.sw_type = MBOOT_SOC_FW_CONFIG_STRING,
.pk_oid = SOC_FW_CONFIG_KEY_OID,
.lock_measurement = true },
{

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <stdint.h>
#include <common/desc_image_load.h>
#include <drivers/measured_boot/rss/dice_prot_env.h>
extern struct dpe_metadata tc_dpe_metadata[];
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
{
int err;
/* Calculate image hash and record it in the DPE service in RSS. */
err = dpe_measure_and_record(tc_dpe_metadata,
image_data->image_base,
image_data->image_size,
image_id);
if (err != 0) {
ERROR("%s%s image id %u (%i)\n",
"Failed to ", "record in DPE", image_id, err);
}
return err;
}
int plat_mboot_measure_key(void *pk_oid, void *pk_ptr, unsigned int pk_len)
{
return dpe_set_signer_id(tc_dpe_metadata, pk_oid, pk_ptr, pk_len);
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef TC_DPE_CERT_H
#define TC_DPE_CERT_H
/*
* The certificate structure on the TC platform:
* - The arrows indicate the parent/child relationships (who loads who).
* - The boxes indicate the certificates.
*
* AP FW Cert.
* +--------------------------------+
* | |
* Plat Cert. | +->SPx | Hyper Cert.
* +--------------------------+ | +->SP1 | +--------------------+
* RoT Cert. | | | +->TOS_FW_CONF | | |
* +------------+ | +->SCP_BL1 +-----+-----+-->FW_CONF +->AP_BL32 | | +->PVMFW |
* | | | | | | | | | | | |
* | RSS_BL1_2--+-----+-->RSS_BL2------->AP_BL1--+-----+------------->AP_BL2------------+-----+-->AP_BL33 |
* | | | | | | | | | | | |
* +------------+ | +->RSS_S +-----+-----+-->TB_FW_CONF +->AP_BL31 | | +->HYPERVISOR |
* | +->RSS_NS | | +->SCP_BL2 | | |
* | | | +->HW_CONF | | |
* +--------------------------+ | +---------------+-----+-->NT_FW_CONF |
* | | | |
* +--------------------------------+ +--------------------+
*/
#define DPE_AP_FW_CERT_ID 0x300 /* Includes: FW_CONF - SP1 */
#define DPE_HYPERVISOR_CERT_ID 0x400 /* Includes: AP_BL33 - PVMFW */
/* Common definition */
#define DPE_CERT_ID_SAME_AS_PARENT 0xFFFFFFFF
#endif /* TC_DPE_CERT_H */

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_acle.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <lib/mmio.h>
#include <lib/smccc.h>
#include <lib/utils_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/trng_svc.h>
#include <smccc_helpers.h>
DEFINE_SVC_UUID2(_plat_trng_uuid,
0x23523c58, 0x7448, 0x4083, 0x9d, 0x16,
0xe3, 0xfa, 0xb9, 0xf1, 0x73, 0xbc
);
uuid_t plat_trng_uuid;
/* Dummy implementation */
bool plat_get_entropy(uint64_t *out)
{
*out = 0xABBAEDDAACDCDEAD;
return true;
}
void plat_entropy_setup(void)
{
uint64_t dummy;
plat_trng_uuid = _plat_trng_uuid;
/* Initialise the entropy source and trigger RNG generation */
plat_get_entropy(&dummy);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -124,6 +124,150 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
}
#if MEASURED_BOOT
#if DICE_PROTECTION_ENVIRONMENT
#include <common/desc_image_load.h>
#define DTB_PROP_DPE_CTX_HANDLE "dpe_ctx_handle"
static int arm_set_dpe_context_handle(uintptr_t config_base,
int *ctx_handle)
{
/* As libfdt uses void *, we can't avoid this cast */
void *dtb = (void *)config_base;
const char *compatible = "arm,dpe_ctx_handle";
int err, node;
/*
* Verify that the DTB is valid, before attempting to write to it,
* and get the DTB root node.
*/
/* Check if the pointer to DT is correct */
err = fdt_check_header(dtb);
if (err < 0) {
WARN("Invalid DTB file passed\n");
return err;
}
/* Assert the node offset point to compatible property */
node = fdt_node_offset_by_compatible(dtb, -1, compatible);
if (node < 0) {
WARN("The compatible property '%s' not%s", compatible,
" found in the config\n");
return node;
}
VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
err = fdtw_write_inplace_cells(dtb, node,
DTB_PROP_DPE_CTX_HANDLE, 1, ctx_handle);
if (err < 0) {
ERROR("%sDTB property '%s'\n",
"Unable to write ", DTB_PROP_DPE_CTX_HANDLE);
} else {
/*
* Ensure that the info written to the DTB is visible
* to other images.
*/
flush_dcache_range(config_base, fdt_totalsize(dtb));
}
return err;
}
/*
* This function writes the DPE context handle value to the NT_FW_CONFIG DTB.
*
* This function is supposed to be called only by BL2.
*
* Returns:
* 0 = success
* < 0 = error
*/
int arm_set_nt_fw_info(int *ctx_handle)
{
uintptr_t config_base;
const bl_mem_params_node_t *cfg_mem_params;
/* Get the config load address and size from NT_FW_CONFIG */
cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
assert(cfg_mem_params != NULL);
config_base = cfg_mem_params->image_info.image_base;
/* Write the context handle value in the DTB */
return arm_set_dpe_context_handle(config_base, ctx_handle);
}
/*
* This function writes the DPE context handle value to the TB_FW_CONFIG DTB.
*
* This function is supposed to be called only by BL1.
*
* Returns:
* 0 = success
* < 0 = error
*/
int arm_set_tb_fw_info(int *ctx_handle)
{
/*
* Read tb_fw_config device tree for Event Log properties
* and write the Event Log address and its size in the DTB
*/
const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
uintptr_t tb_fw_cfg_dtb;
tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
assert(tb_fw_config_info != NULL);
tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
/* Write the context handle value in the DTB */
return arm_set_dpe_context_handle(tb_fw_cfg_dtb, ctx_handle);
}
/*
* This function reads the initial DPE context handle from TB_FW_CONFIG DTB.
*
* This function is supposed to be called only by BL2.
*
* Returns:
* 0 = success
* < 0 = error
*/
int arm_get_tb_fw_info(int *ctx_handle)
{
/* As libfdt uses void *, we can't avoid this cast */
const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
int node, rc;
tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
assert(tb_fw_config_info != NULL);
void *dtb = (void *)tb_fw_config_info->config_addr;
const char *compatible = "arm,dpe_ctx_handle";
/* Assert the node offset point to compatible property */
node = fdt_node_offset_by_compatible(dtb, -1, compatible);
if (node < 0) {
WARN("The compatible property '%s'%s", compatible,
" not specified in TB_FW config.\n");
return node;
}
VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
rc = fdt_read_uint32(dtb, node, DTB_PROP_DPE_CTX_HANDLE, (uint32_t *)ctx_handle);
if (rc != 0) {
ERROR("%s%s", DTB_PROP_DPE_CTX_HANDLE,
" not specified in TB_FW config.\n");
}
return rc;
}
#else
/*
* Write the Event Log address and its size in the DTB.
*
@ -393,4 +537,5 @@ int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
return rc;
}
#endif /* DICE_PROTECTION_ENVIRONMENT */
#endif /* MEASURED_BOOT */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022, Linaro.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -9,6 +9,7 @@
#include "./include/imx8m_measured_boot.h"
#include <drivers/measured_boot/event_log/event_log.h>
#include <drivers/measured_boot/metadata.h>
#include <plat/arm/common/plat_arm.h>
/* Event Log data */
@ -16,11 +17,11 @@ static uint8_t event_log[PLAT_IMX_EVENT_LOG_MAX_SIZE];
/* FVP table with platform specific image IDs, names and PCRs */
static const event_log_metadata_t imx8m_event_log_metadata[] = {
{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022-2023, Linaro.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -8,6 +8,7 @@
#include <stdint.h>
#include <drivers/measured_boot/event_log/event_log.h>
#include <drivers/measured_boot/metadata.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <tools_share/tbbr_oid.h>
@ -20,16 +21,16 @@ static uint64_t event_log_base;
/* QEMU table with platform specific image IDs, names and PCRs */
static const event_log_metadata_t qemu_event_log_metadata[] = {
{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
{ HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 },
{ NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 },
{ SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 },
{ SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 },
{ TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 },
{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
};