1 /*
2 * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9 #include "tfm_plat_crypto_keys.h"
10 #include "tfm_builtin_key_ids.h"
11 #include "region_defs.h"
12 #include "cmsis_compiler.h"
13 #include "tfm_plat_otp.h"
14 #include "psa_manifest/pid.h"
15 #include "tfm_builtin_key_loader.h"
16 #include "kmu_drv.h"
17 #include "device_definition.h"
18 #include "tfm_plat_otp.h"
19 #include "rse_kmu_slot_ids.h"
20
21 #define NUMBER_OF_ELEMENTS_OF(x) sizeof(x)/sizeof(*x)
22 #define MAPPED_RSE_MBOX_NS_AGENT_DEFAULT_CLIENT_ID -0x04000000
23 #define TFM_NS_PARTITION_ID MAPPED_RSE_MBOX_NS_AGENT_DEFAULT_CLIENT_ID
24
tfm_plat_get_huk(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)25 static enum tfm_plat_err_t tfm_plat_get_huk(uint8_t *buf, size_t buf_len,
26 size_t *key_len,
27 psa_key_bits_t *key_bits,
28 psa_algorithm_t *algorithm,
29 psa_key_type_t *type)
30 {
31 enum kmu_error_t kmu_err;
32
33 if (buf_len < 32) {
34 return TFM_PLAT_ERR_SYSTEM_ERR;
35 }
36
37 *key_len = 32;
38 *key_bits = 256;
39 *algorithm = PSA_ALG_HKDF(PSA_ALG_SHA_256);
40 *type = PSA_KEY_TYPE_DERIVE;
41
42 kmu_err = kmu_get_key(&KMU_DEV_S, RSE_KMU_SLOT_VHUK, buf, 32);
43 if (kmu_err != KMU_ERROR_NONE) {
44 return TFM_PLAT_ERR_SYSTEM_ERR;
45 }
46
47 return TFM_PLAT_ERR_SUCCESS;
48 }
49
tfm_plat_get_iak(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)50 static enum tfm_plat_err_t tfm_plat_get_iak(uint8_t *buf, size_t buf_len,
51 size_t *key_len,
52 psa_key_bits_t *key_bits,
53 psa_algorithm_t *algorithm,
54 psa_key_type_t *type)
55 {
56 psa_status_t status;
57 enum kmu_error_t kmu_err;
58 psa_key_attributes_t seed_attributes = PSA_KEY_ATTRIBUTES_INIT;
59 psa_key_attributes_t transient_attr = PSA_KEY_ATTRIBUTES_INIT;
60 psa_key_handle_t seed_key = PSA_KEY_HANDLE_INIT;
61 psa_key_handle_t transient_key = PSA_KEY_HANDLE_INIT;
62 psa_key_derivation_operation_t op = PSA_KEY_DERIVATION_OPERATION_INIT;
63
64 if (buf_len < PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(ATTEST_KEY_BITS)) {
65 return TFM_PLAT_ERR_SYSTEM_ERR;
66 }
67
68 kmu_err = kmu_get_key(&KMU_DEV_S, RSE_KMU_SLOT_CPAK_SEED, buf, 32);
69 if (kmu_err != KMU_ERROR_NONE) {
70 return TFM_PLAT_ERR_SYSTEM_ERR;
71 }
72
73 psa_set_key_type(&seed_attributes, PSA_KEY_TYPE_DERIVE);
74 psa_set_key_algorithm(&seed_attributes, PSA_ALG_HKDF(PSA_ALG_SHA_256));
75 psa_set_key_bits(&seed_attributes, 256);
76 psa_set_key_usage_flags(&seed_attributes, PSA_KEY_USAGE_DERIVE);
77
78 status = psa_import_key(&seed_attributes, buf, 32, &seed_key);
79 if (status != PSA_SUCCESS) {
80 return TFM_PLAT_ERR_SYSTEM_ERR;
81 }
82
83 status = psa_key_derivation_setup(&op, PSA_ALG_HKDF(PSA_ALG_SHA_256));
84 if (status != PSA_SUCCESS) {
85 goto err_release_seed_key;
86 }
87
88 status = psa_key_derivation_input_key(&op, PSA_KEY_DERIVATION_INPUT_SECRET,
89 seed_key);
90 if (status != PSA_SUCCESS) {
91 goto err_release_op;
92 }
93
94 status = psa_key_derivation_input_bytes(&op, PSA_KEY_DERIVATION_INPUT_INFO,
95 NULL, 0);
96 if (status != PSA_SUCCESS) {
97 goto err_release_op;
98 }
99
100 *key_bits = ATTEST_KEY_BITS;
101 #if (ATTEST_KEY_BITS == 256)
102 *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
103 #elif (ATTEST_KEY_BITS == 384)
104 *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
105 #else
106 #error "Unsupported IAK size"
107 #endif
108 *type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
109
110 psa_set_key_type(&transient_attr, *type);
111 psa_set_key_algorithm(&transient_attr, *algorithm);
112 psa_set_key_bits(&transient_attr, *key_bits);
113 psa_set_key_usage_flags(&transient_attr, PSA_KEY_USAGE_EXPORT);
114
115 status = psa_key_derivation_output_key(&transient_attr, &op, &transient_key);
116 if (status != PSA_SUCCESS) {
117 goto err_release_op;
118 }
119
120 status = psa_export_key(transient_key, buf, buf_len, key_len);
121 if (status != PSA_SUCCESS) {
122 goto err_release_transient_key;
123 }
124
125 status = psa_destroy_key(transient_key);
126 if (status != PSA_SUCCESS) {
127 goto err_release_op;
128 }
129
130 status = psa_key_derivation_abort(&op);
131 if (status != PSA_SUCCESS) {
132 goto err_release_seed_key;
133 }
134
135 status = psa_destroy_key(seed_key);
136 if (status != PSA_SUCCESS) {
137 return TFM_PLAT_ERR_SYSTEM_ERR;
138 }
139
140 return PSA_SUCCESS;
141
142 err_release_transient_key:
143 (void)psa_destroy_key(transient_key);
144
145 err_release_op:
146 (void)psa_key_derivation_abort(&op);
147
148 err_release_seed_key:
149 (void)psa_destroy_key(seed_key);
150
151 return TFM_PLAT_ERR_SYSTEM_ERR;
152 }
153
154 #ifdef TFM_PARTITION_DELEGATED_ATTESTATION
tfm_plat_get_dak_seed(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)155 static enum tfm_plat_err_t tfm_plat_get_dak_seed(uint8_t *buf, size_t buf_len,
156 size_t *key_len,
157 psa_key_bits_t *key_bits,
158 psa_algorithm_t *algorithm,
159 psa_key_type_t *type)
160 {
161 enum kmu_error_t kmu_err;
162
163 if (buf_len < 32) {
164 return TFM_PLAT_ERR_SYSTEM_ERR;
165 }
166
167 *key_len = 32;
168 *key_bits = 256;
169 *algorithm = PSA_ALG_HKDF(PSA_ALG_SHA_256);
170 *type = PSA_KEY_TYPE_DERIVE;
171
172 kmu_err = kmu_get_key(&KMU_DEV_S, RSE_KMU_SLOT_DAK_SEED, buf, 32);
173 if (kmu_err != KMU_ERROR_NONE) {
174 return TFM_PLAT_ERR_SYSTEM_ERR;
175 }
176
177 return TFM_PLAT_ERR_SUCCESS;
178 }
179 #endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
180
181 #ifdef TFM_PARTITION_DPE
tfm_plat_get_rot_cdi(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)182 static enum tfm_plat_err_t tfm_plat_get_rot_cdi(uint8_t *buf, size_t buf_len,
183 size_t *key_len,
184 psa_key_bits_t *key_bits,
185 psa_algorithm_t *algorithm,
186 psa_key_type_t *type)
187 {
188 enum kmu_error_t kmu_err;
189
190 if (buf_len < 32) {
191 return TFM_PLAT_ERR_SYSTEM_ERR;
192 }
193
194 *key_len = 32;
195 *key_bits = 256;
196 *algorithm = PSA_ALG_HKDF(PSA_ALG_SHA_256);
197 *type = PSA_KEY_TYPE_DERIVE;
198
199 kmu_err = kmu_get_key(&KMU_DEV_S, RSE_KMU_SLOT_ROT_CDI, buf, 32);
200 if (kmu_err != KMU_ERROR_NONE) {
201 return TFM_PLAT_ERR_SYSTEM_ERR;
202 }
203
204 return TFM_PLAT_ERR_SUCCESS;
205 }
206 #endif /* TFM_PARTITION_DPE */
207
tfm_plat_get_host_s_rotpk(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)208 static enum tfm_plat_err_t tfm_plat_get_host_s_rotpk(uint8_t *buf, size_t buf_len,
209 size_t *key_len,
210 psa_key_bits_t *key_bits,
211 psa_algorithm_t *algorithm,
212 psa_key_type_t *type)
213 {
214 if (buf_len < 96) {
215 return TFM_PLAT_ERR_SYSTEM_ERR;
216 }
217
218 /* P384 public keys are 96 bytes in length */
219 *key_len = 96;
220 *key_bits = 384;
221 *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
222 *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
223
224 return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_S, buf_len, buf);
225 }
226
tfm_plat_get_host_ns_rotpk(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)227 static enum tfm_plat_err_t tfm_plat_get_host_ns_rotpk(uint8_t *buf, size_t buf_len,
228 size_t *key_len,
229 psa_key_bits_t *key_bits,
230 psa_algorithm_t *algorithm,
231 psa_key_type_t *type)
232 {
233 if (buf_len < 96) {
234 return TFM_PLAT_ERR_SYSTEM_ERR;
235 }
236
237 /* P384 public keys are 96 bytes in length */
238 *key_len = 96;
239 *key_bits = 384;
240 *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
241 *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
242
243 return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_NS, buf_len, buf);
244 }
245
tfm_plat_get_host_cca_rotpk(uint8_t * buf,size_t buf_len,size_t * key_len,psa_key_bits_t * key_bits,psa_algorithm_t * algorithm,psa_key_type_t * type)246 static enum tfm_plat_err_t tfm_plat_get_host_cca_rotpk(uint8_t *buf, size_t buf_len,
247 size_t *key_len,
248 psa_key_bits_t *key_bits,
249 psa_algorithm_t *algorithm,
250 psa_key_type_t *type)
251 {
252 if (buf_len < 96) {
253 return TFM_PLAT_ERR_SYSTEM_ERR;
254 }
255
256 /* P384 public keys are 96 bytes in length */
257 *key_len = 96;
258 *key_bits = 384;
259 *algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_384);
260 *type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1);
261
262 return tfm_plat_otp_read(PLAT_OTP_ID_HOST_ROTPK_CCA, buf_len, buf);
263 }
264
265 /**
266 * @brief Table describing per-user key policy for the IAK
267 *
268 */
269 static const tfm_plat_builtin_key_per_user_policy_t g_iak_per_user_policy[] = {
270 #ifdef TFM_PARTITION_INITIAL_ATTESTATION
271 {.user = TFM_SP_INITIAL_ATTESTATION,
272 #ifdef SYMMETRIC_INITIAL_ATTESTATION
273 .usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT,
274 #else
275 .usage = PSA_KEY_USAGE_SIGN_HASH,
276 #endif /* SYMMETRIC_INITIAL_ATTESTATION */
277 },
278 #endif /* TFM_PARTITION_INITIAL_ATTESTATION */
279 #ifdef TEST_S_ATTESTATION
280 {.user = TFM_SP_SECURE_TEST_PARTITION, .usage = PSA_KEY_USAGE_VERIFY_HASH},
281 #endif /* TEST_S_ATTESTATION */
282 #ifdef TEST_NS_ATTESTATION
283 {.user = TFM_NS_PARTITION_ID, .usage = PSA_KEY_USAGE_VERIFY_HASH},
284 #endif /* TEST_NS_ATTESTATION */
285 #ifdef TFM_PARTITION_DPE
286 {.user = TFM_SP_DPE, .usage = PSA_KEY_USAGE_SIGN_HASH},
287 #endif /* TFM_PARTITION_DPE */
288 };
289
290 #ifdef TFM_PARTITION_DELEGATED_ATTESTATION
291 /**
292 * @brief Table describing per-user key policy for the DAK seed
293 *
294 */
295 static const tfm_plat_builtin_key_per_user_policy_t g_dak_seed_per_user_policy[] = {
296 {.user = TFM_SP_DELEGATED_ATTESTATION, .usage = PSA_KEY_USAGE_DERIVE},
297 };
298 #endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
299
300 #ifdef TFM_PARTITION_DPE
301 /**
302 * @brief Table describing per-user key policy for the RoT CDI
303 *
304 */
305 static const tfm_plat_builtin_key_per_user_policy_t g_rot_cdi_per_user_policy[] = {
306 {.user = TFM_SP_DPE,
307 .usage = PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT},
308 };
309 #endif /* TFM_PARTITION_DPE */
310
311 /**
312 * @brief Table describing per-user key policy for all the HOST RoTPK (S, NS, CCA)
313 *
314 */
315 static const tfm_plat_builtin_key_per_user_policy_t g_host_rotpk_per_user_policy[] = {
316 {.user = TFM_NS_PARTITION_ID, .usage = PSA_KEY_USAGE_VERIFY_HASH},
317 };
318
319 /**
320 * @brief Table describing per-key user policies
321 *
322 */
323 static const tfm_plat_builtin_key_policy_t g_builtin_keys_policy[] = {
324 {.key_id = TFM_BUILTIN_KEY_ID_HUK, .per_user_policy = 0, .usage = PSA_KEY_USAGE_DERIVE},
325 {.key_id = TFM_BUILTIN_KEY_ID_IAK,
326 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_iak_per_user_policy),
327 .policy_ptr = g_iak_per_user_policy},
328 #ifdef TFM_PARTITION_DELEGATED_ATTESTATION
329 {.key_id = TFM_BUILTIN_KEY_ID_DAK_SEED,
330 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_dak_seed_per_user_policy),
331 .policy_ptr = g_dak_seed_per_user_policy},
332 #endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
333 {.key_id = TFM_BUILTIN_KEY_ID_HOST_S_ROTPK,
334 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_host_rotpk_per_user_policy),
335 .policy_ptr = g_host_rotpk_per_user_policy},
336 {.key_id = TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK,
337 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_host_rotpk_per_user_policy),
338 .policy_ptr = g_host_rotpk_per_user_policy},
339 {.key_id = TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
340 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_host_rotpk_per_user_policy),
341 .policy_ptr = g_host_rotpk_per_user_policy},
342 #ifdef TFM_PARTITION_DPE
343 {.key_id = TFM_BUILTIN_KEY_ID_ROT_CDI,
344 .per_user_policy = NUMBER_OF_ELEMENTS_OF(g_rot_cdi_per_user_policy),
345 .policy_ptr = g_rot_cdi_per_user_policy},
346 #endif /* TFM_PARTITION_DPE */
347 };
348
349 /**
350 * @brief Table describing the builtin-in keys (plaform keys) available in the platform. Note
351 * that to bind the keys to the tfm_builtin_key_loader driver, the lifetime must be
352 * explicitly set to the one associated to the driver, i.e. TFM_BUILTIN_KEY_LOADER_LIFETIME
353 */
354 static const tfm_plat_builtin_key_descriptor_t g_builtin_keys_desc[] = {
355 {.key_id = TFM_BUILTIN_KEY_ID_HUK,
356 .slot_number = TFM_BUILTIN_KEY_SLOT_HUK,
357 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
358 .loader_key_func = tfm_plat_get_huk},
359 {.key_id = TFM_BUILTIN_KEY_ID_IAK,
360 .slot_number = TFM_BUILTIN_KEY_SLOT_IAK,
361 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
362 .loader_key_func = tfm_plat_get_iak},
363 #ifdef TFM_PARTITION_DELEGATED_ATTESTATION
364 {.key_id = TFM_BUILTIN_KEY_ID_DAK_SEED,
365 .slot_number = TFM_BUILTIN_KEY_SLOT_DAK_SEED,
366 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
367 .loader_key_func = tfm_plat_get_dak_seed},
368 #endif /* TFM_PARTITION_DELEGATED_ATTESTATION */
369 {.key_id = TFM_BUILTIN_KEY_ID_HOST_S_ROTPK,
370 .slot_number = TFM_BUILTIN_KEY_SLOT_HOST_S_ROTPK,
371 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
372 .loader_key_func = tfm_plat_get_host_s_rotpk},
373 {.key_id = TFM_BUILTIN_KEY_ID_HOST_NS_ROTPK,
374 .slot_number = TFM_BUILTIN_KEY_SLOT_HOST_NS_ROTPK,
375 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
376 .loader_key_func = tfm_plat_get_host_ns_rotpk},
377 {.key_id = TFM_BUILTIN_KEY_ID_HOST_CCA_ROTPK,
378 .slot_number = TFM_BUILTIN_KEY_SLOT_HOST_CCA_ROTPK,
379 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
380 .loader_key_func = tfm_plat_get_host_cca_rotpk},
381 #ifdef TFM_PARTITION_DPE
382 {.key_id = TFM_BUILTIN_KEY_ID_ROT_CDI,
383 .slot_number = TFM_BUILTIN_KEY_SLOT_ROT_CDI,
384 .lifetime = TFM_BUILTIN_KEY_LOADER_LIFETIME,
385 .loader_key_func = tfm_plat_get_rot_cdi},
386 #endif /* TFM_PARTITION_DPE */
387 };
388
tfm_plat_builtin_key_get_policy_table_ptr(const tfm_plat_builtin_key_policy_t * desc_ptr[])389 size_t tfm_plat_builtin_key_get_policy_table_ptr(const tfm_plat_builtin_key_policy_t *desc_ptr[])
390 {
391 *desc_ptr = &g_builtin_keys_policy[0];
392 return NUMBER_OF_ELEMENTS_OF(g_builtin_keys_policy);
393 }
394
tfm_plat_builtin_key_get_desc_table_ptr(const tfm_plat_builtin_key_descriptor_t * desc_ptr[])395 size_t tfm_plat_builtin_key_get_desc_table_ptr(const tfm_plat_builtin_key_descriptor_t *desc_ptr[])
396 {
397 *desc_ptr = &g_builtin_keys_desc[0];
398 return NUMBER_OF_ELEMENTS_OF(g_builtin_keys_desc);
399 }
400