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