1 /* 2 * Copyright (c) 2022-2023, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <assert.h> 7 #include <stdint.h> 8 #include <string.h> 9 10 #include <common/debug.h> 11 #include <drivers/auth/crypto_mod.h> 12 #include <drivers/measured_boot/rse/rse_measured_boot.h> 13 #include <lib/psa/measured_boot.h> 14 #include <psa/crypto_types.h> 15 #include <psa/crypto_values.h> 16 #include <psa/error.h> 17 18 #define MBOOT_ALG_SHA512 0 19 #define MBOOT_ALG_SHA384 1 20 #define MBOOT_ALG_SHA256 2 21 22 #if MBOOT_ALG_ID == MBOOT_ALG_SHA512 23 #define CRYPTO_MD_ID CRYPTO_MD_SHA512 24 #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512 25 #elif MBOOT_ALG_ID == MBOOT_ALG_SHA384 26 #define CRYPTO_MD_ID CRYPTO_MD_SHA384 27 #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384 28 #elif MBOOT_ALG_ID == MBOOT_ALG_SHA256 29 #define CRYPTO_MD_ID CRYPTO_MD_SHA256 30 #define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256 31 #else 32 # error Invalid Measured Boot algorithm. 33 #endif /* MBOOT_ALG_ID */ 34 35 #if ENABLE_ASSERTIONS 36 static bool null_arr(const uint8_t *signer_id, size_t signer_id_size) 37 { 38 for (size_t i = 0U; i < signer_id_size; i++) { 39 if (signer_id[i] != 0U) { 40 return false; 41 } 42 } 43 44 return true; 45 } 46 #endif /* ENABLE_ASSERTIONS */ 47 48 /* Functions' declarations */ 49 void rse_measured_boot_init(struct rse_mboot_metadata *metadata_ptr) 50 { 51 assert(metadata_ptr != NULL); 52 53 /* Init the non-const members of the metadata structure */ 54 while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) { 55 assert(null_arr(metadata_ptr->signer_id, MBOOT_DIGEST_SIZE)); 56 metadata_ptr->sw_type_size = 57 strlen((const char *)&metadata_ptr->sw_type) + 1; 58 metadata_ptr++; 59 } 60 } 61 62 int rse_mboot_measure_and_record(struct rse_mboot_metadata *metadata_ptr, 63 uintptr_t data_base, uint32_t data_size, 64 uint32_t data_id) 65 { 66 unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 67 int rc; 68 psa_status_t ret; 69 70 assert(metadata_ptr != NULL); 71 72 /* Get the metadata associated with this image. */ 73 while ((metadata_ptr->id != RSE_MBOOT_INVALID_ID) && 74 (metadata_ptr->id != data_id)) { 75 metadata_ptr++; 76 } 77 78 /* If image is not present in metadata array then skip */ 79 if (metadata_ptr->id == RSE_MBOOT_INVALID_ID) { 80 return 0; 81 } 82 83 /* Calculate hash */ 84 rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 85 (void *)data_base, data_size, hash_data); 86 if (rc != 0) { 87 return rc; 88 } 89 90 ret = rse_measured_boot_extend_measurement( 91 metadata_ptr->slot, 92 metadata_ptr->signer_id, 93 metadata_ptr->signer_id_size, 94 metadata_ptr->version, 95 metadata_ptr->version_size, 96 PSA_CRYPTO_MD_ID, 97 metadata_ptr->sw_type, 98 metadata_ptr->sw_type_size, 99 hash_data, 100 MBOOT_DIGEST_SIZE, 101 metadata_ptr->lock_measurement); 102 if (ret != PSA_SUCCESS) { 103 return ret; 104 } 105 106 return 0; 107 } 108 109 int rse_mboot_set_signer_id(struct rse_mboot_metadata *metadata_ptr, 110 const void *pk_oid, 111 const void *pk_ptr, 112 size_t pk_len) 113 { 114 unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 115 int rc; 116 bool hash_calc_done = false; 117 118 assert(metadata_ptr != NULL); 119 120 /* 121 * Do an exhaustive search over the platform metadata to find 122 * all images whose key OID matches the one passed in argument. 123 * 124 * Note that it is not an error if do not get any matches. 125 * The platform may decide not to measure all of the images 126 * in the system. 127 */ 128 while (metadata_ptr->id != RSE_MBOOT_INVALID_ID) { 129 /* Get the metadata associated with this key-oid */ 130 if (metadata_ptr->pk_oid == pk_oid) { 131 if (hash_calc_done == false) { 132 /* Calculate public key hash */ 133 rc = crypto_mod_calc_hash(CRYPTO_MD_ID, 134 (void *)pk_ptr, 135 pk_len, hash_data); 136 if (rc != 0) { 137 return rc; 138 } 139 140 hash_calc_done = true; 141 } 142 143 /* 144 * Fill the signer-ID field with the newly/already 145 * computed hash of the public key and update its 146 * signer ID size field with compile-time decided 147 * digest size. 148 */ 149 (void)memcpy(metadata_ptr->signer_id, 150 hash_data, 151 MBOOT_DIGEST_SIZE); 152 metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE; 153 } 154 155 metadata_ptr++; 156 } 157 158 return 0; 159 } 160