1 /*
2  * Copyright (c) 2016, NXP Semiconductor, Inc.
3  * Copyright 2021,2023-2024 NXP
4  * All rights reserved.
5  *
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  *  that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  *   of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  *   list of conditions and the following disclaimer in the documentation and/or
16  *   other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  *   contributors may be used to endorse or promote products derived from this
20  *   software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef _loader_v3_h
35 #define _loader_v3_h
36 
37 #include "fsl_common.h"
38 #include <stdint.h>
39 
40 
41 //! @addtogroup sbloader
42 //! @{
43 
44 //! Defines the number of bytes in a cipher block (chunk). This is dictated by
45 //! the encryption algorithm.
46 #define SB3_BYTES_PER_CHUNK 16
47 
48 typedef uint8_t chunk_v3_t[SB3_BYTES_PER_CHUNK];
49 
50 typedef struct _ldr_buf ldr_buf_t;
51 
52 struct _ldr_buf
53 {
54     chunk_v3_t data;
55     uint32_t fillPosition;
56 };
57 
58 // Provides forward reference to the loader context definition.
59 typedef struct _ldr_Context_v3 ldr_Context_v3_t;
60 
61 //! Function pointer definition for all loader action functions.
62 typedef status_t (*pLdrFnc_v3_t)(ldr_Context_v3_t *content);
63 
64 enum _bl_status_groups
65 {
66     kStatusGroup_SBLoader = 101u,
67 };
68 
69 enum _sbloader_status
70 {
71     kStatusRomLdrSectionOverrun = MAKE_STATUS(kStatusGroup_SBLoader, 0),
72     kStatusRomLdrSignature = MAKE_STATUS(kStatusGroup_SBLoader, 1),
73     kStatusRomLdrSectionLength = MAKE_STATUS(kStatusGroup_SBLoader, 2),
74     kStatusRomLdrUnencryptedOnly = MAKE_STATUS(kStatusGroup_SBLoader, 3),
75     kStatusRomLdrEOFReached = MAKE_STATUS(kStatusGroup_SBLoader, 4),
76     kStatusRomLdrChecksum = MAKE_STATUS(kStatusGroup_SBLoader, 5),
77     kStatusRomLdrCrc32Error = MAKE_STATUS(kStatusGroup_SBLoader, 6),
78     kStatusRomLdrUnknownCommand = MAKE_STATUS(kStatusGroup_SBLoader, 7),
79     kStatusRomLdrIdNotFound = MAKE_STATUS(kStatusGroup_SBLoader, 8),
80     kStatusRomLdrDataUnderrun = MAKE_STATUS(kStatusGroup_SBLoader, 9),
81     kStatusRomLdrJumpReturned = MAKE_STATUS(kStatusGroup_SBLoader, 10),
82     kStatusRomLdrCallFailed = MAKE_STATUS(kStatusGroup_SBLoader, 11),
83     kStatusRomLdrKeyNotFound = MAKE_STATUS(kStatusGroup_SBLoader, 12),
84     kStatusRomLdrSecureOnly = MAKE_STATUS(kStatusGroup_SBLoader, 13),
85     kStatusRomLdrResetReturned = MAKE_STATUS(kStatusGroup_SBLoader, 14),
86 
87     kStatusRomLdrRollbackBlocked = MAKE_STATUS(kStatusGroup_SBLoader, 15),
88     kStatusRomLdrInvalidSectionMacCount = MAKE_STATUS(kStatusGroup_SBLoader, 16),
89     kStatusRomLdrUnexpectedCommand = MAKE_STATUS(kStatusGroup_SBLoader, 17),
90     kStatusRomLdrBadSBKEK = MAKE_STATUS(kStatusGroup_SBLoader, 18),
91     kStatusRomLdrPendingJumpCommand = MAKE_STATUS(kStatusGroup_SBLoader, 19),
92 };
93 
94 //! sb3 section definitions
95 
96 //! section type
97 typedef enum _sectionType
98 {
99     kSectionNone       = 0, // end or invalid
100     kSectionDataRange  = 1,
101     kSectionDiffUpdate = 2,
102     kSectionDDRConfig  = 3,
103     kSectionRegister   = 4,
104 } section_type_t;
105 
106 #define SB3_DATA_RANGE_HEADER_FLAGS_ERASE_MASK (0x1U) // bit 0
107 #define SB3_DATA_RANGE_HEADER_FLAGS_LOAD_MASK  (0x2U) // bit 1
108 
109 #define SB3_DATA_RANGE_HEADER_TAG       (0x55aaaa55U)
110 #define SB3_DATA_ALIGNMENT_SIZE_IN_BYTE (16U)
111 #define SB3_LOAD_KEY_BLOB_OTP_MASK      (0xf000)
112 
113 //! section data range structure
114 typedef struct range_header
115 {
116     uint32_t tag;
117     uint32_t startAddress;
118     uint32_t length;
119     uint32_t cmd;
120 } sb3_data_range_header_t;
121 
122 typedef struct range_header_expansion
123 {
124     uint32_t memoryId;
125     uint32_t pad0;
126     uint32_t pad1;
127     uint32_t pad2;
128 } sb3_data_range_expansion_t;
129 
130 typedef struct copy_memory_expansion
131 {
132     uint32_t destAddr;
133     uint32_t memoryIdFrom;
134     uint32_t memoryIdTo;
135     uint32_t pad;
136 } sb3_copy_memory_expansion_t;
137 
138 typedef struct copy
139 {
140     sb3_data_range_header_t header;
141     sb3_copy_memory_expansion_t expansion;
142 } sb3_copy_memory_t;
143 
144 typedef struct load_keyblob
145 {
146     uint32_t tag;
147     uint16_t offset;
148     uint16_t keyWrapId;
149     uint32_t length;
150     uint32_t cmd;
151 } sb3_load_keyblob_t;
152 
153 typedef struct fill_memory_expansion
154 {
155     uint32_t pattern; // word to be used as pattern
156     uint32_t pad0;
157     uint32_t pad1;
158     uint32_t pad2;
159 } sb3_fill_memory_expansion_t;
160 
161 typedef struct fill_memory
162 {
163     sb3_data_range_header_t header;
164     sb3_fill_memory_expansion_t arg;
165 } sb3_fill_memory_t;
166 
167 typedef struct config_memory
168 {
169     uint32_t tag;
170     uint32_t memoryId;
171     uint32_t address; // address of config blob
172     uint32_t cmd;
173 } sb3_config_memory_t;
174 
175 enum
176 {
177     kFwVerChk_Id_none      = 0,
178     kFwVerChk_Id_nonsecure = 1,
179     kFwVerChk_Id_secure    = 2,
180 };
181 
182 typedef struct fw_ver_check
183 {
184     uint32_t tag;
185     uint32_t version;
186     uint32_t id;
187     uint32_t cmd;
188 } sb3_fw_ver_check_t;
189 
190 //! sb3 DATA section header format
191 typedef struct section_header
192 {
193     uint32_t sectionUid;
194     uint32_t sectionType;
195     uint32_t length;
196     uint32_t _pad;
197 } sb3_section_header_t;
198 
199 // loader command enum
200 
201 typedef enum _loader_command_sb3
202 {
203     kSB3_CmdInvalid         = 0,
204     kSB3_CmdErase           = 1,
205     kSB3_CmdLoad            = 2,
206     kSB3_CmdExecute         = 3,
207     kSB3_CmdCall            = 4,
208     kSB3_CmdProgramFuse     = 5,
209     kSB3_CmdProgramIFR      = 6,
210     kSB3_CmdLoadCmac        = 7,
211     kSB3_CmdCopy            = 8,
212     kSB3_CmdLoadHashLocking = 9,
213     kSB3_CmdLoadKeyBlob     = 10,
214     kSB3_CmdConfigMem       = 11,
215     kSB3_CmdFillMem         = 12,
216     kSB3_CmdFwVerCheck      = 13,
217 } sb3_cmd_t;
218 
219 //! The all of the allowed command
220 #define SBLOADER_V3_CMD_SET_ALL                                                                                      \
221     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdCall) |                 \
222      (1u << kSB3_CmdProgramFuse) | (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | \
223      (1u << kSB3_CmdConfigMem) | (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
224 //! The allowed command set in ISP mode
225 #define SBLOADER_V3_CMD_SET_IN_ISP_MODE                                                                            \
226     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdProgramFuse) |        \
227      (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | (1u << kSB3_CmdConfigMem) | \
228      (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
229 //! The allowed command set in recovery mode
230 #define SBLOADER_V3_CMD_SET_IN_REC_MODE                                                                            \
231     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdProgramFuse) |        \
232      (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | (1u << kSB3_CmdConfigMem) | \
233      (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
234 //! The allowed command set in secure ATE mode
235 #define SBLOADER_V3_CMD_SET_IN_SEC_ATE_MODE                                                                        \
236     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdProgramFuse) |        \
237      (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | (1u << kSB3_CmdConfigMem) | \
238      (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
239 
240 #define SB3_DATA_BUFFER_SIZE_IN_BYTE (MAX(128, NBOOT_KEY_BLOB_SIZE_IN_BYTE_MAX))
241 
242 //! Loader context definition.
243 struct _ldr_Context_v3
244 {
245     pLdrFnc_v3_t Action;        //!< pointer to loader action function
246     uint32_t block_size;        //!< size of each block in bytes
247     uint32_t block_data_size;   //!< data size in bytes (NBOOT_SB3_CHUNK_SIZE_IN_BYTES)
248     uint32_t block_data_total;  //!< data max size in bytes (block_size * data_size
249     uint32_t block_buffer_size; //!< block0 and block size
250     uint32_t block_buffer_position;
251     uint8_t block_buffer[MAX(NBOOT_SB3_MANIFEST_MAX_SIZE_IN_BYTES,
252                              NBOOT_SB3_BLOCK_MAX_SIZE_IN_BYTES)]; //! will be used for both block0 and blockx
253     uint32_t processedBlocks;
254 
255     uint8_t data_block_offset; //! data block offset in a block.
256     bool in_data_block;        //!< in progress of handling a data block within a block
257     uint8_t *data_block;
258     uint32_t data_block_position;
259 
260     bool in_data_section; //!< in progress of handling a data section within a data block
261     uint32_t data_section_handled;
262     sb3_section_header_t data_section_header;
263 
264     bool in_data_range; //!< in progress of handling a data range within a data section
265     uint32_t data_range_handled;
266     uint32_t data_range_gap;
267     sb3_data_range_header_t data_range_header;
268     bool has_data_range_expansion;
269     sb3_data_range_expansion_t data_range_expansion;
270 
271     uint32_t commandSet; //!< support command set during sb file handling
272 
273     uint32_t data_position;
274     uint8_t data_buffer[SB3_DATA_BUFFER_SIZE_IN_BYTE]; //!< temporary data buffer
275 
276     uint32_t fuse_cmd_position;
277     uint8_t fuse_cmd_buffer[32 * 4]; //!< used for fuse command
278 
279     // options from ROM API
280     kb_options_t fromAPI;
281 
282     bool do_firmware_load; //!< special handling for firmware loading ourside normal memory regions
283 };
284 
285 #if defined(__cplusplus)
286 extern "C" {
287 #endif // __cplusplus
288 
289 #if defined(__cplusplus)
290 }
291 #endif // __cplusplus
292 
293 //! @}
294 
295 #endif
296