mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
feat(dice): add DPE driver to measured boot
Implement a DPE specific backend within the generic measured boot framework. Signed-off-by: Tamas Ban <tamas.ban@arm.com> Change-Id: Ia3a0eac0ee6f7b4b337a93d08286613e7c8186b4
This commit is contained in:
parent
b03fe8c025
commit
0ae9c631ea
4 changed files with 264 additions and 1 deletions
192
drivers/measured_boot/rss/dice_prot_env.c
Normal file
192
drivers/measured_boot/rss/dice_prot_env.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* 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++;
|
||||
}
|
||||
|
||||
/* TODO: Obtain ctx handle and assign it to 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->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);
|
||||
/* TODO: share 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;
|
||||
}
|
29
drivers/measured_boot/rss/dice_prot_env.mk
Normal file
29
drivers/measured_boot/rss/dice_prot_env.mk
Normal 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
|
|
@ -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,
|
||||
|
|
42
include/drivers/measured_boot/rss/dice_prot_env.h
Normal file
42
include/drivers/measured_boot/rss/dice_prot_env.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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;
|
||||
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);
|
||||
|
||||
#endif /* DICE_PROT_ENV_H */
|
Loading…
Add table
Reference in a new issue