1 /*
2  * Copyright (c) 2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "tfm_plat_otp.h"
9 #include "provisioning_bundle.h"
10 #include "Driver_Flash.h"
11 /* This is a stub to make the linker happy */
__Vectors()12 void __Vectors(){}
13 
14 extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
15 extern const struct provisioning_data_t data;
16 
do_provision(void)17 enum tfm_plat_err_t __attribute__((section("DO_PROVISION"))) do_provision(void) {
18     enum tfm_plat_err_t err;
19     uint32_t new_lcs;
20 
21     err = (enum tfm_plat_err_t)FLASH_DEV_NAME.Initialize(NULL);
22     if (err != TFM_PLAT_ERR_SUCCESS) {
23         return err;
24     }
25 
26     err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_0,
27                              sizeof(data.bl2_assembly_and_test_prov_data.bl2_rotpk_0),
28                              data.bl2_assembly_and_test_prov_data.bl2_rotpk_0);
29     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
30         return err;
31     }
32 
33     err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_1,
34                              sizeof(data.bl2_assembly_and_test_prov_data.bl2_rotpk_1),
35                              data.bl2_assembly_and_test_prov_data.bl2_rotpk_1);
36     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
37         return err;
38     }
39 #if (MCUBOOT_IMAGE_NUMBER > 2)
40     err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_2,
41                              sizeof(data.bl2_assembly_and_test_prov_data.bl2_rotpk_2),
42                              data.bl2_assembly_and_test_prov_data.bl2_rotpk_2);
43     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
44         return err;
45     }
46 #endif /* MCUBOOT_IMAGE_NUMBER > 2 */
47 #if (MCUBOOT_IMAGE_NUMBER > 3)
48     err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_ROTPK_3,
49                              sizeof(data.bl2_assembly_and_test_prov_data.bl2_rotpk_3),
50                              data.bl2_assembly_and_test_prov_data.bl2_rotpk_3);
51     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
52         return err;
53     }
54 #endif /* MCUBOOT_IMAGE_NUMBER > 3 */
55 
56 #ifdef PLATFORM_PSA_ADAC_SECURE_DEBUG
57     err = tfm_plat_otp_write(PLAT_OTP_ID_SECURE_DEBUG_PK,
58                              sizeof(data.bl2_assembly_and_test_prov_data.secure_debug_pk),
59                              data.bl2_assembly_and_test_prov_data.secure_debug_pk);
60     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
61         return err;
62     }
63 #endif /* PLATFORM_PSA_ADAC_SECURE_DEBUG */
64 
65     err = tfm_plat_otp_write(PLAT_OTP_ID_HUK, sizeof(data.assembly_and_test_prov_data.huk),
66                              data.assembly_and_test_prov_data.huk);
67     if (err != TFM_PLAT_ERR_SUCCESS) {
68         return err;
69     }
70 
71     new_lcs = PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
72     err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, sizeof(new_lcs),
73                              (uint8_t*)&new_lcs);
74     if (err != TFM_PLAT_ERR_SUCCESS) {
75         return err;
76     }
77 
78     err = tfm_plat_otp_write(PLAT_OTP_ID_IAK,
79                              sizeof(data.psa_rot_prov_data.iak),
80                              data.psa_rot_prov_data.iak);
81     if (err != TFM_PLAT_ERR_SUCCESS) {
82         return err;
83     }
84     err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_LEN,
85                              sizeof(data.psa_rot_prov_data.iak_len),
86                              (uint8_t*)&data.psa_rot_prov_data.iak_len);
87     if (err != TFM_PLAT_ERR_SUCCESS) {
88         return err;
89     }
90     err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_TYPE,
91                              sizeof(data.psa_rot_prov_data.iak_type),
92                              (uint8_t*)&data.psa_rot_prov_data.iak_type);
93     if (err != TFM_PLAT_ERR_SUCCESS) {
94         return err;
95     }
96 
97 #if ATTEST_INCLUDE_COSE_KEY_ID
98     err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_ID,
99                              sizeof(data.psa_rot_prov_data.iak_id),
100                              data.psa_rot_prov_data.iak_id);
101     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
102         return err;
103     }
104 #endif /* ATTEST_INCLUDE_COSE_KEY_ID */
105 
106     err = tfm_plat_otp_write(PLAT_OTP_ID_BOOT_SEED,
107                              sizeof(data.psa_rot_prov_data.boot_seed),
108                              data.psa_rot_prov_data.boot_seed);
109     if (err != TFM_PLAT_ERR_SUCCESS) {
110         return err;
111     }
112     err = tfm_plat_otp_write(PLAT_OTP_ID_IMPLEMENTATION_ID,
113                              sizeof(data.psa_rot_prov_data.implementation_id),
114                              data.psa_rot_prov_data.implementation_id);
115     if (err != TFM_PLAT_ERR_SUCCESS) {
116         return err;
117     }
118     err = tfm_plat_otp_write(PLAT_OTP_ID_CERT_REF,
119                              sizeof(data.psa_rot_prov_data.cert_ref),
120                              data.psa_rot_prov_data.cert_ref);
121     if (err != TFM_PLAT_ERR_SUCCESS) {
122         return err;
123     }
124     err = tfm_plat_otp_write(PLAT_OTP_ID_VERIFICATION_SERVICE_URL,
125                              sizeof(data.psa_rot_prov_data.verification_service_url),
126                              data.psa_rot_prov_data.verification_service_url);
127     if (err != TFM_PLAT_ERR_SUCCESS) {
128         return err;
129     }
130     err = tfm_plat_otp_write(PLAT_OTP_ID_PROFILE_DEFINITION,
131                              sizeof(data.psa_rot_prov_data.profile_definition),
132                              data.psa_rot_prov_data.profile_definition);
133     if (err != TFM_PLAT_ERR_SUCCESS) {
134         return err;
135     }
136 
137     err = tfm_plat_otp_write(PLAT_OTP_ID_ENTROPY_SEED,
138                              sizeof(data.psa_rot_prov_data.entropy_seed),
139                              data.psa_rot_prov_data.entropy_seed);
140     if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
141         return err;
142     }
143 
144     new_lcs = PLAT_OTP_LCS_SECURED;
145     err = tfm_plat_otp_write(PLAT_OTP_ID_LCS,
146                              sizeof(new_lcs),
147                              (uint8_t*)&new_lcs);
148     if (err != TFM_PLAT_ERR_SUCCESS) {
149         return err;
150     }
151 
152     return err;
153 }
154