blob: 358d7723d3c2a7d0d8cd92875a0349e3de1ecd0c [file] [log] [blame]
Raef Colesaefbe082021-06-18 08:53:43 +01001/*
Tamas Banfc318d72022-06-22 14:23:52 +02002 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
Raef Colesaefbe082021-06-18 08:53:43 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Xinyu Zhangd15f99c2022-10-27 15:03:34 +08008#include "config_attest.h"
Raef Colesaefbe082021-06-18 08:53:43 +01009#include "tfm_plat_provisioning.h"
10
11#include "cmsis_compiler.h"
12#include "tfm_plat_otp.h"
13#include "tfm_attest_hal.h"
14#include "psa/crypto.h"
15#include "tfm_spm_log.h"
Raef Colesaefbe082021-06-18 08:53:43 +010016
17#include <string.h>
18
19#define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
20#define PSA_ROT_PROV_DATA_MAGIC 0xBEEFFEED
21
22__PACKED_STRUCT tfm_assembly_and_test_provisioning_data_t {
23 uint32_t magic;
24 uint8_t huk[32];
25};
26
27__PACKED_STRUCT tfm_psa_rot_provisioning_data_t {
28 uint32_t magic;
29 uint8_t iak[32];
30 uint32_t iak_len;
31 uint32_t iak_type;
32 uint8_t iak_id[32];
33
34 uint8_t boot_seed[32];
35 uint8_t implementation_id[32];
Tamas Banfc318d72022-06-22 14:23:52 +020036 uint8_t cert_ref[32];
Raef Colesaefbe082021-06-18 08:53:43 +010037 uint8_t verification_service_url[32];
38 uint8_t profile_definition[32];
39
40 uint8_t entropy_seed[64];
41};
42
43#ifdef TFM_DUMMY_PROVISIONING
44static const struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data = {
45 ASSEMBLY_AND_TEST_PROV_DATA_MAGIC,
46 /* HUK */
47 {
48 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
49 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
50 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
51 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
52 },
53};
54
55static const struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data = {
56 PSA_ROT_PROV_DATA_MAGIC,
57 /* IAK */
58 {
59 0xA9, 0xB4, 0x54, 0xB2, 0x6D, 0x6F, 0x90, 0xA4,
60 0xEA, 0x31, 0x19, 0x35, 0x64, 0xCB, 0xA9, 0x1F,
61 0xEC, 0x6F, 0x9A, 0x00, 0x2A, 0x7D, 0xC0, 0x50,
62 0x4B, 0x92, 0xA1, 0x93, 0x71, 0x34, 0x58, 0x5F
63 },
64 /* IAK len */
65 32,
66#ifdef SYMMETRIC_INITIAL_ATTESTATION
67 /* IAK type */
68 PSA_ALG_HMAC(PSA_ALG_SHA_256),
69#else
70 /* IAK type */
71 PSA_ECC_FAMILY_SECP_R1,
72#endif /* SYMMETRIC_INITIAL_ATTESTATION */
73 /* IAK id */
74 "kid@trustedfirmware.example",
75 /* boot seed */
76 {
77 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
78 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
79 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
80 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
81 },
82 /* implementation id */
83 {
84 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
85 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
86 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
87 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
88 },
Tamas Banfc318d72022-06-22 14:23:52 +020089 /* certification reference */
Tamas Banfbdbf662022-06-28 15:28:38 +020090 "0604565272829-10010",
Raef Colesaefbe082021-06-18 08:53:43 +010091 /* verification_service_url */
92 "www.trustedfirmware.org",
93 /* attestation_profile_definition */
Xinyu Zhangd15f99c2022-10-27 15:03:34 +080094#if ATTEST_TOKEN_PROFILE_PSA_IOT_1
Raef Colesaefbe082021-06-18 08:53:43 +010095 "PSA_IOT_PROFILE_1",
Xinyu Zhangd15f99c2022-10-27 15:03:34 +080096#elif ATTEST_TOKEN_PROFILE_PSA_2_0_0
Tamas Bana7ef16b2022-06-28 15:03:10 +020097 "http://arm.com/psa/2.0.0",
Xinyu Zhangd15f99c2022-10-27 15:03:34 +080098#elif ATTEST_TOKEN_PROFILE_ARM_CCA
Tamas Ban7a32d9c2022-06-28 15:45:10 +020099 "http://arm.com/CCA-SSD/1.0.0",
Tamas Bana7ef16b2022-06-28 15:03:10 +0200100#else
Raef Coles6e8dfd22022-07-29 12:57:47 +0100101#ifdef TFM_PARTITION_INITIAL_ATTESTATION
Tamas Bana7ef16b2022-06-28 15:03:10 +0200102#error "Attestation token profile is incorrect"
Raef Coles6e8dfd22022-07-29 12:57:47 +0100103#else
104 "UNDEFINED",
105#endif /* TFM_PARTITION_INITIAL_ATTESTATION */
Tamas Bana7ef16b2022-06-28 15:03:10 +0200106#endif
Raef Colesaefbe082021-06-18 08:53:43 +0100107 /* Entropy seed */
108 {
109 0x12, 0x13, 0x23, 0x34, 0x0a, 0x05, 0x89, 0x78,
110 0xa3, 0x66, 0x8c, 0x0d, 0x97, 0x55, 0x53, 0xca,
111 0xb5, 0x76, 0x18, 0x62, 0x29, 0xc6, 0xb6, 0x79,
112 0x75, 0xc8, 0x5a, 0x8d, 0x9e, 0x11, 0x8f, 0x85,
113 0xde, 0xc4, 0x5f, 0x66, 0x21, 0x52, 0xf9, 0x39,
114 0xd9, 0x77, 0x93, 0x28, 0xb0, 0x5e, 0x02, 0xfa,
115 0x58, 0xb4, 0x16, 0xc8, 0x0f, 0x38, 0x91, 0xbb,
116 0x28, 0x17, 0xcd, 0x8a, 0xc9, 0x53, 0x72, 0x66,
117 },
118};
119#else
120static struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data;
121static struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data;
122#endif /* TFM_DUMMY_PROVISIONING */
123
124void tfm_plat_provisioning_check_for_dummy_keys(void)
125{
126 uint64_t iak_start;
127
128 tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
129
130 if(iak_start == 0xA4906F6DB254B4A9) {
131 SPMLOG_ERRMSG("[WRN]\033[1;31m ");
132 SPMLOG_ERRMSG("This device was provisioned with dummy keys. ");
133 SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
134 SPMLOG_ERRMSG("\033[0m\r\n");
135 }
136
Ken Liub671d682022-05-12 20:39:29 +0800137 memset(&iak_start, 0, sizeof(iak_start));
Raef Colesaefbe082021-06-18 08:53:43 +0100138}
139
140int tfm_plat_provisioning_is_required(void)
141{
142 enum tfm_plat_err_t err;
143 enum plat_otp_lcs_t lcs;
144
145 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
146 if (err != TFM_PLAT_ERR_SUCCESS) {
147 return err;
148 }
149
150 return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
151 || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
152}
153
154enum tfm_plat_err_t provision_assembly_and_test(void)
155{
156 enum tfm_plat_err_t err;
157 uint32_t new_lcs;
158
159 err = tfm_plat_otp_write(PLAT_OTP_ID_HUK, sizeof(assembly_and_test_prov_data.huk),
160 assembly_and_test_prov_data.huk);
161 if (err != TFM_PLAT_ERR_SUCCESS) {
162 return err;
163 }
164
165 new_lcs = PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
166 err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, sizeof(new_lcs),
167 (uint8_t*)&new_lcs);
168 if (err != TFM_PLAT_ERR_SUCCESS) {
169 return err;
170 }
171
172 return err;
173}
174
175enum tfm_plat_err_t provision_psa_rot(void)
176{
177 enum tfm_plat_err_t err;
178 uint32_t new_lcs;
179
180 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK,
181 sizeof(psa_rot_prov_data.iak),
182 psa_rot_prov_data.iak);
183 if (err != TFM_PLAT_ERR_SUCCESS) {
184 return err;
185 }
186 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_LEN,
187 sizeof(psa_rot_prov_data.iak_len),
188 (uint8_t*)&psa_rot_prov_data.iak_len);
189 if (err != TFM_PLAT_ERR_SUCCESS) {
190 return err;
191 }
192 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_TYPE,
193 sizeof(psa_rot_prov_data.iak_type),
194 (uint8_t*)&psa_rot_prov_data.iak_type);
195 if (err != TFM_PLAT_ERR_SUCCESS) {
196 return err;
197 }
198
Xinyu Zhangd15f99c2022-10-27 15:03:34 +0800199#if ATTEST_INCLUDE_COSE_KEY_ID
Raef Colesaefbe082021-06-18 08:53:43 +0100200 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_ID,
201 sizeof(psa_rot_prov_data.iak_id),
202 psa_rot_prov_data.iak_id);
203 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
204 return err;
205 }
206#endif /* ATTEST_INCLUDE_COSE_KEY_ID */
207
208 err = tfm_plat_otp_write(PLAT_OTP_ID_BOOT_SEED,
209 sizeof(psa_rot_prov_data.boot_seed),
210 psa_rot_prov_data.boot_seed);
211 if (err != TFM_PLAT_ERR_SUCCESS) {
212 return err;
213 }
214 err = tfm_plat_otp_write(PLAT_OTP_ID_IMPLEMENTATION_ID,
215 sizeof(psa_rot_prov_data.implementation_id),
216 psa_rot_prov_data.implementation_id);
217 if (err != TFM_PLAT_ERR_SUCCESS) {
218 return err;
219 }
Tamas Banfc318d72022-06-22 14:23:52 +0200220 err = tfm_plat_otp_write(PLAT_OTP_ID_CERT_REF,
221 sizeof(psa_rot_prov_data.cert_ref),
222 psa_rot_prov_data.cert_ref);
Raef Colesaefbe082021-06-18 08:53:43 +0100223 if (err != TFM_PLAT_ERR_SUCCESS) {
224 return err;
225 }
226 err = tfm_plat_otp_write(PLAT_OTP_ID_VERIFICATION_SERVICE_URL,
227 sizeof(psa_rot_prov_data.verification_service_url),
228 psa_rot_prov_data.verification_service_url);
229 if (err != TFM_PLAT_ERR_SUCCESS) {
230 return err;
231 }
232 err = tfm_plat_otp_write(PLAT_OTP_ID_PROFILE_DEFINITION,
233 sizeof(psa_rot_prov_data.profile_definition),
234 psa_rot_prov_data.profile_definition);
235 if (err != TFM_PLAT_ERR_SUCCESS) {
236 return err;
237 }
238
239 err = tfm_plat_otp_write(PLAT_OTP_ID_ENTROPY_SEED,
240 sizeof(psa_rot_prov_data.entropy_seed),
241 psa_rot_prov_data.entropy_seed);
242 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
243 return err;
244 }
245
246 new_lcs = PLAT_OTP_LCS_SECURED;
247 err = tfm_plat_otp_write(PLAT_OTP_ID_LCS,
248 sizeof(new_lcs),
249 (uint8_t*)&new_lcs);
250 if (err != TFM_PLAT_ERR_SUCCESS) {
251 return err;
252 }
253
254 return err;
255}
256
257enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
258{
259 enum tfm_plat_err_t err;
260 enum plat_otp_lcs_t lcs;
261
262 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
263 if (err != TFM_PLAT_ERR_SUCCESS) {
264 return err;
265 }
266
267 SPMLOG_INFMSG("[INF] Beginning TF-M provisioning\r\n");
268
269#ifdef TFM_DUMMY_PROVISIONING
270 SPMLOG_ERRMSG("[WRN]\033[1;31m ");
271 SPMLOG_ERRMSG("TFM_DUMMY_PROVISIONING is not suitable for production! ");
272 SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
273 SPMLOG_ERRMSG("\033[0m\r\n");
274#endif /* TFM_DUMMY_PROVISIONING */
275
276 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
277 if (assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
278 SPMLOG_ERRMSG("No valid ASSEMBLY_AND_TEST provisioning data found\r\n");
279 return TFM_PLAT_ERR_INVALID_INPUT;
280 }
281
282 err = provision_assembly_and_test();
283 if (err != TFM_PLAT_ERR_SUCCESS) {
284 return err;
285 }
286 }
287
288 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
289 if (err != TFM_PLAT_ERR_SUCCESS) {
290 return err;
291 }
292 if (lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING) {
293 if (psa_rot_prov_data.magic != PSA_ROT_PROV_DATA_MAGIC) {
294 SPMLOG_ERRMSG("No valid PSA_ROT provisioning data found\r\n");
295 return TFM_PLAT_ERR_INVALID_INPUT;
296 }
297
298 err = provision_psa_rot();
299 if (err != TFM_PLAT_ERR_SUCCESS) {
300 return err;
301 }
302 }
303
304 return TFM_PLAT_ERR_SUCCESS;
305}