DPE: Add new parameters for DeriveContext command
As per spec updates in v1.0 r9, add below new parameters to
DeriveContext command:
* return_certificate [input]
* allow_new_context_to_export [input]
* export_cdi [input]
* new_certificate [output]
* exported_cdi [output]
Signed-off-by: Maulik Patel <maulik.patel@arm.com>
Change-Id: If646caad314f38abcfcca267123aa5d3d477f156
diff --git a/partitions/dice_protection_environment/dpe_context_mngr.c b/partitions/dice_protection_environment/dpe_context_mngr.c
index 4e05da3..3655c2f 100644
--- a/partitions/dice_protection_environment/dpe_context_mngr.c
+++ b/partitions/dice_protection_environment/dpe_context_mngr.c
@@ -63,12 +63,17 @@
static void set_context_to_default(int i)
{
component_ctx_array[i].in_use = false;
- component_ctx_array[i].is_leaf = false;
+ component_ctx_array[i].is_allowed_to_derive = true;
+ /* export CDI attribute is inherited and once disabled, a derived context
+ * and subsequent derivations cannot export CDI, hence enable by default
+ */
+ component_ctx_array[i].is_export_cdi_allowed = true;
component_ctx_array[i].nonce = INVALID_NONCE_VALUE;
component_ctx_array[i].parent_idx = INVALID_COMPONENT_IDX;
component_ctx_array[i].linked_layer_idx = INVALID_LAYER_IDX;
(void)memset(&component_ctx_array[i].data, 0, sizeof(struct component_context_data_t));
//TODO: Question: how to initialise MHU Id mapping?
+ component_ctx_array[i].target_locality = 0;
/* Allow component to be derived by default */
}
@@ -76,6 +81,7 @@
{
layer_ctx_array[i].state = LAYER_STATE_CLOSED;
layer_ctx_array[i].parent_layer_idx = INVALID_LAYER_IDX;
+ layer_ctx_array[i].is_cdi_to_be_exported = false;
(void)memset(&layer_ctx_array[i].attest_cdi_hash_input, 0,
sizeof(layer_ctx_array[i].attest_cdi_hash_input));
(void)psa_destroy_key(layer_ctx_array[i].data.cdi_key_id);
@@ -259,6 +265,39 @@
return status;
}
+static dpe_error_t get_encoded_cdi_to_export(struct layer_context_t *layer_ctx,
+ uint8_t *exported_cdi_buf,
+ size_t exported_cdi_buf_size,
+ size_t *exported_cdi_actual_size)
+{
+ uint8_t cdi_buf[DICE_CDI_SIZE];
+ size_t cdi_size;
+ psa_status_t status;
+ dpe_error_t err;
+
+ /* Get CDI value */
+ status = get_layer_cdi_value(layer_ctx,
+ cdi_buf,
+ sizeof(cdi_buf),
+ &cdi_size);
+ if (status != PSA_SUCCESS) {
+ return DPE_INTERNAL_ERROR;
+ }
+
+ /* Encode CDI value */
+ err = encode_cdi(cdi_buf,
+ cdi_size,
+ exported_cdi_buf,
+ exported_cdi_buf_size,
+ exported_cdi_actual_size);
+ if (err != DPE_NO_ERROR) {
+ return err;
+ }
+ layer_ctx->is_cdi_to_be_exported = true;
+
+ return DPE_NO_ERROR;
+}
+
static dpe_error_t create_layer_certificate(uint16_t layer_idx)
{
uint16_t parent_layer_idx;
@@ -357,9 +396,10 @@
layer_ctx_array[derived_ctx_layer].parent_layer_idx = parent_ctx_layer;
}
-static inline bool is_input_client_id_valid(int32_t client_id)
+static inline bool is_input_client_id_valid(int32_t client_id, int32_t target_locality)
{
- //TODO: Waiting for implementation
+ // TODO: FIXME
+ // return (client_id == target_locality);
return true;
}
@@ -467,13 +507,25 @@
bool create_certificate,
const DiceInputValues *dice_inputs,
int32_t client_id,
+ 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)
+ 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)
{
dpe_error_t err;
struct component_context_t *parent_ctx, *derived_ctx;
- uint16_t parent_ctx_idx;
+ uint16_t parent_ctx_idx, linked_layer_idx;
int free_component_idx;
+ struct layer_context_t *layer_ctx;
+ psa_status_t status;
log_derive_context(input_ctx_handle, retain_parent_context,
allow_new_context_to_derive, create_certificate, dice_inputs,
@@ -490,6 +542,10 @@
}
#endif /* DPE_TEST_MODE */
+ if (export_cdi && !create_certificate) {
+ return DPE_INVALID_ARGUMENT;
+ }
+
/* Validate dice inputs */
if (!is_dice_input_valid(dice_inputs)) {
return DPE_INVALID_ARGUMENT;
@@ -509,8 +565,13 @@
parent_ctx = &component_ctx_array[parent_ctx_idx];
+ /* Check if parent context is allowed to derive */
+ if (!parent_ctx->is_allowed_to_derive) {
+ return DPE_INVALID_ARGUMENT;
+ }
+
//TODO: Question: how to get mhu id of incoming request?
- if (!is_input_client_id_valid(client_id)) {
+ if (!is_input_client_id_valid(client_id, parent_ctx->target_locality)) {
return DPE_INVALID_ARGUMENT;
}
@@ -521,11 +582,25 @@
}
derived_ctx = &component_ctx_array[free_component_idx];
+ if (parent_ctx->is_export_cdi_allowed && allow_new_context_to_export) {
+ /* If parent context has export enabled and input allow_new_context_to_export
+ * is true, then allow context CDI to be exported for derived context
+ */
+ derived_ctx->is_export_cdi_allowed = true;
+ } else {
+ /* Export of new context CDI is NOT allowed */
+ derived_ctx->is_export_cdi_allowed = false;
+ if (export_cdi) {
+ return DPE_INVALID_ARGUMENT;
+ }
+ }
+
/* Copy dice input to the new derived component context */
err = copy_dice_input(derived_ctx, dice_inputs);
if (err != DPE_NO_ERROR) {
return err;
}
+ derived_ctx->target_locality = target_locality;
/* Update parent idx in new derived component context */
derived_ctx->parent_idx = parent_ctx_idx;
@@ -551,7 +626,7 @@
parent_ctx->nonce = INVALID_NONCE_VALUE;
}
- if (allow_new_context_to_derive) {
+ if (!export_cdi) {
/* Return handle to derived context */
*new_context_handle = SET_IDX(*new_context_handle, free_component_idx);
err = renew_nonce(new_context_handle);
@@ -568,7 +643,38 @@
}
if (create_certificate) {
- err = create_layer_certificate(derived_ctx->linked_layer_idx);
+ linked_layer_idx = derived_ctx->linked_layer_idx;
+ assert(linked_layer_idx < MAX_NUM_OF_LAYERS);
+ layer_ctx = &layer_ctx_array[linked_layer_idx];
+ layer_ctx->is_cdi_to_be_exported = export_cdi;
+
+ err = create_layer_certificate(linked_layer_idx);
+ if (err != DPE_NO_ERROR) {
+ return err;
+ }
+
+ if (return_certificate) {
+ if (new_certificate_buf_size < layer_ctx->data.cert_buf_len) {
+ return DPE_INVALID_ARGUMENT;
+ }
+
+ /* Encode and return generated layer certificate */
+ err = add_encoded_layer_certificate(layer_ctx->data.cert_buf,
+ layer_ctx->data.cert_buf_len,
+ new_certificate_buf,
+ new_certificate_buf_size,
+ new_certificate_actual_size);
+ if (err != DPE_NO_ERROR) {
+ return err;
+ }
+ }
+ }
+
+ if (export_cdi) {
+ err = get_encoded_cdi_to_export(layer_ctx,
+ exported_cdi_buf,
+ exported_cdi_buf_size,
+ exported_cdi_actual_size);
if (err != DPE_NO_ERROR) {
return err;
}