DPE: Fix CertifyKey when layer is finalized

When layer is finalized the CertifyKey should open
a new layer.

Change-Id: I7c86d77bf12603472435bb93abd6ef6d42ddccef
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
Signed-off-by: Maulik Patel <maulik.patel@arm.com>
diff --git a/partitions/dice_protection_environment/dpe_context_mngr.c b/partitions/dice_protection_environment/dpe_context_mngr.c
index e907b0c..758d286 100644
--- a/partitions/dice_protection_environment/dpe_context_mngr.c
+++ b/partitions/dice_protection_environment/dpe_context_mngr.c
@@ -840,8 +840,8 @@
     uint16_t input_ctx_idx, input_layer_idx, parent_layer_idx;
     dpe_error_t err;
     psa_status_t status;
-    struct layer_context_t *parent_layer_ctx, *layer_ctx;
-    struct layer_context_t leaf_layer;
+    struct layer_context_t *parent_layer_ctx, *input_layer_ctx;
+    struct layer_context_t leaf_layer = {0};
 
     log_certify_key(input_ctx_handle, retain_context, public_key, public_key_size,
                     label, label_size);
@@ -860,10 +860,20 @@
     /* Get current linked layer idx */
     input_layer_idx = component_ctx_array[input_ctx_idx].linked_layer_idx;
     assert(input_layer_idx < MAX_NUM_OF_LAYERS);
+    input_layer_ctx = &layer_ctx_array[input_layer_idx];
 
-    layer_ctx = &layer_ctx_array[input_layer_idx];
-    /* Create leaf layer as copy of input context linked layer */
-    memcpy(&leaf_layer, layer_ctx, sizeof(leaf_layer));
+    if (input_layer_ctx->state == LAYER_STATE_FINALISED) {
+        /* Input layer is finalised, new leaf layer is its child now */
+        leaf_layer.parent_layer_idx = input_layer_idx;
+        /* Linked components count already initialised to 0 */
+
+    } else {
+        /* Input layer is not finalised, new leaf layer share the same
+         * components as in the input layer
+         */
+        memcpy(&leaf_layer.linked_components, &input_layer_ctx->linked_components,
+                sizeof(input_layer_ctx->linked_components));
+    }
 
     if (public_key_size > sizeof(leaf_layer.data.attest_pub_key)) {
         return DPE_INVALID_ARGUMENT;
@@ -946,6 +956,8 @@
                                  certificate_buf,
                                  *certificate_actual_size);
 
+    destroy_layer_keys(&leaf_layer);
+
     return DPE_NO_ERROR;
 }
 
diff --git a/partitions/dice_protection_environment/dpe_crypto_interface.c b/partitions/dice_protection_environment/dpe_crypto_interface.c
index be8a403..9cd4439 100644
--- a/partitions/dice_protection_environment/dpe_crypto_interface.c
+++ b/partitions/dice_protection_environment/dpe_crypto_interface.c
@@ -335,3 +335,16 @@
 
     return status;
 }
+
+void destroy_layer_keys(const struct layer_context_t *layer_ctx)
+{
+    if (layer_ctx->data.cdi_key_id != PSA_KEY_ID_NULL) {
+        /* Remove any previously derived keys */
+        (void)psa_destroy_key(layer_ctx->data.cdi_key_id);
+    }
+
+    if (layer_ctx->data.attest_key_id != PSA_KEY_ID_NULL) {
+        /* Remove any previously derived keys */
+        (void)psa_destroy_key(layer_ctx->data.attest_key_id);
+    }
+}
diff --git a/partitions/dice_protection_environment/dpe_crypto_interface.h b/partitions/dice_protection_environment/dpe_crypto_interface.h
index 7234816..73c0775 100644
--- a/partitions/dice_protection_environment/dpe_crypto_interface.h
+++ b/partitions/dice_protection_environment/dpe_crypto_interface.h
@@ -110,6 +110,15 @@
  */
 psa_status_t get_rot_cdi_input(uint8_t rot_cdi_input[DICE_CDI_SIZE],
                                size_t rot_cdi_input_size);
+
+/**
+ * @brief Destroy the CDI and attestation keys for a layer.
+ *
+ * \param[in] layer_ctx  Pointer to current layer context.
+ *
+ */
+void destroy_layer_keys(const struct layer_context_t *layer_ctx);
+
 #ifdef __cplusplus
 }
 #endif