blob: da98afe1896f6fc13a5d3b7f4e397f74122edc79 [file] [log] [blame]
Tamas Ban95bcd302023-06-06 14:38:16 +02001/*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <stdint.h>
9#include <string.h>
10
11#include <psa/crypto_types.h>
12#include <psa/crypto_values.h>
13
14#include <common/debug.h>
15#include <drivers/auth/crypto_mod.h>
Tamas Ban0a7cf192024-02-21 12:49:34 +010016#include <drivers/measured_boot/rse/dice_prot_env.h>
Tamas Ban95bcd302023-06-06 14:38:16 +020017#include <lib/cassert.h>
18#include <lib/psa/dice_protection_environment.h>
19
20#include <platform_def.h>
21
22#define DPE_ALG_SHA512 0
23#define DPE_ALG_SHA384 1
24#define DPE_ALG_SHA256 2
25
26#if DPE_ALG_ID == DPE_ALG_SHA512
27#define CRYPTO_MD_ID CRYPTO_MD_SHA512
28#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512
29#elif DPE_ALG_ID == DPE_ALG_SHA384
30#define CRYPTO_MD_ID CRYPTO_MD_SHA384
31#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384
32#elif DPE_ALG_ID == DPE_ALG_SHA256
33#define CRYPTO_MD_ID CRYPTO_MD_SHA256
34#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256
35#else
36# error Invalid DPE hash algorithm.
37#endif /* DPE_ALG_ID */
38
39/* Ensure that computed hash values fits into the DiceInputValues structure */
40CASSERT(DICE_HASH_SIZE >= DPE_DIGEST_SIZE,
41 assert_digest_size_bigger_than_allocated_buffer);
42
43static int initial_context_handle;
44
45static void map_metadata_to_dice_inputs(struct dpe_metadata *metadata,
46 DiceInputValues *dice_inputs)
47{
48 /* Hash of the content certificate signing key (public part) */
49 memcpy(dice_inputs->authority_hash, metadata->signer_id,
50 DPE_DIGEST_SIZE);
51
52 /* SW type string identifier */
53 assert(metadata->sw_type_size < DICE_CODE_DESCRIPTOR_MAX_SIZE);
54 dice_inputs->code_descriptor = metadata->sw_type;
55 dice_inputs->code_descriptor_size = metadata->sw_type_size;
56}
57
58void dpe_init(struct dpe_metadata *metadata)
59{
60 assert(metadata != NULL);
61
62 /* Init the non-const members of the metadata structure */
63 while (metadata->id != DPE_INVALID_ID) {
64 /* Terminating 0 character is not needed due to CBOR encoding */
65 metadata->sw_type_size =
66 strlen((const char *)&metadata->sw_type);
67 metadata++;
68 }
69
Tamas Banae33fa92023-06-07 14:18:46 +020070 plat_dpe_get_context_handle(&initial_context_handle);
Tamas Ban95bcd302023-06-06 14:38:16 +020071}
72
73int dpe_measure_and_record(struct dpe_metadata *metadata,
74 uintptr_t data_base, uint32_t data_size,
75 uint32_t data_id)
76{
77 static int current_context_handle;
78 DiceInputValues dice_inputs = { 0 };
79 int new_parent_context_handle;
80 int new_context_handle;
81 dpe_error_t ret;
82 int rc;
83
84 assert(metadata != NULL);
85
86 /* Get the metadata associated with this image. */
87 while ((metadata->id != DPE_INVALID_ID) && (metadata->id != data_id)) {
88 metadata++;
89 }
90
91 /* If image is not present in metadata array then skip */
92 if (metadata->id == DPE_INVALID_ID) {
93 return 0;
94 }
95
96 /* Calculate hash */
97 rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
98 (void *)data_base, data_size,
99 dice_inputs.code_hash);
100 if (rc != 0) {
101 return rc;
102 }
103
104 map_metadata_to_dice_inputs(metadata, &dice_inputs);
105
106 /* Only at the first call */
107 if (current_context_handle == 0) {
108 current_context_handle = initial_context_handle;
109 }
110
111 VERBOSE("Calling dpe_derive_context, image_id: %d\n", metadata->id);
112 ret = dpe_derive_context(current_context_handle,
Tamas Band571d6e2024-01-30 10:22:29 +0100113 metadata->cert_id,
Tamas Ban95bcd302023-06-06 14:38:16 +0200114 metadata->retain_parent_context,
115 metadata->allow_new_context_to_derive,
116 metadata->create_certificate,
117 &dice_inputs,
118 0, /* target_locality */
119 false, /* return_certificate */
120 true, /* allow_new_context_to_export */
121 false, /* export_cdi */
122 &new_context_handle,
123 &new_parent_context_handle,
124 NULL, 0, NULL, /* new_certificate_* */
125 NULL, 0, NULL); /* exported_cdi_* */
126 if (ret == DPE_NO_ERROR) {
127 current_context_handle = new_parent_context_handle;
128 if (metadata->allow_new_context_to_derive == true) {
129 /* Share new_context_handle with child component:
130 * e.g: BL2, BL33.
131 */
132 VERBOSE("Share new_context_handle with child: 0x%x\n",
133 new_context_handle);
Tamas Ban14d82442024-06-03 16:51:49 +0200134 plat_dpe_share_context_handle(&new_context_handle,
135 &new_parent_context_handle);
Tamas Ban95bcd302023-06-06 14:38:16 +0200136 }
137 } else {
138 ERROR("dpe_derive_context failed: %d\n", ret);
139 }
140
141 return (ret == DPE_NO_ERROR) ? 0 : -1;
142}
143
144int dpe_set_signer_id(struct dpe_metadata *metadata,
145 const void *pk_oid,
146 const void *pk_ptr,
147 size_t pk_len)
148{
149 unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
150 int rc;
151 bool hash_calc_done = false;
152
153 assert(metadata != NULL);
154
155 /*
156 * Do an exhaustive search over the platform metadata to find
157 * all images whose key OID matches the one passed in argument.
158 *
159 * Note that it is not an error if do not get any matches.
160 * The platform may decide not to measure all of the images
161 * in the system.
162 */
163 while (metadata->id != DPE_INVALID_ID) {
164 /* Get the metadata associated with this key-oid */
165 if (metadata->pk_oid == pk_oid) {
166 if (hash_calc_done == false) {
167 /* Calculate public key hash */
168 rc = crypto_mod_calc_hash(CRYPTO_MD_ID,
169 (void *)pk_ptr,
170 pk_len, hash_data);
171 if (rc != 0) {
172 return rc;
173 }
174
175 hash_calc_done = true;
176 }
177
178 /*
179 * Fill the signer-ID field with the newly/already
180 * computed hash of the public key and update its
181 * signer ID size field with compile-time decided
182 * digest size.
183 */
184 (void)memcpy(metadata->signer_id,
185 hash_data,
186 DPE_DIGEST_SIZE);
187 metadata->signer_id_size = DPE_DIGEST_SIZE;
188 }
189
190 metadata++;
191 }
192
193 return 0;
194}