xref: /rk3399_ARM-atf/drivers/measured_boot/rse/rse_measured_boot.c (revision b8245368cc79e0ab8187d805e7e743eeb3d306e7)
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