1 /*
2  * Copyright 2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_NBOOT_H_
8 #define _FSL_NBOOT_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup nboot
14  * @{
15  */
16 /*******************************************************************************
17  * Definitions
18  ******************************************************************************/
19 /** @def NXPCLHASH_WA_SIZE_MAX
20  *  @brief Define the max workarea size required for this component
21  */
22 #define NXPCLHASH_WA_SIZE_MAX (128U+64U)
23 #define NBOOT_ROOT_CERT_COUNT (4U)
24 #define NXPCLCSS_HASH_RTF_OUTPUT_SIZE_HAL ((size_t) 32U) ///< Size of RTF appendix to hash output buffer, in bytes
25 
26 #define NBOOT_KEYINFO_WORDLEN (23U)
27 #define NBOOT_CONTEXT_BYTELEN (192U + NXPCLHASH_WA_SIZE_MAX)
28 #define NBOOT_CONTEXT_WORDLEN (NBOOT_CONTEXT_BYTELEN/sizeof(uint32_t))
29 typedef int romapi_status_t;
30 
31 /*!
32  * @brief NBOOT type for the root key usage
33  *
34  * This type defines the NBOOT root key usage;
35  * any other value means the root key is not valid (treat as if revoked).
36  */
37 #define kNBOOT_RootKeyUsage_DebugCA_ImageCA_FwCA_ImageKey_FwKey (0x0U)
38 #define kNBOOT_RootKeyUsage_DebugCA (0x1U)
39 #define kNBOOT_RootKeyUsage_ImageCA_FwCA (0x2U)
40 #define kNBOOT_RootKeyUsage_DebugCA_ImageCA_FwCA (0x3U)
41 #define kNBOOT_RootKeyUsage_ImageKey_FwKey (0x4U)
42 #define kNBOOT_RootKeyUsage_ImageKey (0x5U)
43 #define kNBOOT_RootKeyUsage_FwKey (0x6U)
44 #define kNBOOT_RootKeyUsage_Unused (0x7U)
45 typedef uint32_t nboot_root_key_usage_t;
46 
47 /*!
48  * @brief NBOOT type for the root key revocation
49  *
50  * This type defines the NBOOT root key revocation;
51  * any other value means the root key is revoked.
52  */
53 #define kNBOOT_RootKey_Enabled (0xAAU)
54 #define kNBOOT_RootKey_Revoked (0xBBU)
55 typedef uint32_t nboot_root_key_revocation_t;
56 
57 /*!
58  * @brief NBOOT type specifying the elliptic curve to be used
59  *
60  * This type defines the elliptic curve type and length
61  */
62 #define kNBOOT_RootKey_Ecdsa_P256 (0x0000FE01U)
63 #define kNBOOT_RootKey_Ecdsa_P384 (0x0000FD02U)
64 typedef uint32_t nboot_root_key_type_and_length_t;
65 
66 /*! @brief Enumeration for SoC Lifecycle. */
67 #define nboot_lc_nxpBlank (0xFFFF0000U)
68 #define nboot_lc_nxpFab (0xFFFE0001U)
69 #define nboot_lc_nxpDev (0xFF0300FCU)
70 #define nboot_lc_nxpProvisioned (0xFFFC0003U)
71 #define nboot_lc_oemOpen          (0xFFFC0003U)
72 #define nboot_lc_oemSecureWorld   (0xFFF80007U)
73 #define nboot_lc_oemClosed        (0xFFF0000FU)
74 #define nboot_lc_oemLocked        (0xFF3000CFU)
75 #define nboot_lc_oemFieldReturn   (0xFFE0001FU)
76 #define nboot_lc_nxpFieldReturn   (0xFF80007FU)
77 #define nboot_lc_shredded         (0xFF0000FFU)
78 typedef uint32_t nboot_soc_lifecycle_t;
79 
80 /*! @brief Type for nboot status codes */
81 typedef uint32_t nboot_status_t;
82 
83 /*! @brief Type for nboot protected status codes */
84 typedef uint64_t nboot_status_protected_t;
85 
86 /*!
87  * @brief nboot status codes.
88  */
89 enum
90 {
91     kStatus_NBOOT_Success = 0x5A5A5A5AU,    /*!< Operation completed successfully. */
92     kStatus_NBOOT_Fail = 0x5A5AA5A5U,    /*!< Operation failed. */
93     kStatus_NBOOT_InvalidArgument = 0x5A5AA5F0U,    /*!< Invalid argument passed to the function. */
94     kStatus_NBOOT_RequestTimeout = 0x5A5AA5E1U,    /*!< Operation timed out. */
95     kStatus_NBOOT_KeyNotLoaded = 0x5A5AA5E2U,    /*!< The requested key is not loaded. */
96     kStatus_NBOOT_AuthFail = 0x5A5AA5E4U,    /*!< Authentication failed. */
97     kStatus_NBOOT_OperationNotAvaialable = 0x5A5AA5E5U,    /*!< Operation not available on this HW. */
98     kStatus_NBOOT_KeyNotAvailable = 0x5A5AA5E6U,    /*!< Key is not avaialble. */
99     kStatus_NBOOT_IvCounterOverflow = 0x5A5AA5E7U,    /*!< Overflow of IV counter (PRINCE/IPED). */
100     kStatus_NBOOT_SelftestFail = 0x5A5AA5E8U,    /*!< FIPS self-test failure. */
101     kStatus_NBOOT_InvalidDataFormat = 0x5A5AA5E9U,    /*!< Invalid data format for example antipole */
102     kStatus_NBOOT_IskCertUserDataTooBig = 0x5A5AA5EAU,    /*!< Size of User data in ISK certificate is greater than 96 bytes */
103     kStatus_NBOOT_IskCertSignatureOffsetTooSmall = 0x5A5AA5EBU,    /*!< Signature offset in ISK certificate is smaller than expected */
104     kStatus_NBOOT_MemcpyFail =0x5A5A845AU,      /*!< Unexpected error detected during nboot_memcpy() */
105 };
106 
107 /*! @brief Data structure holding secure counter value used by nboot library */
108 typedef struct _nboot_secure_counter
109 {
110     uint32_t sc;
111     uint32_t scAp;
112 } nboot_secure_counter_t;
113 
114 /*!
115  * @brief NBOOT context type
116  *
117  * This type defines the NBOOT context
118  *
119  */
120 typedef struct _nboot_context
121 {
122     uint32_t totalBlocks;   /*!< holds number of SB3 blocks. Initialized by nboot_sb3_load_header(). */
123     uint32_t processData;   /*!< flag, initialized by nboot_sb3_load_header().
124                                SB3 related flag set by NBOOT in case the nboot_sb3_load_block()
125                                provides plain data to output buffer (for processing by ROM SB3 loader */
126     uint32_t timeout;       /*!< timeout value for css operation. In case it is 0, infinite wait is performed */
127     uint32_t keyinfo[NBOOT_KEYINFO_WORDLEN]; /*!< data for NBOOT key management. */
128     uint32_t context[NBOOT_CONTEXT_WORDLEN]; /*!< work area for NBOOT lib. */
129     uint32_t uuid[4]; /*!< holds UUID value from NMPA */
130     uint32_t prngReadyFlag; /*!< flag, used by nboot_rng_generate_lq_random() to determine whether CSS is ready to generate rnd number */
131     uint32_t multipartMacBuffer[1024/sizeof(uint32_t)];
132     uint32_t oemShareValidFlag; /*!< flag, used during TP to determine whether valid oemShare was set by nboot_tp_isp_gen_oem_master_share() */
133     uint32_t oemShare[4]; /*!< buffer to store OEM_SHARE computed by nxpCLTrustProv_nboot_isp_gen_oem_master_share() */
134     nboot_secure_counter_t secureCounter; /*!< Secure counter used by nboot */
135     uint32_t rtf[NXPCLCSS_HASH_RTF_OUTPUT_SIZE_HAL/sizeof(uint32_t)];
136     uint32_t imageHash[48/sizeof(uint32_t)];
137     uint32_t authStatus;
138 } nboot_context_t;
139 
140 /*!
141  * @brief NBOOT type for the root of trust parameters
142  *
143  * This type defines the NBOOT root of trust parameters
144  *
145  */
146 typedef struct _nboot_rot_auth_parms
147 {
148     /* trusted information originated from CFPA */
149     nboot_root_key_revocation_t soc_rootKeyRevocation[NBOOT_ROOT_CERT_COUNT]; /*!< Provided by caller based on NVM information in CFPA: ROTKH_REVOKE */
150     uint32_t soc_imageKeyRevocation; /*!< Provided by caller based on NVM information in CFPA: IMAGE_KEY_REVOKE */
151 
152     /* trusted information originated from CMPA */
153     uint32_t soc_rkh[12]; /*!< Provided by caller based on NVM information in CMPA: ROTKH (hash of hashes) */
154                           /*!< In case of kNBOOT_RootKey_Ecdsa_P384, sock_rkh[0..11] are used */
155                           /*!< In case of kNBOOT_RootKey_Ecdsa_P256, sock_rkh[0..7] are used */
156 
157     uint32_t soc_numberOfRootKeys; /*!< unsigned int, between minimum = 1 and maximum = 4; */
158     nboot_root_key_usage_t soc_rootKeyUsage[NBOOT_ROOT_CERT_COUNT]; /*!< CMPA */
159     nboot_root_key_type_and_length_t soc_rootKeyTypeAndLength; /*!< static selection between ECDSA P-256 or ECDSA P-384 based root keys */
160 
161     /* trusted information originated from OTP fuses */
162     nboot_soc_lifecycle_t soc_lifecycle;
163 } nboot_rot_auth_parms_t;
164 
165 /*!
166  * @brief manifest loading parameters
167  *
168  * This type defines the NBOOT SB3.1 manifest loading parameters
169  *
170  */typedef struct _nboot_sb3_load_manifest_parms
171 {
172     nboot_rot_auth_parms_t soc_RoTNVM;      /*!< trusted information originated from CFPA and NMPA */
173     uint32_t soc_trustedFirmwareVersion;    /*!< Provided by caller based on NVM information in CFPA: Secure_FW_Version */
174     uint8_t pckBlob[48];
175 } nboot_sb3_load_manifest_parms_t;
176 
177 /*!
178  * @brief Data structure holding input arguments to POR secure boot (authentication) algorithm.
179  * Shall be read from SoC trusted NVM or SoC fuses.
180  */
181 typedef struct _nboot_img_auth_ecdsa_parms
182 {
183     nboot_rot_auth_parms_t soc_RoTNVM;   /*!< trusted information originated from CFPA and NMPA */
184     uint32_t soc_trustedFirmwareVersion; /*!< Provided by caller based on NVM information in CFPA: Secure_FW_Version */
185 } nboot_img_auth_ecdsa_parms_t;
186 
187 /*! @brief Data structure holding input arguments for CMAC authentication */
188 typedef struct _nboot_cmac_authenticate_parms
189 {
190     uint32_t expectedMAC[4];  /*!< expected MAC result */
191 } nboot_img_authenticate_cmac_parms_t;
192 
193 /*!
194  * @brief Boolean type for the NBOOT functions
195  *
196  * This type defines boolean values used by NBOOT functions that are not easily disturbed by Fault Attacks
197  */
198 typedef enum _nboot_bool
199 {
200     kNBOOT_TRUE                   = 0x3C5AC33CU, /*!< Value for TRUE.  */
201     kNBOOT_TRUE256                = 0x3C5AC35AU, /*!< Value for TRUE when P256 was used to sign the image.  */
202     kNBOOT_TRUE384                = 0x3C5AC3A5U, /*!< Value for TRUE when P384 was used to sign the image.  */
203     kNBOOT_FALSE                  = 0x5AA55AA5U, /*!< Value for FALSE. */
204     kNBOOT_OperationAllowed       = 0x3c5a33ccU,
205     kNBOOT_OperationDisallowed    = 0x5aa5cc33U,
206 } nboot_bool_t;
207 
208 #ifdef __cplusplus
209 extern "C" {
210 #endif
211 
212 /*******************************************************************************
213  * API
214  ******************************************************************************/
215 
216 /*!
217  * @brief This API function is used to generate random number with specified length.
218  *
219  * @param output Pointer to random number buffer
220  * @param outputByteLen length of generated random number in bytes. Length has to be in range <1, 2^16>
221  *
222  * @retval #kStatus_NBOOT_InvalidArgument Invalid input parameters (Input pointers points to NULL or length is invalid)
223  * @retval #kStatus_NBOOT_Success Operation successfully finished
224  * @retval #kStatus_NBOOT_Fail Error occured during operation
225  */
226 status_t NBOOT_GenerateRandom(uint8_t *output, size_t outputByteLen);
227 
228 /*!
229  * @brief The function is used for initializing of the nboot context data structure.
230  *        It should be called prior to any other calls of nboot API.
231  *
232  * @param nbootCtx Pointer to nboot_context_t structure.
233  *
234  * @retval #kStatus_NBOOT_Success Operation successfully finished
235  * @retval #kStatus_NBOOT_Fail Error occured during operation
236 */
237 nboot_status_t NBOOT_ContextInit(nboot_context_t *context);
238 
239 /*!
240  * @brief The function is used to deinitialize nboot context data structure.
241  * Its contents are overwritten with random data so that any sensitive data does not remain in memory.
242  *
243  * @param context Pointer to nboot_context_t structure.
244 
245  * @retval #kStatus_NBOOT_Success Operation successfully finished
246  * @retval #kStatus_NBOOT_Fail Error occured during operation
247  */
248 nboot_status_t NBOOT_ContextDeinit(nboot_context_t *context);
249 
250 /*!
251  * @brief Verify NBOOT SB3.1 manifest (header message)
252  *
253  * This function verifies the NBOOT SB3.1 manifest (header message), initializes
254  * the context and loads keys into the CSS key store so that they can be used by nboot_sb3_load_block
255  * function. The NBOOT context has to be initialized by the function nboot_context_init before calling
256  * this function. Please note that this API is intended to be used only by users who needs to split
257  * FW update process (loading of SB3.1 file) to partial steps to customize whole operation.
258  * For regular SB3.1 processing, please use API described in chapter ��SBloader APIs��.
259  *
260  * @param nbootCtx Pointer to nboot_context_t structure.
261  * @param manifest Pointer to the input manifest buffer
262  * @param params additional input parameters. Please refer to nboot_sb3_load_manifest_parms_t definition for details.
263  *
264  * @retval #kStatus_NBOOT_Success Operation successfully finished
265  * @retval #kStatus_NBOOT_Fail Error occured during operation
266  */
267 nboot_status_protected_t NBOOT_Sb3LoadManifest(nboot_context_t *context,
268                                   uint32_t *manifest,
269                                   nboot_sb3_load_manifest_parms_t *parms);
270 
271 /*!
272  * @brief Verify NBOOT SB3.1 block
273  *
274  * This function verifies and decrypts an NBOOT SB3.1 block. Decryption is performed in-place.
275  * The NBOOT context has to be initialized by the function nboot_context_init before calling this function.
276  * Please note that this API is intended to be used only by users who needs to split FW update process
277  * (loading of SB3.1 file) to partial steps to customize whole operation. For regular SB3.1 processing,
278  * please use API described in chapter ��SBloader APIs��.
279  *
280  * @param context Pointer to nboot_context_t structure.
281  * @param block Pointer to the input SB3.1 data block
282  *
283  * @retval #kStatus_NBOOT_Success successfully finished
284  * @retval #kStatus_NBOOT_Fail occured during operation
285 */
286  nboot_status_protected_t NBOOT_Sb3LoadBlock(nboot_context_t *context, uint32_t *block);
287 
288 /*!
289  * @brief This function authenticates image with asymmetric cryptography.
290  *        The NBOOT context has to be initialized by the function nboot_context_init
291  *        before calling this function.
292  *
293  * @param context Pointer to nboot_context_t structure.
294  * @param imageStartAddress Pointer to start of the image in memory.
295  * @param isSignatureVerified Pointer to memory holding function call result.
296  *                            After the function returns, the value will be set to kNBOOT_TRUE when the image is authentic.
297  *                            Any other value means the authentication does not pass.
298  *
299  * @param parms Pointer to a data structure in trusted memory, holding input parameters for the algorithm.
300  *              The data structure shall be correctly filled before the function call.
301  *
302  * @retval #kStatus_NBOOT_Success Operation successfully finished
303  * @retval #kStatus_NBOOT_Fail Returned in all other cases. Doesn't always mean invalid image,
304  *         it could also mean transient error caused by short time environmental conditions.
305 */
306 nboot_status_protected_t NBOOT_ImgAuthenticateEcdsa(nboot_context_t *context,
307                                             uint8_t imageStartAddress[],
308                                             nboot_bool_t *isSignatureVerified,
309                                             nboot_img_auth_ecdsa_parms_t *parms);
310 
311 /*!
312  * @brief This function calculates the CMAC over the given image and compares it to the expected value.
313  * To be more resistant against SPA, it is recommended that imageStartAddress is word aligned.
314  * The NBOOT context has to be initialized by the nboot_context_init() before calling this function.
315  *
316  * @param context Pointer to nboot_context_t structure.
317  * @param imageStartAddress Pointer to start of the image in memory.
318  * @param isSignatureVerified Pointer to memory holding function call result.
319                               After the function returns, the value will be set to
320  * @param parms Pointer to a data structure in trusted memory, holding the reference MAC.
321                 The data structure shall be correctly filled before the function call.
322  *
323  * @retval kStatus_NBOOT_Success
324  * @retval kStatus_NBOOT_Fail
325  */
326 nboot_status_protected_t NBOOT_ImgAuthenticateCmac(nboot_context_t *context,
327                                                      uint8_t imageStartAddress[],
328                                                      nboot_bool_t *isSignatureVerified,
329                                                      nboot_img_authenticate_cmac_parms_t *parms);
330 
331 #ifdef __cplusplus
332 }
333 #endif
334 
335 /**
336  * @}
337  */
338 
339 #endif /* _FSL_NBOOT_H_ */
340