1 /*
2 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3 *
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 "bootutil/bootutil_log.h"
15
16 #include <string.h>
17
18 #define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
19
20 #ifdef MCUBOOT_SIGN_EC384
21 #define PUB_KEY_HASH_SIZE (48)
22 #define PUB_KEY_SIZE (100) /* Size must be aligned to 4 Bytes */
23 #else
24 #define PUB_KEY_HASH_SIZE (32)
25 #define PUB_KEY_SIZE (68) /* Size must be aligned to 4 Bytes */
26 #endif /* MCUBOOT_SIGN_EC384 */
27
28 #ifdef MCUBOOT_BUILTIN_KEY
29 #define PROV_ROTPK_DATA_SIZE PUB_KEY_SIZE
30 #else
31 #define PROV_ROTPK_DATA_SIZE PUB_KEY_HASH_SIZE
32 #endif /* MCUBOOT_BUILTIN_KEY */
33
34 __PACKED_STRUCT bl2_assembly_and_test_provisioning_data_t {
35 uint32_t magic;
36 uint8_t bl2_rotpk_0[PROV_ROTPK_DATA_SIZE];
37 uint8_t bl2_rotpk_1[PROV_ROTPK_DATA_SIZE];
38 #if (MCUBOOT_IMAGE_NUMBER > 2)
39 uint8_t bl2_rotpk_2[PROV_ROTPK_DATA_SIZE];
40 #endif
41 #if (MCUBOOT_IMAGE_NUMBER > 3)
42 uint8_t bl2_rotpk_3[PROV_ROTPK_DATA_SIZE];
43 #endif
44
45 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
46 uint8_t secure_debug_pk[32];
47 #endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
48 };
49
50 #ifdef TFM_DUMMY_PROVISIONING
51
52 #if !defined(MCUBOOT_BUILTIN_KEY)
53 /* List of BL2 Root of Trust public key hashes */
54 #if defined(MCUBOOT_SIGN_RSA)
55 #if (MCUBOOT_SIGN_RSA_LEN == 2048)
56 /* SHA-256 hashes of RSA-2048 public keys (in PKCS#1 format)
57 * DATA_KIND_0: hash of PK(bl2/ext/mcuboot/root-RSA-2048.pem)
58 * DATA_KIND_1: hash of PK(bl2/ext/mcuboot/root-RSA-2048_1.pem)
59 */
60 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { \
61 0xfc, 0x57, 0x01, 0xdc, 0x61, 0x35, 0xe1, 0x32, \
62 0x38, 0x47, 0xbd, 0xc4, 0x0f, 0x04, 0xd2, 0xe5, \
63 0xbe, 0xe5, 0x83, 0x3b, 0x23, 0xc2, 0x9f, 0x93, \
64 0x59, 0x3d, 0x00, 0x01, 0x8c, 0xfa, 0x99, 0x94, \
65 }
66 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { \
67 0xe1, 0x80, 0x15, 0x99, 0x3d, 0x6d, 0x27, 0x60, \
68 0xb4, 0x99, 0x27, 0x4b, 0xae, 0xf2, 0x64, 0xb8, \
69 0x3a, 0xf2, 0x29, 0xe9, 0xa7, 0x85, 0xf3, 0xd5, \
70 0xbf, 0x00, 0xb9, 0xd3, 0x2c, 0x1f, 0x03, 0x96, \
71 }
72 #elif (MCUBOOT_SIGN_RSA_LEN == 3072)
73 /* SHA-256 hashes of RSA-3072 public keys (in PKCS#1 format)
74 * DATA_KIND_0: hash of PK(bl2/ext/mcuboot/root-RSA-3072.pem)
75 * DATA_KIND_1: hash of PK(bl2/ext/mcuboot/root-RSA-3072_1.pem)
76 */
77 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { \
78 0xbf, 0xe6, 0xd8, 0x6f, 0x88, 0x26, 0xf4, 0xff, \
79 0x97, 0xfb, 0x96, 0xc4, 0xe6, 0xfb, 0xc4, 0x99, \
80 0x3e, 0x46, 0x19, 0xfc, 0x56, 0x5d, 0xa2, 0x6a, \
81 0xdf, 0x34, 0xc3, 0x29, 0x48, 0x9a, 0xdc, 0x38, \
82 }
83 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { \
84 0xb3, 0x60, 0xca, 0xf5, 0xc9, 0x8c, 0x6b, 0x94, \
85 0x2a, 0x48, 0x82, 0xfa, 0x9d, 0x48, 0x23, 0xef, \
86 0xb1, 0x66, 0xa9, 0xef, 0x6a, 0x6e, 0x4a, 0xa3, \
87 0x7c, 0x19, 0x19, 0xed, 0x1f, 0xcc, 0xc0, 0x49, \
88 }
89 #endif /* MCUBOOT_SIGN_RSA_LEN */
90 #elif defined(MCUBOOT_SIGN_EC256)
91 /* SHA-256 hashes of EC-P256 public keys
92 * (in SubjectPublicKeyInfo format, see RFC5480)
93 * DATA_KIND_0: hash of PK(bl2/ext/mcuboot/root-EC-P256.pem)
94 * DATA_KIND_1: hash of PK(bl2/ext/mcuboot/root-EC-P256_1.pem)
95 */
96 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { \
97 0xe3, 0x04, 0x66, 0xf6, 0xb8, 0x47, 0x0c, 0x1f, \
98 0x29, 0x07, 0x0b, 0x17, 0xf1, 0xe2, 0xd3, 0xe9, \
99 0x4d, 0x44, 0x5e, 0x3f, 0x60, 0x80, 0x87, 0xfd, \
100 0xc7, 0x11, 0xe4, 0x38, 0x2b, 0xb5, 0x38, 0xb6, \
101 }
102 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { \
103 0x82, 0xa5, 0xb4, 0x43, 0x59, 0x48, 0x53, 0xd4, \
104 0xbf, 0x0f, 0xdd, 0x89, 0xa9, 0x14, 0xa5, 0xdc, \
105 0x16, 0xf8, 0x67, 0x54, 0x82, 0x07, 0xd7, 0x07, \
106 0x7e, 0x74, 0xd8, 0x0c, 0x06, 0x3e, 0xfd, 0xa9, \
107 }
108 #elif defined(MCUBOOT_SIGN_EC384)
109 /* SHA-384 hashes of EC-P384 public keys
110 * (in SubjectPublicKeyInfo format, see RFC5480)
111 * DATA_KIND_0: hash of PK(bl2/ext/mcuboot/root-EC-P384.pem)
112 * DATA_KIND_1: hash of PK(bl2/ext/mcuboot/root-EC-P384_1.pem)
113 */
114 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { \
115 0x85, 0xb7, 0xbd, 0x5f, 0x5d, 0xff, 0x9a, 0x03, \
116 0xa9, 0x99, 0x27, 0xad, 0xaf, 0x6c, 0xa6, 0xfe, \
117 0xbd, 0xe8, 0x22, 0xc1, 0xa4, 0x80, 0x92, 0x83, \
118 0x24, 0xa8, 0xe6, 0x03, 0x23, 0x71, 0x5c, 0x57, \
119 0x79, 0x46, 0x1c, 0x49, 0x6a, 0x95, 0xae, 0xe8, \
120 0xc4, 0xf9, 0x0b, 0x99, 0x77, 0x9f, 0x84, 0x8a, \
121 }
122 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { \
123 0xae, 0x13, 0xb7, 0x1d, 0xae, 0x49, 0xa7, 0xb8, \
124 0x9d, 0x4d, 0x8e, 0xe5, 0x09, 0x5c, 0xb8, 0xd4, \
125 0x5a, 0x32, 0xbd, 0x9c, 0x7d, 0x50, 0x1c, 0xd3, \
126 0xb8, 0xf8, 0x6c, 0xbc, 0x8b, 0x41, 0x43, 0x9b, \
127 0x1b, 0x22, 0x5c, 0xc3, 0x6a, 0x5b, 0xa8, 0x08, \
128 0x1d, 0xf0, 0x71, 0xe0, 0xcb, 0xbc, 0x61, 0x92, \
129 }
130 #endif /* MCUBOOT_SIGN_RSA */
131
132 #else /* !MCUBOOT_BUILTIN_KEY */
133 /* List of BL2 Root of Trust public keys */
134 #if defined(MCUBOOT_SIGN_EC256)
135 /* EC-P256 public keys
136 * (raw keys as subjectPublicKey (bit string), see RFC5480)
137 * DATA_KIND_0: PK(bl2/ext/mcuboot/root-EC-P256.pem)
138 * DATA_KIND_1: PK(bl2/ext/mcuboot/root-EC-P256_1.pem)
139 */
140 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { \
141 0x04, 0x2a, 0xcb, 0x40, 0x3c, 0xe8, 0xfe, 0xed, \
142 0x5b, 0xa4, 0x49, 0x95, 0xa1, 0xa9, 0x1d, 0xae, \
143 0xe8, 0xdb, 0xbe, 0x19, 0x37, 0xcd, 0x14, 0xfb, \
144 0x2f, 0x24, 0x57, 0x37, 0xe5, 0x95, 0x39, 0x88, \
145 0xd9, 0x94, 0xb9, 0xd6, 0x5a, 0xeb, 0xd7, 0xcd, \
146 0xd5, 0x30, 0x8a, 0xd6, 0xfe, 0x48, 0xb2, 0x4a, \
147 0x6a, 0x81, 0x0e, 0xe5, 0xf0, 0x7d, 0x8b, 0x68, \
148 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53, 0x8e, 0xfa, \
149 0xc1, \
150 }
151 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { \
152 0x04, 0xe8, 0x09, 0x08, 0x12, 0x3a, 0x0f, 0xad, \
153 0x40, 0xe0, 0x33, 0x8a, 0xa6, 0x54, 0xf8, 0x83, \
154 0x95, 0x41, 0x8e, 0x44, 0x99, 0xa2, 0x0f, 0xae, \
155 0x85, 0x69, 0x2b, 0xf9, 0x26, 0xb5, 0xe9, 0x9e, \
156 0x16, 0x2c, 0x87, 0x76, 0x62, 0x7f, 0x32, 0x6c, \
157 0x9b, 0x70, 0x78, 0x06, 0x52, 0x52, 0x52, 0xca, \
158 0x2b, 0xd2, 0xb7, 0xc7, 0x50, 0x07, 0x66, 0x3b, \
159 0x3b, 0xdf, 0xe1, 0x99, 0x69, 0x00, 0x26, 0x2c, \
160 0x33, \
161 }
162 #elif defined(MCUBOOT_SIGN_EC384)
163 /* EC-P384 public keys
164 * (raw keys as subjectPublicKey (bit string), see RFC5480)
165 * DATA_KIND_0: PK(bl2/ext/mcuboot/root-EC-P384.pem)
166 * DATA_KIND_1: PK(bl2/ext/mcuboot/root-EC-P384_1.pem)
167 */
168 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_0 { 0x04, \
169 0x0c, 0x76, 0xca, 0xae, 0x72, 0x3a, 0xa5, 0xe8, \
170 0xf0, 0xd4, 0xf1, 0x16, 0xb5, 0x02, 0xef, 0x77, \
171 0xa1, 0x1b, 0x93, 0x61, 0x78, 0xc0, 0x09, 0x26, \
172 0x7b, 0x3b, 0x40, 0x9c, 0xee, 0x49, 0x85, 0xe0, \
173 0xc9, 0x4f, 0xe7, 0xf2, 0xba, 0x97, 0x6c, 0xf3, \
174 0x82, 0x65, 0x14, 0x2c, 0xf5, 0x0c, 0x73, 0x33, \
175 0x4d, 0x32, 0xe7, 0x9b, 0xd3, 0x42, 0xcc, 0x95, \
176 0x5a, 0xe5, 0xe2, 0xf5, 0xf4, 0x6e, 0x45, 0xe0, \
177 0xed, 0x20, 0x35, 0x5c, 0xaf, 0x52, 0x35, 0x81, \
178 0xd4, 0xdc, 0x9c, 0xe3, 0x9e, 0x22, 0x3e, 0xfb, \
179 0x3f, 0x22, 0x10, 0xda, 0x70, 0x03, 0x37, 0xad, \
180 0xa8, 0xf2, 0x48, 0xfe, 0x3a, 0x60, 0x69, 0xa5, \
181 }
182 #define ASSEMBLY_AND_TEST_PROV_DATA_KIND_1 { 0x04, \
183 0x34, 0x43, 0xad, 0x59, 0x83, 0xd9, 0x41, 0x65, \
184 0xdc, 0x20, 0xb8, 0x62, 0x35, 0xf8, 0x7d, 0x94, \
185 0x13, 0x5e, 0x75, 0xe6, 0xa8, 0x79, 0xe9, 0xcb, \
186 0xfd, 0xa7, 0x2e, 0x92, 0x95, 0x82, 0xa6, 0xc5, \
187 0xdd, 0x53, 0xc7, 0x3d, 0x46, 0xed, 0x75, 0xd5, \
188 0x20, 0xb5, 0xbe, 0x74, 0x2a, 0x6d, 0x30, 0xe2, \
189 0x31, 0x50, 0x1c, 0x7f, 0xc7, 0x7b, 0x4a, 0x73, \
190 0x55, 0xf8, 0x92, 0x60, 0xff, 0x2f, 0x18, 0x04, \
191 0xbc, 0xc7, 0xd9, 0xce, 0xda, 0xa6, 0x36, 0x52, \
192 0xec, 0x2b, 0x64, 0x6e, 0x7a, 0x97, 0x60, 0x9d, \
193 0x8c, 0xba, 0xfe, 0xec, 0x9a, 0xb0, 0xc2, 0x6e, \
194 0x3d, 0x75, 0x2a, 0x98, 0xb2, 0xa3, 0x09, 0x84, \
195 }
196 #endif /* MCUBOOT_SIGN_EC256 */
197 #endif /* !MCUBOOT_BUILTIN_KEY */
198
199 static const struct bl2_assembly_and_test_provisioning_data_t bl2_assembly_and_test_prov_data = {
200 ASSEMBLY_AND_TEST_PROV_DATA_MAGIC,
201 #if defined(MCUBOOT_SIGN_RSA)
202 #if (MCUBOOT_SIGN_RSA_LEN == 2048)
203 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 0 */
204 ASSEMBLY_AND_TEST_PROV_DATA_KIND_1, /* bl2 rotpk 1 */
205 #if (MCUBOOT_IMAGE_NUMBER > 2)
206 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 2 */
207 #endif
208 #if (MCUBOOT_IMAGE_NUMBER > 3)
209 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 3 */
210 #endif
211
212 #elif (MCUBOOT_SIGN_RSA_LEN == 3072)
213 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 0 */
214 ASSEMBLY_AND_TEST_PROV_DATA_KIND_1, /* bl2 rotpk 1 */
215 #if (MCUBOOT_IMAGE_NUMBER > 2)
216 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 2 */
217 #endif
218 #if (MCUBOOT_IMAGE_NUMBER > 3)
219 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 3 */
220 #endif
221 #endif /* MCUBOOT_SIGN_RSA_LEN */
222
223 #elif defined(MCUBOOT_SIGN_EC256)
224 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 0 */
225 ASSEMBLY_AND_TEST_PROV_DATA_KIND_1, /* bl2 rotpk 1 */
226 #if MCUBOOT_IMAGE_NUMBER > 2
227 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 2 */
228 #endif
229 #if MCUBOOT_IMAGE_NUMBER > 3
230 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 3 */
231 #endif
232
233 #elif defined(MCUBOOT_SIGN_EC384)
234 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 0 */
235 ASSEMBLY_AND_TEST_PROV_DATA_KIND_1, /* bl2 rotpk 1 */
236 #if MCUBOOT_IMAGE_NUMBER > 2
237 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 2 */
238 #endif
239 #if MCUBOOT_IMAGE_NUMBER > 3
240 ASSEMBLY_AND_TEST_PROV_DATA_KIND_0, /* bl2 rotpk 3 */
241 #endif
242 #else
243 #error "No public key available for given signing algorithm."
244 #endif /* MCUBOOT_SIGN_RSA */
245
246 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
247 {
248 0xf4, 0x0c, 0x8f, 0xbf, 0x12, 0xdb, 0x78, 0x2a,
249 0xfd, 0xf4, 0x75, 0x96, 0x6a, 0x06, 0x82, 0x36,
250 0xe0, 0x32, 0xab, 0x80, 0xd1, 0xb7, 0xf1, 0xbc,
251 0x9f, 0xe7, 0xd8, 0x7a, 0x88, 0xcb, 0x26, 0xd0,
252 },
253 #endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
254 };
255 #else
256 static const struct bl2_assembly_and_test_provisioning_data_t bl2_assembly_and_test_prov_data;
257 #endif /* TFM_DUMMY_PROVISIONING */
258
tfm_plat_provisioning_check_for_dummy_keys(void)259 void tfm_plat_provisioning_check_for_dummy_keys(void)
260 {
261 uint64_t iak_start;
262
263 tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
264
265 if(iak_start == 0xA4906F6DB254B4A9) {
266 BOOT_LOG_WRN("%s%s%s%s",
267 "\033[1;31m",
268 "This device was provisioned with dummy keys. ",
269 "This device is \033[1;1mNOT SECURE",
270 "\033[0m");
271 }
272
273 memset(&iak_start, 0, sizeof(iak_start));
274 }
275
tfm_plat_provisioning_is_required(void)276 int tfm_plat_provisioning_is_required(void)
277 {
278 enum tfm_plat_err_t err;
279 enum plat_otp_lcs_t lcs;
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
286 return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
287 || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
288 }
289
provision_assembly_and_test(void)290 enum tfm_plat_err_t provision_assembly_and_test(void)
291 {
292 enum tfm_plat_err_t err;
293
294 err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_0,
295 sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_0),
296 bl2_assembly_and_test_prov_data.bl2_rotpk_0);
297 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
298 return err;
299 }
300 err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_1,
301 sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_1),
302 bl2_assembly_and_test_prov_data.bl2_rotpk_1);
303 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
304 return err;
305 }
306 #if (MCUBOOT_IMAGE_NUMBER > 2)
307 err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_2,
308 sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_2),
309 bl2_assembly_and_test_prov_data.bl2_rotpk_2);
310 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
311 return err;
312 }
313 #endif /* MCUBOOT_IMAGE_NUMBER > 2 */
314 #if (MCUBOOT_IMAGE_NUMBER > 3)
315 err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_3,
316 sizeof(bl2_assembly_and_test_prov_data.bl2_rotpk_3),
317 bl2_assembly_and_test_prov_data.bl2_rotpk_3);
318 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
319 return err;
320 }
321 #endif /* MCUBOOT_IMAGE_NUMBER > 3 */
322
323 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
324 err = tfm_plat_otp_write(PLAT_OTP_ID_SECURE_DEBUG_PK,
325 sizeof(bl2_assembly_and_test_prov_data.secure_debug_pk),
326 bl2_assembly_and_test_prov_data.secure_debug_pk);
327 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
328 return err;
329 }
330 #endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
331
332 return err;
333 }
334
tfm_plat_provisioning_perform(void)335 enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
336 {
337 enum tfm_plat_err_t err;
338 enum plat_otp_lcs_t lcs;
339
340 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
341 if (err != TFM_PLAT_ERR_SUCCESS) {
342 return err;
343 }
344
345 BOOT_LOG_INF("Beginning BL2 provisioning");
346
347 #ifdef TFM_DUMMY_PROVISIONING
348 BOOT_LOG_WRN("%s%s%s%s",
349 "\033[1;31m",
350 "TFM_DUMMY_PROVISIONING is not suitable for production! ",
351 "This device is \033[1;1mNOT SECURE",
352 "\033[0m");
353 #endif /* TFM_DUMMY_PROVISIONING */
354
355 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
356 if (bl2_assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
357 BOOT_LOG_ERR("No valid ASSEMBLY_AND_TEST provisioning data found");
358 return TFM_PLAT_ERR_INVALID_INPUT;
359 }
360
361 err = tfm_plat_otp_secure_provisioning_start();
362 if (err != TFM_PLAT_ERR_SUCCESS) {
363 return err;
364 }
365
366 err = provision_assembly_and_test();
367 if (err != TFM_PLAT_ERR_SUCCESS) {
368 return err;
369 }
370
371 err = tfm_plat_otp_secure_provisioning_finish();
372 if (err != TFM_PLAT_ERR_SUCCESS) {
373 return err;
374 }
375 }
376
377 return TFM_PLAT_ERR_SUCCESS;
378 }
379