1 /* 2 * Copyright (c) 2020-2021, Freescale Semiconductor, Inc. 3 * All rights reserved. 4 * 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef FSL_IAP_KBP_H_ 10 #define FSL_IAP_KBP_H_ 11 12 #include "fsl_common.h" 13 14 /*! 15 * @addtogroup kb_driver 16 * @{ 17 */ 18 /******************************************************************************* 19 * Definitions 20 *******************************************************************************/ 21 22 /*! @brief ROM API status group number */ 23 #define kStatusGroup_RomApi (108U) 24 25 /*! @brief ROM API status codes. */ 26 enum 27 { 28 kStatus_RomApiExecuteCompleted = kStatus_Success, /*!< ROM successfully process the whole sb file/boot image.*/ 29 kStatus_RomApiNeedMoreData = 30 MAKE_STATUS(kStatusGroup_RomApi, 1), /*!< ROM needs more data to continue processing the boot image.*/ 31 kStatus_RomApiBufferSizeNotEnough = 32 MAKE_STATUS(kStatusGroup_RomApi, 33 2), /*!< The user buffer is not enough for use by Kboot during execution of the operation.*/ 34 kStatus_RomApiInvalidBuffer = 35 MAKE_STATUS(kStatusGroup_RomApi, 3), /*!< The user buffer is not ok for sbloader or authentication.*/ 36 }; 37 38 /*! 39 * @brief Details of the operation to be performed by the ROM. 40 * 41 * The #kRomAuthenticateImage operation requires the entire signed image to be 42 * available to the application. 43 */ 44 typedef enum _kb_operation 45 { 46 kRomAuthenticateImage = 1, /*!< Authenticate a signed image.*/ 47 kRomLoadImage = 2, /*!< Load SB file.*/ 48 kRomOperationCount = 3, 49 } kb_operation_t; 50 51 /*! 52 * @brief Security constraint flags, Security profile flags. 53 */ 54 enum _kb_security_profile 55 { 56 kKbootMinRSA4096 = (1 << 16), 57 }; 58 59 /*! 60 * @brief Memory region definition. 61 */ 62 typedef struct _kb_region 63 { 64 uint32_t address; 65 uint32_t length; 66 } kb_region_t; 67 68 /*! 69 * @brief User-provided options passed into kb_init(). 70 * 71 * The buffer field is a pointer to memory provided by the caller for use by 72 * Kboot during execution of the operation. Minimum size is the size of each 73 * certificate in the chain plus 432 bytes additional per certificate. 74 * 75 * The profile field is a mask that specifies which features are required in 76 * the SB file or image being processed. This includes the minimum AES and RSA 77 * key sizes. See the _kb_security_profile enum for profile mask constants. 78 * The image being loaded or authenticated must match the profile or an error will 79 * be returned. 80 * 81 * minBuildNumber is an optional field that can be used to prevent version 82 * rollback. The API will check the build number of the image, and if it is less 83 * than minBuildNumber will fail with an error. 84 * 85 * maxImageLength is used to verify the offsetToCertificateBlockHeaderInBytes 86 * value at the beginning of a signed image. It should be set to the length of 87 * the SB file. If verifying an image in flash, it can be set to the internal 88 * flash size or a large number like 0x10000000. 89 * 90 * userRHK can optionally be used by the user to override the RHK in IFR. If 91 * userRHK is not NULL, it points to a 32-byte array containing the SHA-256 of 92 * the root certificate's RSA public key. 93 * 94 * The regions field points to an array of memory regions that the SB file being 95 * loaded is allowed to access. If regions is NULL, then all memory is 96 * accessible by the SB file. This feature is required to prevent a malicious 97 * image from erasing good code or RAM contents while it is being loaded, only 98 * for us to find that the image is inauthentic when we hit the end of the 99 * section. 100 * 101 * overrideSBBootSectionID lets the caller override the default section of the 102 * SB file that is processed during a kKbootLoadSB operation. By default, 103 * the section specified in the firstBootableSectionID field of the SB header 104 * is loaded. If overrideSBBootSectionID is non-zero, then the section with 105 * the given ID will be loaded instead. 106 * 107 * The userSBKEK field lets a user provide their own AES-256 key for unwrapping 108 * keys in an SB file during the kKbootLoadSB operation. userSBKEK should point 109 * to a 32-byte AES-256 key. If userSBKEK is NULL then the IFR SBKEK will be used. 110 * After kb_init() returns, the caller should zero out the data pointed to by 111 * userSBKEK, as the API will have installed the key in the CAU3. 112 */ 113 114 typedef struct _kb_load_sb 115 { 116 uint32_t profile; 117 uint32_t minBuildNumber; 118 uint32_t overrideSBBootSectionID; 119 uint32_t *userSBKEK; 120 uint32_t regionCount; 121 const kb_region_t *regions; 122 } kb_load_sb_t; 123 124 typedef struct _kb_authenticate 125 { 126 uint32_t profile; 127 uint32_t minBuildNumber; 128 uint32_t maxImageLength; 129 uint32_t *userRHK; 130 } kb_authenticate_t; 131 132 typedef struct _kb_options 133 { 134 uint32_t version; /*!< Should be set to kKbootApiVersion.*/ 135 uint8_t *buffer; /*!< Caller-provided buffer used by Kboot.*/ 136 uint32_t bufferLength; 137 kb_operation_t op; 138 union 139 { 140 kb_authenticate_t authenticate; /*! Settings for kKbootAuthenticate operation.*/ 141 kb_load_sb_t loadSB; /*! Settings for kKbootLoadSB operation.*/ 142 }; 143 } kb_options_t; 144 145 /*! 146 * @brief Interface to memory operations for one region of memory. 147 */ 148 typedef struct _memory_region_interface 149 { 150 status_t (*init)(void); 151 status_t (*read)(uint32_t address, uint32_t length, uint8_t *buffer); 152 status_t (*write)(uint32_t address, uint32_t length, const uint8_t *buffer); 153 status_t (*fill)(uint32_t address, uint32_t length, uint32_t pattern); 154 status_t (*flush)(void); 155 status_t (*erase)(uint32_t address, uint32_t length); 156 status_t (*config)(uint32_t *buffer); 157 status_t (*erase_all)(void); 158 } memory_region_interface_t; 159 160 /*! 161 * @brief Structure of a memory map entry. 162 */ 163 typedef struct _memory_map_entry 164 { 165 uint32_t startAddress; 166 uint32_t endAddress; 167 uint32_t memoryProperty; 168 uint32_t memoryId; 169 const memory_region_interface_t *memoryInterface; 170 } memory_map_entry_t; 171 172 typedef struct _kb_opaque_session_ref 173 { 174 kb_options_t context; 175 bool cau3Initialized; 176 memory_map_entry_t *memoryMap; 177 } kb_session_ref_t; 178 179 /******************************************************************************* 180 * API 181 ******************************************************************************/ 182 #if defined(__cplusplus) 183 extern "C" { 184 #endif 185 186 /*! 187 * @brief Initialize ROM API for a given operation. 188 * 189 * Inits the ROM API based on the options provided by the application in the second 190 * argument. Every call to rom_init() should be paired with a call to rom_deinit(). 191 * 192 * @retval #kStatus_Success API was executed successfully. 193 * @retval #kStatus_InvalidArgument An invalid argument is provided. 194 * @retval #kStatus_RomApiBufferSizeNotEnough The user buffer is not enough for use by Kboot during execution of the 195 * operation. 196 * @retval #kStatus_RomApiInvalidBuffer The user buffer is not ok for sbloader or authentication. 197 * @retval #kStatus_SKBOOT_Fail Return the failed status of secure boot. 198 * @retval #kStatus_SKBOOT_KeyStoreMarkerInvalid The key code for the particular PRINCE region is not present in the 199 * keystore 200 * @retval #kStatus_SKBOOT_Success Return the successful status of secure boot. 201 */ 202 status_t kb_init(kb_session_ref_t **session, const kb_options_t *options); 203 204 /*! 205 * @brief Cleans up the ROM API context. 206 * 207 * After this call, the context parameter can be reused for another operation 208 * by calling rom_init() again. 209 * 210 * @retval #kStatus_Success API was executed successfully 211 */ 212 status_t kb_deinit(kb_session_ref_t *session); 213 214 /*! 215 * Perform the operation configured during init. 216 * 217 * This application must call this API repeatedly, passing in sequential chunks of 218 * data from the boot image (SB file) that is to be processed. The ROM will perform 219 * the selected operation on this data and return. The application may call this 220 * function with as much or as little data as it wishes, which can be used to select 221 * the granularity of time given to the application in between executing the operation. 222 * 223 * @param session Current ROM context pointer. 224 * @param data Buffer of boot image data provided to the ROM by the application. 225 * @param dataLength Length in bytes of the data in the buffer provided to the ROM. 226 * 227 * @retval #kStatus_Success ROM successfully process the part of sb file/boot image. 228 * @retval #kStatus_RomApiExecuteCompleted ROM successfully process the whole sb file/boot image. 229 * @retval #kStatus_Fail An error occurred while executing the operation. 230 * @retval #kStatus_RomApiNeedMoreData No error occurred, but the ROM needs more data to 231 * continue processing the boot image. 232 * @retval #kStatus_RomApiBufferSizeNotEnough user buffer is not enough for 233 * use by Kboot during execution of the operation. 234 */ 235 status_t kb_execute(kb_session_ref_t *session, const uint8_t *data, uint32_t dataLength); 236 237 #if defined(__cplusplus) 238 } 239 #endif 240 241 /*! 242 *@} 243 */ 244 245 #endif /* FSL_IAP_KBP_H_ */ 246