1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef FSL_SBLOADER_V3_H_
8 #define FSL_SBLOADER_V3_H_
9 
10 #include <stdint.h>
11 
12 #include "fsl_romapi_nboot.h"
13 
14 /*! @addtogroup sbloader */
15 /*! @{ */
16 
17 /*******************************************************************************
18  * Definitions
19  *****************************************************************************/
20 
21 /*!
22  * @brief Defines the number of bytes in a cipher block (chunk). This is dictated by
23  * the encryption algorithm.
24  */
25 #define SB3_BYTES_PER_CHUNK 16
26 
27 typedef uint8_t chunk_v3_t[SB3_BYTES_PER_CHUNK];
28 
29 typedef struct _ldr_buf ldr_buf_t;
30 
31 struct _ldr_buf
32 {
33     chunk_v3_t data;
34     uint32_t fillPosition;
35 };
36 
37 /*! @brief Provides forward reference to the loader context definition. */
38 typedef struct _ldr_Context_v3 ldr_Context_v3_t;
39 
40 /*! @brief Function pointer definition for all loader action functions. */
41 typedef status_t (*pLdrFnc_v3_t)(ldr_Context_v3_t *content);
42 
43 /*! @brief sb3 section definitions */
44 /*! @brief section type */
45 typedef enum _sectionType
46 {
47     kSectionNone       = 0, /*!< end or invalid */
48     kSectionDataRange  = 1,
49     kSectionDiffUpdate = 2,
50     kSectionDDRConfig  = 3,
51     kSectionRegister   = 4,
52 } section_type_t;
53 
54 #define SB3_DATA_RANGE_HEADER_FLAGS_ERASE_MASK (0x1u) /*!< bit 0 */
55 #define SB3_DATA_RANGE_HEADER_FLAGS_LOAD_MASK  (0x2u) /*!< bit 1 */
56 
57 /*! @brief section data range structure */
58 typedef struct range_header
59 {
60     uint32_t tag;
61     uint32_t startAddress;
62     uint32_t length;
63     uint32_t cmd;
64 } sb3_data_range_header_t;
65 
66 typedef struct range_header_expansion
67 {
68     uint32_t memoryId;
69     uint32_t pad0;
70     uint32_t pad1;
71     uint32_t pad2;
72 } sb3_data_range_expansion_t;
73 
74 typedef struct copy_memory_expansion
75 {
76     uint32_t destAddr;
77     uint32_t memoryIdFrom;
78     uint32_t memoryIdTo;
79     uint32_t pad;
80 } sb3_copy_memory_expansion_t;
81 
82 typedef struct copy
83 {
84     sb3_data_range_header_t header;
85     sb3_copy_memory_expansion_t expansion;
86 } sb3_copy_memory_t;
87 
88 typedef struct load_keyblob
89 {
90     uint32_t tag;
91     uint16_t offset;
92     uint16_t keyWrapId;
93     uint32_t length;
94     uint32_t cmd;
95 } sb3_load_keyblob_t;
96 
97 typedef struct fill_memory_expansion
98 {
99     uint32_t pattern; /*!< word to be used as pattern */
100     uint32_t pad0;
101     uint32_t pad1;
102     uint32_t pad2;
103 } sb3_fill_memory_expansion_t;
104 
105 typedef struct fill_memory
106 {
107     sb3_data_range_header_t header;
108     sb3_fill_memory_expansion_t arg;
109 } sb3_fill_memory_t;
110 
111 typedef struct config_memory
112 {
113     uint32_t tag;
114     uint32_t memoryId;
115     uint32_t address; /*!< address of config blob */
116     uint32_t cmd;
117 } sb3_config_memory_t;
118 
119 enum
120 {
121     kFwVerChk_Id_none      = 0,
122     kFwVerChk_Id_nonsecure = 1,
123     kFwVerChk_Id_secure    = 2,
124 };
125 
126 typedef struct fw_ver_check
127 {
128     uint32_t tag;
129     uint32_t version;
130     uint32_t id;
131     uint32_t cmd;
132 } sb3_fw_ver_check_t;
133 
134 /*! @brief sb3 DATA section header format */
135 typedef struct section_header
136 {
137     uint32_t sectionUid;
138     uint32_t sectionType;
139     uint32_t length;
140     uint32_t _pad;
141 } sb3_section_header_t;
142 
143 /*! @brief loader command enum */
144 typedef enum _loader_command_sb3
145 {
146     kSB3_CmdInvalid         = 0,
147     kSB3_CmdErase           = 1,
148     kSB3_CmdLoad            = 2,
149     kSB3_CmdExecute         = 3,
150     kSB3_CmdCall            = 4,
151     kSB3_CmdProgramFuse     = 5,
152     kSB3_CmdProgramIFR      = 6,
153     kSB3_CmdLoadCmac        = 7,
154     kSB3_CmdCopy            = 8,
155     kSB3_CmdLoadHashLocking = 9,
156     kSB3_CmdLoadKeyBlob     = 10,
157     kSB3_CmdConfigMem       = 11,
158     kSB3_CmdFillMem         = 12,
159     kSB3_CmdFwVerCheck      = 13,
160 } sb3_cmd_t;
161 
162 /*! @brief The all of the allowed command */
163 #define SBLOADER_V3_CMD_SET_ALL                                                                                      \
164     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdCall) |                 \
165      (1u << kSB3_CmdProgramFuse) | (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | \
166      (1u << kSB3_CmdConfigMem) | (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
167 /*! @brief The allowed command set in ISP mode */
168 #define SBLOADER_V3_CMD_SET_IN_ISP_MODE                                                                            \
169     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdProgramFuse) |        \
170      (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | (1u << kSB3_CmdConfigMem) | \
171      (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
172 /*! @brief The allowed command set in recovery mode */
173 #define SBLOADER_V3_CMD_SET_IN_REC_MODE                                                                            \
174     ((1u << kSB3_CmdErase) | (1u << kSB3_CmdLoad) | (1u << kSB3_CmdExecute) | (1u << kSB3_CmdProgramFuse) |        \
175      (1u << kSB3_CmdProgramIFR) | (1u << kSB3_CmdCopy) | (1u << kSB3_CmdLoadKeyBlob) | (1u << kSB3_CmdConfigMem) | \
176      (1u << kSB3_CmdFillMem) | (1u << kSB3_CmdFwVerCheck))
177 
178 #define SB3_DATA_BUFFER_SIZE_IN_BYTE (MAX(128, NBOOT_KEY_BLOB_SIZE_IN_BYTE_MAX))
179 
180 /*! @brief Memory region definition. */
181 typedef struct
182 {
183     uint32_t address;
184     uint32_t length;
185 } kb_region_t;
186 
187 /*!
188  * @brief Details of the operation to be performed by the ROM.
189  *
190  * The #kRomAuthenticateImage operation requires the entire signed image to be
191  * available to the application.
192  */
193 typedef enum
194 {
195     kRomAuthenticateImage = 1, /*!< Authenticate a signed image. */
196     kRomLoadImage         = 2, /*!< Load SB file. */
197     kRomOperationCount    = 3,
198 } kb_operation_t;
199 
200 typedef struct
201 {
202     uint32_t profile;
203     uint32_t minBuildNumber;
204     uint32_t overrideSBBootSectionID;
205     uint32_t *userSBKEK;
206     uint32_t regionCount;
207     const kb_region_t *regions;
208 } kb_load_sb_t;
209 
210 typedef struct
211 {
212     uint32_t profile;
213     uint32_t minBuildNumber;
214     uint32_t maxImageLength;
215     uint32_t *userRHK;
216 } kb_authenticate_t;
217 
218 typedef struct
219 {
220     uint32_t version; /*!< Should be set to #kKbootApiVersion. */
221     uint8_t *buffer;  /*!< Caller-provided buffer used by Kboot. */
222     uint32_t bufferLength;
223     kb_operation_t op;
224     union
225     {
226         kb_authenticate_t authenticate; /*!< Settings for #kKbootAuthenticate operation.*/
227         kb_load_sb_t loadSB;            /*!< Settings for #kKbootLoadSB operation.*/
228     };
229 } kb_options_t;
230 
231 /*! @brief Loader context definition. */
232 struct _ldr_Context_v3
233 {
234     pLdrFnc_v3_t Action;        /*!< pointer to loader action function */
235     uint32_t block_size;        /*!< size of each block in bytes */
236     uint32_t block_data_size;   /*!< data size in bytes (NBOOT_SB3_CHUNK_SIZE_IN_BYTES) */
237     uint32_t block_data_total;  /*!< data max size in bytes (block_size * data_size */
238     uint32_t block_buffer_size; /*!< block0 and block size */
239     uint32_t block_buffer_position;
240     uint8_t block_buffer[MAX(NBOOT_SB3_MANIFEST_MAX_SIZE_IN_BYTES,
241                              NBOOT_SB3_BLOCK_MAX_SIZE_IN_BYTES)]; /*! will be used for both block0 and blockx */
242     uint32_t processedBlocks;
243 
244     uint8_t data_block_offset; /*! data block offset in a block. */
245     bool in_data_block;        /*!< in progress of handling a data block within a block */
246     uint8_t *data_block;
247     uint32_t data_block_position;
248 
249     bool in_data_section; /*!< in progress of handling a data section within a data block */
250     uint32_t data_section_handled;
251     sb3_section_header_t data_section_header;
252 
253     bool in_data_range; /*!< in progress of handling a data range within a data section */
254     uint32_t data_range_handled;
255     uint32_t data_range_gap;
256     sb3_data_range_header_t data_range_header;
257     bool has_data_range_expansion;
258     sb3_data_range_expansion_t data_range_expansion;
259 
260     uint32_t commandSet; /*!< support command set during sb file handling */
261 
262     uint32_t data_position;
263     uint8_t data_buffer[SB3_DATA_BUFFER_SIZE_IN_BYTE]; /*!< temporary data buffer */
264 
265     kb_options_t fromAPI;                              /*!< options from ROM API */
266 };
267 
268 /*! @} */
269 
270 #endif /* FSL_SBLOADER_V3_H_ */
271