File indexing completed on 2025-05-11 08:22:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_dcp.h"
0010 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
0011 #include "fsl_cache.h"
0012 #endif
0013
0014
0015
0016
0017
0018
0019 #ifndef FSL_COMPONENT_ID
0020 #define FSL_COMPONENT_ID "platform.drivers.dcp"
0021 #endif
0022
0023
0024 #define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
0025
0026 #define dcp_memcpy memcpy
0027
0028
0029 typedef enum _dcp_hash_algo_state
0030 {
0031 kDCP_StateHashInit = 1u,
0032 kDCP_StateHashUpdate,
0033 } dcp_hash_algo_state_t;
0034
0035
0036 typedef union _dcp_hash_block
0037 {
0038 uint32_t w[DCP_HASH_BLOCK_SIZE / 4];
0039 uint8_t b[DCP_HASH_BLOCK_SIZE];
0040 } dcp_hash_block_t;
0041
0042
0043 typedef struct _dcp_hash_ctx_internal
0044 {
0045 dcp_hash_block_t blk;
0046 size_t blksz;
0047 dcp_hash_algo_t algo;
0048 dcp_hash_algo_state_t state;
0049 uint32_t fullMessageSize;
0050 uint32_t ctrl0;
0051 uint32_t runningHash[9];
0052 dcp_handle_t *handle;
0053 } dcp_hash_ctx_internal_t;
0054
0055
0056 enum _dcp_hash_digest_len
0057 {
0058 kDCP_OutLenSha1 = 20u,
0059 kDCP_OutLenSha256 = 32u,
0060 kDCP_OutLenCrc32 = 4u,
0061 };
0062
0063 enum _dcp_work_packet_bit_definitions
0064 {
0065 kDCP_CONTROL0_DECR_SEMAPHOR = 1u << 1,
0066 kDCP_CONTROL0_ENABLE_HASH = 1u << 6,
0067 kDCP_CONTROL0_HASH_INIT = 1u << 12,
0068 kDCP_CONTROL0_HASH_TERM = 1u << 13,
0069 kDCP_CONTROL1_HASH_SELECT_SHA256 = 2u << 16,
0070 kDCP_CONTROL1_HASH_SELECT_SHA1 = 0u << 16,
0071 kDCP_CONTROL1_HASH_SELECT_CRC32 = 1u << 16,
0072 };
0073
0074
0075 typedef union _dcp_sha_block
0076 {
0077 uint32_t w[64 / 4];
0078 uint8_t b[64];
0079 } dcp_sha_block_t;
0080
0081 #if defined(DCP_HASH_CAVP_COMPATIBLE)
0082
0083 static uint8_t s_nullSha1[] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
0084 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09};
0085
0086 static uint8_t s_nullSha256[] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
0087 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
0088 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
0089 #endif
0090
0091
0092
0093
0094 AT_NONCACHEABLE_SECTION_INIT(static dcp_context_t s_dcpContextSwitchingBuffer);
0095
0096
0097
0098
0099
0100 static void dcp_reverse_and_copy(uint8_t *src, uint8_t *dest, size_t src_len)
0101 {
0102 for (uint32_t i = 0; i < src_len; i++)
0103 {
0104 dest[i] = src[src_len - 1U - i];
0105 }
0106 }
0107
0108 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0109 static inline uint32_t *DCP_FindCacheLine(uint8_t *dcpWorkExt)
0110 {
0111 while (0U != ((uint32_t)dcpWorkExt & ((uint32_t)FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1U)))
0112 {
0113 dcpWorkExt++;
0114 }
0115 return (uint32_t *)(uint32_t)dcpWorkExt;
0116 }
0117 #endif
0118
0119 static status_t dcp_get_channel_status(DCP_Type *base, dcp_channel_t channel)
0120 {
0121 uint32_t statReg = 0;
0122 uint32_t semaReg = 0;
0123 status_t status = kStatus_Fail;
0124
0125 switch (channel)
0126 {
0127 case kDCP_Channel0:
0128 statReg = base->CH0STAT;
0129 semaReg = base->CH0SEMA;
0130 break;
0131
0132 case kDCP_Channel1:
0133 statReg = base->CH1STAT;
0134 semaReg = base->CH1SEMA;
0135 break;
0136
0137 case kDCP_Channel2:
0138 statReg = base->CH2STAT;
0139 semaReg = base->CH2SEMA;
0140 break;
0141
0142 case kDCP_Channel3:
0143 statReg = base->CH3STAT;
0144 semaReg = base->CH3SEMA;
0145 break;
0146
0147 default:
0148
0149 break;
0150 }
0151
0152 if (!((0U != (semaReg & DCP_CH0SEMA_VALUE_MASK)) || (0U != (statReg & DCP_CH0STAT_ERROR_CODE_MASK))))
0153 {
0154 status = kStatus_Success;
0155 }
0156
0157 return status;
0158 }
0159
0160 static void dcp_clear_status(DCP_Type *base)
0161 {
0162 volatile uint32_t *dcpStatClrPtr = (volatile uint32_t *)&base->STAT + 2u;
0163 *dcpStatClrPtr = 0xFFu;
0164
0165 while ((base->STAT & 0xffu) != 0U)
0166 {
0167 }
0168 }
0169
0170 static void dcp_clear_channel_status(DCP_Type *base, uint32_t mask)
0171 {
0172 volatile uint32_t *chStatClrPtr;
0173
0174 if (0U != (mask & (uint32_t)kDCP_Channel0))
0175 {
0176 chStatClrPtr = &base->CH0STAT_CLR;
0177 *chStatClrPtr = 0xFFu;
0178 }
0179 if (0U != (mask & (uint32_t)kDCP_Channel1))
0180 {
0181 chStatClrPtr = &base->CH1STAT_CLR;
0182 *chStatClrPtr = 0xFFu;
0183 }
0184 if (0U != (mask & (uint32_t)kDCP_Channel2))
0185 {
0186 chStatClrPtr = &base->CH2STAT_CLR;
0187 *chStatClrPtr = 0xFFu;
0188 }
0189 if (0U != (mask & (uint32_t)kDCP_Channel3))
0190 {
0191 chStatClrPtr = &base->CH3STAT_CLR;
0192 *chStatClrPtr = 0xFFu;
0193 }
0194 }
0195
0196 static status_t dcp_aes_set_sram_based_key(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key)
0197 {
0198 base->KEY = DCP_KEY_INDEX(handle->keySlot) | DCP_KEY_SUBWORD(0);
0199
0200 int i = 0;
0201 size_t keySize = 16u;
0202 while (keySize != 0U)
0203 {
0204 keySize -= sizeof(uint32_t);
0205 base->KEYDATA = ((uint32_t *)(uintptr_t)key)[i];
0206 i++;
0207 }
0208 return kStatus_Success;
0209 }
0210
0211
0212 #if defined(__GNUC__)
0213 #pragma GCC push_options
0214 #pragma GCC optimize("O0")
0215 #endif
0216 static status_t dcp_schedule_work(DCP_Type *base, dcp_handle_t *handle, dcp_work_packet_t *dcpPacket)
0217 {
0218 status_t status;
0219
0220
0221 if ((base->STAT & (uint32_t)handle->channel) != (uint32_t)handle->channel)
0222 {
0223
0224 uint32_t currPriMask = DisableGlobalIRQ();
0225
0226
0227 if ((base->STAT & (uint32_t)handle->channel) == 0U)
0228 {
0229 volatile uint32_t *cmdptr = NULL;
0230 volatile uint32_t *chsema = NULL;
0231
0232 switch (handle->channel)
0233 {
0234 case kDCP_Channel0:
0235 cmdptr = &base->CH0CMDPTR;
0236 chsema = &base->CH0SEMA;
0237 break;
0238
0239 case kDCP_Channel1:
0240 cmdptr = &base->CH1CMDPTR;
0241 chsema = &base->CH1SEMA;
0242 break;
0243
0244 case kDCP_Channel2:
0245 cmdptr = &base->CH2CMDPTR;
0246 chsema = &base->CH2SEMA;
0247 break;
0248
0249 case kDCP_Channel3:
0250 cmdptr = &base->CH3CMDPTR;
0251 chsema = &base->CH3SEMA;
0252 break;
0253
0254 default:
0255
0256 break;
0257 }
0258
0259 if ((NULL != cmdptr) && (NULL != chsema))
0260 {
0261
0262 *cmdptr = (uint32_t)dcpPacket;
0263
0264 #if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0265
0266 DCACHE_CleanByRange((uint32_t)dcpPacket, sizeof(dcp_work_packet_t));
0267 #endif
0268
0269 __DSB();
0270 __ISB();
0271
0272
0273 *chsema = 1u;
0274 }
0275
0276 status = kStatus_Success;
0277 }
0278
0279 else
0280 {
0281 status = (int32_t)kStatus_DCP_Again;
0282 }
0283
0284 EnableGlobalIRQ(currPriMask);
0285 }
0286
0287 else
0288 {
0289 return (int32_t)kStatus_DCP_Again;
0290 }
0291
0292 return status;
0293 }
0294 #if defined(__GNUC__)
0295 #pragma GCC pop_options
0296 #endif
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize)
0317 {
0318 status_t status = kStatus_Fail;
0319
0320 if ((kDCP_OtpKey == handle->keySlot) || (kDCP_OtpUniqueKey == handle->keySlot))
0321 {
0322
0323 if ((base->STAT & DCP_STAT_OTP_KEY_READY_MASK) == DCP_STAT_OTP_KEY_READY_MASK)
0324 {
0325 status = kStatus_Success;
0326 }
0327 }
0328 else
0329 {
0330
0331 if ((0x3U & (uintptr_t)key) != 0U)
0332 {
0333 return kStatus_InvalidArgument;
0334 }
0335
0336
0337 if (keySize != 16U)
0338 {
0339 return kStatus_InvalidArgument;
0340 }
0341
0342
0343 int i = 0;
0344 while (keySize != 0U)
0345 {
0346 keySize -= sizeof(uint32_t);
0347 handle->keyWord[i] = ((uint32_t *)(uintptr_t)key)[i];
0348 i++;
0349 }
0350
0351 if (kDCP_PayloadKey != handle->keySlot)
0352 {
0353
0354 status = dcp_aes_set_sram_based_key(base, handle, key);
0355 }
0356 else
0357 {
0358
0359 status = kStatus_Success;
0360 }
0361 }
0362
0363 return status;
0364 }
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 status_t DCP_AES_EncryptEcb(
0380 DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
0381 {
0382 status_t completionStatus = kStatus_Fail;
0383
0384
0385 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0386 dcp_work_packet_t *dcpWork;
0387 uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
0388 dcpWork = (dcp_work_packet_t *)(uint32_t)DCP_FindCacheLine(dcpWorkExt);
0389 #else
0390 dcp_work_packet_t dcpWorkPacket = {0};
0391 dcp_work_packet_t *dcpWork = &dcpWorkPacket;
0392 #endif
0393
0394 do
0395 {
0396 completionStatus = DCP_AES_EncryptEcbNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size);
0397 } while (completionStatus == (int32_t)kStatus_DCP_Again);
0398
0399 if (completionStatus != kStatus_Success)
0400 {
0401 return completionStatus;
0402 }
0403
0404 return DCP_WaitForChannelComplete(base, handle);
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
0422 dcp_handle_t *handle,
0423 dcp_work_packet_t *dcpPacket,
0424 const uint8_t *plaintext,
0425 uint8_t *ciphertext,
0426 size_t size)
0427 {
0428
0429 if ((size < 16u) || (0U != (size % 16u)))
0430 {
0431 return kStatus_InvalidArgument;
0432 }
0433
0434 dcpPacket->control0 =
0435 0x122u | (handle->swapConfig & 0xFC0000u);
0436 dcpPacket->sourceBufferAddress = (uint32_t)plaintext;
0437 dcpPacket->destinationBufferAddress = (uint32_t)ciphertext;
0438 dcpPacket->bufferSize = (uint32_t)size;
0439
0440 if (handle->keySlot == kDCP_OtpKey)
0441 {
0442 dcpPacket->control0 |= ((uint32_t)1u << 10);
0443 dcpPacket->control1 = ((uint32_t)0xFFu << 8);
0444 }
0445 else if (handle->keySlot == kDCP_OtpUniqueKey)
0446 {
0447 dcpPacket->control0 |= ((uint32_t)1u << 10);
0448 dcpPacket->control1 = ((uint32_t)0xFEu << 8);
0449 }
0450 else if (handle->keySlot == kDCP_PayloadKey)
0451 {
0452
0453 dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
0454 dcpPacket->control0 |= ((uint32_t)1u << 11);
0455 }
0456 else
0457 {
0458 dcpPacket->control1 = ((uint32_t)handle->keySlot << 8);
0459 }
0460
0461 return dcp_schedule_work(base, handle, dcpPacket);
0462 }
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 status_t DCP_AES_DecryptEcb(
0478 DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
0479 {
0480 status_t completionStatus = kStatus_Fail;
0481
0482
0483 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0484 dcp_work_packet_t *dcpWork;
0485 uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
0486 dcpWork = (dcp_work_packet_t *)(uint32_t)DCP_FindCacheLine(dcpWorkExt);
0487 #else
0488 dcp_work_packet_t dcpWorkPacket = {0};
0489 dcp_work_packet_t *dcpWork = &dcpWorkPacket;
0490 #endif
0491
0492 do
0493 {
0494 completionStatus = DCP_AES_DecryptEcbNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size);
0495 } while (completionStatus == (int32_t)(kStatus_DCP_Again));
0496
0497 if (completionStatus != kStatus_Success)
0498 {
0499 return completionStatus;
0500 }
0501
0502 return DCP_WaitForChannelComplete(base, handle);
0503 }
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519 status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
0520 dcp_handle_t *handle,
0521 dcp_work_packet_t *dcpPacket,
0522 const uint8_t *ciphertext,
0523 uint8_t *plaintext,
0524 size_t size)
0525 {
0526
0527 if ((size < 16u) || (0U != (size % 16u)))
0528 {
0529 return kStatus_InvalidArgument;
0530 }
0531
0532 dcpPacket->control0 = 0x22u | (handle->swapConfig & 0xFC0000u);
0533 dcpPacket->sourceBufferAddress = (uint32_t)ciphertext;
0534 dcpPacket->destinationBufferAddress = (uint32_t)plaintext;
0535 dcpPacket->bufferSize = (uint32_t)size;
0536
0537 if (handle->keySlot == kDCP_OtpKey)
0538 {
0539 dcpPacket->control0 |= ((uint32_t)1u << 10);
0540 dcpPacket->control1 = ((uint32_t)0xFFu << 8);
0541 }
0542 else if (handle->keySlot == kDCP_OtpUniqueKey)
0543 {
0544 dcpPacket->control0 |= ((uint32_t)1u << 10);
0545 dcpPacket->control1 = ((uint32_t)0xFEu << 8);
0546 }
0547 else if (handle->keySlot == kDCP_PayloadKey)
0548 {
0549
0550 dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
0551 dcpPacket->control0 |= ((uint32_t)1u << 11);
0552 }
0553 else
0554 {
0555 dcpPacket->control1 = ((uint32_t)handle->keySlot << 8);
0556 }
0557
0558 return dcp_schedule_work(base, handle, dcpPacket);
0559 }
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575 status_t DCP_AES_EncryptCbc(DCP_Type *base,
0576 dcp_handle_t *handle,
0577 const uint8_t *plaintext,
0578 uint8_t *ciphertext,
0579 size_t size,
0580 const uint8_t iv[16])
0581 {
0582 status_t completionStatus = kStatus_Fail;
0583
0584
0585 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0586 dcp_work_packet_t *dcpWork;
0587 uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
0588 dcpWork = (dcp_work_packet_t *)(uint32_t)DCP_FindCacheLine(dcpWorkExt);
0589 #else
0590 dcp_work_packet_t dcpWorkPacket = {0};
0591 dcp_work_packet_t *dcpWork = &dcpWorkPacket;
0592 #endif
0593
0594 do
0595 {
0596 completionStatus = DCP_AES_EncryptCbcNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size, iv);
0597 } while (completionStatus == (int32_t)kStatus_DCP_Again);
0598
0599 if (completionStatus != kStatus_Success)
0600 {
0601 return completionStatus;
0602 }
0603
0604 return DCP_WaitForChannelComplete(base, handle);
0605 }
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
0623 dcp_handle_t *handle,
0624 dcp_work_packet_t *dcpPacket,
0625 const uint8_t *plaintext,
0626 uint8_t *ciphertext,
0627 size_t size,
0628 const uint8_t *iv)
0629 {
0630
0631 if ((size < 16u) || (0U != (size % 16u)))
0632 {
0633 return kStatus_InvalidArgument;
0634 }
0635
0636 dcpPacket->control0 =
0637 0x322u | (handle->swapConfig & 0xFC0000u);
0638 dcpPacket->control1 = 0x10u;
0639 dcpPacket->sourceBufferAddress = (uint32_t)plaintext;
0640 dcpPacket->destinationBufferAddress = (uint32_t)ciphertext;
0641 dcpPacket->bufferSize = (uint32_t)size;
0642
0643 if (handle->keySlot == kDCP_OtpKey)
0644 {
0645 dcpPacket->payloadPointer = (uint32_t)iv;
0646 dcpPacket->control0 |= ((uint32_t)1u << 10);
0647 dcpPacket->control1 |= ((uint32_t)0xFFu << 8);
0648 }
0649 else if (handle->keySlot == kDCP_OtpUniqueKey)
0650 {
0651 dcpPacket->payloadPointer = (uint32_t)iv;
0652 dcpPacket->control0 |= ((uint32_t)1u << 10);
0653 dcpPacket->control1 |= ((uint32_t)0xFEu << 8);
0654 }
0655 else if (handle->keySlot == kDCP_PayloadKey)
0656 {
0657
0658
0659 (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16);
0660 dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
0661 dcpPacket->control0 |= ((uint32_t)1u << 11);
0662 }
0663 else
0664 {
0665 dcpPacket->payloadPointer = (uint32_t)iv;
0666 dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8);
0667 }
0668
0669 return dcp_schedule_work(base, handle, dcpPacket);
0670 }
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686 status_t DCP_AES_DecryptCbc(DCP_Type *base,
0687 dcp_handle_t *handle,
0688 const uint8_t *ciphertext,
0689 uint8_t *plaintext,
0690 size_t size,
0691 const uint8_t iv[16])
0692 {
0693 status_t completionStatus = kStatus_Fail;
0694
0695
0696 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0697 dcp_work_packet_t *dcpWork;
0698 uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
0699 dcpWork = (dcp_work_packet_t *)(uint32_t)DCP_FindCacheLine(dcpWorkExt);
0700 #else
0701 dcp_work_packet_t dcpWorkPacket = {0};
0702 dcp_work_packet_t *dcpWork = &dcpWorkPacket;
0703 #endif
0704
0705 do
0706 {
0707 completionStatus = DCP_AES_DecryptCbcNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size, iv);
0708 } while (completionStatus == (int32_t)kStatus_DCP_Again);
0709
0710 if (completionStatus != (int32_t)kStatus_Success)
0711 {
0712 return completionStatus;
0713 }
0714
0715 return DCP_WaitForChannelComplete(base, handle);
0716 }
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733 status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
0734 dcp_handle_t *handle,
0735 dcp_work_packet_t *dcpPacket,
0736 const uint8_t *ciphertext,
0737 uint8_t *plaintext,
0738 size_t size,
0739 const uint8_t *iv)
0740 {
0741
0742 if ((size < 16u) || (0U != (size % 16u)))
0743 {
0744 return kStatus_InvalidArgument;
0745 }
0746
0747 dcpPacket->control0 = 0x222u | (handle->swapConfig & 0xFC0000u);
0748 dcpPacket->control1 = 0x10u;
0749 dcpPacket->sourceBufferAddress = (uint32_t)ciphertext;
0750 dcpPacket->destinationBufferAddress = (uint32_t)plaintext;
0751 dcpPacket->bufferSize = (uint32_t)size;
0752
0753 if (handle->keySlot == kDCP_OtpKey)
0754 {
0755 dcpPacket->payloadPointer = (uint32_t)iv;
0756 dcpPacket->control0 |= ((uint32_t)1u << 10);
0757 dcpPacket->control1 |= ((uint32_t)0xFFu << 8);
0758 }
0759 else if (handle->keySlot == kDCP_OtpUniqueKey)
0760 {
0761 dcpPacket->payloadPointer = (uint32_t)iv;
0762 dcpPacket->control0 |= ((uint32_t)1u << 10);
0763 dcpPacket->control1 |= ((uint32_t)0xFEu << 8);
0764 }
0765 else if (handle->keySlot == kDCP_PayloadKey)
0766 {
0767
0768
0769 (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16);
0770 dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
0771 dcpPacket->control0 |= ((uint32_t)1u << 11);
0772 }
0773 else
0774 {
0775 dcpPacket->payloadPointer = (uint32_t)iv;
0776 dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8);
0777 }
0778
0779 return dcp_schedule_work(base, handle, dcpPacket);
0780 }
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795 void DCP_GetDefaultConfig(dcp_config_t *config)
0796 {
0797
0798
0799
0800
0801
0802
0803 (void)memset(config, 0, sizeof(*config));
0804
0805 dcp_config_t userConfig = {
0806 true, false, true, (uint8_t)kDCP_chEnableAll, (uint8_t)kDCP_chIntDisable,
0807 };
0808
0809 *config = userConfig;
0810 }
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 void DCP_Init(DCP_Type *base, const dcp_config_t *config)
0821 {
0822 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0823 CLOCK_EnableClock(kCLOCK_Dcp);
0824 #endif
0825
0826 base->CTRL = 0xF0800000u;
0827 base->CTRL = 0x30800000u;
0828
0829 dcp_clear_status(base);
0830 dcp_clear_channel_status(
0831 base, (uint32_t)kDCP_Channel0 | (uint32_t)kDCP_Channel1 | (uint32_t)kDCP_Channel2 | (uint32_t)kDCP_Channel3);
0832
0833 base->CTRL = DCP_CTRL_GATHER_RESIDUAL_WRITES(config->gatherResidualWrites) |
0834 DCP_CTRL_ENABLE_CONTEXT_CACHING(config->enableContextCaching) |
0835 DCP_CTRL_ENABLE_CONTEXT_SWITCHING(config->enableContextSwitching) |
0836 DCP_CTRL_CHANNEL_INTERRUPT_ENABLE(config->enableChannelInterrupt);
0837
0838
0839 base->CHANNELCTRL = DCP_CHANNELCTRL_ENABLE_CHANNEL(config->enableChannel);
0840
0841
0842 base->CONTEXT = (uint32_t)&s_dcpContextSwitchingBuffer;
0843 }
0844
0845
0846
0847
0848
0849
0850
0851
0852 void DCP_Deinit(DCP_Type *base)
0853 {
0854 base->CTRL = 0xF0800000u;
0855 (void)memset(&s_dcpContextSwitchingBuffer, 0, sizeof(s_dcpContextSwitchingBuffer));
0856
0857 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0858 CLOCK_DisableClock(kCLOCK_Dcp);
0859 #endif
0860 }
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872 status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle)
0873 {
0874
0875 while ((base->STAT & (uint32_t)handle->channel) == (uint32_t)handle->channel)
0876 {
0877 }
0878
0879 if (dcp_get_channel_status(base, handle->channel) != kStatus_Success)
0880 {
0881 dcp_clear_status(base);
0882 dcp_clear_channel_status(base, (uint32_t)handle->channel);
0883 return kStatus_Fail;
0884 }
0885
0886 dcp_clear_status(base);
0887 return kStatus_Success;
0888 }
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898 static status_t dcp_hash_check_input_alg(dcp_hash_algo_t algo)
0899 {
0900 if ((algo != kDCP_Sha256) && (algo != kDCP_Sha1) && (algo != kDCP_Crc32))
0901 {
0902 return kStatus_InvalidArgument;
0903 }
0904 return kStatus_Success;
0905 }
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918 static status_t dcp_hash_check_input_args(DCP_Type *base, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo)
0919 {
0920
0921 if (kStatus_Success != dcp_hash_check_input_alg(algo))
0922 {
0923 return kStatus_InvalidArgument;
0924 }
0925
0926 if ((NULL == ctx) || (NULL == base))
0927 {
0928 return kStatus_InvalidArgument;
0929 }
0930
0931 return kStatus_Success;
0932 }
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943 static status_t dcp_hash_check_context(dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *message)
0944 {
0945 if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != dcp_hash_check_input_alg(ctxInternal->algo)))
0946 {
0947 return kStatus_InvalidArgument;
0948 }
0949
0950 return kStatus_Success;
0951 }
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961 static status_t dcp_hash_engine_init(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal)
0962 {
0963 status_t status;
0964
0965 status = kStatus_InvalidArgument;
0966
0967 if ((kDCP_Sha256 == ctxInternal->algo) || (kDCP_Sha1 == ctxInternal->algo) || (kDCP_Crc32 == ctxInternal->algo))
0968 {
0969 ctxInternal->ctrl0 = (uint32_t)kDCP_CONTROL0_HASH_INIT;
0970 status = kStatus_Success;
0971 }
0972
0973 return status;
0974 }
0975
0976 static status_t dcp_hash_update_non_blocking(
0977 DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, dcp_work_packet_t *dcpPacket, const uint8_t *msg, size_t size)
0978 {
0979 dcpPacket->control0 = ctxInternal->ctrl0 | (ctxInternal->handle->swapConfig & 0xFC0000u) |
0980 (uint32_t)kDCP_CONTROL0_ENABLE_HASH | (uint32_t)kDCP_CONTROL0_DECR_SEMAPHOR;
0981 if (ctxInternal->algo == kDCP_Sha256)
0982 {
0983 dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA256;
0984 }
0985 else if (ctxInternal->algo == kDCP_Sha1)
0986 {
0987 dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA1;
0988 }
0989 else if (ctxInternal->algo == kDCP_Crc32)
0990 {
0991
0992 if (size == 0U)
0993 {
0994 #if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
0995
0996 DCACHE_CleanByRange((uint32_t)ctxInternal, sizeof(dcp_hash_ctx_internal_t));
0997 #endif
0998
0999 __DSB();
1000 __ISB();
1001 return kStatus_Success;
1002 }
1003 dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_CRC32;
1004 }
1005 else
1006 {
1007 return kStatus_Fail;
1008 }
1009 dcpPacket->sourceBufferAddress = (uint32_t)msg;
1010 dcpPacket->destinationBufferAddress = 0;
1011 dcpPacket->bufferSize = size;
1012 dcpPacket->payloadPointer = (uint32_t)ctxInternal->runningHash;
1013
1014 #if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1015
1016 DCACHE_CleanByRange((uint32_t)ctxInternal, sizeof(dcp_hash_ctx_internal_t));
1017 #endif
1018
1019 __DSB();
1020 __ISB();
1021
1022 return dcp_schedule_work(base, ctxInternal->handle, dcpPacket);
1023 }
1024
1025 static status_t dcp_hash_update(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *msg, size_t size)
1026 {
1027 status_t completionStatus = kStatus_Fail;
1028
1029
1030 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1031 dcp_work_packet_t *dcpWork;
1032 uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
1033 dcpWork = (dcp_work_packet_t *)(uint32_t)DCP_FindCacheLine(dcpWorkExt);
1034 #else
1035 dcp_work_packet_t dcpWorkPacket = {0};
1036 dcp_work_packet_t *dcpWork = &dcpWorkPacket;
1037 #endif
1038
1039 do
1040 {
1041 completionStatus = dcp_hash_update_non_blocking(base, ctxInternal, dcpWork, msg, size);
1042 } while (completionStatus == (int32_t)kStatus_DCP_Again);
1043
1044 completionStatus = DCP_WaitForChannelComplete(base, ctxInternal->handle);
1045
1046 ctxInternal->ctrl0 = 0;
1047 return (completionStatus);
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 static status_t dcp_hash_process_message_data(DCP_Type *base,
1064 dcp_hash_ctx_internal_t *ctxInternal,
1065 const uint8_t *message,
1066 size_t messageSize)
1067 {
1068 status_t status = kStatus_Fail;
1069
1070
1071 if (ctxInternal->blksz > 0U)
1072 {
1073 size_t toCopy = DCP_HASH_BLOCK_SIZE - ctxInternal->blksz;
1074 (void)dcp_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
1075 message += toCopy;
1076 messageSize -= toCopy;
1077
1078
1079 status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], DCP_HASH_BLOCK_SIZE);
1080 if (kStatus_Success != status)
1081 {
1082 return status;
1083 }
1084 }
1085
1086
1087 uint32_t fullBlocksSize = ((messageSize >> 6) << 6);
1088 if (fullBlocksSize > 0U)
1089 {
1090 status = dcp_hash_update(base, ctxInternal, message, fullBlocksSize);
1091 if (kStatus_Success != status)
1092 {
1093 return status;
1094 }
1095 message += fullBlocksSize;
1096 messageSize -= fullBlocksSize;
1097 }
1098
1099
1100 (void)dcp_memcpy(&ctxInternal->blk.b[0], message, messageSize);
1101 ctxInternal->blksz = messageSize;
1102
1103 return status;
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115 static status_t dcp_hash_finalize(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal)
1116 {
1117 status_t status;
1118
1119 ctxInternal->ctrl0 |= (uint32_t)kDCP_CONTROL0_HASH_TERM;
1120 status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], ctxInternal->blksz);
1121
1122 return status;
1123 }
1124
1125 static void dcp_hash_save_running_hash(dcp_hash_ctx_internal_t *ctxInternal)
1126 {
1127 uint32_t *srcAddr = NULL;
1128
1129 switch (ctxInternal->handle->channel)
1130 {
1131 case kDCP_Channel0:
1132 srcAddr = &s_dcpContextSwitchingBuffer.x[43];
1133 break;
1134
1135 case kDCP_Channel1:
1136 srcAddr = &s_dcpContextSwitchingBuffer.x[30];
1137 break;
1138
1139 case kDCP_Channel2:
1140 srcAddr = &s_dcpContextSwitchingBuffer.x[17];
1141 break;
1142
1143 case kDCP_Channel3:
1144 srcAddr = &s_dcpContextSwitchingBuffer.x[4];
1145 break;
1146
1147 default:
1148
1149 break;
1150 }
1151 if (srcAddr != NULL)
1152 {
1153 DCACHE_InvalidateByRange((uint32_t)srcAddr, sizeof(ctxInternal->runningHash));
1154 (void)dcp_memcpy(ctxInternal->runningHash, srcAddr, sizeof(ctxInternal->runningHash));
1155 }
1156 }
1157
1158 static void dcp_hash_restore_running_hash(dcp_hash_ctx_internal_t *ctxInternal)
1159 {
1160 uint32_t *destAddr = NULL;
1161
1162 switch (ctxInternal->handle->channel)
1163 {
1164 case kDCP_Channel0:
1165 destAddr = &s_dcpContextSwitchingBuffer.x[43];
1166 break;
1167
1168 case kDCP_Channel1:
1169 destAddr = &s_dcpContextSwitchingBuffer.x[30];
1170 break;
1171
1172 case kDCP_Channel2:
1173 destAddr = &s_dcpContextSwitchingBuffer.x[17];
1174 break;
1175
1176 case kDCP_Channel3:
1177 destAddr = &s_dcpContextSwitchingBuffer.x[4];
1178 break;
1179
1180 default:
1181
1182 break;
1183 }
1184 if (destAddr != NULL)
1185 {
1186 (void)dcp_memcpy(destAddr, ctxInternal->runningHash, sizeof(ctxInternal->runningHash));
1187 }
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201 status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo)
1202 {
1203 status_t status;
1204
1205 dcp_hash_ctx_internal_t *ctxInternal;
1206
1207 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1208 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)((uint8_t *)ctx + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE);
1209 #else
1210 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
1211 #endif
1212
1213
1214 BUILD_ASSURE(sizeof(dcp_hash_ctx_t) >= sizeof(dcp_hash_ctx_internal_t), dcp_hash_ctx_t_size);
1215 uint32_t i;
1216
1217 status = dcp_hash_check_input_args(base, ctx, algo);
1218 if (status != kStatus_Success)
1219 {
1220 return status;
1221 }
1222
1223
1224 ctxInternal->algo = algo;
1225 ctxInternal->blksz = 0u;
1226
1227 const uint32_t j = sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]);
1228 for (i = 0; i < j; i++)
1229 {
1230 ctxInternal->blk.w[i] = 0u;
1231 }
1232 ctxInternal->state = kDCP_StateHashInit;
1233 ctxInternal->fullMessageSize = 0;
1234 ctxInternal->handle = handle;
1235 return status;
1236 }
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
1254 {
1255 bool isUpdateState;
1256 status_t status;
1257 dcp_hash_ctx_internal_t *ctxInternal;
1258 size_t blockSize;
1259
1260
1261 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1262 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)((uint8_t *)ctx + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE);
1263 #else
1264 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
1265 #endif
1266
1267 if (inputSize == 0U)
1268 {
1269 return kStatus_Success;
1270 }
1271
1272 status = dcp_hash_check_context(ctxInternal, input);
1273 if (kStatus_Success != status)
1274 {
1275 return status;
1276 }
1277
1278 ctxInternal->fullMessageSize += inputSize;
1279 blockSize = DCP_HASH_BLOCK_SIZE;
1280
1281 if ((ctxInternal->blksz + inputSize) <= blockSize)
1282 {
1283 (void)dcp_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
1284 ctxInternal->blksz += inputSize;
1285 return status;
1286 }
1287 else
1288 {
1289 isUpdateState = ctxInternal->state == kDCP_StateHashUpdate;
1290 if (!isUpdateState)
1291 {
1292
1293 status = dcp_hash_engine_init(base, ctxInternal);
1294 if (status != kStatus_Success)
1295 {
1296 return status;
1297 }
1298 ctxInternal->state = kDCP_StateHashUpdate;
1299 }
1300 else
1301 {
1302 dcp_hash_restore_running_hash(ctxInternal);
1303 }
1304 }
1305
1306
1307 status = dcp_hash_process_message_data(base, ctxInternal, input, inputSize);
1308 dcp_hash_save_running_hash(ctxInternal);
1309 return status;
1310 }
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
1324 {
1325 size_t algOutSize = 0;
1326 status_t status;
1327 dcp_hash_ctx_internal_t *ctxInternal;
1328
1329
1330 #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1331 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)((uint8_t *)ctx + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE);
1332 #else
1333 ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
1334 #endif
1335
1336 status = dcp_hash_check_context(ctxInternal, output);
1337
1338 if (kStatus_Success != status)
1339 {
1340 return status;
1341 }
1342
1343 if (ctxInternal->state == kDCP_StateHashInit)
1344 {
1345 status = dcp_hash_engine_init(base, ctxInternal);
1346 if (status != kStatus_Success)
1347 {
1348 return status;
1349 }
1350 }
1351 else
1352 {
1353 dcp_hash_restore_running_hash(ctxInternal);
1354 }
1355
1356 size_t outSize = 0u;
1357
1358
1359 switch (ctxInternal->algo)
1360 {
1361 case kDCP_Sha256:
1362 outSize = (uint32_t)kDCP_OutLenSha256;
1363 break;
1364 case kDCP_Sha1:
1365 outSize = (uint32_t)kDCP_OutLenSha1;
1366 break;
1367 case kDCP_Crc32:
1368 outSize = (uint32_t)kDCP_OutLenCrc32;
1369 break;
1370 default:
1371
1372 break;
1373 }
1374 algOutSize = outSize;
1375
1376 #if defined(DCP_HASH_CAVP_COMPATIBLE)
1377 if (ctxInternal->fullMessageSize == 0U)
1378 {
1379 switch (ctxInternal->algo)
1380 {
1381 case kDCP_Sha256:
1382 (void)dcp_memcpy(&output[0], &s_nullSha256, 32);
1383 break;
1384 case kDCP_Sha1:
1385 (void)dcp_memcpy(&output[0], &s_nullSha1, 20);
1386 break;
1387 default:
1388
1389 break;
1390 }
1391
1392 return kStatus_Success;
1393 }
1394 #endif
1395
1396
1397 status = dcp_hash_finalize(base, ctxInternal);
1398
1399 if (outputSize != NULL)
1400 {
1401 if (algOutSize < *outputSize)
1402 {
1403 *outputSize = algOutSize;
1404 }
1405 else
1406 {
1407 algOutSize = *outputSize;
1408 }
1409 }
1410
1411 #if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
1412 DCACHE_InvalidateByRange((uint32_t)ctxInternal->runningHash, sizeof(ctxInternal->runningHash));
1413 #endif
1414
1415 dcp_reverse_and_copy((uint8_t *)ctxInternal->runningHash, &output[0], algOutSize);
1416
1417 (void)memset(ctx, 0, sizeof(dcp_hash_ctx_t));
1418 return status;
1419 }
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 status_t DCP_HASH(DCP_Type *base,
1436 dcp_handle_t *handle,
1437 dcp_hash_algo_t algo,
1438 const uint8_t *input,
1439 size_t inputSize,
1440 uint8_t *output,
1441 size_t *outputSize)
1442 {
1443 dcp_hash_ctx_t hashCtx = {0};
1444 status_t status;
1445
1446 status = DCP_HASH_Init(base, handle, &hashCtx, algo);
1447 if (status != kStatus_Success)
1448 {
1449 return status;
1450 }
1451
1452 status = DCP_HASH_Update(base, &hashCtx, input, inputSize);
1453 if (status != kStatus_Success)
1454 {
1455 return status;
1456 }
1457
1458 status = DCP_HASH_Finish(base, &hashCtx, output, outputSize);
1459
1460 return status;
1461 }