blob: d90a863b0a7b1625665bde6bfe6b0b1554595527 [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",
97#else
Raef Coles6e8dfd22022-07-29 12:57:47 +010098#ifdef TFM_PARTITION_INITIAL_ATTESTATION
Tamas Bana7ef16b2022-06-28 15:03:10 +020099#error "Attestation token profile is incorrect"
Raef Coles6e8dfd22022-07-29 12:57:47 +0100100#else
101 "UNDEFINED",
102#endif /* TFM_PARTITION_INITIAL_ATTESTATION */
Tamas Bana7ef16b2022-06-28 15:03:10 +0200103#endif
Raef Colesaefbe082021-06-18 08:53:43 +0100104 /* Entropy seed */
105 {
106 0x12, 0x13, 0x23, 0x34, 0x0a, 0x05, 0x89, 0x78,
107 0xa3, 0x66, 0x8c, 0x0d, 0x97, 0x55, 0x53, 0xca,
108 0xb5, 0x76, 0x18, 0x62, 0x29, 0xc6, 0xb6, 0x79,
109 0x75, 0xc8, 0x5a, 0x8d, 0x9e, 0x11, 0x8f, 0x85,
110 0xde, 0xc4, 0x5f, 0x66, 0x21, 0x52, 0xf9, 0x39,
111 0xd9, 0x77, 0x93, 0x28, 0xb0, 0x5e, 0x02, 0xfa,
112 0x58, 0xb4, 0x16, 0xc8, 0x0f, 0x38, 0x91, 0xbb,
113 0x28, 0x17, 0xcd, 0x8a, 0xc9, 0x53, 0x72, 0x66,
114 },
115};
116#else
117static struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data;
118static struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data;
119#endif /* TFM_DUMMY_PROVISIONING */
120
121void tfm_plat_provisioning_check_for_dummy_keys(void)
122{
123 uint64_t iak_start;
124
125 tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
126
127 if(iak_start == 0xA4906F6DB254B4A9) {
128 SPMLOG_ERRMSG("[WRN]\033[1;31m ");
129 SPMLOG_ERRMSG("This device was provisioned with dummy keys. ");
130 SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
131 SPMLOG_ERRMSG("\033[0m\r\n");
132 }
133
Ken Liub671d682022-05-12 20:39:29 +0800134 memset(&iak_start, 0, sizeof(iak_start));
Raef Colesaefbe082021-06-18 08:53:43 +0100135}
136
137int tfm_plat_provisioning_is_required(void)
138{
139 enum tfm_plat_err_t err;
140 enum plat_otp_lcs_t lcs;
141
142 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
143 if (err != TFM_PLAT_ERR_SUCCESS) {
144 return err;
145 }
146
147 return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
148 || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
149}
150
151enum tfm_plat_err_t provision_assembly_and_test(void)
152{
153 enum tfm_plat_err_t err;
154 uint32_t new_lcs;
155
156 err = tfm_plat_otp_write(PLAT_OTP_ID_HUK, sizeof(assembly_and_test_prov_data.huk),
157 assembly_and_test_prov_data.huk);
158 if (err != TFM_PLAT_ERR_SUCCESS) {
159 return err;
160 }
161
162 new_lcs = PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
163 err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, sizeof(new_lcs),
164 (uint8_t*)&new_lcs);
165 if (err != TFM_PLAT_ERR_SUCCESS) {
166 return err;
167 }
168
169 return err;
170}
171
172enum tfm_plat_err_t provision_psa_rot(void)
173{
174 enum tfm_plat_err_t err;
175 uint32_t new_lcs;
176
177 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK,
178 sizeof(psa_rot_prov_data.iak),
179 psa_rot_prov_data.iak);
180 if (err != TFM_PLAT_ERR_SUCCESS) {
181 return err;
182 }
183 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_LEN,
184 sizeof(psa_rot_prov_data.iak_len),
185 (uint8_t*)&psa_rot_prov_data.iak_len);
186 if (err != TFM_PLAT_ERR_SUCCESS) {
187 return err;
188 }
189 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_TYPE,
190 sizeof(psa_rot_prov_data.iak_type),
191 (uint8_t*)&psa_rot_prov_data.iak_type);
192 if (err != TFM_PLAT_ERR_SUCCESS) {
193 return err;
194 }
195
196#ifdef ATTEST_INCLUDE_COSE_KEY_ID
197 err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_ID,
198 sizeof(psa_rot_prov_data.iak_id),
199 psa_rot_prov_data.iak_id);
200 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
201 return err;
202 }
203#endif /* ATTEST_INCLUDE_COSE_KEY_ID */
204
205 err = tfm_plat_otp_write(PLAT_OTP_ID_BOOT_SEED,
206 sizeof(psa_rot_prov_data.boot_seed),
207 psa_rot_prov_data.boot_seed);
208 if (err != TFM_PLAT_ERR_SUCCESS) {
209 return err;
210 }
211 err = tfm_plat_otp_write(PLAT_OTP_ID_IMPLEMENTATION_ID,
212 sizeof(psa_rot_prov_data.implementation_id),
213 psa_rot_prov_data.implementation_id);
214 if (err != TFM_PLAT_ERR_SUCCESS) {
215 return err;
216 }
Tamas Banfc318d72022-06-22 14:23:52 +0200217 err = tfm_plat_otp_write(PLAT_OTP_ID_CERT_REF,
218 sizeof(psa_rot_prov_data.cert_ref),
219 psa_rot_prov_data.cert_ref);
Raef Colesaefbe082021-06-18 08:53:43 +0100220 if (err != TFM_PLAT_ERR_SUCCESS) {
221 return err;
222 }
223 err = tfm_plat_otp_write(PLAT_OTP_ID_VERIFICATION_SERVICE_URL,
224 sizeof(psa_rot_prov_data.verification_service_url),
225 psa_rot_prov_data.verification_service_url);
226 if (err != TFM_PLAT_ERR_SUCCESS) {
227 return err;
228 }
229 err = tfm_plat_otp_write(PLAT_OTP_ID_PROFILE_DEFINITION,
230 sizeof(psa_rot_prov_data.profile_definition),
231 psa_rot_prov_data.profile_definition);
232 if (err != TFM_PLAT_ERR_SUCCESS) {
233 return err;
234 }
235
236 err = tfm_plat_otp_write(PLAT_OTP_ID_ENTROPY_SEED,
237 sizeof(psa_rot_prov_data.entropy_seed),
238 psa_rot_prov_data.entropy_seed);
239 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
240 return err;
241 }
242
243 new_lcs = PLAT_OTP_LCS_SECURED;
244 err = tfm_plat_otp_write(PLAT_OTP_ID_LCS,
245 sizeof(new_lcs),
246 (uint8_t*)&new_lcs);
247 if (err != TFM_PLAT_ERR_SUCCESS) {
248 return err;
249 }
250
251 return err;
252}
253
254enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
255{
256 enum tfm_plat_err_t err;
257 enum plat_otp_lcs_t lcs;
258
259 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
260 if (err != TFM_PLAT_ERR_SUCCESS) {
261 return err;
262 }
263
264 SPMLOG_INFMSG("[INF] Beginning TF-M provisioning\r\n");
265
266#ifdef TFM_DUMMY_PROVISIONING
267 SPMLOG_ERRMSG("[WRN]\033[1;31m ");
268 SPMLOG_ERRMSG("TFM_DUMMY_PROVISIONING is not suitable for production! ");
269 SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE");
270 SPMLOG_ERRMSG("\033[0m\r\n");
271#endif /* TFM_DUMMY_PROVISIONING */
272
273 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
274 if (assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
275 SPMLOG_ERRMSG("No valid ASSEMBLY_AND_TEST provisioning data found\r\n");
276 return TFM_PLAT_ERR_INVALID_INPUT;
277 }
278
279 err = provision_assembly_and_test();
280 if (err != TFM_PLAT_ERR_SUCCESS) {
281 return err;
282 }
283 }
284
285 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
286 if (err != TFM_PLAT_ERR_SUCCESS) {
287 return err;
288 }
289 if (lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING) {
290 if (psa_rot_prov_data.magic != PSA_ROT_PROV_DATA_MAGIC) {
291 SPMLOG_ERRMSG("No valid PSA_ROT provisioning data found\r\n");
292 return TFM_PLAT_ERR_INVALID_INPUT;
293 }
294
295 err = provision_psa_rot();
296 if (err != TFM_PLAT_ERR_SUCCESS) {
297 return err;
298 }
299 }
300
301 return TFM_PLAT_ERR_SUCCESS;
302}