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