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