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