1 /*
2 * Copyright 2020 - 2021,2024 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 */
8
9 #include <limits.h>
10 #include "fusemap.h"
11 #include "fsl_loader_utils.h"
12 #include "life_cycle.h"
13 #include "fsl_ocotp.h"
14
15 /*******************************************************************************
16 * Definitions
17 ******************************************************************************/
18 #define NBOOT_HAL_PRINTF(...)
19
20 /*******************************************************************************
21 * Prototype
22 ******************************************************************************/
23 /*!
24 * @brief Get the root security parameters.
25 *
26 * Read the root security configurations from OTP.
27 *
28 * @param context NBOOT context.
29 * @param parms Root security parameters.
30 * @retval kStatus_NBOOT_Fail Operate successfully.
31 * @retval kStatus_NBOOT_InvalidArgument Invalid values of the parms
32 * @retval kStatus_NBOOT_Fail Failed to operate.
33 */
34 static fsl_nboot_status_t nboot_hal_get_root_auth_parms(fsl_nboot_context_t *context, fsl_nboot_rot_auth_parms_t *parms);
35
36 /*!
37 * @brief Get the ROTK revoke settings.
38 *
39 * Read the OTP_ROTK_REVOKE.
40 *
41 * @param rotkRevoke ROTK revoke state.
42 * @param rotkCnt ROTK count.
43 * @retval kStatus_NBOOT_Fail Operate successfully.
44 * @retval kStatus_NBOOT_Fail Failed to operate.
45 */
46 static inline fsl_nboot_status_t nboot_hal_get_rotk_revoke(fsl_nboot_root_key_revocation_t *rotkRevoke, uint32_t rotkCnt);
47
48 /*!
49 * @brief Get the ROTKH.
50 *
51 * Read the IFR_ROTKH.
52 *
53 * @param rotkh ROTKH value.
54 * @param rotkhSize ROTKH size in bytes.
55 * @retval kStatus_NBOOT_Fail Operate successfully.
56 * @retval kStatus_NBOOT_Fail Failed to operate.
57 */
58 static fsl_nboot_status_t nboot_hal_get_rotkh(uint32_t *rotkh, uint32_t rotkhSize);
59
60 /*!
61 * @brief Get the type of the root keys.
62 *
63 * Get the root key type
64 *
65 * @param rootKeyType Type of the root keys.
66 * @retval kStatus_NBOOT_Fail Operate successfully.
67 * @retval kStatus_NBOOT_Fail Failed to operate.
68 */
69 static inline fsl_nboot_status_t nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t *rootKeyType);
70
71 /*!
72 * @brief Get the Part Common Key(PCK).
73 *
74 * Read the IFR_PCK_BLOB.
75 *
76 * @param pckBlob PCK blob.
77 * @param pckBlobSize PCK blob size in byte.
78 * @retval kStatus_NBOOT_Fail Operate successfully.
79 * @retval kStatus_NBOOT_Fail Failed to operate.
80 */
81 static inline fsl_nboot_status_t nboot_hal_get_pck_blob(uint8_t *pckBlob, uint32_t pckBlobSize);
82
83 /*******************************************************************************
84 * Codes
85 ******************************************************************************/
set_antipole(uint32_t value)86 static inline uint32_t set_antipole(uint32_t value)
87 {
88 return (value & 0xFFFFu) | (~(value & 0xFFFFu) << 16);
89 }
90
nboot_hal_get_root_auth_parms(fsl_nboot_context_t * context,fsl_nboot_rot_auth_parms_t * parms)91 static fsl_nboot_status_t nboot_hal_get_root_auth_parms(fsl_nboot_context_t *context, fsl_nboot_rot_auth_parms_t *parms)
92 {
93 if ((NULL == context) || (NULL == parms))
94 {
95 return kStatus_NBOOT_InvalidArgument;
96 }
97
98 fsl_nboot_status_t status = kStatus_NBOOT_Fail;
99 do
100 {
101 status =
102 nboot_hal_get_rotk_revoke(&parms->soc_rootKeyRevocation[0],
103 sizeof(parms->soc_rootKeyRevocation) / sizeof(parms->soc_rootKeyRevocation[0]));
104 if (status != kStatus_NBOOT_Success)
105 {
106 break;
107 }
108
109 status = nboot_hal_get_rotkh(&parms->soc_rkh[0], sizeof(parms->soc_rkh));
110 if (status != kStatus_NBOOT_Success)
111 {
112 break;
113 }
114
115 parms->soc_numberOfRootKeys = 0u;
116 parms->soc_rootKeyUsage[1] = kNBOOT_RootKeyUsage_Unused;
117 parms->soc_rootKeyUsage[2] = kNBOOT_RootKeyUsage_Unused;
118 parms->soc_rootKeyUsage[3] = kNBOOT_RootKeyUsage_Unused;
119 for (size_t i = 0; i < (sizeof(parms->soc_rootKeyUsage) / sizeof(parms->soc_rootKeyUsage[0])); i++)
120 {
121 if ((parms->soc_rootKeyUsage[i] & OTP_ROTK0_USAGE_FUSE_MASK) != kNBOOT_RootKeyUsage_Unused)
122 {
123 parms->soc_numberOfRootKeys++;
124 }
125 }
126
127 status = nboot_hal_get_root_key_type(&parms->soc_rootKeyTypeAndLength);
128 if (status != kStatus_NBOOT_Success)
129 {
130 break;
131 }
132
133 parms->soc_lifecycle = (fsl_nboot_soc_lifecycle_t)set_antipole(get_lifecycle_state());
134 status = kStatus_NBOOT_Success;
135 } while (false);
136
137 if (status != kStatus_NBOOT_Success)
138 {
139 (void)memset(parms, 0, sizeof(*parms));
140 }
141
142 return status;
143 }
144
nboot_hal_get_rotk_revoke(fsl_nboot_root_key_revocation_t * rotkRevoke,uint32_t rotkCnt)145 static inline fsl_nboot_status_t nboot_hal_get_rotk_revoke(fsl_nboot_root_key_revocation_t *rotkRevoke, uint32_t rotkCnt)
146 {
147 /* No need to check the input arguments for this inline functions. */
148 assert(rotkRevoke);
149 assert(rotkCnt == NBOOT_ROOT_CERT_COUNT);
150
151 /* Set all root key to 'revoked' state */
152 for (uint32_t i = 0u; i < rotkCnt; i++)
153 {
154 rotkRevoke[i] = kNBOOT_RootKey_Enabled;
155 }
156
157 return kStatus_NBOOT_Success;
158 }
159
nboot_hal_get_rotkh(uint32_t * rotkh,uint32_t rotkhSize)160 static fsl_nboot_status_t nboot_hal_get_rotkh(uint32_t *rotkh, uint32_t rotkhSize)
161 {
162 /* No need to check the input arguments for this inline functions. */
163 assert(rotkh);
164 assert(rotkhSize == (uint32_t)NBOOT_ROOT_ROTKH_SIZE_IN_BYTE);
165
166 fsl_nboot_status_t status = kStatus_NBOOT_Success;
167
168 /* root key hash fixed in Flash memory */
169 #ifdef USE_ENG_CERTIFICATE
170 rotkh[0] = 0xd0cfb419U;
171 rotkh[1] = 0x4037ee3cU;
172 rotkh[2] = 0xde74393eU;
173 rotkh[3] = 0x0156d0a3U;
174 rotkh[4] = 0x373b8677U;
175 rotkh[5] = 0x6b6aee3dU;
176 rotkh[6] = 0x619b459eU;
177 rotkh[7] = 0xfa33f31dU;
178 rotkh[8] = 0x00000000U;
179 rotkh[9] = 0x00000000U;
180 rotkh[10] = 0x00000000U;
181 rotkh[11] = 0x00000000U;
182 #else
183 if ((get_chip_revision() == 0U))
184 {
185 rotkh[0] = 0x60DFBEE6U;
186 rotkh[1] = 0x8799305FU;
187 rotkh[2] = 0xBA9E4AE6U;
188 rotkh[3] = 0x1908394FU;
189 rotkh[4] = 0x7AC4F934U;
190 rotkh[5] = 0xEF76BF41U;
191 rotkh[6] = 0x2E27796EU;
192 rotkh[7] = 0x94DB19A0U;
193 rotkh[8] = 0x00000000U;
194 rotkh[9] = 0x00000000U;
195 rotkh[10] = 0x00000000U;
196 rotkh[11] = 0x00000000U;
197 }
198 else if ((get_chip_revision() == 1U))
199 {
200 rotkh[0] = 0x9C758C58U;
201 rotkh[1] = 0x0A5CCEAAU;
202 rotkh[2] = 0x850DAD41U;
203 rotkh[3] = 0x1371EEBAU;
204 rotkh[4] = 0xB7874851U;
205 rotkh[5] = 0x53C5BA44U;
206 rotkh[6] = 0xF236F964U;
207 rotkh[7] = 0x3320ECDFU;
208 rotkh[8] = 0x00000000U;
209 rotkh[9] = 0x00000000U;
210 rotkh[10] = 0x00000000U;
211 rotkh[11] = 0x00000000U;
212 }
213 else if ((get_chip_revision() == 2U))
214 {
215 rotkh[0] = 0xE7C7E9BBU;
216 rotkh[1] = 0x12C8C535U;
217 rotkh[2] = 0x37E61148U;
218 rotkh[3] = 0x2BE7F18CU;
219 rotkh[4] = 0x8F0E3094U;
220 rotkh[5] = 0xB2BA7F32U;
221 rotkh[6] = 0xEC9B4ECBU;
222 rotkh[7] = 0xAD9FC941U;
223 rotkh[8] = 0x00000000U;
224 rotkh[9] = 0x00000000U;
225 rotkh[10] = 0x00000000U;
226 rotkh[11] = 0x00000000U;
227 }
228 else
229 {
230 ; /* none to do */
231 }
232 #endif
233 return status;
234 }
235
nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t * rootKeyType)236 static inline fsl_nboot_status_t nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t *rootKeyType)
237 {
238 /* No need to check the input arguments for this inline functions. */
239 assert(rootKeyType);
240
241 *rootKeyType = kNBOOT_RootKey_Ecdsa_P256;
242
243 return kStatus_NBOOT_Success;
244 }
245
nboot_hal_get_pck_blob(uint8_t * pckBlob,uint32_t pckBlobSize)246 static inline fsl_nboot_status_t nboot_hal_get_pck_blob(uint8_t *pckBlob, uint32_t pckBlobSize)
247 {
248 /* No need to check the input arguments for this inline functions. */
249 assert(pckBlob);
250 assert(pckBlobSize == (uint32_t)NBOOT_PCK_BLOB_SIZE_IN_BYTE);
251
252 fsl_nboot_status_t status = kStatus_NBOOT_Fail;
253 status_t otpStatus = kStatus_Fail;
254
255 do
256 {
257 uint32_t fuseIdxStart = OTP_NXP_WIFI_SK_MK_31_0_FUSE_IDX;
258 for (int i = 0; i < (NBOOT_PCK_BLOB_SIZE_IN_BYTE / 4); i++)
259 {
260 otpStatus = OCOTP_OtpFuseRead(fuseIdxStart, (uint32_t *)(&pckBlob[4 * i]));
261 if (otpStatus != kStatus_Success)
262 {
263 return kStatus_NBOOT_Fail;
264 }
265 ++fuseIdxStart;
266 }
267 status = kStatus_NBOOT_Success;
268 } while (false);
269
270 return status;
271 }
272
nboot_hal_get_sb3_manifest_params(fsl_nboot_context_t * context,fsl_nboot_sb3_load_manifest_parms_t * parms)273 fsl_nboot_status_t nboot_hal_get_sb3_manifest_params(fsl_nboot_context_t *context, fsl_nboot_sb3_load_manifest_parms_t *parms)
274 {
275 if ((NULL == context) || (NULL == parms))
276 {
277 return kStatus_NBOOT_InvalidArgument;
278 }
279
280 fsl_nboot_status_t status = kStatus_NBOOT_Fail;
281 do
282 {
283 status = nboot_hal_get_root_auth_parms(context, &parms->soc_RoTNVM);
284 if (status != kStatus_NBOOT_Success)
285 {
286 break;
287 }
288
289 status = nboot_hal_get_pck_blob(&parms->pckBlob[0], sizeof(parms->pckBlob));
290 if (status != kStatus_NBOOT_Success)
291 {
292 break;
293 }
294
295 status = kStatus_NBOOT_Success;
296 } while (false);
297
298 if (status != kStatus_NBOOT_Success)
299 {
300 (void)memset(parms, 0, sizeof(*parms));
301 }
302
303 return status;
304 }
305