xref: /rk3399_ARM-atf/drivers/measured_boot/rse/dice_prot_env.c (revision 203575c397c24a7ad1b3a858fe267909b018a646)
1024c4948STamas Ban /*
2*0c3b84c1SBoyan Karatotev  * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
3024c4948STamas Ban  *
4024c4948STamas Ban  * SPDX-License-Identifier: BSD-3-Clause
5024c4948STamas Ban  */
6024c4948STamas Ban 
7024c4948STamas Ban #include <assert.h>
8024c4948STamas Ban #include <stdint.h>
9024c4948STamas Ban #include <string.h>
10024c4948STamas Ban 
11024c4948STamas Ban #include <psa/crypto_types.h>
12024c4948STamas Ban #include <psa/crypto_values.h>
13024c4948STamas Ban 
14024c4948STamas Ban #include <common/debug.h>
15024c4948STamas Ban #include <drivers/auth/crypto_mod.h>
16b8245368STamas Ban #include <drivers/measured_boot/rse/dice_prot_env.h>
17024c4948STamas Ban #include <lib/cassert.h>
18024c4948STamas Ban #include <lib/psa/dice_protection_environment.h>
19024c4948STamas Ban 
20024c4948STamas Ban #include <platform_def.h>
21024c4948STamas Ban 
22024c4948STamas Ban #define DPE_ALG_SHA512 0
23024c4948STamas Ban #define DPE_ALG_SHA384 1
24024c4948STamas Ban #define DPE_ALG_SHA256 2
25024c4948STamas Ban 
26024c4948STamas Ban #if DPE_ALG_ID == DPE_ALG_SHA512
27024c4948STamas Ban #define	CRYPTO_MD_ID		CRYPTO_MD_SHA512
28024c4948STamas Ban #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_512
29024c4948STamas Ban #elif DPE_ALG_ID == DPE_ALG_SHA384
30024c4948STamas Ban #define	CRYPTO_MD_ID		CRYPTO_MD_SHA384
31024c4948STamas Ban #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_384
32024c4948STamas Ban #elif DPE_ALG_ID == DPE_ALG_SHA256
33024c4948STamas Ban #define	CRYPTO_MD_ID		CRYPTO_MD_SHA256
34024c4948STamas Ban #define PSA_CRYPTO_MD_ID	PSA_ALG_SHA_256
35024c4948STamas Ban #else
36024c4948STamas Ban #  error Invalid DPE hash algorithm.
37024c4948STamas Ban #endif /* DPE_ALG_ID */
38024c4948STamas Ban 
39024c4948STamas Ban /* Ensure that computed hash values fits into the DiceInputValues structure */
40024c4948STamas Ban CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
41024c4948STamas Ban 	assert_digest_size_bigger_than_allocated_buffer);
42024c4948STamas Ban 
43024c4948STamas Ban static int initial_context_handle;
44024c4948STamas Ban 
map_metadata_to_dice_inputs(struct dpe_metadata * metadata,DiceInputValues * dice_inputs)45024c4948STamas Ban static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
46024c4948STamas Ban 					DiceInputValues  *dice_inputs)
47024c4948STamas Ban {
48024c4948STamas Ban 	/* Hash of the content certificate signing key (public part) */
49024c4948STamas Ban 	memcpy(dice_inputs->authority_hash, metadata->signer_id,
50024c4948STamas Ban 	       DPE_DIGEST_SIZE);
51024c4948STamas Ban 
52024c4948STamas Ban 	/* SW type string identifier */
53024c4948STamas Ban 	assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
54024c4948STamas Ban 	dice_inputs->code_descriptor = metadata->sw_type;
55024c4948STamas Ban 	dice_inputs->code_descriptor_size = metadata->sw_type_size;
56024c4948STamas Ban }
57024c4948STamas Ban 
dpe_init(struct dpe_metadata * metadata)58024c4948STamas Ban void dpe_init(struct dpe_metadata *metadata)
59024c4948STamas Ban {
60024c4948STamas Ban 	assert(metadata != NULL);
61024c4948STamas Ban 
62024c4948STamas Ban 	/* Init the non-const members of the metadata structure */
63024c4948STamas Ban 	while (metadata->id != DPE_INVALID_ID) {
64024c4948STamas Ban 		/* Terminating 0 character is not needed due to CBOR encoding */
65024c4948STamas Ban 		metadata->sw_type_size =
66024c4948STamas Ban 			strlen((const char *)&metadata->sw_type);
67024c4948STamas Ban 		metadata++;
68024c4948STamas Ban 	}
69024c4948STamas Ban 
70024c4948STamas Ban 	plat_dpe_get_context_handle(&initial_context_handle);
71024c4948STamas Ban }
72024c4948STamas Ban 
dpe_measure_and_record(struct dpe_metadata * metadata,uintptr_t data_base,uint32_t data_size,uint32_t data_id)73024c4948STamas Ban int dpe_measure_and_record(struct dpe_metadata *metadata,
74024c4948STamas Ban 			   uintptr_t data_base, uint32_t data_size,
75024c4948STamas Ban 			   uint32_t data_id)
76024c4948STamas Ban {
77024c4948STamas Ban 	static int current_context_handle;
78024c4948STamas Ban 	DiceInputValues dice_inputs = { 0 };
79*0c3b84c1SBoyan Karatotev 	int new_parent_context_handle = 0;
80024c4948STamas Ban 	int new_context_handle;
81024c4948STamas Ban 	dpe_error_t ret;
82024c4948STamas Ban 	int rc;
83024c4948STamas Ban 
84024c4948STamas Ban 	assert(metadata != NULL);
85024c4948STamas Ban 
86024c4948STamas Ban 	/* Get the metadata associated with this image. */
87024c4948STamas Ban 	while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
88024c4948STamas Ban 		metadata++;
89024c4948STamas Ban 	}
90024c4948STamas Ban 
91024c4948STamas Ban 	/* If image is not present in metadata array then skip */
92024c4948STamas Ban 	if (metadata->id == DPE_INVALID_ID) {
93024c4948STamas Ban 		return 0;
94024c4948STamas Ban 	}
95024c4948STamas Ban 
96024c4948STamas Ban 	/* Calculate hash */
97024c4948STamas Ban 	rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
98024c4948STamas Ban 				  (void *)data_base, data_size,
99024c4948STamas Ban 				   dice_inputs.code_hash);
100024c4948STamas Ban 	if (rc != 0) {
101024c4948STamas Ban 		return rc;
102024c4948STamas Ban 	}
103024c4948STamas Ban 
104024c4948STamas Ban 	map_metadata_to_dice_inputs(metadata, &dice_inputs);
105024c4948STamas Ban 
106024c4948STamas Ban 	/* Only at the first call */
107024c4948STamas Ban 	if (current_context_handle == 0) {
108024c4948STamas Ban 		current_context_handle = initial_context_handle;
109024c4948STamas Ban 	}
110024c4948STamas Ban 
111024c4948STamas Ban 	VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
112024c4948STamas Ban 	ret = dpe_derive_context(current_context_handle,
113024c4948STamas Ban 				 metadata->cert_id,
114024c4948STamas Ban 				 metadata->retain_parent_context,
115024c4948STamas Ban 				 metadata->allow_new_context_to_derive,
116024c4948STamas Ban 				 metadata->create_certificate,
117024c4948STamas Ban 				 &dice_inputs,
1183201faf3STamas Ban 				 metadata->target_locality,
119024c4948STamas Ban 				 false, /* return_certificate */
120024c4948STamas Ban 				 true, /* allow_new_context_to_export */
121024c4948STamas Ban 				 false, /* export_cdi */
122024c4948STamas Ban 				 &new_context_handle,
123024c4948STamas Ban 				 &new_parent_context_handle,
124024c4948STamas Ban 				 NULL, 0, NULL,  /* new_certificate_* */
125024c4948STamas Ban 				 NULL, 0, NULL); /* exported_cdi_* */
126024c4948STamas Ban 	if (ret == DPE_NO_ERROR) {
127024c4948STamas Ban 		current_context_handle = new_parent_context_handle;
128024c4948STamas Ban 		if (metadata->allow_new_context_to_derive == true) {
129024c4948STamas Ban 			/* Share new_context_handle with child component:
130024c4948STamas Ban 			 * e.g: BL2, BL33.
131024c4948STamas Ban 			 */
132024c4948STamas Ban 			VERBOSE("Share new_context_handle with child: 0x%x\n",
133024c4948STamas Ban 				new_context_handle);
1348e0fd0bfSTamas Ban 			plat_dpe_share_context_handle(&new_context_handle,
1358e0fd0bfSTamas Ban 						      &new_parent_context_handle);
136024c4948STamas Ban 		}
137024c4948STamas Ban 	} else {
138024c4948STamas Ban 		ERROR("dpe_derive_context failed: %d\n", ret);
139024c4948STamas Ban 	}
140024c4948STamas Ban 
141024c4948STamas Ban 	return (ret == DPE_NO_ERROR) ? 0 : -1;
142024c4948STamas Ban }
143024c4948STamas Ban 
dpe_set_signer_id(struct dpe_metadata * metadata,const void * pk_oid,const void * pk_ptr,size_t pk_len)144024c4948STamas Ban int dpe_set_signer_id(struct dpe_metadata *metadata,
145024c4948STamas Ban 		      const void *pk_oid,
146024c4948STamas Ban 		      const void *pk_ptr,
147024c4948STamas Ban 		      size_t pk_len)
148024c4948STamas Ban {
149024c4948STamas Ban 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
150024c4948STamas Ban 	int rc;
151024c4948STamas Ban 	bool hash_calc_done = false;
152024c4948STamas Ban 
153024c4948STamas Ban 	assert(metadata != NULL);
154024c4948STamas Ban 
155024c4948STamas Ban 	/*
156024c4948STamas Ban 	 * Do an exhaustive search over the platform metadata to find
157024c4948STamas Ban 	 * all images whose key OID matches the one passed in argument.
158024c4948STamas Ban 	 *
159024c4948STamas Ban 	 * Note that it is not an error if do not get any matches.
160024c4948STamas Ban 	 * The platform may decide not to measure all of the images
161024c4948STamas Ban 	 * in the system.
162024c4948STamas Ban 	 */
163024c4948STamas Ban 	while (metadata->id != DPE_INVALID_ID) {
164024c4948STamas Ban 		/* Get the metadata associated with this key-oid */
165024c4948STamas Ban 		if (metadata->pk_oid == pk_oid) {
166024c4948STamas Ban 			if (hash_calc_done == false) {
167024c4948STamas Ban 				/* Calculate public key hash */
168024c4948STamas Ban 				rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
169024c4948STamas Ban 							  (void *)pk_ptr,
170024c4948STamas Ban 							  pk_len, hash_data);
171024c4948STamas Ban 				if (rc != 0) {
172024c4948STamas Ban 					return rc;
173024c4948STamas Ban 				}
174024c4948STamas Ban 
175024c4948STamas Ban 				hash_calc_done = true;
176024c4948STamas Ban 			}
177024c4948STamas Ban 
178024c4948STamas Ban 			/*
179024c4948STamas Ban 			 * Fill the signer-ID field with the newly/already
180024c4948STamas Ban 			 * computed hash of the public key and update its
181024c4948STamas Ban 			 * signer ID size field with compile-time decided
182024c4948STamas Ban 			 * digest size.
183024c4948STamas Ban 			 */
184024c4948STamas Ban 			(void)memcpy(metadata->signer_id,
185024c4948STamas Ban 				     hash_data,
186024c4948STamas Ban 				     DPE_DIGEST_SIZE);
187024c4948STamas Ban 			metadata->signer_id_size = DPE_DIGEST_SIZE;
188024c4948STamas Ban 		}
189024c4948STamas Ban 
190024c4948STamas Ban 		metadata++;
191024c4948STamas Ban 	}
192024c4948STamas Ban 
193024c4948STamas Ban 	return 0;
194024c4948STamas Ban }
195