1024c4948STamas Ban /* 2024c4948STamas Ban * Copyright (c) 2022-2023, Arm Limited. All rights reserved. 3024c4948STamas Ban * 4024c4948STamas Ban * SPDX-License-Identifier: BSD-3-Clause 5024c4948STamas Ban */ 6024c4948STamas Ban #include <assert.h> 7024c4948STamas Ban #include <stdint.h> 8024c4948STamas Ban #include <string.h> 9024c4948STamas Ban 10024c4948STamas Ban #include <common/debug.h> 11024c4948STamas Ban #include <drivers/auth/crypto_mod.h> 12*b8245368STamas Ban #include <drivers/measured_boot/rse/rse_measured_boot.h> 13024c4948STamas Ban #include <lib/psa/measured_boot.h> 14024c4948STamas Ban #include <psa/crypto_types.h> 15024c4948STamas Ban #include <psa/crypto_values.h> 16024c4948STamas Ban #include <psa/error.h> 17024c4948STamas Ban 18024c4948STamas Ban #define MBOOT_ALG_SHA512 0 19024c4948STamas Ban #define MBOOT_ALG_SHA384 1 20024c4948STamas Ban #define MBOOT_ALG_SHA256 2 21024c4948STamas Ban 22024c4948STamas Ban #if MBOOT_ALG_ID == MBOOT_ALG_SHA512 23024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA512 24024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512 25024c4948STamas Ban #elif MBOOT_ALG_ID == MBOOT_ALG_SHA384 26024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA384 27024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384 28024c4948STamas Ban #elif MBOOT_ALG_ID == MBOOT_ALG_SHA256 29024c4948STamas Ban #define CRYPTO_MD_ID CRYPTO_MD_SHA256 30024c4948STamas Ban #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256 31024c4948STamas Ban #else 32024c4948STamas Ban # error Invalid Measured Boot algorithm. 33024c4948STamas Ban #endif /* MBOOT_ALG_ID */ 34024c4948STamas Ban 35024c4948STamas Ban #if ENABLE_ASSERTIONS 36024c4948STamas Ban static bool null_arr(const uint8_t *signer_id, size_t signer_id_size) 37024c4948STamas Ban { 38024c4948STamas Ban for (size_t i = 0U; i < signer_id_size; i++) { 39024c4948STamas Ban if (signer_id[i] != 0U) { 40024c4948STamas Ban return false; 41024c4948STamas Ban } 42024c4948STamas Ban } 43024c4948STamas Ban 44024c4948STamas Ban return true; 45024c4948STamas Ban } 46024c4948STamas Ban #endif /* ENABLE_ASSERTIONS */ 47024c4948STamas Ban 48024c4948STamas Ban /* Functions' declarations */ 49*b8245368STamas Ban void rse_measured_boot_init(struct rse_mboot_metadata *metadata_ptr) 50024c4948STamas Ban { 51024c4948STamas Ban assert(metadata_ptr != NULL); 52024c4948STamas Ban 53024c4948STamas Ban /* Init the non-const members of the metadata structure */ 54*b8245368STamas Ban while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) { 55024c4948STamas Ban assert(null_arr(metadata_ptr->signer_id, MBOOT_DIGEST_SIZE)); 56024c4948STamas Ban metadata_ptr->sw_type_size = 57024c4948STamas Ban strlen((const char *)&metadata_ptr->sw_type) + 1; 58024c4948STamas Ban metadata_ptr++; 59024c4948STamas Ban } 60024c4948STamas Ban } 61024c4948STamas Ban 62*b8245368STamas Ban int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr, 63024c4948STamas Ban uintptr_t data_base, uint32_t data_size, 64024c4948STamas Ban uint32_t data_id) 65024c4948STamas Ban { 66024c4948STamas Ban unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 67024c4948STamas Ban int rc; 68024c4948STamas Ban psa_status_t ret; 69024c4948STamas Ban 70024c4948STamas Ban assert(metadata_ptr != NULL); 71024c4948STamas Ban 72024c4948STamas Ban /* Get the metadata associated with this image. */ 73*b8245368STamas Ban while ((metadata_ptr->id != RSE_MBOOT_INVALID_ID) && 74024c4948STamas Ban (metadata_ptr->id != data_id)) { 75024c4948STamas Ban metadata_ptr++; 76024c4948STamas Ban } 77024c4948STamas Ban 78024c4948STamas Ban /* If image is not present in metadata array then skip */ 79*b8245368STamas Ban if (metadata_ptr->id == RSE_MBOOT_INVALID_ID) { 80024c4948STamas Ban return 0; 81024c4948STamas Ban } 82024c4948STamas Ban 83024c4948STamas Ban /* Calculate hash */ 84024c4948STamas Ban rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 85024c4948STamas Ban (void *)data_base, data_size, hash_data); 86024c4948STamas Ban if (rc != 0) { 87024c4948STamas Ban return rc; 88024c4948STamas Ban } 89024c4948STamas Ban 90*b8245368STamas Ban ret = rse_measured_boot_extend_measurement( 91024c4948STamas Ban metadata_ptr->slot, 92024c4948STamas Ban metadata_ptr->signer_id, 93024c4948STamas Ban metadata_ptr->signer_id_size, 94024c4948STamas Ban metadata_ptr->version, 95024c4948STamas Ban metadata_ptr->version_size, 96024c4948STamas Ban PSA_CRYPTO_MD_ID, 97024c4948STamas Ban metadata_ptr->sw_type, 98024c4948STamas Ban metadata_ptr->sw_type_size, 99024c4948STamas Ban hash_data, 100024c4948STamas Ban MBOOT_DIGEST_SIZE, 101024c4948STamas Ban metadata_ptr->lock_measurement); 102024c4948STamas Ban if (ret != PSA_SUCCESS) { 103024c4948STamas Ban return ret; 104024c4948STamas Ban } 105024c4948STamas Ban 106024c4948STamas Ban return 0; 107024c4948STamas Ban } 108024c4948STamas Ban 109*b8245368STamas Ban int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr, 110024c4948STamas Ban const void *pk_oid, 111024c4948STamas Ban const void *pk_ptr, 112024c4948STamas Ban size_t pk_len) 113024c4948STamas Ban { 114024c4948STamas Ban unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 115024c4948STamas Ban int rc; 116024c4948STamas Ban bool hash_calc_done = false; 117024c4948STamas Ban 118024c4948STamas Ban assert(metadata_ptr != NULL); 119024c4948STamas Ban 120024c4948STamas Ban /* 121024c4948STamas Ban * Do an exhaustive search over the platform metadata to find 122024c4948STamas Ban * all images whose key OID matches the one passed in argument. 123024c4948STamas Ban * 124024c4948STamas Ban * Note that it is not an error if do not get any matches. 125024c4948STamas Ban * The platform may decide not to measure all of the images 126024c4948STamas Ban * in the system. 127024c4948STamas Ban */ 128*b8245368STamas Ban while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) { 129024c4948STamas Ban /* Get the metadata associated with this key-oid */ 130024c4948STamas Ban if (metadata_ptr->pk_oid == pk_oid) { 131024c4948STamas Ban if (hash_calc_done == false) { 132024c4948STamas Ban /* Calculate public key hash */ 133024c4948STamas Ban rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 134024c4948STamas Ban (void *)pk_ptr, 135024c4948STamas Ban pk_len, hash_data); 136024c4948STamas Ban if (rc != 0) { 137024c4948STamas Ban return rc; 138024c4948STamas Ban } 139024c4948STamas Ban 140024c4948STamas Ban hash_calc_done = true; 141024c4948STamas Ban } 142024c4948STamas Ban 143024c4948STamas Ban /* 144024c4948STamas Ban * Fill the signer-ID field with the newly/already 145024c4948STamas Ban * computed hash of the public key and update its 146024c4948STamas Ban * signer ID size field with compile-time decided 147024c4948STamas Ban * digest size. 148024c4948STamas Ban */ 149024c4948STamas Ban (void)memcpy(metadata_ptr->signer_id, 150024c4948STamas Ban hash_data, 151024c4948STamas Ban MBOOT_DIGEST_SIZE); 152024c4948STamas Ban metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE; 153024c4948STamas Ban } 154024c4948STamas Ban 155024c4948STamas Ban metadata_ptr++; 156024c4948STamas Ban } 157024c4948STamas Ban 158024c4948STamas Ban return 0; 159024c4948STamas Ban } 160