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