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