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) && (parms != NULL))
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 == 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] = 0xd0cfb419;
171 rotkh[1] = 0x4037ee3c;
172 rotkh[2] = 0xde74393e;
173 rotkh[3] = 0x0156d0a3;
174 rotkh[4] = 0x373b8677;
175 rotkh[5] = 0x6b6aee3d;
176 rotkh[6] = 0x619b459e;
177 rotkh[7] = 0xfa33f31d;
178 rotkh[8] = 0x00000000;
179 rotkh[9] = 0x00000000;
180 rotkh[10] = 0x00000000;
181 rotkh[11] = 0x00000000;
182 #else
183 if ((get_chip_revision() == 0))
184 {
185 rotkh[0] = 0x60DFBEE6;
186 rotkh[1] = 0x8799305F;
187 rotkh[2] = 0xBA9E4AE6;
188 rotkh[3] = 0x1908394F;
189 rotkh[4] = 0x7AC4F934;
190 rotkh[5] = 0xEF76BF41;
191 rotkh[6] = 0x2E27796E;
192 rotkh[7] = 0x94DB19A0;
193 rotkh[8] = 0x00000000;
194 rotkh[9] = 0x00000000;
195 rotkh[10] = 0x00000000;
196 rotkh[11] = 0x00000000;
197 }
198 else if ((get_chip_revision() == 1))
199 {
200 rotkh[0] = 0x9C758C58;
201 rotkh[1] = 0x0A5CCEAA;
202 rotkh[2] = 0x850DAD41;
203 rotkh[3] = 0x1371EEBA;
204 rotkh[4] = 0xB7874851;
205 rotkh[5] = 0x53C5BA44;
206 rotkh[6] = 0xF236F964;
207 rotkh[7] = 0x3320ECDF;
208 rotkh[8] = 0x00000000;
209 rotkh[9] = 0x00000000;
210 rotkh[10] = 0x00000000;
211 rotkh[11] = 0x00000000;
212 }
213 else if ((get_chip_revision() == 2))
214 {
215 rotkh[0] = 0xE7C7E9BB;
216 rotkh[1] = 0x12C8C535;
217 rotkh[2] = 0x37E61148;
218 rotkh[3] = 0x2BE7F18C;
219 rotkh[4] = 0x8F0E3094;
220 rotkh[5] = 0xB2BA7F32;
221 rotkh[6] = 0xEC9B4ECB;
222 rotkh[7] = 0xAD9FC941;
223 rotkh[8] = 0x00000000;
224 rotkh[9] = 0x00000000;
225 rotkh[10] = 0x00000000;
226 rotkh[11] = 0x00000000;
227 }
228 #endif
229 return status;
230 }
231
nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t * rootKeyType)232 static inline fsl_nboot_status_t nboot_hal_get_root_key_type(fsl_nboot_root_key_type_and_length_t *rootKeyType)
233 {
234 /* No need to check the input arguments for this inline functions. */
235 assert(rootKeyType);
236
237 *rootKeyType = kNBOOT_RootKey_Ecdsa_P256;
238
239 return kStatus_NBOOT_Success;
240 }
241
nboot_hal_get_pck_blob(uint8_t * pckBlob,uint32_t pckBlobSize)242 static inline fsl_nboot_status_t nboot_hal_get_pck_blob(uint8_t *pckBlob, uint32_t pckBlobSize)
243 {
244 /* No need to check the input arguments for this inline functions. */
245 assert(pckBlob);
246 assert(pckBlobSize == NBOOT_PCK_BLOB_SIZE_IN_BYTE);
247
248 fsl_nboot_status_t status = kStatus_NBOOT_Fail;
249 status_t otpStatus = kStatus_Fail;
250
251 do
252 {
253 uint32_t fuseIdxStart = OTP_NXP_WIFI_SK_MK_31_0_FUSE_IDX;
254 for (int i = 0; i < (NBOOT_PCK_BLOB_SIZE_IN_BYTE / 4); i++)
255 {
256 otpStatus = OCOTP_OtpFuseRead(fuseIdxStart, (uint32_t *)(&pckBlob[4 * i]));
257 if (otpStatus != kStatus_Success)
258 {
259 return kStatus_NBOOT_Fail;
260 }
261 ++fuseIdxStart;
262 }
263 status = kStatus_NBOOT_Success;
264 } while (false);
265
266 return status;
267 }
268
nboot_hal_get_sb3_manifest_params(fsl_nboot_context_t * context,fsl_nboot_sb3_load_manifest_parms_t * parms)269 fsl_nboot_status_t nboot_hal_get_sb3_manifest_params(fsl_nboot_context_t *context, fsl_nboot_sb3_load_manifest_parms_t *parms)
270 {
271 if ((NULL == context) || (NULL == parms))
272 {
273 return kStatus_NBOOT_InvalidArgument;
274 }
275
276 fsl_nboot_status_t status = kStatus_NBOOT_Fail;
277 do
278 {
279 status = nboot_hal_get_root_auth_parms(context, &parms->soc_RoTNVM);
280 if (status != kStatus_NBOOT_Success)
281 {
282 break;
283 }
284
285 status = nboot_hal_get_pck_blob(&parms->pckBlob[0], sizeof(parms->pckBlob));
286 if (status != kStatus_NBOOT_Success)
287 {
288 break;
289 }
290
291 status = kStatus_NBOOT_Success;
292 } while (false);
293
294 if ((status != kStatus_NBOOT_Success) && (parms != NULL))
295 {
296 (void)memset(parms, 0, sizeof(*parms));
297 }
298
299 return status;
300 }
301