246 lines
8.6 KiB
C
246 lines
8.6 KiB
C
/*
|
|
* Copyright (c) 2020-2021, Freescale Semiconductor, Inc.
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef FSL_IAP_KBP_H_
|
|
#define FSL_IAP_KBP_H_
|
|
|
|
#include "fsl_common.h"
|
|
|
|
/*!
|
|
* @addtogroup kb_driver
|
|
* @{
|
|
*/
|
|
/*******************************************************************************
|
|
* Definitions
|
|
*******************************************************************************/
|
|
|
|
/*! @brief ROM API status group number */
|
|
#define kStatusGroup_RomApi (108U)
|
|
|
|
/*! @brief ROM API status codes. */
|
|
enum
|
|
{
|
|
kStatus_RomApiExecuteCompleted = kStatus_Success, /*!< ROM successfully process the whole sb file/boot image.*/
|
|
kStatus_RomApiNeedMoreData =
|
|
MAKE_STATUS(kStatusGroup_RomApi, 1), /*!< ROM needs more data to continue processing the boot image.*/
|
|
kStatus_RomApiBufferSizeNotEnough =
|
|
MAKE_STATUS(kStatusGroup_RomApi,
|
|
2), /*!< The user buffer is not enough for use by Kboot during execution of the operation.*/
|
|
kStatus_RomApiInvalidBuffer =
|
|
MAKE_STATUS(kStatusGroup_RomApi, 3), /*!< The user buffer is not ok for sbloader or authentication.*/
|
|
};
|
|
|
|
/*!
|
|
* @brief Details of the operation to be performed by the ROM.
|
|
*
|
|
* The #kRomAuthenticateImage operation requires the entire signed image to be
|
|
* available to the application.
|
|
*/
|
|
typedef enum _kb_operation
|
|
{
|
|
kRomAuthenticateImage = 1, /*!< Authenticate a signed image.*/
|
|
kRomLoadImage = 2, /*!< Load SB file.*/
|
|
kRomOperationCount = 3,
|
|
} kb_operation_t;
|
|
|
|
/*!
|
|
* @brief Security constraint flags, Security profile flags.
|
|
*/
|
|
enum _kb_security_profile
|
|
{
|
|
kKbootMinRSA4096 = (1 << 16),
|
|
};
|
|
|
|
/*!
|
|
* @brief Memory region definition.
|
|
*/
|
|
typedef struct _kb_region
|
|
{
|
|
uint32_t address;
|
|
uint32_t length;
|
|
} kb_region_t;
|
|
|
|
/*!
|
|
* @brief User-provided options passed into kb_init().
|
|
*
|
|
* The buffer field is a pointer to memory provided by the caller for use by
|
|
* Kboot during execution of the operation. Minimum size is the size of each
|
|
* certificate in the chain plus 432 bytes additional per certificate.
|
|
*
|
|
* The profile field is a mask that specifies which features are required in
|
|
* the SB file or image being processed. This includes the minimum AES and RSA
|
|
* key sizes. See the _kb_security_profile enum for profile mask constants.
|
|
* The image being loaded or authenticated must match the profile or an error will
|
|
* be returned.
|
|
*
|
|
* minBuildNumber is an optional field that can be used to prevent version
|
|
* rollback. The API will check the build number of the image, and if it is less
|
|
* than minBuildNumber will fail with an error.
|
|
*
|
|
* maxImageLength is used to verify the offsetToCertificateBlockHeaderInBytes
|
|
* value at the beginning of a signed image. It should be set to the length of
|
|
* the SB file. If verifying an image in flash, it can be set to the internal
|
|
* flash size or a large number like 0x10000000.
|
|
*
|
|
* userRHK can optionally be used by the user to override the RHK in IFR. If
|
|
* userRHK is not NULL, it points to a 32-byte array containing the SHA-256 of
|
|
* the root certificate's RSA public key.
|
|
*
|
|
* The regions field points to an array of memory regions that the SB file being
|
|
* loaded is allowed to access. If regions is NULL, then all memory is
|
|
* accessible by the SB file. This feature is required to prevent a malicious
|
|
* image from erasing good code or RAM contents while it is being loaded, only
|
|
* for us to find that the image is inauthentic when we hit the end of the
|
|
* section.
|
|
*
|
|
* overrideSBBootSectionID lets the caller override the default section of the
|
|
* SB file that is processed during a kKbootLoadSB operation. By default,
|
|
* the section specified in the firstBootableSectionID field of the SB header
|
|
* is loaded. If overrideSBBootSectionID is non-zero, then the section with
|
|
* the given ID will be loaded instead.
|
|
*
|
|
* The userSBKEK field lets a user provide their own AES-256 key for unwrapping
|
|
* keys in an SB file during the kKbootLoadSB operation. userSBKEK should point
|
|
* to a 32-byte AES-256 key. If userSBKEK is NULL then the IFR SBKEK will be used.
|
|
* After kb_init() returns, the caller should zero out the data pointed to by
|
|
* userSBKEK, as the API will have installed the key in the CAU3.
|
|
*/
|
|
|
|
typedef struct _kb_load_sb
|
|
{
|
|
uint32_t profile;
|
|
uint32_t minBuildNumber;
|
|
uint32_t overrideSBBootSectionID;
|
|
uint32_t *userSBKEK;
|
|
uint32_t regionCount;
|
|
const kb_region_t *regions;
|
|
} kb_load_sb_t;
|
|
|
|
typedef struct _kb_authenticate
|
|
{
|
|
uint32_t profile;
|
|
uint32_t minBuildNumber;
|
|
uint32_t maxImageLength;
|
|
uint32_t *userRHK;
|
|
} kb_authenticate_t;
|
|
|
|
typedef struct _kb_options
|
|
{
|
|
uint32_t version; /*!< Should be set to kKbootApiVersion.*/
|
|
uint8_t *buffer; /*!< Caller-provided buffer used by Kboot.*/
|
|
uint32_t bufferLength;
|
|
kb_operation_t op;
|
|
union
|
|
{
|
|
kb_authenticate_t authenticate; /*! Settings for kKbootAuthenticate operation.*/
|
|
kb_load_sb_t loadSB; /*! Settings for kKbootLoadSB operation.*/
|
|
};
|
|
} kb_options_t;
|
|
|
|
/*!
|
|
* @brief Interface to memory operations for one region of memory.
|
|
*/
|
|
typedef struct _memory_region_interface
|
|
{
|
|
status_t (*init)(void);
|
|
status_t (*read)(uint32_t address, uint32_t length, uint8_t *buffer);
|
|
status_t (*write)(uint32_t address, uint32_t length, const uint8_t *buffer);
|
|
status_t (*fill)(uint32_t address, uint32_t length, uint32_t pattern);
|
|
status_t (*flush)(void);
|
|
status_t (*erase)(uint32_t address, uint32_t length);
|
|
status_t (*config)(uint32_t *buffer);
|
|
status_t (*erase_all)(void);
|
|
} memory_region_interface_t;
|
|
|
|
/*!
|
|
* @brief Structure of a memory map entry.
|
|
*/
|
|
typedef struct _memory_map_entry
|
|
{
|
|
uint32_t startAddress;
|
|
uint32_t endAddress;
|
|
uint32_t memoryProperty;
|
|
uint32_t memoryId;
|
|
const memory_region_interface_t *memoryInterface;
|
|
} memory_map_entry_t;
|
|
|
|
typedef struct _kb_opaque_session_ref
|
|
{
|
|
kb_options_t context;
|
|
bool cau3Initialized;
|
|
memory_map_entry_t *memoryMap;
|
|
} kb_session_ref_t;
|
|
|
|
/*******************************************************************************
|
|
* API
|
|
******************************************************************************/
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*!
|
|
* @brief Initialize ROM API for a given operation.
|
|
*
|
|
* Inits the ROM API based on the options provided by the application in the second
|
|
* argument. Every call to rom_init() should be paired with a call to rom_deinit().
|
|
*
|
|
* @retval #kStatus_Success API was executed successfully.
|
|
* @retval #kStatus_InvalidArgument An invalid argument is provided.
|
|
* @retval #kStatus_RomApiBufferSizeNotEnough The user buffer is not enough for use by Kboot during execution of the
|
|
* operation.
|
|
* @retval #kStatus_RomApiInvalidBuffer The user buffer is not ok for sbloader or authentication.
|
|
* @retval #kStatus_SKBOOT_Fail Return the failed status of secure boot.
|
|
* @retval #kStatus_SKBOOT_KeyStoreMarkerInvalid The key code for the particular PRINCE region is not present in the
|
|
* keystore
|
|
* @retval #kStatus_SKBOOT_Success Return the successful status of secure boot.
|
|
*/
|
|
status_t kb_init(kb_session_ref_t **session, const kb_options_t *options);
|
|
|
|
/*!
|
|
* @brief Cleans up the ROM API context.
|
|
*
|
|
* After this call, the context parameter can be reused for another operation
|
|
* by calling rom_init() again.
|
|
*
|
|
* @retval #kStatus_Success API was executed successfully
|
|
*/
|
|
status_t kb_deinit(kb_session_ref_t *session);
|
|
|
|
/*!
|
|
* Perform the operation configured during init.
|
|
*
|
|
* This application must call this API repeatedly, passing in sequential chunks of
|
|
* data from the boot image (SB file) that is to be processed. The ROM will perform
|
|
* the selected operation on this data and return. The application may call this
|
|
* function with as much or as little data as it wishes, which can be used to select
|
|
* the granularity of time given to the application in between executing the operation.
|
|
*
|
|
* @param session Current ROM context pointer.
|
|
* @param data Buffer of boot image data provided to the ROM by the application.
|
|
* @param dataLength Length in bytes of the data in the buffer provided to the ROM.
|
|
*
|
|
* @retval #kStatus_Success ROM successfully process the part of sb file/boot image.
|
|
* @retval #kStatus_RomApiExecuteCompleted ROM successfully process the whole sb file/boot image.
|
|
* @retval #kStatus_Fail An error occurred while executing the operation.
|
|
* @retval #kStatus_RomApiNeedMoreData No error occurred, but the ROM needs more data to
|
|
* continue processing the boot image.
|
|
* @retval #kStatus_RomApiBufferSizeNotEnough user buffer is not enough for
|
|
* use by Kboot during execution of the operation.
|
|
*/
|
|
status_t kb_execute(kb_session_ref_t *session, const uint8_t *data, uint32_t dataLength);
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
/*!
|
|
*@}
|
|
*/
|
|
|
|
#endif /* FSL_IAP_KBP_H_ */
|