xref: /arm-trusted-firmware/drivers/measured_boot/rss/rss_measured_boot.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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