fsl_dcp.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. /*
  2. * Copyright 2017 NXP
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #ifndef _FSL_DCP_H_
  31. #define _FSL_DCP_H_
  32. #include "fsl_common.h"
  33. /*! @brief DCP status return codes. */
  34. enum _dcp_status
  35. {
  36. kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */
  37. };
  38. /*******************************************************************************
  39. * Definitions
  40. *******************************************************************************/
  41. /*!
  42. * @addtogroup dcp_driver
  43. * @{
  44. */
  45. /*! @name Driver version */
  46. /*@{*/
  47. /*! @brief DCP driver version. Version 2.0.0.
  48. *
  49. * Current version: 2.0.0
  50. *
  51. * Change log:
  52. * - Version 2.0.0
  53. * - Initial version
  54. */
  55. #define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
  56. /*@}*/
  57. /*! @brief DCP channel enable.
  58. *
  59. */
  60. typedef enum _dcp_ch_enable
  61. {
  62. kDCP_chDisable = 0U, /*!< DCP channel disable */
  63. kDCP_ch0Enable = 1U, /*!< DCP channel 0 enable */
  64. kDCP_ch1Enable = 2U, /*!< DCP channel 1 enable */
  65. kDCP_ch2Enable = 4U, /*!< DCP channel 2 enable */
  66. kDCP_ch3Enable = 8U, /*!< DCP channel 3 enable */
  67. kDCP_chEnableAll = 15U, /*!< DCP channel enable all */
  68. } _dcp_ch_enable_t;
  69. /*! @brief DCP interrupt enable.
  70. *
  71. */
  72. typedef enum _dcp_ch_int_enable
  73. {
  74. kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */
  75. kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */
  76. kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */
  77. kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */
  78. kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */
  79. } _dcp_ch_int_enable_t;
  80. /*! @brief DCP channel selection.
  81. *
  82. */
  83. typedef enum _dcp_channel
  84. {
  85. kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */
  86. kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */
  87. kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */
  88. kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */
  89. } dcp_channel_t;
  90. /*! @brief DCP key slot selection.
  91. *
  92. */
  93. typedef enum _dcp_key_slot
  94. {
  95. kDCP_KeySlot0 = 0U, /*!< DCP key slot 0. */
  96. kDCP_KeySlot1 = 1U, /*!< DCP key slot 1. */
  97. kDCP_KeySlot2 = 2U, /*!< DCP key slot 2.*/
  98. kDCP_KeySlot3 = 3U, /*!< DCP key slot 3. */
  99. kDCP_OtpKey = 4U, /*!< DCP OTP key. */
  100. kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */
  101. kDCP_PayloadKey = 6U, /*!< DCP payload key. */
  102. } dcp_key_slot_t;
  103. /*! @brief DCP's work packet. */
  104. typedef struct _dcp_work_packet
  105. {
  106. uint32_t nextCmdAddress;
  107. uint32_t control0;
  108. uint32_t control1;
  109. uint32_t sourceBufferAddress;
  110. uint32_t destinationBufferAddress;
  111. uint32_t bufferSize;
  112. uint32_t payloadPointer;
  113. uint32_t status;
  114. } dcp_work_packet_t;
  115. /*! @brief Specify DCP's key resource and DCP channel. */
  116. typedef struct _dcp_handle
  117. {
  118. dcp_channel_t channel; /*!< Specify DCP channel. */
  119. dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */
  120. uint32_t keyWord[4];
  121. uint32_t iv[4];
  122. } dcp_handle_t;
  123. /*! @brief DCP's context buffer, used by DCP for context switching between channels. */
  124. typedef struct _dcp_context
  125. {
  126. uint32_t x[208 / sizeof(uint32_t)];
  127. } dcp_context_t;
  128. /*! @brief DCP's configuration structure. */
  129. typedef struct _dcp_config
  130. {
  131. bool gatherResidualWrites; /*!< Enable the ragged writes to the unaligned buffers. */
  132. bool enableContextCaching; /*!< Enable the caching of contexts between the operations. */
  133. bool enableContextSwitching; /*!< Enable automatic context switching for the channels. */
  134. uint8_t enableChannel; /*!< DCP channel enable. */
  135. uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */
  136. } dcp_config_t;
  137. /*! @} */
  138. /*******************************************************************************
  139. * AES Definitions
  140. *******************************************************************************/
  141. /*!
  142. * @addtogroup dcp_driver_aes
  143. * @{
  144. */
  145. /*! AES block size in bytes */
  146. #define DCP_AES_BLOCK_SIZE 16
  147. /*!
  148. *@}
  149. */ /* end of dcp_driver_aes */
  150. /*******************************************************************************
  151. * HASH Definitions
  152. ******************************************************************************/
  153. /*!
  154. * @addtogroup dcp_driver_hash
  155. * @{
  156. */
  157. /* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct
  158. * hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this
  159. * feature to reduce code size */
  160. #define DCP_HASH_CAVP_COMPATIBLE
  161. /*! @brief Supported cryptographic block cipher functions for HASH creation */
  162. typedef enum _dcp_hash_algo_t
  163. {
  164. kDCP_Sha1, /*!< SHA_1 */
  165. kDCP_Sha256, /*!< SHA_256 */
  166. kDCP_Crc32, /*!< CRC_32 */
  167. } dcp_hash_algo_t;
  168. /*! @brief DCP HASH Context size. */
  169. #define DCP_SHA_BLOCK_SIZE 128 /*!< internal buffer block size */
  170. #define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size */
  171. /*! @brief DCP HASH Context size. */
  172. #define DCP_HASH_CTX_SIZE 58
  173. /*! @brief Storage type used to save hash context. */
  174. typedef struct _dcp_hash_ctx_t
  175. {
  176. uint32_t x[DCP_HASH_CTX_SIZE];
  177. } dcp_hash_ctx_t;
  178. /*!
  179. *@}
  180. */ /* end of dcp_driver_hash */
  181. /*******************************************************************************
  182. * API
  183. ******************************************************************************/
  184. #if defined(__cplusplus)
  185. extern "C" {
  186. #endif
  187. /*!
  188. * @addtogroup dcp_driver
  189. * @{
  190. */
  191. /*!
  192. * @brief Enables clock to and enables DCP
  193. *
  194. * Enable DCP clock and configure DCP.
  195. *
  196. * @param base DCP base address
  197. * @param config Pointer to configuration structure.
  198. */
  199. void DCP_Init(DCP_Type *base, const dcp_config_t *config);
  200. /*!
  201. * @brief Disable DCP clock
  202. *
  203. * Reset DCP and Disable DCP clock.
  204. *
  205. * @param base DCP base address
  206. */
  207. void DCP_Deinit(DCP_Type *base);
  208. /*!
  209. * @brief Gets the default configuration structure.
  210. *
  211. * This function initializes the DCP configuration structure to a default value. The default
  212. * values are as follows.
  213. * dcpConfig->gatherResidualWrites = true;
  214. * dcpConfig->enableContextCaching = true;
  215. * dcpConfig->enableContextSwitching = true;
  216. * dcpConfig->enableChannnel = kDCP_chEnableAll;
  217. * dcpConfig->enableChannelInterrupt = kDCP_chIntDisable;
  218. *
  219. * @param[out] config Pointer to configuration structure.
  220. */
  221. void DCP_GetDefaultConfig(dcp_config_t *config);
  222. /*!
  223. * @brief Poll and wait on DCP channel.
  224. *
  225. * Polls the specified DCP channel until current it completes activity.
  226. *
  227. * @param base DCP peripheral base address.
  228. * @param handle Specifies DCP channel.
  229. * @return kStatus_Success When data processing completes without error.
  230. * @return kStatus_Fail When error occurs.
  231. */
  232. status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle);
  233. /*!
  234. *@}
  235. */ /* end of dcp_driver */
  236. /*******************************************************************************
  237. * AES API
  238. ******************************************************************************/
  239. /*!
  240. * @addtogroup dcp_driver_aes
  241. * @{
  242. */
  243. /*!
  244. * @brief Set AES key to dcp_handle_t struct and optionally to DCP.
  245. *
  246. * Sets the AES key for encryption/decryption with the dcp_handle_t structure.
  247. * The dcp_handle_t input argument specifies keySlot.
  248. * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use
  249. * status.
  250. * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct.
  251. * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2,
  252. * kDCP_KeySlot3),
  253. * this function will also load the supplied key to the specified keySlot in DCP.
  254. *
  255. * @param base DCP peripheral base address.
  256. * @param handle Handle used for the request.
  257. * @param key 0-mod-4 aligned pointer to AES key.
  258. * @param keySize AES key size in bytes. Shall equal 16.
  259. * @return status from set key operation
  260. */
  261. status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize);
  262. /*!
  263. * @brief Encrypts AES on one or multiple 128-bit block(s).
  264. *
  265. * Encrypts AES.
  266. * The source plaintext and destination ciphertext can overlap in system memory.
  267. *
  268. * @param base DCP peripheral base address
  269. * @param handle Handle used for this request.
  270. * @param plaintext Input plain text to encrypt
  271. * @param[out] ciphertext Output cipher text
  272. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  273. * @return Status from encrypt operation
  274. */
  275. status_t DCP_AES_EncryptEcb(
  276. DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
  277. /*!
  278. * @brief Decrypts AES on one or multiple 128-bit block(s).
  279. *
  280. * Decrypts AES.
  281. * The source ciphertext and destination plaintext can overlap in system memory.
  282. *
  283. * @param base DCP peripheral base address
  284. * @param handle Handle used for this request.
  285. * @param ciphertext Input plain text to encrypt
  286. * @param[out] plaintext Output cipher text
  287. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  288. * @return Status from decrypt operation
  289. */
  290. status_t DCP_AES_DecryptEcb(
  291. DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
  292. /*!
  293. * @brief Encrypts AES using CBC block mode.
  294. *
  295. * Encrypts AES using CBC block mode.
  296. * The source plaintext and destination ciphertext can overlap in system memory.
  297. *
  298. * @param base DCP peripheral base address
  299. * @param handle Handle used for this request.
  300. * @param plaintext Input plain text to encrypt
  301. * @param[out] ciphertext Output cipher text
  302. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  303. * @param iv Input initial vector to combine with the first input block.
  304. * @return Status from encrypt operation
  305. */
  306. status_t DCP_AES_EncryptCbc(DCP_Type *base,
  307. dcp_handle_t *handle,
  308. const uint8_t *plaintext,
  309. uint8_t *ciphertext,
  310. size_t size,
  311. const uint8_t iv[16]);
  312. /*!
  313. * @brief Decrypts AES using CBC block mode.
  314. *
  315. * Decrypts AES using CBC block mode.
  316. * The source ciphertext and destination plaintext can overlap in system memory.
  317. *
  318. * @param base DCP peripheral base address
  319. * @param handle Handle used for this request.
  320. * @param ciphertext Input cipher text to decrypt
  321. * @param[out] plaintext Output plain text
  322. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  323. * @param iv Input initial vector to combine with the first input block.
  324. * @return Status from decrypt operation
  325. */
  326. status_t DCP_AES_DecryptCbc(DCP_Type *base,
  327. dcp_handle_t *handle,
  328. const uint8_t *ciphertext,
  329. uint8_t *plaintext,
  330. size_t size,
  331. const uint8_t iv[16]);
  332. /*!
  333. *@}
  334. */ /* end of dcp_driver_aes */
  335. /*!
  336. * @addtogroup dcp_nonblocking_driver_aes
  337. * @{
  338. */
  339. /*!
  340. * @brief Encrypts AES using the ECB block mode.
  341. *
  342. * Puts AES ECB encrypt work packet to DCP channel.
  343. *
  344. * @param base DCP peripheral base address
  345. * @param handle Handle used for this request.
  346. * @param[out] dcpPacket Memory for the DCP work packet.
  347. * @param plaintext Input plain text to encrypt.
  348. * @param[out] ciphertext Output cipher text
  349. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  350. * @return kStatus_Success The work packet has been scheduled at DCP channel.
  351. * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
  352. */
  353. status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
  354. dcp_handle_t *handle,
  355. dcp_work_packet_t *dcpPacket,
  356. const uint8_t *plaintext,
  357. uint8_t *ciphertext,
  358. size_t size);
  359. /*!
  360. * @brief Decrypts AES using ECB block mode.
  361. *
  362. * Puts AES ECB decrypt dcpPacket to DCP input job ring.
  363. *
  364. * @param base DCP peripheral base address
  365. * @param handle Handle used for this request.
  366. * @param[out] dcpPacket Memory for the DCP work packet.
  367. * @param ciphertext Input cipher text to decrypt
  368. * @param[out] plaintext Output plain text
  369. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  370. * @return kStatus_Success The work packet has been scheduled at DCP channel.
  371. * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
  372. */
  373. status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
  374. dcp_handle_t *handle,
  375. dcp_work_packet_t *dcpPacket,
  376. const uint8_t *ciphertext,
  377. uint8_t *plaintext,
  378. size_t size);
  379. /*!
  380. * @brief Encrypts AES using CBC block mode.
  381. *
  382. * Puts AES CBC encrypt dcpPacket to DCP input job ring.
  383. *
  384. * @param base DCP peripheral base address
  385. * @param handle Handle used for this request. Specifies jobRing.
  386. * @param[out] dcpPacket Memory for the DCP work packet.
  387. * @param plaintext Input plain text to encrypt
  388. * @param[out] ciphertext Output cipher text
  389. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  390. * @param iv Input initial vector to combine with the first input block.
  391. * @return kStatus_Success The work packet has been scheduled at DCP channel.
  392. * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
  393. */
  394. status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
  395. dcp_handle_t *handle,
  396. dcp_work_packet_t *dcpPacket,
  397. const uint8_t *plaintext,
  398. uint8_t *ciphertext,
  399. size_t size,
  400. const uint8_t *iv);
  401. /*!
  402. * @brief Decrypts AES using CBC block mode.
  403. *
  404. * Puts AES CBC decrypt dcpPacket to DCP input job ring.
  405. *
  406. * @param base DCP peripheral base address
  407. * @param handle Handle used for this request. Specifies jobRing.
  408. * @param[out] dcpPacket Memory for the DCP work packet.
  409. * @param ciphertext Input cipher text to decrypt
  410. * @param[out] plaintext Output plain text
  411. * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  412. * @param iv Input initial vector to combine with the first input block.
  413. * @return kStatus_Success The work packet has been scheduled at DCP channel.
  414. * @return kStatus_DCP_Again The DCP channel is busy processing previous request.
  415. */
  416. status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
  417. dcp_handle_t *handle,
  418. dcp_work_packet_t *dcpPacket,
  419. const uint8_t *ciphertext,
  420. uint8_t *plaintext,
  421. size_t size,
  422. const uint8_t *iv);
  423. /*!
  424. *@}
  425. */ /* end of dcp_nonblocking_driver_aes */
  426. /*******************************************************************************
  427. * HASH API
  428. ******************************************************************************/
  429. /*!
  430. * @addtogroup dcp_driver_hash
  431. * @{
  432. */
  433. /*!
  434. * @brief Initialize HASH context
  435. *
  436. * This function initializes the HASH.
  437. *
  438. * @param base DCP peripheral base address
  439. * @param handle Specifies the DCP channel used for hashing.
  440. * @param[out] ctx Output hash context
  441. * @param algo Underlaying algorithm to use for hash computation.
  442. * @return Status of initialization
  443. */
  444. status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo);
  445. /*!
  446. * @brief Add data to current HASH
  447. *
  448. * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
  449. * hashed. The functions blocks. If it returns kStatus_Success, the running hash
  450. * has been updated (DCP has processed the input data), so the memory at @ref input pointer
  451. * can be released back to system. The DCP context buffer is updated with the running hash
  452. * and with all necessary information to support possible context switch.
  453. *
  454. * @param base DCP peripheral base address
  455. * @param[in,out] ctx HASH context
  456. * @param input Input data
  457. * @param inputSize Size of input data in bytes
  458. * @return Status of the hash update operation
  459. */
  460. status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);
  461. /*!
  462. * @brief Finalize hashing
  463. *
  464. * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context.
  465. *
  466. * @param[in,out] ctx Input hash context
  467. * @param[out] output Output hash data
  468. * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
  469. * output[] buffer. On function return, it stores the number of updated output bytes.
  470. * @return Status of the hash finish operation
  471. */
  472. status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);
  473. /*!
  474. * @brief Create HASH on given data
  475. *
  476. * Perform the full SHA or CRC32 in one function call. The function is blocking.
  477. *
  478. * @param base DCP peripheral base address
  479. * @param handle Handle used for the request.
  480. * @param algo Underlaying algorithm to use for hash computation.
  481. * @param input Input data
  482. * @param inputSize Size of input data in bytes
  483. * @param[out] output Output hash data
  484. * @param[out] outputSize Output parameter storing the size of the output hash in bytes
  485. * @return Status of the one call hash operation.
  486. */
  487. status_t DCP_HASH(DCP_Type *base,
  488. dcp_handle_t *handle,
  489. dcp_hash_algo_t algo,
  490. const uint8_t *input,
  491. size_t inputSize,
  492. uint8_t *output,
  493. size_t *outputSize);
  494. /*!
  495. *@}
  496. */ /* end of dcp_driver_hash */
  497. #if defined(__cplusplus)
  498. }
  499. #endif
  500. #endif /* _FSL_DCP_H_ */