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 =
103         0x5A5AA5EAU,                        /*!< Size of User data in ISK certificate is greater than 96 bytes */
104     kStatus_NBOOT_IskCertSignatureOffsetTooSmall =
105         0x5A5AA5EBU,                        /*!< Signature offset in ISK certificate is smaller than expected */
106     kStatus_NBOOT_MemcpyFail = 0x5A5A845AU, /*!< Unexpected error detected during nboot_memcpy() */
107 };
108 
109 /*! @brief Data structure holding secure counter value used by nboot library */
110 typedef struct _nboot_secure_counter
111 {
112     uint32_t sc;
113     uint32_t scAp;
114 } nboot_secure_counter_t;
115 
116 /*!
117  * @brief NBOOT context type
118  *
119  * This type defines the NBOOT context
120  *
121  */
122 typedef struct _nboot_context
123 {
124     uint32_t totalBlocks; /*!< holds number of SB3 blocks. Initialized by nboot_sb3_load_header(). */
125     uint32_t processData; /*!< flag, initialized by nboot_sb3_load_header().
126                              SB3 related flag set by NBOOT in case the nboot_sb3_load_block()
127                              provides plain data to output buffer (for processing by ROM SB3 loader */
128     uint32_t timeout;     /*!< timeout value for css operation. In case it is 0, infinite wait is performed */
129     uint32_t keyinfo[NBOOT_KEYINFO_WORDLEN]; /*!< data for NBOOT key management. */
130     uint32_t context[NBOOT_CONTEXT_WORDLEN]; /*!< work area for NBOOT lib. */
131     uint32_t uuid[4];                        /*!< holds UUID value from NMPA */
132     uint32_t prngReadyFlag;     /*!< flag, used by nboot_rng_generate_lq_random() to determine whether CSS is ready to
133                                    generate rnd number */
134     uint32_t multipartMacBuffer[1024 / sizeof(uint32_t)];
135     uint32_t oemShareValidFlag; /*!< flag, used during TP to determine whether valid oemShare was set by
136                                    nboot_tp_isp_gen_oem_master_share() */
137     uint32_t oemShare[4]; /*!< buffer to store OEM_SHARE computed by nxpCLTrustProv_nboot_isp_gen_oem_master_share() */
138     nboot_secure_counter_t secureCounter; /*!< Secure counter used by nboot */
139     uint32_t rtf[NXPCLCSS_HASH_RTF_OUTPUT_SIZE_HAL / sizeof(uint32_t)];
140     uint32_t imageHash[48 / sizeof(uint32_t)];
141     uint32_t authStatus;
142 } nboot_context_t;
143 
144 /*!
145  * @brief NBOOT type for the root of trust parameters
146  *
147  * This type defines the NBOOT root of trust parameters
148  *
149  */
150 typedef struct _nboot_rot_auth_parms
151 {
152     /* trusted information originated from CFPA */
153     nboot_root_key_revocation_t soc_rootKeyRevocation[NBOOT_ROOT_CERT_COUNT]; /*!< Provided by caller based on NVM
154                                                                                  information in CFPA: ROTKH_REVOKE */
155     uint32_t soc_imageKeyRevocation; /*!< Provided by caller based on NVM information in CFPA: IMAGE_KEY_REVOKE */
156 
157     /* trusted information originated from CMPA */
158     uint32_t soc_rkh[12];          /*!< Provided by caller based on NVM information in CMPA: ROTKH (hash of hashes) */
159                                    /*!< In case of kNBOOT_RootKey_Ecdsa_P384, sock_rkh[0..11] are used */
160                                    /*!< In case of kNBOOT_RootKey_Ecdsa_P256, sock_rkh[0..7] are used */
161 
162     uint32_t soc_numberOfRootKeys; /*!< unsigned int, between minimum = 1 and maximum = 4; */
163     nboot_root_key_usage_t soc_rootKeyUsage[NBOOT_ROOT_CERT_COUNT]; /*!< CMPA */
164     nboot_root_key_type_and_length_t
165         soc_rootKeyTypeAndLength; /*!< static selection between ECDSA P-256 or ECDSA P-384 based root keys */
166 
167     /* trusted information originated from OTP fuses */
168     nboot_soc_lifecycle_t soc_lifecycle;
169 } nboot_rot_auth_parms_t;
170 
171 /*!
172  * @brief manifest loading parameters
173  *
174  * This type defines the NBOOT SB3.1 manifest loading parameters
175  *
176  */
177 typedef struct _nboot_sb3_load_manifest_parms
178 {
179     nboot_rot_auth_parms_t soc_RoTNVM;   /*!< trusted information originated from CFPA and NMPA */
180     uint32_t soc_trustedFirmwareVersion; /*!< Provided by caller based on NVM information in CFPA: Secure_FW_Version */
181     uint8_t pckBlob[48];
182 } nboot_sb3_load_manifest_parms_t;
183 
184 /*!
185  * @brief Data structure holding input arguments to POR secure boot (authentication) algorithm.
186  * Shall be read from SoC trusted NVM or SoC fuses.
187  */
188 typedef struct _nboot_img_auth_ecdsa_parms
189 {
190     nboot_rot_auth_parms_t soc_RoTNVM;   /*!< trusted information originated from CFPA and NMPA */
191     uint32_t soc_trustedFirmwareVersion; /*!< Provided by caller based on NVM information in CFPA: Secure_FW_Version */
192 } nboot_img_auth_ecdsa_parms_t;
193 
194 /*! @brief Data structure holding input arguments for CMAC authentication */
195 typedef struct _nboot_cmac_authenticate_parms
196 {
197     uint32_t expectedMAC[4]; /*!< expected MAC result */
198 } nboot_img_authenticate_cmac_parms_t;
199 
200 /*!
201  * @brief Boolean type for the NBOOT functions
202  *
203  * This type defines boolean values used by NBOOT functions that are not easily disturbed by Fault Attacks
204  */
205 typedef enum _nboot_bool
206 {
207     kNBOOT_TRUE                = 0x3C5AC33CU, /*!< Value for TRUE.  */
208     kNBOOT_TRUE256             = 0x3C5AC35AU, /*!< Value for TRUE when P256 was used to sign the image.  */
209     kNBOOT_TRUE384             = 0x3C5AC3A5U, /*!< Value for TRUE when P384 was used to sign the image.  */
210     kNBOOT_FALSE               = 0x5AA55AA5U, /*!< Value for FALSE. */
211     kNBOOT_OperationAllowed    = 0x3c5a33ccU,
212     kNBOOT_OperationDisallowed = 0x5aa5cc33U,
213 } nboot_bool_t;
214 
215 #ifdef __cplusplus
216 extern "C" {
217 #endif
218 
219 /*******************************************************************************
220  * API
221  ******************************************************************************/
222 
223 /*!
224  * @brief This API function is used to generate random number with specified length.
225  *
226  * @param output Pointer to random number buffer
227  * @param outputByteLen length of generated random number in bytes. Length has to be in range <1, 2^16>
228  *
229  * @retval #kStatus_NBOOT_InvalidArgument Invalid input parameters (Input pointers points to NULL or length is invalid)
230  * @retval #kStatus_NBOOT_Success Operation successfully finished
231  * @retval #kStatus_NBOOT_Fail Error occured during operation
232  */
233 status_t NBOOT_GenerateRandom(uint8_t *output, size_t outputByteLen);
234 
235 /*!
236  * @brief The function is used for initializing of the nboot context data structure.
237  *        It should be called prior to any other calls of nboot API.
238  *
239  * @param context Pointer to nboot_context_t structure.
240  *
241  * @retval #kStatus_NBOOT_Success Operation successfully finished
242  * @retval #kStatus_NBOOT_Fail Error occured during operation
243  */
244 nboot_status_t NBOOT_ContextInit(nboot_context_t *context);
245 
246 /*!
247  * @brief The function is used to deinitialize nboot context data structure.
248  * Its contents are overwritten with random data so that any sensitive data does not remain in memory.
249  *
250  * @param context Pointer to nboot_context_t structure.
251 
252  * @retval #kStatus_NBOOT_Success Operation successfully finished
253  * @retval #kStatus_NBOOT_Fail Error occured during operation
254  */
255 nboot_status_t NBOOT_ContextDeinit(nboot_context_t *context);
256 
257 /*!
258  * @brief Verify NBOOT SB3.1 manifest (header message)
259  *
260  * This function verifies the NBOOT SB3.1 manifest (header message), initializes
261  * the context and loads keys into the CSS key store so that they can be used by nboot_sb3_load_block
262  * function. The NBOOT context has to be initialized by the function nboot_context_init before calling
263  * this function. Please note that this API is intended to be used only by users who needs to split
264  * FW update process (loading of SB3.1 file) to partial steps to customize whole operation.
265  * For regular SB3.1 processing, please use API described in chapter SBloader APIs.
266  *
267  * @param context Pointer to nboot_context_t structure.
268  * @param manifest Pointer to the input manifest buffer
269  * @param params additional input parameters. Please refer to nboot_sb3_load_manifest_parms_t definition for details.
270  *
271  * @retval #kStatus_NBOOT_Success Operation successfully finished
272  * @retval #kStatus_NBOOT_Fail Error occured during operation
273  */
274 nboot_status_protected_t NBOOT_Sb3LoadManifest(nboot_context_t *context,
275                                                uint32_t *manifest,
276                                                nboot_sb3_load_manifest_parms_t *params);
277 
278 /*!
279  * @brief Verify NBOOT SB3.1 block
280  *
281  * This function verifies and decrypts an NBOOT SB3.1 block. Decryption is performed in-place.
282  * The NBOOT context has to be initialized by the function nboot_context_init before calling this function.
283  * Please note that this API is intended to be used only by users who needs to split FW update process
284  * (loading of SB3.1 file) to partial steps to customize whole operation. For regular SB3.1 processing,
285  * please use API described in chapter SBloader APIs.
286  *
287  * @param context Pointer to nboot_context_t structure.
288  * @param block Pointer to the input SB3.1 data block
289  *
290  * @retval #kStatus_NBOOT_Success successfully finished
291  * @retval #kStatus_NBOOT_Fail occured during operation
292  */
293 nboot_status_protected_t NBOOT_Sb3LoadBlock(nboot_context_t *context, uint32_t *block);
294 
295 /*!
296  * @brief This function authenticates image with asymmetric cryptography.
297  *        The NBOOT context has to be initialized by the function nboot_context_init
298  *        before calling this function.
299  *
300  * @param context Pointer to nboot_context_t structure.
301  * @param imageStartAddress Pointer to start of the image in memory.
302  * @param isSignatureVerified Pointer to memory holding function call result.
303  *                            After the function returns, the value will be set to kNBOOT_TRUE when the image is
304  * authentic. Any other value means the authentication does not pass.
305  *
306  * @param parms Pointer to a data structure in trusted memory, holding input parameters for the algorithm.
307  *              The data structure shall be correctly filled before the function call.
308  *
309  * @retval #kStatus_NBOOT_Success Operation successfully finished
310  * @retval #kStatus_NBOOT_Fail Returned in all other cases. Doesn't always mean invalid image,
311  *         it could also mean transient error caused by short time environmental conditions.
312  */
313 nboot_status_protected_t NBOOT_ImgAuthenticateEcdsa(nboot_context_t *context,
314                                                     uint8_t imageStartAddress[],
315                                                     nboot_bool_t *isSignatureVerified,
316                                                     nboot_img_auth_ecdsa_parms_t *parms);
317 
318 /*!
319  * @brief This function calculates the CMAC over the given image and compares it to the expected value.
320  * To be more resistant against SPA, it is recommended that imageStartAddress is word aligned.
321  * The NBOOT context has to be initialized by the nboot_context_init() before calling this function.
322  *
323  * @param context Pointer to nboot_context_t structure.
324  * @param imageStartAddress Pointer to start of the image in memory.
325  * @param isSignatureVerified Pointer to memory holding function call result.
326                               After the function returns, the value will be set to
327  * @param parms Pointer to a data structure in trusted memory, holding the reference MAC.
328                 The data structure shall be correctly filled before the function call.
329  *
330  * @retval kStatus_NBOOT_Success
331  * @retval kStatus_NBOOT_Fail
332  */
333 nboot_status_protected_t NBOOT_ImgAuthenticateCmac(nboot_context_t *context,
334                                                    uint8_t imageStartAddress[],
335                                                    nboot_bool_t *isSignatureVerified,
336                                                    nboot_img_authenticate_cmac_parms_t *parms);
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 /**
343  * @}
344  */
345 
346 #endif /* _FSL_NBOOT_H_ */
347