DPE: Add CDI and key pair derivation
Signed-off-by: Maulik Patel <maulik.patel@arm.com>
Change-Id: I33854414c5206b65831687f3280f125327763227
diff --git a/partitions/dice_protection_environment/dpe_crypto_interface.c b/partitions/dice_protection_environment/dpe_crypto_interface.c
new file mode 100644
index 0000000..8f83666
--- /dev/null
+++ b/partitions/dice_protection_environment/dpe_crypto_interface.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "dpe_crypto_interface.h"
+#include <stdbool.h>
+#include <string.h>
+#include "dpe_context_mngr.h"
+#include "dpe_crypto_config.h"
+#include "psa/crypto.h"
+#include "tfm_crypto_defs.h"
+
+static const char attest_cdi_label[] = DPE_ATTEST_CDI_LABEL;
+static const char attest_key_pair_label[] = DPE_ATTEST_KEY_PAIR_LABEL;
+static const uint8_t attest_key_salt[] = DPE_ATTEST_KEY_SALT;
+
+static psa_status_t perform_derivation(psa_key_id_t base_key,
+ const psa_key_attributes_t *key_attr,
+ const uint8_t *key_label,
+ size_t key_label_len,
+ const uint8_t *salt,
+ size_t salt_len,
+ psa_key_id_t *out_key_id)
+{
+ psa_status_t status;
+ psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT;
+
+ assert((key_label_len != 0) && (key_label != NULL) &&
+ (base_key != 0) && (key_attr != NULL) &&
+ (salt_len != 0) && (salt != NULL));
+
+ status = psa_key_derivation_setup(&op, PSA_ALG_HKDF(PSA_ALG_SHA_256));
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_SALT,
+ salt, salt_len);
+ if (status != PSA_SUCCESS) {
+ goto err_abort;
+ }
+
+ status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET,
+ base_key);
+ if (status != PSA_SUCCESS) {
+ goto err_abort;
+ }
+
+ /* Supply the key label as an input to the key derivation */
+ status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_INFO,
+ key_label, key_label_len);
+ if (status != PSA_SUCCESS) {
+ goto err_abort;
+ }
+
+ status = psa_key_derivation_output_key(key_attr, &op, out_key_id);
+ if (status != PSA_SUCCESS) {
+ goto err_abort;
+ }
+
+ /* Free resources associated with the key derivation operation */
+ status = psa_key_derivation_abort(&op);
+ if (status == PSA_SUCCESS) {
+ goto done;
+ }
+
+ (void)psa_destroy_key(*out_key_id);
+
+err_abort:
+ (void)psa_key_derivation_abort(&op);
+
+done:
+ return status;
+}
+
+psa_status_t derive_attestation_cdi(struct layer_context_t *layer_ctx,
+ const struct layer_context_t *parent_layer_ctx)
+{
+ psa_key_attributes_t derive_key_attr = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Set key attributes for CDI key */
+ psa_set_key_type(&derive_key_attr, DPE_CDI_KEY_TYPE);
+ psa_set_key_algorithm(&derive_key_attr, DPE_CDI_KEY_ALG);
+ psa_set_key_bits(&derive_key_attr, DPE_CDI_KEY_BITS);
+ psa_set_key_usage_flags(&derive_key_attr, DPE_CDI_KEY_USAGE);
+
+ /* Perform CDI derivation */
+ /* Parent layer CDI is the base key (input secret to key derivation) */
+ return perform_derivation(parent_layer_ctx->data.cdi_key_id,
+ &derive_key_attr,
+ (uint8_t *) &attest_cdi_label[0],
+ sizeof(attest_cdi_label),
+ layer_ctx->attest_cdi_hash_input,
+ sizeof(layer_ctx->attest_cdi_hash_input),
+ &layer_ctx->data.cdi_key_id);
+}
+
+psa_status_t derive_attestation_key(struct layer_context_t *layer_ctx)
+{
+ psa_key_attributes_t attest_key_attr = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Set key attributes for Attest key pair derivation */
+ psa_set_key_type(&attest_key_attr, DPE_ATTEST_KEY_TYPE);
+ psa_set_key_algorithm(&attest_key_attr, DPE_ATTEST_KEY_ALG);
+ psa_set_key_bits(&attest_key_attr, DPE_ATTEST_KEY_BITS);
+ psa_set_key_usage_flags(&attest_key_attr, DPE_ATTEST_KEY_USAGE);
+
+ /* Perform key pair derivation */
+ return perform_derivation(layer_ctx->data.cdi_key_id,
+ &attest_key_attr,
+ (uint8_t *)&attest_key_pair_label[0],
+ sizeof(attest_key_pair_label),
+ attest_key_salt,
+ sizeof(attest_key_salt),
+ &layer_ctx->data.attest_key_id);
+}
+
+psa_status_t create_layer_cdi_key(struct layer_context_t *layer_ctx,
+ const uint8_t *cdi_input,
+ size_t cdi_input_size)
+{
+ psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* Set key attributes for CDI key */
+ psa_set_key_type(&base_attributes, DPE_CDI_KEY_TYPE);
+ psa_set_key_algorithm(&base_attributes, DPE_CDI_KEY_ALG);
+ psa_set_key_bits(&base_attributes, DPE_CDI_KEY_BITS);
+ psa_set_key_usage_flags(&base_attributes, DPE_CDI_KEY_USAGE);
+
+ return psa_import_key(&base_attributes,
+ cdi_input,
+ cdi_input_size,
+ &layer_ctx->data.cdi_key_id);
+}
+
+psa_status_t derive_sealing_cdi(struct layer_context_t *layer_ctx)
+{
+ //TODO:
+ (void)layer_ctx;
+ return PSA_SUCCESS;
+}
+
+psa_status_t derive_wrapping_key(struct layer_context_t *layer_ctx)
+{
+ //TODO:
+ (void)layer_ctx;
+ return PSA_SUCCESS;
+}
+
+psa_status_t create_layer_certificate(struct layer_context_t *layer_ctx)
+{
+ //TODO:
+ (void)layer_ctx;
+ return PSA_SUCCESS;
+}
+
+psa_status_t store_layer_certificate(struct layer_context_t *layer_ctx)
+{
+ //TODO:
+ (void)layer_ctx;
+ return PSA_SUCCESS;
+}