1 /* 2 * Copyright 2017-2020 NXP 3 * All rights reserved. 4 * 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef _FSL_DCP_H_ 10 #define _FSL_DCP_H_ 11 12 #include "fsl_common.h" 13 14 /******************************************************************************* 15 * Definitions 16 *******************************************************************************/ 17 18 /*! 19 * @addtogroup dcp_driver 20 * @{ 21 */ 22 /*! @name Driver version */ 23 /*@{*/ 24 /*! @brief DCP driver version. Version 2.1.7. 25 * 26 * Current version: 2.1.7 27 * 28 * Change log: 29 * 30 * - Version 2.1.7 31 * - Bug Fix 32 * - Reduce optimization level for critical functions working with SRF. 33 * 34 * - Version 2.1.6 35 * - Bug Fix 36 * - MISRA C-2012 issue fix. 37 * 38 * - Version 2.1.5 39 * - Improvements 40 * - Add support for DCACHE. 41 * 42 * - Version 2.1.4 43 * - Bug Fix 44 * - Fix CRC-32 computation issue on the code's block boundary size. 45 * 46 * - Version 2.1.3 47 * - Bug Fix 48 * - MISRA C-2012 issue fixed: rule 10.1, 10.3, 10.4, 11.9, 14.4, 16.4 and 17.7. 49 * 50 * - Version 2.1.2 51 * - Fix sign-compare warning in dcp_reverse_and_copy. 52 * 53 * - Version 2.1.1 54 * - Add DCP status clearing when channel operation is complete 55 * 56 * - 2.1.0 57 * - Add byte/word swap feature for key, input and output data 58 * 59 * - Version 2.0.0 60 * - Initial version 61 */ 62 #define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 1, 7)) 63 /*@}*/ 64 65 /*! @brief DCP status return codes. */ 66 enum _dcp_status 67 { 68 kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */ 69 }; 70 71 /*! @brief DCP channel enable. 72 * 73 */ 74 typedef enum _dcp_ch_enable 75 { 76 kDCP_chDisable = 0U, /*!< DCP channel disable */ 77 kDCP_ch0Enable = 1U, /*!< DCP channel 0 enable */ 78 kDCP_ch1Enable = 2U, /*!< DCP channel 1 enable */ 79 kDCP_ch2Enable = 4U, /*!< DCP channel 2 enable */ 80 kDCP_ch3Enable = 8U, /*!< DCP channel 3 enable */ 81 kDCP_chEnableAll = 15U, /*!< DCP channel enable all */ 82 } _dcp_ch_enable_t; 83 84 /*! @brief DCP interrupt enable. 85 * 86 */ 87 typedef enum _dcp_ch_int_enable 88 { 89 kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */ 90 kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */ 91 kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */ 92 kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */ 93 kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */ 94 } _dcp_ch_int_enable_t; 95 96 /*! @brief DCP channel selection. 97 * 98 */ 99 typedef enum _dcp_channel 100 { 101 kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */ 102 kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */ 103 kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */ 104 kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */ 105 } dcp_channel_t; 106 107 /*! @brief DCP key slot selection. 108 * 109 */ 110 typedef enum _dcp_key_slot 111 { 112 kDCP_KeySlot0 = 0U, /*!< DCP key slot 0. */ 113 kDCP_KeySlot1 = 1U, /*!< DCP key slot 1. */ 114 kDCP_KeySlot2 = 2U, /*!< DCP key slot 2.*/ 115 kDCP_KeySlot3 = 3U, /*!< DCP key slot 3. */ 116 kDCP_OtpKey = 4U, /*!< DCP OTP key. */ 117 kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */ 118 kDCP_PayloadKey = 6U, /*!< DCP payload key. */ 119 } dcp_key_slot_t; 120 121 /*! @brief DCP key, input & output swap options 122 * 123 */ 124 typedef enum _dcp_swap 125 { 126 kDCP_NoSwap = 0x0U, 127 kDCP_KeyByteSwap = 0x40000U, 128 kDCP_KeyWordSwap = 0x80000U, 129 kDCP_InputByteSwap = 0x100000U, 130 kDCP_InputWordSwap = 0x200000U, 131 kDCP_OutputByteSwap = 0x400000U, 132 kDCP_OutputWordSwap = 0x800000U, 133 } dcp_swap_t; 134 135 /*! @brief DCP's work packet. */ 136 typedef struct _dcp_work_packet 137 { 138 uint32_t nextCmdAddress; 139 uint32_t control0; 140 uint32_t control1; 141 uint32_t sourceBufferAddress; 142 uint32_t destinationBufferAddress; 143 uint32_t bufferSize; 144 uint32_t payloadPointer; 145 uint32_t status; 146 } dcp_work_packet_t; 147 148 /*! @brief Specify DCP's key resource and DCP channel. */ 149 typedef struct _dcp_handle 150 { 151 dcp_channel_t channel; /*!< Specify DCP channel. */ 152 dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */ 153 uint32_t swapConfig; /*!< For configuration of key, input, output byte/word swap options */ 154 uint32_t keyWord[4]; 155 uint32_t iv[4]; 156 } dcp_handle_t; 157 158 /*! @brief DCP's context buffer, used by DCP for context switching between channels. */ 159 typedef struct _dcp_context 160 { 161 uint32_t x[208 / sizeof(uint32_t)]; 162 } dcp_context_t; 163 164 /*! @brief DCP's configuration structure. */ 165 typedef struct _dcp_config 166 { 167 bool gatherResidualWrites; /*!< Enable the ragged writes to the unaligned buffers. */ 168 bool enableContextCaching; /*!< Enable the caching of contexts between the operations. */ 169 bool enableContextSwitching; /*!< Enable automatic context switching for the channels. */ 170 uint8_t enableChannel; /*!< DCP channel enable. */ 171 uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */ 172 } dcp_config_t; 173 174 /*! @} */ 175 176 #ifndef DCP_USE_DCACHE 177 #define DCP_USE_DCACHE 1 178 #endif 179 /* 1 - driver supports DCACHE, 0 - drivers does not support DCACHE */ 180 /* When enable (DCP_USE_DCACHE = 1) Input/output buffers and hash ctx should be in */ 181 /* non-cached memory or handled properly (Clean & Invalidate DCACHE) */ 182 183 /******************************************************************************* 184 * AES Definitions 185 *******************************************************************************/ 186 187 /*! 188 * @addtogroup dcp_driver_aes 189 * @{ 190 */ 191 192 /*! AES block size in bytes */ 193 #define DCP_AES_BLOCK_SIZE 16 194 195 /*! 196 *@} 197 */ /* end of dcp_driver_aes */ 198 199 /******************************************************************************* 200 * HASH Definitions 201 ******************************************************************************/ 202 /*! 203 * @addtogroup dcp_driver_hash 204 * @{ 205 */ 206 207 /* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct 208 * hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this 209 * feature to reduce code size */ 210 #define DCP_HASH_CAVP_COMPATIBLE 211 212 /*! @brief Supported cryptographic block cipher functions for HASH creation */ 213 typedef enum _dcp_hash_algo_t 214 { 215 kDCP_Sha1, /*!< SHA_1 */ 216 kDCP_Sha256, /*!< SHA_256 */ 217 kDCP_Crc32, /*!< CRC_32 */ 218 } dcp_hash_algo_t; 219 220 /*! @brief DCP HASH Context size. */ 221 #define DCP_SHA_BLOCK_SIZE 128U /*!< internal buffer block size */ 222 #define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size */ 223 224 /*! @brief DCP HASH Context size. */ 225 #define DCP_HASH_CTX_SIZE 64 226 227 /*! @brief Storage type used to save hash context. */ 228 typedef struct _dcp_hash_ctx_t 229 { 230 uint32_t x[DCP_HASH_CTX_SIZE]; 231 } dcp_hash_ctx_t; 232 233 /*! 234 *@} 235 */ /* end of dcp_driver_hash */ 236 237 /******************************************************************************* 238 * API 239 ******************************************************************************/ 240 #if defined(__cplusplus) 241 extern "C" { 242 #endif 243 244 /*! 245 * @addtogroup dcp_driver 246 * @{ 247 */ 248 249 /*! 250 * @brief Enables clock to and enables DCP 251 * 252 * Enable DCP clock and configure DCP. 253 * 254 * @param base DCP base address 255 * @param config Pointer to configuration structure. 256 */ 257 void DCP_Init(DCP_Type *base, const dcp_config_t *config); 258 259 /*! 260 * @brief Disable DCP clock 261 * 262 * Reset DCP and Disable DCP clock. 263 * 264 * @param base DCP base address 265 */ 266 void DCP_Deinit(DCP_Type *base); 267 268 /*! 269 * @brief Gets the default configuration structure. 270 * 271 * This function initializes the DCP configuration structure to a default value. The default 272 * values are as follows. 273 * dcpConfig->gatherResidualWrites = true; 274 * dcpConfig->enableContextCaching = true; 275 * dcpConfig->enableContextSwitching = true; 276 * dcpConfig->enableChannnel = kDCP_chEnableAll; 277 * dcpConfig->enableChannelInterrupt = kDCP_chIntDisable; 278 * 279 * @param[out] config Pointer to configuration structure. 280 */ 281 void DCP_GetDefaultConfig(dcp_config_t *config); 282 283 /*! 284 * @brief Poll and wait on DCP channel. 285 * 286 * Polls the specified DCP channel until current it completes activity. 287 * 288 * @param base DCP peripheral base address. 289 * @param handle Specifies DCP channel. 290 * @return kStatus_Success When data processing completes without error. 291 * @return kStatus_Fail When error occurs. 292 */ 293 status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle); 294 295 /*! 296 *@} 297 */ /* end of dcp_driver */ 298 299 /******************************************************************************* 300 * AES API 301 ******************************************************************************/ 302 303 /*! 304 * @addtogroup dcp_driver_aes 305 * @{ 306 */ 307 308 /*! 309 * @brief Set AES key to dcp_handle_t struct and optionally to DCP. 310 * 311 * Sets the AES key for encryption/decryption with the dcp_handle_t structure. 312 * The dcp_handle_t input argument specifies keySlot. 313 * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use 314 * status. 315 * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct. 316 * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2, 317 * kDCP_KeySlot3), 318 * this function will also load the supplied key to the specified keySlot in DCP. 319 * 320 * @param base DCP peripheral base address. 321 * @param handle Handle used for the request. 322 * @param key 0-mod-4 aligned pointer to AES key. 323 * @param keySize AES key size in bytes. Shall equal 16. 324 * @return status from set key operation 325 */ 326 status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize); 327 328 /*! 329 * @brief Encrypts AES on one or multiple 128-bit block(s). 330 * 331 * Encrypts AES. 332 * The source plaintext and destination ciphertext can overlap in system memory. 333 * 334 * @param base DCP peripheral base address 335 * @param handle Handle used for this request. 336 * @param plaintext Input plain text to encrypt 337 * @param[out] ciphertext Output cipher text 338 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 339 * @return Status from encrypt operation 340 */ 341 status_t DCP_AES_EncryptEcb( 342 DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size); 343 344 /*! 345 * @brief Decrypts AES on one or multiple 128-bit block(s). 346 * 347 * Decrypts AES. 348 * The source ciphertext and destination plaintext can overlap in system memory. 349 * 350 * @param base DCP peripheral base address 351 * @param handle Handle used for this request. 352 * @param ciphertext Input plain text to encrypt 353 * @param[out] plaintext Output cipher text 354 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 355 * @return Status from decrypt operation 356 */ 357 status_t DCP_AES_DecryptEcb( 358 DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size); 359 360 /*! 361 * @brief Encrypts AES using CBC block mode. 362 * 363 * Encrypts AES using CBC block mode. 364 * The source plaintext and destination ciphertext can overlap in system memory. 365 * 366 * @param base DCP peripheral base address 367 * @param handle Handle used for this request. 368 * @param plaintext Input plain text to encrypt 369 * @param[out] ciphertext Output cipher text 370 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 371 * @param iv Input initial vector to combine with the first input block. 372 * @return Status from encrypt operation 373 */ 374 status_t DCP_AES_EncryptCbc(DCP_Type *base, 375 dcp_handle_t *handle, 376 const uint8_t *plaintext, 377 uint8_t *ciphertext, 378 size_t size, 379 const uint8_t iv[16]); 380 381 /*! 382 * @brief Decrypts AES using CBC block mode. 383 * 384 * Decrypts AES using CBC block mode. 385 * The source ciphertext and destination plaintext can overlap in system memory. 386 * 387 * @param base DCP peripheral base address 388 * @param handle Handle used for this request. 389 * @param ciphertext Input cipher text to decrypt 390 * @param[out] plaintext Output plain text 391 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 392 * @param iv Input initial vector to combine with the first input block. 393 * @return Status from decrypt operation 394 */ 395 status_t DCP_AES_DecryptCbc(DCP_Type *base, 396 dcp_handle_t *handle, 397 const uint8_t *ciphertext, 398 uint8_t *plaintext, 399 size_t size, 400 const uint8_t iv[16]); 401 402 /*! 403 *@} 404 */ /* end of dcp_driver_aes */ 405 406 /*! 407 * @addtogroup dcp_nonblocking_driver_aes 408 * @{ 409 */ 410 /*! 411 * @brief Encrypts AES using the ECB block mode. 412 * 413 * Puts AES ECB encrypt work packet to DCP channel. 414 * 415 * @param base DCP peripheral base address 416 * @param handle Handle used for this request. 417 * @param[out] dcpPacket Memory for the DCP work packet. 418 * @param plaintext Input plain text to encrypt. 419 * @param[out] ciphertext Output cipher text 420 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 421 * @return kStatus_Success The work packet has been scheduled at DCP channel. 422 * @return kStatus_DCP_Again The DCP channel is busy processing previous request. 423 */ 424 status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base, 425 dcp_handle_t *handle, 426 dcp_work_packet_t *dcpPacket, 427 const uint8_t *plaintext, 428 uint8_t *ciphertext, 429 size_t size); 430 431 /*! 432 * @brief Decrypts AES using ECB block mode. 433 * 434 * Puts AES ECB decrypt dcpPacket to DCP input job ring. 435 * 436 * @param base DCP peripheral base address 437 * @param handle Handle used for this request. 438 * @param[out] dcpPacket Memory for the DCP work packet. 439 * @param ciphertext Input cipher text to decrypt 440 * @param[out] plaintext Output plain text 441 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 442 * @return kStatus_Success The work packet has been scheduled at DCP channel. 443 * @return kStatus_DCP_Again The DCP channel is busy processing previous request. 444 */ 445 status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base, 446 dcp_handle_t *handle, 447 dcp_work_packet_t *dcpPacket, 448 const uint8_t *ciphertext, 449 uint8_t *plaintext, 450 size_t size); 451 452 /*! 453 * @brief Encrypts AES using CBC block mode. 454 * 455 * Puts AES CBC encrypt dcpPacket to DCP input job ring. 456 * 457 * @param base DCP peripheral base address 458 * @param handle Handle used for this request. Specifies jobRing. 459 * @param[out] dcpPacket Memory for the DCP work packet. 460 * @param plaintext Input plain text to encrypt 461 * @param[out] ciphertext Output cipher text 462 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 463 * @param iv Input initial vector to combine with the first input block. 464 * @return kStatus_Success The work packet has been scheduled at DCP channel. 465 * @return kStatus_DCP_Again The DCP channel is busy processing previous request. 466 */ 467 status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base, 468 dcp_handle_t *handle, 469 dcp_work_packet_t *dcpPacket, 470 const uint8_t *plaintext, 471 uint8_t *ciphertext, 472 size_t size, 473 const uint8_t *iv); 474 475 /*! 476 * @brief Decrypts AES using CBC block mode. 477 * 478 * Puts AES CBC decrypt dcpPacket to DCP input job ring. 479 * 480 * @param base DCP peripheral base address 481 * @param handle Handle used for this request. Specifies jobRing. 482 * @param[out] dcpPacket Memory for the DCP work packet. 483 * @param ciphertext Input cipher text to decrypt 484 * @param[out] plaintext Output plain text 485 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes. 486 * @param iv Input initial vector to combine with the first input block. 487 * @return kStatus_Success The work packet has been scheduled at DCP channel. 488 * @return kStatus_DCP_Again The DCP channel is busy processing previous request. 489 */ 490 status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base, 491 dcp_handle_t *handle, 492 dcp_work_packet_t *dcpPacket, 493 const uint8_t *ciphertext, 494 uint8_t *plaintext, 495 size_t size, 496 const uint8_t *iv); 497 498 /*! 499 *@} 500 */ /* end of dcp_nonblocking_driver_aes */ 501 502 /******************************************************************************* 503 * HASH API 504 ******************************************************************************/ 505 506 /*! 507 * @addtogroup dcp_driver_hash 508 * @{ 509 */ 510 /*! 511 * @brief Initialize HASH context 512 * 513 * This function initializes the HASH. 514 * 515 * @param base DCP peripheral base address 516 * @param handle Specifies the DCP channel used for hashing. 517 * @param[out] ctx Output hash context 518 * @param algo Underlaying algorithm to use for hash computation. 519 * @return Status of initialization 520 */ 521 status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo); 522 523 /*! 524 * @brief Add data to current HASH 525 * 526 * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be 527 * hashed. The functions blocks. If it returns kStatus_Success, the running hash 528 * has been updated (DCP has processed the input data), so the memory at the input pointer 529 * can be released back to system. The DCP context buffer is updated with the running hash 530 * and with all necessary information to support possible context switch. 531 * 532 * @param base DCP peripheral base address 533 * @param[in,out] ctx HASH context 534 * @param input Input data 535 * @param inputSize Size of input data in bytes 536 * @return Status of the hash update operation 537 */ 538 status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize); 539 540 /*! 541 * @brief Finalize hashing 542 * 543 * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context. 544 * 545 * @param base DCP peripheral base address 546 * @param[in,out] ctx Input hash context 547 * @param[out] output Output hash data 548 * @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of 549 * output[] buffer. On function return, it stores the number of updated output bytes. 550 * @return Status of the hash finish operation 551 */ 552 status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize); 553 554 /*! 555 * @brief Create HASH on given data 556 * 557 * Perform the full SHA or CRC32 in one function call. The function is blocking. 558 * 559 * @param base DCP peripheral base address 560 * @param handle Handle used for the request. 561 * @param algo Underlaying algorithm to use for hash computation. 562 * @param input Input data 563 * @param inputSize Size of input data in bytes 564 * @param[out] output Output hash data 565 * @param[out] outputSize Output parameter storing the size of the output hash in bytes 566 * @return Status of the one call hash operation. 567 */ 568 status_t DCP_HASH(DCP_Type *base, 569 dcp_handle_t *handle, 570 dcp_hash_algo_t algo, 571 const uint8_t *input, 572 size_t inputSize, 573 uint8_t *output, 574 size_t *outputSize); 575 576 /*! 577 *@} 578 */ /* end of dcp_driver_hash */ 579 580 #if defined(__cplusplus) 581 } 582 #endif 583 584 #endif /* _FSL_DCP_H_ */ 585