1024c4948STamas Ban /* 2024c4948STamas Ban * Copyright (c) 2024, Arm Limited. All rights reserved. 3024c4948STamas Ban * 4024c4948STamas Ban * SPDX-License-Identifier: BSD-3-Clause 5024c4948STamas Ban */ 6024c4948STamas Ban 7024c4948STamas Ban #include <assert.h> 8024c4948STamas Ban #include <stdint.h> 9024c4948STamas Ban #include <string.h> 10024c4948STamas Ban 11024c4948STamas Ban #include <psa/crypto_types.h> 12024c4948STamas Ban #include <psa/crypto_values.h> 13024c4948STamas Ban 14024c4948STamas Ban #include <common/debug.h> 15024c4948STamas Ban #include <drivers/auth/crypto_mod.h> 16b8245368STamas Ban #include <drivers/measured_boot/rse/dice_prot_env.h> 17024c4948STamas Ban #include <lib/cassert.h> 18024c4948STamas Ban #include <lib/psa/dice_protection_environment.h> 19024c4948STamas Ban 20024c4948STamas Ban #include <platform_def.h> 21024c4948STamas Ban 22024c4948STamas Ban #define DPE_ALG_SHA512 0 23024c4948STamas Ban #define DPE_ALG_SHA384 1 24024c4948STamas Ban #define DPE_ALG_SHA256 2 25024c4948STamas Ban 26024c4948STamas Ban #if DPE_ALG_ID == DPE_ALG_SHA512 27024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA512 28024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512 29024c4948STamas Ban #elif DPE_ALG_ID == DPE_ALG_SHA384 30024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA384 31024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384 32024c4948STamas Ban #elif DPE_ALG_ID == DPE_ALG_SHA256 33024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA256 34024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256 35024c4948STamas Ban #else 36024c4948STamas Ban # error Invalid DPE hash algorithm. 37024c4948STamas Ban #endif /* DPE_ALG_ID */ 38024c4948STamas Ban 39024c4948STamas Ban /* Ensure that computed hash values fits into the DiceInputValues structure */ 40024c4948STamas Ban CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE, 41024c4948STamas Ban assert_digest_size_bigger_than_allocated_buffer); 42024c4948STamas Ban 43024c4948STamas Ban static int initial_context_handle; 44024c4948STamas Ban 45024c4948STamas Ban static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata, 46024c4948STamas Ban DiceInputValues *dice_inputs) 47024c4948STamas Ban { 48024c4948STamas Ban /* Hash of the content certificate signing key (public part) */ 49024c4948STamas Ban memcpy(dice_inputs->authority_hash, metadata->signer_id, 50024c4948STamas Ban DPE_DIGEST_SIZE); 51024c4948STamas Ban 52024c4948STamas Ban /* SW type string identifier */ 53024c4948STamas Ban assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE); 54024c4948STamas Ban dice_inputs->code_descriptor = metadata->sw_type; 55024c4948STamas Ban dice_inputs->code_descriptor_size = metadata->sw_type_size; 56024c4948STamas Ban } 57024c4948STamas Ban 58024c4948STamas Ban void dpe_init(struct dpe_metadata *metadata) 59024c4948STamas Ban { 60024c4948STamas Ban assert(metadata != NULL); 61024c4948STamas Ban 62024c4948STamas Ban /* Init the non-const members of the metadata structure */ 63024c4948STamas Ban while (metadata->id != DPE_INVALID_ID) { 64024c4948STamas Ban /* Terminating 0 character is not needed due to CBOR encoding */ 65024c4948STamas Ban metadata->sw_type_size = 66024c4948STamas Ban strlen((const char *)&metadata->sw_type); 67024c4948STamas Ban metadata++; 68024c4948STamas Ban } 69024c4948STamas Ban 70024c4948STamas Ban plat_dpe_get_context_handle(&initial_context_handle); 71024c4948STamas Ban } 72024c4948STamas Ban 73024c4948STamas Ban int dpe_measure_and_record(struct dpe_metadata *metadata, 74024c4948STamas Ban uintptr_t data_base, uint32_t data_size, 75024c4948STamas Ban uint32_t data_id) 76024c4948STamas Ban { 77024c4948STamas Ban static int current_context_handle; 78024c4948STamas Ban DiceInputValues dice_inputs = { 0 }; 79024c4948STamas Ban int new_parent_context_handle; 80024c4948STamas Ban int new_context_handle; 81024c4948STamas Ban dpe_error_t ret; 82024c4948STamas Ban int rc; 83024c4948STamas Ban 84024c4948STamas Ban assert(metadata != NULL); 85024c4948STamas Ban 86024c4948STamas Ban /* Get the metadata associated with this image. */ 87024c4948STamas Ban while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) { 88024c4948STamas Ban metadata++; 89024c4948STamas Ban } 90024c4948STamas Ban 91024c4948STamas Ban /* If image is not present in metadata array then skip */ 92024c4948STamas Ban if (metadata->id == DPE_INVALID_ID) { 93024c4948STamas Ban return 0; 94024c4948STamas Ban } 95024c4948STamas Ban 96024c4948STamas Ban /* Calculate hash */ 97024c4948STamas Ban rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 98024c4948STamas Ban (void *)data_base, data_size, 99024c4948STamas Ban dice_inputs.code_hash); 100024c4948STamas Ban if (rc != 0) { 101024c4948STamas Ban return rc; 102024c4948STamas Ban } 103024c4948STamas Ban 104024c4948STamas Ban map_metadata_to_dice_inputs(metadata, &dice_inputs); 105024c4948STamas Ban 106024c4948STamas Ban /* Only at the first call */ 107024c4948STamas Ban if (current_context_handle == 0) { 108024c4948STamas Ban current_context_handle = initial_context_handle; 109024c4948STamas Ban } 110024c4948STamas Ban 111024c4948STamas Ban VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id); 112024c4948STamas Ban ret = dpe_derive_context(current_context_handle, 113024c4948STamas Ban metadata->cert_id, 114024c4948STamas Ban metadata->retain_parent_context, 115024c4948STamas Ban metadata->allow_new_context_to_derive, 116024c4948STamas Ban metadata->create_certificate, 117024c4948STamas Ban &dice_inputs, 118024c4948STamas Ban 0, /* target_locality */ 119024c4948STamas Ban false, /* return_certificate */ 120024c4948STamas Ban true, /* allow_new_context_to_export */ 121024c4948STamas Ban false, /* export_cdi */ 122024c4948STamas Ban &new_context_handle, 123024c4948STamas Ban &new_parent_context_handle, 124024c4948STamas Ban NULL, 0, NULL, /* new_certificate_* */ 125024c4948STamas Ban NULL, 0, NULL); /* exported_cdi_* */ 126024c4948STamas Ban if (ret == DPE_NO_ERROR) { 127024c4948STamas Ban current_context_handle = new_parent_context_handle; 128024c4948STamas Ban if (metadata->allow_new_context_to_derive == true) { 129024c4948STamas Ban /* Share new_context_handle with child component: 130024c4948STamas Ban * e.g: BL2, BL33. 131024c4948STamas Ban */ 132024c4948STamas Ban VERBOSE("Share new_context_handle with child: 0x%x\n", 133024c4948STamas Ban new_context_handle); 134*8e0fd0bfSTamas Ban plat_dpe_share_context_handle(&new_context_handle, 135*8e0fd0bfSTamas Ban &new_parent_context_handle); 136024c4948STamas Ban } 137024c4948STamas Ban } else { 138024c4948STamas Ban ERROR("dpe_derive_context failed: %d\n", ret); 139024c4948STamas Ban } 140024c4948STamas Ban 141024c4948STamas Ban return (ret == DPE_NO_ERROR) ? 0 : -1; 142024c4948STamas Ban } 143024c4948STamas Ban 144024c4948STamas Ban int dpe_set_signer_id(struct dpe_metadata *metadata, 145024c4948STamas Ban const void *pk_oid, 146024c4948STamas Ban const void *pk_ptr, 147024c4948STamas Ban size_t pk_len) 148024c4948STamas Ban { 149024c4948STamas Ban unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 150024c4948STamas Ban int rc; 151024c4948STamas Ban bool hash_calc_done = false; 152024c4948STamas Ban 153024c4948STamas Ban assert(metadata != NULL); 154024c4948STamas Ban 155024c4948STamas Ban /* 156024c4948STamas Ban * Do an exhaustive search over the platform metadata to find 157024c4948STamas Ban * all images whose key OID matches the one passed in argument. 158024c4948STamas Ban * 159024c4948STamas Ban * Note that it is not an error if do not get any matches. 160024c4948STamas Ban * The platform may decide not to measure all of the images 161024c4948STamas Ban * in the system. 162024c4948STamas Ban */ 163024c4948STamas Ban while (metadata->id != DPE_INVALID_ID) { 164024c4948STamas Ban /* Get the metadata associated with this key-oid */ 165024c4948STamas Ban if (metadata->pk_oid == pk_oid) { 166024c4948STamas Ban if (hash_calc_done == false) { 167024c4948STamas Ban /* Calculate public key hash */ 168024c4948STamas Ban rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 169024c4948STamas Ban (void *)pk_ptr, 170024c4948STamas Ban pk_len, hash_data); 171024c4948STamas Ban if (rc != 0) { 172024c4948STamas Ban return rc; 173024c4948STamas Ban } 174024c4948STamas Ban 175024c4948STamas Ban hash_calc_done = true; 176024c4948STamas Ban } 177024c4948STamas Ban 178024c4948STamas Ban /* 179024c4948STamas Ban * Fill the signer-ID field with the newly/already 180024c4948STamas Ban * computed hash of the public key and update its 181024c4948STamas Ban * signer ID size field with compile-time decided 182024c4948STamas Ban * digest size. 183024c4948STamas Ban */ 184024c4948STamas Ban (void)memcpy(metadata->signer_id, 185024c4948STamas Ban hash_data, 186024c4948STamas Ban DPE_DIGEST_SIZE); 187024c4948STamas Ban metadata->signer_id_size = DPE_DIGEST_SIZE; 188024c4948STamas Ban } 189024c4948STamas Ban 190024c4948STamas Ban metadata++; 191024c4948STamas Ban } 192024c4948STamas Ban 193024c4948STamas Ban return 0; 194024c4948STamas Ban } 195