Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:58

0001 /*
0002  * Copyright 2017-2020 NXP
0003  * All rights reserved.
0004  *
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #ifndef _FSL_DCP_H_
0010 #define _FSL_DCP_H_
0011 
0012 #include "fsl_common.h"
0013 
0014 /*******************************************************************************
0015  * Definitions
0016  *******************************************************************************/
0017 
0018 /*!
0019  * @addtogroup dcp_driver
0020  * @{
0021  */
0022 /*! @name Driver version */
0023 /*@{*/
0024 /*! @brief DCP driver version. Version 2.1.6.
0025  *
0026  * Current version: 2.1.6
0027  *
0028  * Change log:
0029  *
0030  * - Version 2.1.6
0031  *  - Bug Fix
0032  *   - MISRA C-2012 issue fix.
0033  *
0034  * - Version 2.1.5
0035  *  - Improvements
0036  *   - Add support for DCACHE.
0037  *
0038  * - Version 2.1.4
0039  *  - Bug Fix
0040  *   - Fix CRC-32 computation issue on the code's block boundary size.
0041  *
0042  * - Version 2.1.3
0043  *  - Bug Fix
0044  *   - MISRA C-2012 issue fixed: rule 10.1, 10.3, 10.4, 11.9, 14.4, 16.4 and 17.7.
0045  *
0046  * - Version 2.1.2
0047  *   - Fix sign-compare warning in dcp_reverse_and_copy.
0048  *
0049  * - Version 2.1.1
0050  *   - Add DCP status clearing when channel operation is complete
0051  *
0052  * - 2.1.0
0053  *   - Add byte/word swap feature for key, input and output data
0054  *
0055  * - Version 2.0.0
0056  *   - Initial version
0057  */
0058 #define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 1, 6))
0059 /*@}*/
0060 
0061 /*! @brief DCP status return codes. */
0062 enum _dcp_status
0063 {
0064     kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */
0065 };
0066 
0067 /*! @brief DCP channel enable.
0068  *
0069  */
0070 typedef enum _dcp_ch_enable
0071 {
0072     kDCP_chDisable   = 0U,  /*!< DCP channel disable */
0073     kDCP_ch0Enable   = 1U,  /*!< DCP channel 0 enable */
0074     kDCP_ch1Enable   = 2U,  /*!< DCP channel 1 enable */
0075     kDCP_ch2Enable   = 4U,  /*!< DCP channel 2 enable */
0076     kDCP_ch3Enable   = 8U,  /*!< DCP channel 3 enable */
0077     kDCP_chEnableAll = 15U, /*!< DCP channel enable all */
0078 } _dcp_ch_enable_t;
0079 
0080 /*! @brief DCP interrupt enable.
0081  *
0082  */
0083 typedef enum _dcp_ch_int_enable
0084 {
0085     kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */
0086     kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */
0087     kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */
0088     kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */
0089     kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */
0090 } _dcp_ch_int_enable_t;
0091 
0092 /*! @brief DCP channel selection.
0093  *
0094  */
0095 typedef enum _dcp_channel
0096 {
0097     kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */
0098     kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */
0099     kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */
0100     kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */
0101 } dcp_channel_t;
0102 
0103 /*! @brief DCP key slot selection.
0104  *
0105  */
0106 typedef enum _dcp_key_slot
0107 {
0108     kDCP_KeySlot0     = 0U, /*!< DCP key slot 0. */
0109     kDCP_KeySlot1     = 1U, /*!< DCP key slot 1. */
0110     kDCP_KeySlot2     = 2U, /*!< DCP key slot 2.*/
0111     kDCP_KeySlot3     = 3U, /*!< DCP key slot 3. */
0112     kDCP_OtpKey       = 4U, /*!< DCP OTP key. */
0113     kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */
0114     kDCP_PayloadKey   = 6U, /*!< DCP payload key. */
0115 } dcp_key_slot_t;
0116 
0117 /*! @brief DCP key, input & output swap options
0118  *
0119  */
0120 typedef enum _dcp_swap
0121 {
0122     kDCP_NoSwap         = 0x0U,
0123     kDCP_KeyByteSwap    = 0x40000U,
0124     kDCP_KeyWordSwap    = 0x80000U,
0125     kDCP_InputByteSwap  = 0x100000U,
0126     kDCP_InputWordSwap  = 0x200000U,
0127     kDCP_OutputByteSwap = 0x400000U,
0128     kDCP_OutputWordSwap = 0x800000U,
0129 } dcp_swap_t;
0130 
0131 /*! @brief DCP's work packet. */
0132 typedef struct _dcp_work_packet
0133 {
0134     uint32_t nextCmdAddress;
0135     uint32_t control0;
0136     uint32_t control1;
0137     uint32_t sourceBufferAddress;
0138     uint32_t destinationBufferAddress;
0139     uint32_t bufferSize;
0140     uint32_t payloadPointer;
0141     uint32_t status;
0142 } dcp_work_packet_t;
0143 
0144 /*! @brief Specify DCP's key resource and DCP channel. */
0145 typedef struct _dcp_handle
0146 {
0147     dcp_channel_t channel;  /*!< Specify DCP channel. */
0148     dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */
0149     uint32_t swapConfig;    /*!< For configuration of key, input, output byte/word swap options */
0150     uint32_t keyWord[4];
0151     uint32_t iv[4];
0152 } dcp_handle_t;
0153 
0154 /*! @brief DCP's context buffer, used by DCP for context switching between channels. */
0155 typedef struct _dcp_context
0156 {
0157     uint32_t x[208 / sizeof(uint32_t)];
0158 } dcp_context_t;
0159 
0160 /*! @brief DCP's configuration structure. */
0161 typedef struct _dcp_config
0162 {
0163     bool gatherResidualWrites;      /*!< Enable the ragged writes to the unaligned buffers. */
0164     bool enableContextCaching;      /*!< Enable the caching of contexts between the operations. */
0165     bool enableContextSwitching;    /*!< Enable automatic context switching for the channels. */
0166     uint8_t enableChannel;          /*!< DCP channel enable. */
0167     uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */
0168 } dcp_config_t;
0169 
0170 /*! @} */
0171 
0172 #ifndef DCP_USE_DCACHE
0173 #define DCP_USE_DCACHE 1
0174 #endif
0175 /* 1 - driver supports DCACHE, 0 - drivers does not support DCACHE */
0176 /* When enable (DCP_USE_DCACHE = 1) Input/output buffers and hash ctx should be in */
0177 /* non-cached memory or handled properly (Clean & Invalidate DCACHE) */
0178 
0179 /*******************************************************************************
0180  * AES Definitions
0181  *******************************************************************************/
0182 
0183 /*!
0184  * @addtogroup dcp_driver_aes
0185  * @{
0186  */
0187 
0188 /*! AES block size in bytes */
0189 #define DCP_AES_BLOCK_SIZE 16
0190 
0191 /*!
0192  *@}
0193  */ /* end of dcp_driver_aes */
0194 
0195 /*******************************************************************************
0196  * HASH Definitions
0197  ******************************************************************************/
0198 /*!
0199  * @addtogroup dcp_driver_hash
0200  * @{
0201  */
0202 
0203 /* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct
0204  * hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this
0205  * feature to reduce code size */
0206 #define DCP_HASH_CAVP_COMPATIBLE
0207 
0208 /*! @brief Supported cryptographic block cipher functions for HASH creation */
0209 typedef enum _dcp_hash_algo_t
0210 {
0211     kDCP_Sha1,   /*!< SHA_1 */
0212     kDCP_Sha256, /*!< SHA_256 */
0213     kDCP_Crc32,  /*!< CRC_32 */
0214 } dcp_hash_algo_t;
0215 
0216 /*! @brief DCP HASH Context size. */
0217 #define DCP_SHA_BLOCK_SIZE  128U               /*!< internal buffer block size  */
0218 #define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size  */
0219 
0220 /*! @brief DCP HASH Context size. */
0221 #define DCP_HASH_CTX_SIZE 64
0222 
0223 /*! @brief Storage type used to save hash context. */
0224 typedef struct _dcp_hash_ctx_t
0225 {
0226     uint32_t x[DCP_HASH_CTX_SIZE];
0227 } dcp_hash_ctx_t;
0228 
0229 /*!
0230  *@}
0231  */ /* end of dcp_driver_hash */
0232 
0233 /*******************************************************************************
0234  * API
0235  ******************************************************************************/
0236 #if defined(__cplusplus)
0237 extern "C" {
0238 #endif
0239 
0240 /*!
0241  * @addtogroup dcp_driver
0242  * @{
0243  */
0244 
0245 /*!
0246  * @brief   Enables clock to and enables DCP
0247  *
0248  * Enable DCP clock and configure DCP.
0249  *
0250  * @param base DCP base address
0251  * @param config Pointer to configuration structure.
0252  */
0253 void DCP_Init(DCP_Type *base, const dcp_config_t *config);
0254 
0255 /*!
0256  * @brief   Disable DCP clock
0257  *
0258  * Reset DCP and Disable DCP clock.
0259  *
0260  * @param base DCP base address
0261  */
0262 void DCP_Deinit(DCP_Type *base);
0263 
0264 /*!
0265  * @brief Gets the default configuration structure.
0266  *
0267  * This function initializes the DCP configuration structure to a default value. The default
0268  * values are as follows.
0269  *   dcpConfig->gatherResidualWrites = true;
0270  *   dcpConfig->enableContextCaching = true;
0271  *   dcpConfig->enableContextSwitching = true;
0272  *   dcpConfig->enableChannnel = kDCP_chEnableAll;
0273  *   dcpConfig->enableChannelInterrupt = kDCP_chIntDisable;
0274  *
0275  * @param[out] config Pointer to configuration structure.
0276  */
0277 void DCP_GetDefaultConfig(dcp_config_t *config);
0278 
0279 /*!
0280  * @brief Poll and wait on DCP channel.
0281  *
0282  * Polls the specified DCP channel until current it completes activity.
0283  *
0284  * @param   base DCP peripheral base address.
0285  * @param   handle Specifies DCP channel.
0286  * @return  kStatus_Success When data processing completes without error.
0287  * @return  kStatus_Fail When error occurs.
0288  */
0289 status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle);
0290 
0291 /*!
0292  *@}
0293  */ /* end of dcp_driver */
0294 
0295 /*******************************************************************************
0296  * AES API
0297  ******************************************************************************/
0298 
0299 /*!
0300  * @addtogroup dcp_driver_aes
0301  * @{
0302  */
0303 
0304 /*!
0305  * @brief Set AES key to dcp_handle_t struct and optionally to DCP.
0306  *
0307  * Sets the AES key for encryption/decryption with the dcp_handle_t structure.
0308  * The dcp_handle_t input argument specifies keySlot.
0309  * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use
0310  * status.
0311  * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct.
0312  * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2,
0313  * kDCP_KeySlot3),
0314  * this function will also load the supplied key to the specified keySlot in DCP.
0315  *
0316  * @param   base DCP peripheral base address.
0317  * @param   handle Handle used for the request.
0318  * @param   key 0-mod-4 aligned pointer to AES key.
0319  * @param   keySize AES key size in bytes. Shall equal 16.
0320  * @return  status from set key operation
0321  */
0322 status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize);
0323 
0324 /*!
0325  * @brief Encrypts AES on one or multiple 128-bit block(s).
0326  *
0327  * Encrypts AES.
0328  * The source plaintext and destination ciphertext can overlap in system memory.
0329  *
0330  * @param base DCP peripheral base address
0331  * @param handle Handle used for this request.
0332  * @param plaintext Input plain text to encrypt
0333  * @param[out] ciphertext Output cipher text
0334  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0335  * @return Status from encrypt operation
0336  */
0337 status_t DCP_AES_EncryptEcb(
0338     DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
0339 
0340 /*!
0341  * @brief Decrypts AES on one or multiple 128-bit block(s).
0342  *
0343  * Decrypts AES.
0344  * The source ciphertext and destination plaintext can overlap in system memory.
0345  *
0346  * @param base DCP peripheral base address
0347  * @param handle Handle used for this request.
0348  * @param ciphertext Input plain text to encrypt
0349  * @param[out] plaintext Output cipher text
0350  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0351  * @return Status from decrypt operation
0352  */
0353 status_t DCP_AES_DecryptEcb(
0354     DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
0355 
0356 /*!
0357  * @brief Encrypts AES using CBC block mode.
0358  *
0359  * Encrypts AES using CBC block mode.
0360  * The source plaintext and destination ciphertext can overlap in system memory.
0361  *
0362  * @param base DCP peripheral base address
0363  * @param handle Handle used for this request.
0364  * @param plaintext Input plain text to encrypt
0365  * @param[out] ciphertext Output cipher text
0366  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0367  * @param iv Input initial vector to combine with the first input block.
0368  * @return Status from encrypt operation
0369  */
0370 status_t DCP_AES_EncryptCbc(DCP_Type *base,
0371                             dcp_handle_t *handle,
0372                             const uint8_t *plaintext,
0373                             uint8_t *ciphertext,
0374                             size_t size,
0375                             const uint8_t iv[16]);
0376 
0377 /*!
0378  * @brief Decrypts AES using CBC block mode.
0379  *
0380  * Decrypts AES using CBC block mode.
0381  * The source ciphertext and destination plaintext can overlap in system memory.
0382  *
0383  * @param base DCP peripheral base address
0384  * @param handle Handle used for this request.
0385  * @param ciphertext Input cipher text to decrypt
0386  * @param[out] plaintext Output plain text
0387  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0388  * @param iv Input initial vector to combine with the first input block.
0389  * @return Status from decrypt operation
0390  */
0391 status_t DCP_AES_DecryptCbc(DCP_Type *base,
0392                             dcp_handle_t *handle,
0393                             const uint8_t *ciphertext,
0394                             uint8_t *plaintext,
0395                             size_t size,
0396                             const uint8_t iv[16]);
0397 
0398 /*!
0399  *@}
0400  */ /* end of dcp_driver_aes */
0401 
0402 /*!
0403  * @addtogroup dcp_nonblocking_driver_aes
0404  * @{
0405  */
0406 /*!
0407  * @brief Encrypts AES using the ECB block mode.
0408  *
0409  * Puts AES ECB encrypt work packet to DCP channel.
0410  *
0411  * @param base DCP peripheral base address
0412  * @param handle Handle used for this request.
0413  * @param[out] dcpPacket Memory for the DCP work packet.
0414  * @param plaintext Input plain text to encrypt.
0415  * @param[out] ciphertext Output cipher text
0416  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0417  * @return kStatus_Success The work packet has been scheduled at DCP channel.
0418  * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
0419  */
0420 status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
0421                                        dcp_handle_t *handle,
0422                                        dcp_work_packet_t *dcpPacket,
0423                                        const uint8_t *plaintext,
0424                                        uint8_t *ciphertext,
0425                                        size_t size);
0426 
0427 /*!
0428  * @brief Decrypts AES using ECB block mode.
0429  *
0430  * Puts AES ECB decrypt dcpPacket to DCP input job ring.
0431  *
0432  * @param base DCP peripheral base address
0433  * @param handle Handle used for this request.
0434  * @param[out] dcpPacket Memory for the DCP work packet.
0435  * @param ciphertext Input cipher text to decrypt
0436  * @param[out] plaintext Output plain text
0437  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0438  * @return kStatus_Success The work packet has been scheduled at DCP channel.
0439  * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
0440  */
0441 status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
0442                                        dcp_handle_t *handle,
0443                                        dcp_work_packet_t *dcpPacket,
0444                                        const uint8_t *ciphertext,
0445                                        uint8_t *plaintext,
0446                                        size_t size);
0447 
0448 /*!
0449  * @brief Encrypts AES using CBC block mode.
0450  *
0451  * Puts AES CBC encrypt dcpPacket to DCP input job ring.
0452  *
0453  * @param base DCP peripheral base address
0454  * @param handle Handle used for this request. Specifies jobRing.
0455  * @param[out] dcpPacket Memory for the DCP work packet.
0456  * @param plaintext Input plain text to encrypt
0457  * @param[out] ciphertext Output cipher text
0458  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0459  * @param iv Input initial vector to combine with the first input block.
0460  * @return kStatus_Success The work packet has been scheduled at DCP channel.
0461  * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
0462  */
0463 status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
0464                                        dcp_handle_t *handle,
0465                                        dcp_work_packet_t *dcpPacket,
0466                                        const uint8_t *plaintext,
0467                                        uint8_t *ciphertext,
0468                                        size_t size,
0469                                        const uint8_t *iv);
0470 
0471 /*!
0472  * @brief Decrypts AES using CBC block mode.
0473  *
0474  * Puts AES CBC decrypt dcpPacket to DCP input job ring.
0475  *
0476  * @param base DCP peripheral base address
0477  * @param handle Handle used for this request. Specifies jobRing.
0478  * @param[out] dcpPacket Memory for the DCP work packet.
0479  * @param ciphertext Input cipher text to decrypt
0480  * @param[out] plaintext Output plain text
0481  * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
0482  * @param iv Input initial vector to combine with the first input block.
0483  * @return kStatus_Success The work packet has been scheduled at DCP channel.
0484  * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
0485  */
0486 status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
0487                                        dcp_handle_t *handle,
0488                                        dcp_work_packet_t *dcpPacket,
0489                                        const uint8_t *ciphertext,
0490                                        uint8_t *plaintext,
0491                                        size_t size,
0492                                        const uint8_t *iv);
0493 
0494 /*!
0495  *@}
0496  */ /* end of dcp_nonblocking_driver_aes */
0497 
0498 /*******************************************************************************
0499  * HASH API
0500  ******************************************************************************/
0501 
0502 /*!
0503  * @addtogroup dcp_driver_hash
0504  * @{
0505  */
0506 /*!
0507  * @brief Initialize HASH context
0508  *
0509  * This function initializes the HASH.
0510  *
0511  * @param base DCP peripheral base address
0512  * @param handle Specifies the DCP channel used for hashing.
0513  * @param[out] ctx Output hash context
0514  * @param algo Underlaying algorithm to use for hash computation.
0515  * @return Status of initialization
0516  */
0517 status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo);
0518 
0519 /*!
0520  * @brief Add data to current HASH
0521  *
0522  * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
0523  * hashed. The functions blocks. If it returns kStatus_Success, the running hash
0524  * has been updated (DCP has processed the input data), so the memory at the input pointer
0525  * can be released back to system. The DCP context buffer is updated with the running hash
0526  * and with all necessary information to support possible context switch.
0527  *
0528  * @param base DCP peripheral base address
0529  * @param[in,out] ctx HASH context
0530  * @param input Input data
0531  * @param inputSize Size of input data in bytes
0532  * @return Status of the hash update operation
0533  */
0534 status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);
0535 
0536 /*!
0537  * @brief Finalize hashing
0538  *
0539  * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context.
0540  *
0541  * @param base DCP peripheral base address
0542  * @param[in,out] ctx Input hash context
0543  * @param[out] output Output hash data
0544  * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
0545  * output[] buffer. On function return, it stores the number of updated output bytes.
0546  * @return Status of the hash finish operation
0547  */
0548 status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);
0549 
0550 /*!
0551  * @brief Create HASH on given data
0552  *
0553  * Perform the full SHA or CRC32 in one function call. The function is blocking.
0554  *
0555  * @param base DCP peripheral base address
0556  * @param handle Handle used for the request.
0557  * @param algo Underlaying algorithm to use for hash computation.
0558  * @param input Input data
0559  * @param inputSize Size of input data in bytes
0560  * @param[out] output Output hash data
0561  * @param[out] outputSize Output parameter storing the size of the output hash in bytes
0562  * @return Status of the one call hash operation.
0563  */
0564 status_t DCP_HASH(DCP_Type *base,
0565                   dcp_handle_t *handle,
0566                   dcp_hash_algo_t algo,
0567                   const uint8_t *input,
0568                   size_t inputSize,
0569                   uint8_t *output,
0570                   size_t *outputSize);
0571 
0572 /*!
0573  *@}
0574  */ /* end of dcp_driver_hash */
0575 
0576 #if defined(__cplusplus)
0577 }
0578 #endif
0579 
0580 #endif /* _FSL_DCP_H_ */