| /* |
| * Copyright 2017 NXP |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * |
| * o Redistributions of source code must retain the above copyright notice, this list |
| * of conditions and the following disclaimer. |
| * |
| * o Redistributions in binary form must reproduce the above copyright notice, this |
| * list of conditions and the following disclaimer in the documentation and/or |
| * other materials provided with the distribution. |
| * |
| * o Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef _FSL_DCP_H_ |
| #define _FSL_DCP_H_ |
| |
| #include "fsl_common.h" |
| |
| /*! @brief DCP status return codes. */ |
| enum _dcp_status |
| { |
| kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */ |
| }; |
| |
| /******************************************************************************* |
| * Definitions |
| *******************************************************************************/ |
| |
| /*! |
| * @addtogroup dcp_driver |
| * @{ |
| */ |
| /*! @name Driver version */ |
| /*@{*/ |
| /*! @brief DCP driver version. Version 2.0.0. |
| * |
| * Current version: 2.0.0 |
| * |
| * Change log: |
| * - Version 2.0.0 |
| * - Initial version |
| */ |
| #define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) |
| /*@}*/ |
| |
| /*! @brief DCP channel enable. |
| * |
| */ |
| typedef enum _dcp_ch_enable |
| { |
| kDCP_chDisable = 0U, /*!< DCP channel disable */ |
| kDCP_ch0Enable = 1U, /*!< DCP channel 0 enable */ |
| kDCP_ch1Enable = 2U, /*!< DCP channel 1 enable */ |
| kDCP_ch2Enable = 4U, /*!< DCP channel 2 enable */ |
| kDCP_ch3Enable = 8U, /*!< DCP channel 3 enable */ |
| kDCP_chEnableAll = 15U, /*!< DCP channel enable all */ |
| } _dcp_ch_enable_t; |
| |
| /*! @brief DCP interrupt enable. |
| * |
| */ |
| typedef enum _dcp_ch_int_enable |
| { |
| kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */ |
| kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */ |
| kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */ |
| kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */ |
| kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */ |
| } _dcp_ch_int_enable_t; |
| |
| /*! @brief DCP channel selection. |
| * |
| */ |
| typedef enum _dcp_channel |
| { |
| kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */ |
| kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */ |
| kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */ |
| kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */ |
| } dcp_channel_t; |
| |
| /*! @brief DCP key slot selection. |
| * |
| */ |
| typedef enum _dcp_key_slot |
| { |
| kDCP_KeySlot0 = 0U, /*!< DCP key slot 0. */ |
| kDCP_KeySlot1 = 1U, /*!< DCP key slot 1. */ |
| kDCP_KeySlot2 = 2U, /*!< DCP key slot 2.*/ |
| kDCP_KeySlot3 = 3U, /*!< DCP key slot 3. */ |
| kDCP_OtpKey = 4U, /*!< DCP OTP key. */ |
| kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */ |
| kDCP_PayloadKey = 6U, /*!< DCP payload key. */ |
| } dcp_key_slot_t; |
| |
| /*! @brief DCP's work packet. */ |
| typedef struct _dcp_work_packet |
| { |
| uint32_t nextCmdAddress; |
| uint32_t control0; |
| uint32_t control1; |
| uint32_t sourceBufferAddress; |
| uint32_t destinationBufferAddress; |
| uint32_t bufferSize; |
| uint32_t payloadPointer; |
| uint32_t status; |
| } dcp_work_packet_t; |
| |
| /*! @brief Specify DCP's key resource and DCP channel. */ |
| typedef struct _dcp_handle |
| { |
| dcp_channel_t channel; /*!< Specify DCP channel. */ |
| dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */ |
| uint32_t keyWord[4]; |
| uint32_t iv[4]; |
| } dcp_handle_t; |
| |
| /*! @brief DCP's context buffer, used by DCP for context switching between channels. */ |
| typedef struct _dcp_context |
| { |
| uint32_t x[208 / sizeof(uint32_t)]; |
| } dcp_context_t; |
| |
| /*! @brief DCP's configuration structure. */ |
| typedef struct _dcp_config |
| { |
| bool gatherResidualWrites; /*!< Enable the ragged writes to the unaligned buffers. */ |
| bool enableContextCaching; /*!< Enable the caching of contexts between the operations. */ |
| bool enableContextSwitching; /*!< Enable automatic context switching for the channels. */ |
| uint8_t enableChannel; /*!< DCP channel enable. */ |
| uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */ |
| } dcp_config_t; |
| |
| /*! @} */ |
| |
| /******************************************************************************* |
| * AES Definitions |
| *******************************************************************************/ |
| |
| /*! |
| * @addtogroup dcp_driver_aes |
| * @{ |
| */ |
| |
| /*! AES block size in bytes */ |
| #define DCP_AES_BLOCK_SIZE 16 |
| |
| /*! |
| *@} |
| */ /* end of dcp_driver_aes */ |
| |
| /******************************************************************************* |
| * HASH Definitions |
| ******************************************************************************/ |
| /*! |
| * @addtogroup dcp_driver_hash |
| * @{ |
| */ |
| |
| /* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct |
| * hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this |
| * feature to reduce code size */ |
| #define DCP_HASH_CAVP_COMPATIBLE |
| |
| /*! @brief Supported cryptographic block cipher functions for HASH creation */ |
| typedef enum _dcp_hash_algo_t |
| { |
| kDCP_Sha1, /*!< SHA_1 */ |
| kDCP_Sha256, /*!< SHA_256 */ |
| kDCP_Crc32, /*!< CRC_32 */ |
| } dcp_hash_algo_t; |
| |
| /*! @brief DCP HASH Context size. */ |
| #define DCP_SHA_BLOCK_SIZE 128 /*!< internal buffer block size */ |
| #define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size */ |
| |
| /*! @brief DCP HASH Context size. */ |
| #define DCP_HASH_CTX_SIZE 58 |
| |
| /*! @brief Storage type used to save hash context. */ |
| typedef struct _dcp_hash_ctx_t |
| { |
| uint32_t x[DCP_HASH_CTX_SIZE]; |
| } dcp_hash_ctx_t; |
| |
| /*! |
| *@} |
| */ /* end of dcp_driver_hash */ |
| |
| /******************************************************************************* |
| * API |
| ******************************************************************************/ |
| #if defined(__cplusplus) |
| extern "C" { |
| #endif |
| |
| /*! |
| * @addtogroup dcp_driver |
| * @{ |
| */ |
| |
| /*! |
| * @brief Enables clock to and enables DCP |
| * |
| * Enable DCP clock and configure DCP. |
| * |
| * @param base DCP base address |
| * @param config Pointer to configuration structure. |
| */ |
| void DCP_Init(DCP_Type *base, const dcp_config_t *config); |
| |
| /*! |
| * @brief Disable DCP clock |
| * |
| * Reset DCP and Disable DCP clock. |
| * |
| * @param base DCP base address |
| */ |
| void DCP_Deinit(DCP_Type *base); |
| |
| /*! |
| * @brief Gets the default configuration structure. |
| * |
| * This function initializes the DCP configuration structure to a default value. The default |
| * values are as follows. |
| * dcpConfig->gatherResidualWrites = true; |
| * dcpConfig->enableContextCaching = true; |
| * dcpConfig->enableContextSwitching = true; |
| * dcpConfig->enableChannnel = kDCP_chEnableAll; |
| * dcpConfig->enableChannelInterrupt = kDCP_chIntDisable; |
| * |
| * @param[out] config Pointer to configuration structure. |
| */ |
| void DCP_GetDefaultConfig(dcp_config_t *config); |
| |
| /*! |
| * @brief Poll and wait on DCP channel. |
| * |
| * Polls the specified DCP channel until current it completes activity. |
| * |
| * @param base DCP peripheral base address. |
| * @param handle Specifies DCP channel. |
| * @return kStatus_Success When data processing completes without error. |
| * @return kStatus_Fail When error occurs. |
| */ |
| status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle); |
| |
| /*! |
| *@} |
| */ /* end of dcp_driver */ |
| |
| /******************************************************************************* |
| * AES API |
| ******************************************************************************/ |
| |
| /*! |
| * @addtogroup dcp_driver_aes |
| * @{ |
| */ |
| |
| /*! |
| * @brief Set AES key to dcp_handle_t struct and optionally to DCP. |
| * |
| * Sets the AES key for encryption/decryption with the dcp_handle_t structure. |
| * The dcp_handle_t input argument specifies keySlot. |
| * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use |
| * status. |
| * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct. |
| * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2, |
| * kDCP_KeySlot3), |
| * this function will also load the supplied key to the specified keySlot in DCP. |
| * |
| * @param base DCP peripheral base address. |
| * @param handle Handle used for the request. |
| * @param key 0-mod-4 aligned pointer to AES key. |
| * @param keySize AES key size in bytes. Shall equal 16. |
| * @return status from set key operation |
| */ |
| status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize); |
| |
| /*! |
| * @brief Encrypts AES on one or multiple 128-bit block(s). |
| * |
| * Encrypts AES. |
| * The source plaintext and destination ciphertext can overlap in system memory. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param plaintext Input plain text to encrypt |
| * @param[out] ciphertext Output cipher text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @return Status from encrypt operation |
| */ |
| status_t DCP_AES_EncryptEcb( |
| DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size); |
| |
| /*! |
| * @brief Decrypts AES on one or multiple 128-bit block(s). |
| * |
| * Decrypts AES. |
| * The source ciphertext and destination plaintext can overlap in system memory. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param ciphertext Input plain text to encrypt |
| * @param[out] plaintext Output cipher text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @return Status from decrypt operation |
| */ |
| status_t DCP_AES_DecryptEcb( |
| DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size); |
| |
| /*! |
| * @brief Encrypts AES using CBC block mode. |
| * |
| * Encrypts AES using CBC block mode. |
| * The source plaintext and destination ciphertext can overlap in system memory. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param plaintext Input plain text to encrypt |
| * @param[out] ciphertext Output cipher text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @param iv Input initial vector to combine with the first input block. |
| * @return Status from encrypt operation |
| */ |
| status_t DCP_AES_EncryptCbc(DCP_Type *base, |
| dcp_handle_t *handle, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| size_t size, |
| const uint8_t iv[16]); |
| |
| /*! |
| * @brief Decrypts AES using CBC block mode. |
| * |
| * Decrypts AES using CBC block mode. |
| * The source ciphertext and destination plaintext can overlap in system memory. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param ciphertext Input cipher text to decrypt |
| * @param[out] plaintext Output plain text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @param iv Input initial vector to combine with the first input block. |
| * @return Status from decrypt operation |
| */ |
| status_t DCP_AES_DecryptCbc(DCP_Type *base, |
| dcp_handle_t *handle, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| size_t size, |
| const uint8_t iv[16]); |
| |
| /*! |
| *@} |
| */ /* end of dcp_driver_aes */ |
| |
| /*! |
| * @addtogroup dcp_nonblocking_driver_aes |
| * @{ |
| */ |
| /*! |
| * @brief Encrypts AES using the ECB block mode. |
| * |
| * Puts AES ECB encrypt work packet to DCP channel. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param[out] dcpPacket Memory for the DCP work packet. |
| * @param plaintext Input plain text to encrypt. |
| * @param[out] ciphertext Output cipher text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @return kStatus_Success The work packet has been scheduled at DCP channel. |
| * @return kStatus_DCP_Again The DCP channel is busy processing previous request. |
| */ |
| status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base, |
| dcp_handle_t *handle, |
| dcp_work_packet_t *dcpPacket, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| size_t size); |
| |
| /*! |
| * @brief Decrypts AES using ECB block mode. |
| * |
| * Puts AES ECB decrypt dcpPacket to DCP input job ring. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. |
| * @param[out] dcpPacket Memory for the DCP work packet. |
| * @param ciphertext Input cipher text to decrypt |
| * @param[out] plaintext Output plain text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @return kStatus_Success The work packet has been scheduled at DCP channel. |
| * @return kStatus_DCP_Again The DCP channel is busy processing previous request. |
| */ |
| status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base, |
| dcp_handle_t *handle, |
| dcp_work_packet_t *dcpPacket, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| size_t size); |
| |
| /*! |
| * @brief Encrypts AES using CBC block mode. |
| * |
| * Puts AES CBC encrypt dcpPacket to DCP input job ring. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. Specifies jobRing. |
| * @param[out] dcpPacket Memory for the DCP work packet. |
| * @param plaintext Input plain text to encrypt |
| * @param[out] ciphertext Output cipher text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @param iv Input initial vector to combine with the first input block. |
| * @return kStatus_Success The work packet has been scheduled at DCP channel. |
| * @return kStatus_DCP_Again The DCP channel is busy processing previous request. |
| */ |
| status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base, |
| dcp_handle_t *handle, |
| dcp_work_packet_t *dcpPacket, |
| const uint8_t *plaintext, |
| uint8_t *ciphertext, |
| size_t size, |
| const uint8_t *iv); |
| |
| /*! |
| * @brief Decrypts AES using CBC block mode. |
| * |
| * Puts AES CBC decrypt dcpPacket to DCP input job ring. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for this request. Specifies jobRing. |
| * @param[out] dcpPacket Memory for the DCP work packet. |
| * @param ciphertext Input cipher text to decrypt |
| * @param[out] plaintext Output plain text |
| * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. |
| * @param iv Input initial vector to combine with the first input block. |
| * @return kStatus_Success The work packet has been scheduled at DCP channel. |
| * @return kStatus_DCP_Again The DCP channel is busy processing previous request. |
| */ |
| status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base, |
| dcp_handle_t *handle, |
| dcp_work_packet_t *dcpPacket, |
| const uint8_t *ciphertext, |
| uint8_t *plaintext, |
| size_t size, |
| const uint8_t *iv); |
| |
| /*! |
| *@} |
| */ /* end of dcp_nonblocking_driver_aes */ |
| |
| /******************************************************************************* |
| * HASH API |
| ******************************************************************************/ |
| |
| /*! |
| * @addtogroup dcp_driver_hash |
| * @{ |
| */ |
| /*! |
| * @brief Initialize HASH context |
| * |
| * This function initializes the HASH. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Specifies the DCP channel used for hashing. |
| * @param[out] ctx Output hash context |
| * @param algo Underlaying algorithm to use for hash computation. |
| * @return Status of initialization |
| */ |
| status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo); |
| |
| /*! |
| * @brief Add data to current HASH |
| * |
| * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be |
| * hashed. The functions blocks. If it returns kStatus_Success, the running hash |
| * has been updated (DCP has processed the input data), so the memory at @ref input pointer |
| * can be released back to system. The DCP context buffer is updated with the running hash |
| * and with all necessary information to support possible context switch. |
| * |
| * @param base DCP peripheral base address |
| * @param[in,out] ctx HASH context |
| * @param input Input data |
| * @param inputSize Size of input data in bytes |
| * @return Status of the hash update operation |
| */ |
| status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize); |
| |
| /*! |
| * @brief Finalize hashing |
| * |
| * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context. |
| * |
| * @param[in,out] ctx Input hash context |
| * @param[out] output Output hash data |
| * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of |
| * output[] buffer. On function return, it stores the number of updated output bytes. |
| * @return Status of the hash finish operation |
| */ |
| status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize); |
| |
| /*! |
| * @brief Create HASH on given data |
| * |
| * Perform the full SHA or CRC32 in one function call. The function is blocking. |
| * |
| * @param base DCP peripheral base address |
| * @param handle Handle used for the request. |
| * @param algo Underlaying algorithm to use for hash computation. |
| * @param input Input data |
| * @param inputSize Size of input data in bytes |
| * @param[out] output Output hash data |
| * @param[out] outputSize Output parameter storing the size of the output hash in bytes |
| * @return Status of the one call hash operation. |
| */ |
| status_t DCP_HASH(DCP_Type *base, |
| dcp_handle_t *handle, |
| dcp_hash_algo_t algo, |
| const uint8_t *input, |
| size_t inputSize, |
| uint8_t *output, |
| size_t *outputSize); |
| |
| /*! |
| *@} |
| */ /* end of dcp_driver_hash */ |
| |
| #if defined(__cplusplus) |
| } |
| #endif |
| |
| #endif /* _FSL_DCP_H_ */ |