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