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