ADuCM4x50 Device Drivers API Reference Manual  Release 4.0.0.0
adi_crypto.c
1 
44 /*======== I N C L U D E ========*/
45 
47 #include <adi_processor.h>
48 #include <assert.h>
49 #include <string.h>
50 
51 /* main crypto include file */
52 #include <drivers/crypto/adi_crypto.h>
53 
54 /* private crypto defines */
55 #include "adi_crypto_def.h"
56 
57 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
58 /* dma interface */
59 #include <drivers/dma/adi_dma.h>
60 #endif
61 
62 
63 /*======== D E F I N E S ========*/
64 
65 #ifdef __ICCARM__
66 /*
67 * IAR MISRA C 2004 error suppressions.
68 *
69 * Pm123 (rule 8.5): there shall be no definition of objects or functions in a header file
70 * Pm140 (rule 11.3): a cast should not be performed between a pointer type and an integral type
71 * Pm050 (rule 14.2): a null statement shall only occur on a line by itself
72 * Pm088 (rule 17.4): pointer arithmetic should not be used.
73 * Pm073 (rule 14.7): a function should have a single point of exit
74 * Pm143 (rule 14.7): a function should have a single point of exit at the end of the function
75 * Pm152 (rule 17.4): array indexing shall only be applied to objects defined as an array type
76 */
77 #pragma diag_suppress=Pm123,Pm140,Pm050,Pm088,Pm073,Pm143,Pm152
78 #endif /* __ICCARM__ */
79 
80 /* Utility Macros */
81 #define CLR_BITS(REG,BITS) ((REG) &= ~(BITS))
82 #define SET_BITS(REG,BITS) ((REG) |= (BITS))
83 #define IS_ANY_BIT_SET(REG,BITS) (((REG) & (BITS)) != 0u)
84 
85 
86 /* Number of crypto device for the given processor */
87 #define NUM_DEVICES (1u)
88 
89 /* Compiler-specific mapping of assembly-level byte-swap instruction
90  IAR is "__REV", and we think Keil is "__rev", but lets see how that
91  goes when it is undefined for Keil.
92 */
93 #if defined ( __ICCARM__ )
94 #define __ADI_BYTE_SWAP(X) __REV(X)
95 #elif defined (__GNUC__)
96 #define __ADI_BYTE_SWAP(X) __builtin_bswap32(X)
97 #elif defined (__CC_ARM)
98 #define __ADI_BYTE_SWAP(X) __rev(X)
99 #else
100 #error "This toolchain is not supported"
101 #endif
102 
103 
104 /*======== L O C A L F U N C D E C L ========*/
105 
106 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
107 static void dmaCallback (void *pCBParam, uint32_t Event, void *pArg);
108 #endif
109 
110 #ifdef ADI_DEBUG
111 /* Validatation routines */
112 static ADI_CRYPTO_RESULT ValidateHandle (ADI_CRYPTO_HANDLE const hDevice);
113 static ADI_CRYPTO_RESULT ValidateUserBuffer (ADI_CRYPTO_TRANSACTION * const pBuffer);
114 #endif
115 
116 /* Generate a uint32_t value from a pointer to a uint8_t buffer */
117 static uint32_t u32FromU8p (uint8_t * const pFourBytes);
118 
119 /* load AES KEY registers with provided key */
120 static void loadAesKey (uint8_t * const pKey, ADI_CRYPTO_AES_KEY_LEN const keyLen);
121 
122 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
123 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
124 
125 /* load 512-bit/32-bytes HMAC KEY registers with provided key */
126 static void loadHmacKey (ADI_CRYPTO_HANDLE const hDevice, uint8_t * const pKey);
127 
128 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
129 #endif /* defined (__ADUCM4x50__) */
130 
131 /* Initialize the internal device handle object (user memory) */
132 static void InitializeDevData (ADI_CRYPTO_HANDLE const hDevice);
133 
134 /* Initiate the computation for a buffer */
135 static void StartCompute (ADI_CRYPTO_HANDLE const hDevice);
136 
137 /* Stop the device */
138 static void StopCompute (ADI_CRYPTO_HANDLE const hDevice);
139 
140 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
141 static void programDMA (ADI_CRYPTO_HANDLE const hDevice);
142 #endif
143 
144 /* PIO mode write input data */
145 static void writePioInputData (ADI_CRYPTO_HANDLE const hDevice, uint32_t const status);
146 
147 /* PIO mode read output data */
148 static void readPioOutputData (ADI_CRYPTO_HANDLE const hDevice, uint32_t const status);
149 
150 /* Flush the input and output buffers */
151 static void FlushInputOutputRegisters (ADI_CRYPTO_HANDLE const hDevice);
152 
153 
154 /* pre-defined Crypto interrupt handler prototypes, as linked in IVT */
155 void Crypto_Int_Handler(void);
156 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
157 void DMA_AES0_IN_Int_Handler (void);
158 void DMA_AES0_OUT_Int_Handler (void);
159 #endif
160 
161 
162 /*======== D A T A ========*/
163 /* Internal device structure */
164 
165 static CRYPTO_INFO CryptoDevInfo[] = {
166  {pADI_CRYPT0, /* physical device controller pointer */
167  NULL, /* hDevice */
168 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
169  DMA0_CH13_DONE_IRQn, /* DMA input interrupt number */
170  DMA0_CH14_DONE_IRQn, /* DMA output interrupt number */
171  AES0_IN_CHANn, /* DMA input channel */
172  AES0_OUT_CHANn, /* DMA output channel */
173  ADI_CRYPTO_SUCCESS, /* DMA error state */
174 #endif
175  }
176 };
177 
180 /*======== C O D E ========*/
181 
182 
183 /* include PKSTOR extensions into CRYPTO driver... */
184 #if (defined (__ADUCM4x50__) && (1 == ADI_CRYPTO_ENABLE_PKSTOR_SUPPORT))
185 #include "adi_pkstor.c"
186 #endif
187 
188 
189 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
190 
191 /* Internal Crypto registered DMA Callback for receiving DMA
192  fault notifications from the shared DMA error handler */
193 static void dmaCallback(void *pCBParam, uint32_t Event, void *pArg)
194 {
195  /* recover device handle */
196  ADI_CRYPTO_HANDLE hDevice = CryptoDevInfo[0].hDevice;
197 
198  /* recover failing channel number */
199  uint32_t failingChannel = (uint32_t)pCBParam;
200 
201  /* save the DMA error */
202  switch (Event) {
204  hDevice->dmaErrorCode = ADI_CRYPTO_ERR_DMA_BUS_FAULT;
205  break;
207  hDevice->dmaErrorCode = ADI_CRYPTO_ERR_DMA_INVALID_DESCR;
208  break;
209  default:
210  hDevice->dmaErrorCode = ADI_CRYPTO_ERR_DMA_UNKNOWN_ERROR;
211  break;
212  }
213 
214  /* transfer is toast... post semaphore to unblock any waiters */
215  SEM_POST(hDevice);
216 
217  /* call user's callback */
218  if (0u != hDevice->pfCallback) {
219  hDevice->pfCallback (hDevice->pCBParam, (uint32_t)hDevice->dmaErrorCode, (void*)failingChannel);
220  }
221 
222  /* game over... */
223  StopCompute(hDevice);
224 }
225 #endif
226 
227 
228 #ifdef ADI_DEBUG
229 /* Validate the given handle */
230 static ADI_CRYPTO_RESULT ValidateHandle(ADI_CRYPTO_HANDLE const hDevice)
231 {
233  uint32_t x;
234 
235  for (x = 0u; x < NUM_DEVICES; x++) {
236  if (CryptoDevInfo[x].hDevice == hDevice) {
237  result = ADI_CRYPTO_SUCCESS;
238  break;
239  }
240  }
241 
242  return result;
243 }
244 #endif
245 
246 
247 #ifdef ADI_DEBUG
248 static ADI_CRYPTO_RESULT ValidateUserBuffer(ADI_CRYPTO_TRANSACTION * const pBuffer)
249 {
250 
251  /* null pointer and zero count checks */
252  if (
253  (pBuffer->pInputData == NULL)
254  ||((pBuffer->numInputBytes == 0u) && (ADI_CRYPTO_MODE_CCM != pBuffer->eCipherMode))
255  || (pBuffer->pOutputData == NULL)
256  || (pBuffer->numOutputBytes == 0u)
257  || (
259  && (pBuffer->eAesByteSwap != ADI_CRYPTO_AES_BIG_ENDIAN))
260  )
261  {
263  }
264 
265  /* check buffer pointers for 32-bit alignment */
266  if ( (0u != (3u & (uint32_t)pBuffer->pAuthData)) || (0u != (3u & (uint32_t)pBuffer->pInputData)) || (0u != (3u & (uint32_t)pBuffer->pOutputData)) ) {
268  }
269 
270 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
271 
275  if ( (MAX_CRYPTO_DMA_BYTES < pBuffer->numAuthBytes)
276  || (MAX_CRYPTO_DMA_BYTES < pBuffer->numOutputBytes)
277  || ( (MAX_CRYPTO_DMA_BYTES < pBuffer->numInputBytes)
278 #if defined (__ADUCM4x50__)
279  && (ADI_CRYPTO_MODE_HMAC != pBuffer->eCipherMode)
280 #endif
281  && (ADI_CRYPTO_MODE_SHA != pBuffer->eCipherMode)
282  )
283  )
284  {
286  }
287 #endif
288 
289 #if ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1
290  if (pBuffer->eCipherMode == ADI_CRYPTO_MODE_SHA)
291  {
292  /* SHA output digest is 256-bit and hence the output buffer size should be at least 32 bytes */
293  if (pBuffer->numOutputBytes < SHA_OUTPUT_SIZE_IN_BYTES) {
295  }
296  }
297  else
298 #endif
299 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
300 #if ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1
301  if (pBuffer->eCipherMode == ADI_CRYPTO_MODE_HMAC)
302  {
303  /* HMAC output digest is 256-bit and hence the output buffer size should be at least 32 bytes */
304  if (pBuffer->numOutputBytes < SHA_OUTPUT_SIZE_IN_BYTES) {
306  }
307  }
308  else
309 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
310 #endif /* defined (__ADUCM4x50__) */
311  {
312 
313 #if ADI_CRYPTO_ENABLE_CMAC_SUPPORT == 1
314  if (pBuffer->eCipherMode == ADI_CRYPTO_MODE_CMAC) {
315  /* CMAC output is always a 128-bit block */
316  if (pBuffer->numOutputBytes < CRYPTO_INPUT_SIZE_IN_BYTES) {
318  }
319  }
320  else
321 #endif
322  {
323  if (
324  (pBuffer->pAesKey == NULL)
325  || ( (pBuffer->eAesKeyLen != ADI_CRYPTO_AES_KEY_LEN_128_BIT)
327  || ( (pBuffer->eCodingMode != ADI_CRYPTO_ENCODE)
328  && (pBuffer->eCodingMode != ADI_CRYPTO_DECODE)))
329  {
331  }
332 
333 #if ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1
334  if (pBuffer->eCipherMode == ADI_CRYPTO_MODE_CTR)
335  {
336  if ((pBuffer->CounterInit & (0xFFF00000u)) != 0u) {
338  }
339  }
340 #endif
341 
342 #if ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1
343  if (pBuffer->eCipherMode == ADI_CRYPTO_MODE_CCM)
344  {
345  if ( ((pBuffer->CounterInit & (0xFFFF0000u)) != 0u)
346  || ( (pBuffer->pAuthData != NULL)
347  && (
348  (pBuffer->numAuthBytes == 0u)
349  || (pBuffer->numValidBytes == 0u)
350  || (pBuffer->numValidBytes > CRYPTO_INPUT_SIZE_IN_BYTES)
351  || (pBuffer->numOutputBytes < (pBuffer->numInputBytes + CRYPTO_INPUT_SIZE_IN_BYTES))
352  )
353  )
354  )
355  {
357  }
358  }
359  else
360 #endif
361  {
362  if (pBuffer->numOutputBytes < pBuffer->numInputBytes)
363  {
365  }
366  }
367  }
368  }
369 
370  return ADI_CRYPTO_SUCCESS;
371 }
372 #endif
373 
374 
395 ADI_CRYPTO_RESULT adi_crypto_Open (uint32_t const nDeviceNum, void * const pMemory, uint32_t const nMemorySize, ADI_CRYPTO_HANDLE * const phDevice)
396 {
397  ADI_CRYPTO_HANDLE hDevice = NULL;
398 
399 #ifdef ADI_DEBUG
400  if (nDeviceNum >= NUM_DEVICES) {
402  }
403 
404  if ((pMemory == NULL) || (phDevice == NULL)) {
406  }
407 
408  if (nMemorySize < ADI_CRYPTO_MEMORY_SIZE) {
410  }
411 
412  if (CryptoDevInfo[nDeviceNum].hDevice != NULL) {
414  }
415 
416  /* reality checks */
417  assert (ADI_CRYPTO_MEMORY_SIZE == sizeof(ADI_CRYPTO_DEV_DATA_TYPE));
418  assert (sizeof(ADI_CRYPTO_TRANSACTION) == sizeof(CRYPTO_COMPUTE));
419 
420 #endif /* ADI_DEBUG */
421 
422  /* store a bad handle in case of failure */
423  *phDevice = NULL;
424 
425  /* point local device handle to the user memory */
426  hDevice = (ADI_CRYPTO_HANDLE)pMemory;
427 
428  /* link CRYPTO controller register set */
429  hDevice->pDev = CryptoDevInfo[nDeviceNum].pDev;
430 
431  /* link device info */
432  hDevice->pDevInfo = CryptoDevInfo;
433 
434  /* cross-link device handle into device info */
435  CryptoDevInfo[nDeviceNum].hDevice = hDevice;
436 
437  /* Initialize the driver internals */
438  InitializeDevData(hDevice);
439 
440  /* create the semaphore */
441  SEM_CREATE(hDevice, "crypto_sem", ADI_CRYPTO_ERR_SEMAPHORE_FAILED);
442 
443 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
444  /* initialize DMA core */
445  adi_dma_Init();
446 
447  /* register DMA error callback for INPUT channel */
448  if (ADI_DMA_SUCCESS != adi_dma_RegisterCallback(hDevice->pDevInfo->dmaInputChanNum, dmaCallback, (void*)hDevice)) {
449  /* uninitialize crypto driver and fail */
450  adi_crypto_Close(hDevice);
452  }
453  /* register DMA error callback for OUTPUT channel */
454  if (ADI_DMA_SUCCESS != adi_dma_RegisterCallback(hDevice->pDevInfo->dmaOutputChanNum, dmaCallback, (void*)hDevice)) {
455  /* uninitialize crypto driver and fail */
456  adi_crypto_Close(hDevice);
458  }
459 #endif
460 
461  /* Give the handle back to the application */
462  *phDevice = hDevice;
463 
464  /* Return success */
465  return ADI_CRYPTO_SUCCESS;
466 }
467 
481 {
482  uint32_t x;
483  ADI_CRYPTO_RESULT result;
484 
485 #ifdef ADI_DEBUG
486  if ((result = ValidateHandle(hDevice)) != ADI_CRYPTO_SUCCESS) {
487  return result;
488  }
489 #endif /* ADI_DEBUG */
490 
491  /* IF (The device is enabled) */
492  if (hDevice->bDeviceEnabled) {
493  result = adi_crypto_Enable(hDevice, false);
494  if (result != ADI_CRYPTO_SUCCESS) {
495  return result;
496  }
497  }
498 
499  /* Destroy the semaphore */
500  SEM_DELETE(hDevice, ADI_CRYPTO_ERR_SEMAPHORE_FAILED);
501 
502  /* Close the device */
503  for (x=0u; x < NUM_DEVICES; x++) {
504  if (CryptoDevInfo[x].hDevice == hDevice) {
505  CryptoDevInfo[x].hDevice = NULL;
506  break;
507  }
508  }
509 
510  return ADI_CRYPTO_SUCCESS;
511 }
512 
513 
532  ADI_CRYPTO_RESULT adi_crypto_RegisterCallback (ADI_CRYPTO_HANDLE const hDevice, ADI_CALLBACK const pfCallback, void * const pCBParam)
533 {
534 #ifdef ADI_DEBUG
535  ADI_CRYPTO_RESULT result;
536 
537  if ((result = ValidateHandle(hDevice)) != ADI_CRYPTO_SUCCESS) {
538  return result;
539  }
540 #endif /* ADI_DEBUG */
541 
542  /* store user's callback values (critical section) */
543  ADI_INT_STATUS_ALLOC();
544  ADI_ENTER_CRITICAL_REGION();
545  hDevice->pfCallback = pfCallback;
546  hDevice->pCBParam = pCBParam;
547  ADI_EXIT_CRITICAL_REGION();
548 
549  return ADI_CRYPTO_SUCCESS;
550 }
551 
552 
586 {
588 
589  /* reject if we already have a user buffer */
590  if (NULL != hDevice->pUserBuffer) {
591  /* computation already active */
593  }
594 
595 #ifdef ADI_DEBUG
596  if (ADI_CRYPTO_SUCCESS != (result = ValidateHandle(hDevice))) {
597  return result;
598  }
599 
600  /* validate user Buffer */
601  if (ADI_CRYPTO_SUCCESS != (result = ValidateUserBuffer(pBuffer))) {
602  return result;
603  }
604 #endif
605 
606  /* store user buffer pointer to return later */
607  hDevice->pUserBuffer = pBuffer;
608 
609  /* initialize internal compute state from user buffer */
610  memcpy(&hDevice->Computation, pBuffer, sizeof(ADI_CRYPTO_TRANSACTION));
611 
612  /* don't initiate transaction until we get adi_crypto_Enable() */
613 
614  /* reset dma error code */
615  hDevice->dmaErrorCode = ADI_CRYPTO_SUCCESS;
616 
617  return result;
618 }
619 
620 
644 {
646 
647 #ifdef ADI_DEBUG
648  if (ppBuffer == NULL) {
650  }
651  if (ADI_CRYPTO_SUCCESS != (result = ValidateHandle(hDevice))) {
652  return result;
653  }
654 #endif /* ADI_DEBUG */
655 
656  if (NULL != hDevice->pfCallback) {
658  }
659 
660  /* pend on completion (even if already complete) */
661  SEM_PEND(hDevice, ADI_CRYPTO_ERR_SEMAPHORE_FAILED);
662 
663  /* give back the user's buffer */
664  *ppBuffer = hDevice->pUserBuffer;
665 
666  /* clear internal user buffer pointer */
667  hDevice->pUserBuffer = NULL;
668 
669  /* if we had a DMA error, return that instead of success */
670  if (ADI_CRYPTO_SUCCESS != hDevice->dmaErrorCode) {
671  result = hDevice->dmaErrorCode;
672  }
673 
674  return result;
675 }
676 
677 
697 ADI_CRYPTO_RESULT adi_crypto_IsBufferAvailable (ADI_CRYPTO_HANDLE const hDevice, bool * const pbAvailable)
698 {
700 
701 #ifdef ADI_DEBUG
702  if (pbAvailable == NULL)
703  {
705  }
706  if (ADI_CRYPTO_SUCCESS != (result = ValidateHandle(hDevice))) {
707  return result;
708  }
709 #endif /* ADI_DEBUG */
710 
711  /* let the respective PIO/DMA interrupts drive completion... just return that state here */
712  *pbAvailable = hDevice->bCompletion;
713 
714  /* if we had a DMA error, return that instead of success */
715  if (ADI_CRYPTO_SUCCESS != hDevice->dmaErrorCode) {
716  result = hDevice->dmaErrorCode;
717  }
718 
719  return result;
720 }
721 
722 
736 ADI_CRYPTO_RESULT adi_crypto_Enable (ADI_CRYPTO_HANDLE const hDevice, bool const bEnable)
737 {
739 
740 #ifdef ADI_DEBUG
741  if (ADI_CRYPTO_SUCCESS != (result = ValidateHandle(hDevice))) {
742  return result;
743  }
744  if (bEnable == hDevice->bDeviceEnabled) {
746  }
747 #endif /* ADI_DEBUG */
748 
749  if (true == bEnable) {
750 
751  /* device enable */
752 
753  /* Enable the IRQs */
754  NVIC_EnableIRQ(CRYPT_EVT_IRQn);
755 
756 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
757  /* Enable the DMA interrupts */
758  NVIC_EnableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
759  NVIC_EnableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
760 #endif
761 
762  /* Mark the device as enabled */
763  hDevice->bDeviceEnabled = true;
764 
765  /* Start processing buffer */
766  StartCompute(hDevice);
767 
768  } else {
769 
770  /* device disable */
771 
772  /* Disable the IRQs */
773  NVIC_DisableIRQ(CRYPT_EVT_IRQn);
774 
775 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
776  /* Enable the DMA interrupts */
777  NVIC_DisableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
778  NVIC_DisableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
779 #endif
780 
781  /* Stop the device */
782  StopCompute(hDevice);
783 
784  /* if we had a DMA error, return that instead of success */
785  if (ADI_CRYPTO_SUCCESS != hDevice->dmaErrorCode) {
786  result = hDevice->dmaErrorCode;
787  }
788  }
789 
790  /* Return success */
791  return result;
792 }
793 
794 
795 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
796 
816 ADI_CRYPTO_RESULT adi_crypto_EnableDmaMode (ADI_CRYPTO_HANDLE const hDevice, bool const bEnable)
817 {
818 #ifdef ADI_DEBUG
819  ADI_CRYPTO_RESULT result;
820 
821  if ((result = ValidateHandle(hDevice)) != ADI_CRYPTO_SUCCESS) {
822  return result;
823  }
824  if (hDevice->bDeviceEnabled) {
826  }
827 #endif /* ADI_DEBUG */
828 
829  if (bEnable)
830  {
831  /* Enable DMA and map data pump handler */
832  hDevice->bDmaEnabled = true;
833 
834  /* Enable the DMA interrupts */
835  NVIC_EnableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
836  NVIC_EnableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
837  }
838  else
839  {
840  /* Disable DMA and map data pump handler */
841  hDevice->bDmaEnabled = false;
842 
843  /* Disable the DMA interrupts */
844  NVIC_DisableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
845  NVIC_DisableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
846  }
847 
848  /* Return success */
849  return ADI_CRYPTO_SUCCESS;
850 }
851 #endif
852 
853 
854 
857 /*======== L O C A L F U N C T I O N D E F I N I T I O N S ========*/
858 
859 
860 /* Convert from a (4-byte) byte pointer to a u32 */
861 static uint32_t u32FromU8p(uint8_t * const pFourBytes)
862 {
863  return ( (((uint32_t)pFourBytes[3]) << 24ul) | (((uint32_t)pFourBytes[2]) << 16ul) | (((uint32_t)pFourBytes[1]) << 8ul) | (((uint32_t)pFourBytes[0])) );
864 }
865 
866 
867 /* load AES KEY register set by length */
868 static void loadAesKey(uint8_t * const pKey, ADI_CRYPTO_AES_KEY_LEN const keyLen)
869 {
870  uint32_t volatile *pKeyReg = pREG_CRYPT0_AESKEY0;
871  uint8_t *pUserKey = pKey;
872  uint32_t numKeyWords;
873 
874  /* set AES KEY length register */
875  CLR_BITS(*pREG_CRYPT0_CFG, BITM_CRYPT_CFG_AESKEYLEN);
876  SET_BITS(*pREG_CRYPT0_CFG, (uint32_t)keyLen); /* pre-shifted */
877 
878  /* Set the number of keywords to write to the 32-bit keyword registers */
879  switch (keyLen) {
881  numKeyWords = 4u;
882  break;
884  numKeyWords = 8u;
885  break;
886  default:
887  numKeyWords = 0u; /* hardware only supports only 128-bit and 256-bit key length (no 192-bit) */
888  break;
889  }
890 
891  /* load the key (key registers have write-no-read attribute) */
892  for (uint32_t count = 0u; count < numKeyWords; count++) {
893  *pKeyReg = u32FromU8p(pUserKey);
894  pKeyReg++;
895  pUserKey += sizeof(uint32_t);
896  }
897 }
898 
899 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
900 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
901 
902 /* load 512-bit/32-bytes HMAC key in KUWn registers */
903 static void loadHmacKey(ADI_CRYPTO_HANDLE const hDevice, uint8_t * const pKey)
904 {
905  uint32_t volatile *pKeyReg = pREG_CRYPT0_KUW0;
906  uint8_t *pUserKey = pKey;
907  const uint32_t numKeyWords = 16u; /* 16 32-bit registers to write: REG_CRYPT0_KUW0 to REG_CRYPT0_KUW15 */
908 
914  SET_BITS(hDevice->pDev->CFG, (uint32_t)ADI_PK_KUW_LEN_512);
915 
916  /* load the key (key registers have write-no-read attribute) */
917  for (uint32_t count = 0u; count < numKeyWords; count++) {
918  *pKeyReg = u32FromU8p(pUserKey);
919  pKeyReg++;
920  pUserKey += sizeof(uint32_t);
921  }
922 }
923 
924 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
925 #endif /* defined (__ADUCM4x50__) */
926 
927 /* Initialize the device structure */
928 static void InitializeDevData (ADI_CRYPTO_HANDLE const hDevice)
929 {
930  /* Clear the device structure */
931  memset(hDevice, 0, sizeof(ADI_CRYPTO_HANDLE));
932 
933 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
934  #if (ADI_CRYPTO_ENABLE_DMA == 1)
935  hDevice->bDmaEnabled = true;
936  NVIC_EnableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
937  NVIC_EnableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
938  #else
939  hDevice->bDmaEnabled = false;
940  NVIC_DisableIRQ(hDevice->pDevInfo->dmaInputIrqNum);
941  NVIC_DisableIRQ(hDevice->pDevInfo->dmaOutputIrqNum);
942  #endif
943 #else
944  /* no DMA support */
945  hDevice->bDmaEnabled = false;
946 #endif
947 }
948 
949 
950 /* initiate buffer processing (called from crypto enable) */
951 static void StartCompute(ADI_CRYPTO_HANDLE const hDevice)
952 {
953  /* clear completion flag */
954  hDevice->bCompletion = false;
955 
956  /* Get pointer to the compute buffer */
957  CRYPTO_COMPUTE* pCompute = &hDevice->Computation;
958 
959  /* Clear any pending interrupts (all are R/W1C) */
960  const uint32_t status = hDevice->pDev->STAT;
961  hDevice->pDev->STAT = status;
962 
963  /* reset crypto config register */
964  hDevice->pDev->CFG = 0u;
965 
966 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
967  /* reset SHA hardware machine state */
968  if (ADI_CRYPTO_MODE_SHA == pCompute->eCipherMode) {
969  SET_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_SHAINIT);
970  }
971 #endif
972  /* program main config register settings */
973  SET_BITS(hDevice->pDev->CFG,
974  ( (uint32_t)pCompute->eCipherMode /* cipher mode */
975 #if defined (__ADUCM4x50__)
976  | (uint32_t)pCompute->eKeyByteSwap /* KEY endianness */
977  | (uint32_t)pCompute->eShaByteSwap /* SHA endianness */
978 #endif /*ADUCM4x50*/
979  | (uint32_t)pCompute->eAesByteSwap /* AES endianness */
980  | (uint32_t)pCompute->eAesKeyLen /* AES key length */
981  | (uint32_t)pCompute->eCodingMode /* encode mode */
982  )
983  );
984 
985 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
986 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
987 
988  if ((ADI_CRYPTO_MODE_HMAC == pCompute->eCipherMode) && (NULL != pCompute->pHmacKey)) {
989  /* load 512-bit HMAC key directly from compute block... */
990  loadHmacKey(hDevice, pCompute->pHmacKey);
991  }
992 
993 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
994 #endif /* defined (__ADUCM4x50__) */
995 
996 #if (CRYPTO_SUPPORT_KEY_REQUIRED)
997 
998 #if (defined (__ADUCM4x50__) && (1 == ADI_CRYPTO_ENABLE_PKSTOR_SUPPORT))
999 
1000  /* if PKSTOR extensions enabled... check is actually in use. */
1001 
1002  /* load AES key indirectly from encrypted key in PKSTOR (no 512-bit keys allowed here) */
1003  if ( (true == pCompute->bUsePKSTOR) && ((ADI_PK_KUW_LEN_128 == pCompute->pkKuwLen) || (ADI_PK_KUW_LEN_256 == pCompute->pkKuwLen)) )
1004  {
1005  /* retrieve and unwrap key from PKSTOR and "use" it (load it into AES register set) */
1006  adi_crypto_pk_EnablePKSTOR (hDevice, true);
1007  adi_crypto_pk_SetKuwLen (hDevice, pCompute->pkKuwLen);
1008  adi_crypto_pk_LoadDeviceKey (hDevice);
1009  adi_crypto_pk_RetrieveKey (hDevice, pCompute->pkIndex);
1010  adi_crypto_pk_UnwrapKuwReg (hDevice);
1011  adi_crypto_pk_UseDecryptedKey (hDevice);
1012  adi_crypto_pk_EnablePKSTOR (hDevice, false);
1013  }
1014  else
1015 #endif /*ADI_CRYPTO_ENABLE_PKSTOR_SUPPORT */
1016  {
1017  /* load AES key directly from compute block... */
1018  if (NULL != pCompute->pAesKey) {
1019  loadAesKey(pCompute->pAesKey, pCompute->eAesKeyLen);
1020  }
1021  } /* if PKSTOR / else */
1022 
1023 #endif /* (CRYPTO_SUPPORT_KEY_REQUIRED) */
1024 
1025 #if (ADI_CRYPTO_ENABLE_CMAC_SUPPORT == 1)
1026  if (ADI_CRYPTO_MODE_CMAC == pCompute->eCipherMode) {
1027  /* program CMAC-specific registers */
1028  /* DATALEN in CMAC mode is number of 128 bit pages (or 16, 8 byte pages) */
1029  hDevice->pDev->DATALEN = pCompute->numInputBytesRemaining / CRYPTO_INPUT_SIZE_IN_BYTES;
1030  }
1031 #endif /* (ADI_CRYPTO_ENABLE_CMAC_SUPPORT == 1) */
1032 
1033 #if (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1)
1034  if (ADI_CRYPTO_MODE_CCM == pCompute->eCipherMode) {
1035  /* program CMM-specific registers */
1036  hDevice->pDev->PREFIXLEN = pCompute->numAuthBytesRemaining / CRYPTO_INPUT_SIZE_IN_BYTES;
1037  hDevice->pDev->DATALEN = pCompute->numInputBytesRemaining / CRYPTO_INPUT_SIZE_IN_BYTES;
1038  hDevice->pDev->CCM_NUM_VALID_BYTES = pCompute->numValidBytes;
1039  }
1040 #endif /* (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) */
1041 
1042 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1)
1043 
1044  if ( (ADI_CRYPTO_MODE_CBC == pCompute->eCipherMode) || (ADI_CRYPTO_MODE_CCM == pCompute->eCipherMode) || (ADI_CRYPTO_MODE_CTR == pCompute->eCipherMode) )
1045  {
1046  /* program NONCE/IV for CBC, CCM and CTR modes */
1047  assert (NULL != pCompute->pNonceIV);
1048 
1049  /* Configure Counter Init and NONCE values */
1050  hDevice->pDev->CNTRINIT = pCompute->CounterInit;
1051 
1052  hDevice->pDev->NONCE0 = u32FromU8p(&pCompute->pNonceIV[0]);
1053  hDevice->pDev->NONCE1 = u32FromU8p(&pCompute->pNonceIV[4]);
1054  hDevice->pDev->NONCE2 = u32FromU8p(&pCompute->pNonceIV[8]);
1055 
1056  hDevice->pDev->NONCE3 = ((uint32_t)pCompute->pNonceIV[12] << 0u) | ((uint32_t)pCompute->pNonceIV[13] << 8u);
1057 
1058 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1)
1059  if (ADI_CRYPTO_MODE_CBC == pCompute->eCipherMode) {
1060 
1061  /* additionally, CBC mode requires remaining IV data */
1062  hDevice->pDev->NONCE3 |= ( ((uint32_t)pCompute->pNonceIV[14] << 16u) | ((uint32_t)pCompute->pNonceIV[15] << 24u) );
1063  }
1064 #endif /* (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) */
1065  }
1066 #endif /* (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1) */
1067 
1068 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
1069 
1070  /* only enable DMA for non-SHA mode and non-HMAC mode or SHA/HMAC mode with > 4 bytes of input... */
1071  if ( (true == hDevice->bDmaEnabled)
1072  && ( ( (ADI_CRYPTO_MODE_SHA != pCompute->eCipherMode)
1073 #if defined (__ADUCM4x50__)
1074  && (ADI_CRYPTO_MODE_HMAC != pCompute->eCipherMode)
1075 #endif
1076  )
1077  || (4u < pCompute->numInputBytesRemaining)
1078  )
1079  )
1080  {
1081  /* DMA startup... */
1082  programDMA(hDevice);
1083 
1084  /* mode-specific DMA interrupt enables */
1085  switch (pCompute->eCipherMode) {
1086 #if defined (__ADUCM4x50__)
1087  case ADI_CRYPTO_MODE_HMAC:
1088  /* enable HMAC done and overrun interrupts (via PIO handler) */
1089  SET_BITS(hDevice->pDev->INTEN, (BITM_CRYPT_INTEN_HMACDONEEN | BITM_CRYPT_INTEN_INOVREN));
1090  SET_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1091  break;
1092 #endif /*ADUCM4x50__*/
1093  case ADI_CRYPTO_MODE_SHA:
1094  /* enable SHA done and overrun interrupts */
1095  SET_BITS(hDevice->pDev->INTEN, (BITM_CRYPT_INTEN_SHADONEN | BITM_CRYPT_INTEN_INOVREN));
1096  SET_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1097  break;
1098  default:
1099  /* enable DMA I/O interrupts */
1100  SET_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_OUTDMAEN | BITM_CRYPT_CFG_INDMAEN));
1101  break;
1102  }
1103 
1104  /* crypto hardware enable */
1105  SET_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_BLKEN);
1106 
1107 #if defined (__ADUCM4x50__)
1108  if(ADI_CRYPTO_MODE_HMAC == pCompute->eCipherMode)
1109  {
1110  SET_BITS(hDevice->pDev->STAT, (uint32_t)BITP_CRYPT_STAT_HMACMSGRDY);
1111  }
1112 #endif /*ADUCM4x50__*/
1113 
1114  } else
1115 #endif
1116  {
1117  /* mode-specific PIO interrupt enables */
1118  switch (pCompute->eCipherMode) {
1119 #if defined (__ADUCM4x50__)
1120  case ADI_CRYPTO_MODE_HMAC:
1126  SET_BITS(hDevice->pDev->INTEN, (BITM_CRYPT_INTEN_HMACDONEEN | BITM_CRYPT_INTEN_HMACMSGRDYEN | BITM_CRYPT_INTEN_INOVREN));
1127  break;
1128 #endif /*ADUCM4x50__*/
1129  case ADI_CRYPTO_MODE_SHA:
1130  /* SHA done interrupts via PIO handler (do NOT use INRDY in SHA mode) */
1131  SET_BITS(hDevice->pDev->INTEN, (BITM_CRYPT_INTEN_SHADONEN | BITM_CRYPT_INTEN_INOVREN));
1132  break;
1133  default:
1134  SET_BITS(hDevice->pDev->INTEN, (BITM_CRYPT_INTEN_INOVREN | BITM_CRYPT_INTEN_OUTRDYEN | BITM_CRYPT_INTEN_INRDYEN));
1135  break;
1136  }
1137 
1138  /* crypto hardware enable */
1139  SET_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_BLKEN);
1140 
1141 #if defined (__ADUCM4x50__)
1142 
1147  if (ADI_CRYPTO_MODE_HMAC != pCompute->eCipherMode)
1148 #endif
1149  {
1150  /* manual write of 1st input data batch... (interrupt-driven hereafter...) */
1151  writePioInputData(hDevice, hDevice->pDev->STAT);
1152  }
1153  }
1154 }
1155 
1156 
1157 /* halt computation */
1158 static void StopCompute (ADI_CRYPTO_HANDLE const hDevice)
1159 {
1160 
1161 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
1162  /* disable Crypto DMA */
1163  CLR_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN | BITM_CRYPT_CFG_OUTDMAEN));
1164 #endif
1165 
1166  /* clear all interrupt enables */
1167  hDevice->pDev->INTEN = 0u;
1168 
1169  /* Flush the buffers */
1170  FlushInputOutputRegisters(hDevice);
1171 
1172  /* device disable */
1173  CLR_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_BLKEN);
1174 
1175  /* Mark the device as disabled */
1176  hDevice->bDeviceEnabled = false;
1177 }
1178 
1179 
1180 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
1181 static void programDMA(ADI_CRYPTO_HANDLE const hDevice)
1182 {
1183  CRYPTO_COMPUTE* pCompute = &hDevice->Computation;
1184  ADI_DCC_TypeDef* pCCD; /* pointer to DMA Control Data Descriptor */
1185  uint32_t channelBit;
1186  uint32_t num32BitWords;
1187 
1188  /* start with INPUT channel */
1189  channelBit = 1u << hDevice->pDevInfo->dmaInputChanNum;
1190  pADI_DMA0->SRCADDR_CLR = channelBit; /* disable src endpointer decrement mode */
1191  pADI_DMA0->DSTADDR_CLR = channelBit; /* disable dst endpointer decrement mode */
1192  pADI_DMA0->EN_SET = channelBit; /* channel enable */
1193  pADI_DMA0->RMSK_CLR = channelBit; /* allow Crypto to request DMA service */
1194 
1195 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1)
1196  /* program input descriptor(s) */
1197  if (0u != pCompute->pNextAuthInput) {
1198 
1199  /* schedule authentication data into primary descriptor
1200  * - using ping-pong mode if there's a payload
1201  * - using basic mode else
1202  */
1203 
1204  pADI_DMA0->ALT_CLR = channelBit; /* activate PRIMARY descriptor */
1205  pCCD = pPrimaryCCD + hDevice->pDevInfo->dmaInputChanNum; /* point to primary INPUT descriptor */
1206 
1207  /* setup the endpoints (point to input register & last 4 bytes of input array) */
1208  pCCD->DMASRCEND = (uint32_t)pCompute->pNextAuthInput + sizeof(uint32_t) * (pCompute->numAuthBytesRemaining / FIFO_WIDTH_IN_BYTES - 1u);
1209  pCCD->DMADSTEND = (uint32_t)&hDevice->pDev->INBUF;
1210 
1211  /* program DMA Control Data Config register */
1212  num32BitWords = pCompute->numAuthBytesRemaining / sizeof(uint32_t);
1213  if (0u == pCompute->numInputBytesRemaining) {
1214 
1215  pCCD->DMACDC =
1216  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1217  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1218  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1219  | ((uint32_t)ADI_DMA_RPOWER_4 << DMA_BITP_CTL_R_POWER)
1220  | (uint32_t)((num32BitWords - 1u) << DMA_BITP_CTL_N_MINUS_1)
1221  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1222 
1223  } else {
1224 
1225  pCCD->DMACDC =
1226  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1227  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1228  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1229  | ((uint32_t)ADI_DMA_RPOWER_4 << DMA_BITP_CTL_R_POWER)
1230  | (uint32_t)((num32BitWords - 1u) << DMA_BITP_CTL_N_MINUS_1)
1231  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_PING_PONG << DMA_BITP_CTL_CYCLE_CTL) );
1232 
1233  /* schedule input data into alternate descriptor (in basic mode) */
1234  pADI_DMA0->PRI_CLR = channelBit; /* activate ALTERNATE descriptor */
1235  pCCD = pAlternateCCD + hDevice->pDevInfo->dmaInputChanNum; /* point to alternate INPUT descriptor */
1236 
1237  /* setup the endpoints (point to input register & last 4 bytes of input array) */
1238  pCCD->DMASRCEND = (uint32_t)pCompute->pNextInput + sizeof(uint32_t) * (pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES - 1u);
1239  pCCD->DMADSTEND = (uint32_t)&hDevice->pDev->INBUF;
1240 
1241  /* program DMA Control Data Config register */
1242  num32BitWords = pCompute->numInputBytesRemaining / sizeof(uint32_t);
1243  pCCD->DMACDC =
1244  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1245  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1246  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1247  | ((uint32_t)ADI_DMA_RPOWER_4 << DMA_BITP_CTL_R_POWER)
1248  | (uint32_t)((num32BitWords - 1u) << DMA_BITP_CTL_N_MINUS_1)
1249  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1250  }
1251  } else
1252 #endif /* #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1) */
1253  {
1254 
1255  /* no authentication data, just schedule input data into primary descriptor (in basic mode) */
1256 
1257  pADI_DMA0->ALT_CLR = channelBit; /* activate PRIMARY descriptor */
1258  pCCD = pPrimaryCCD + hDevice->pDevInfo->dmaInputChanNum; /* point to primary INPUT descriptor */
1259 
1260  /* setup the endpoints (point to input register & last 4 bytes of input array) */
1261 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
1262  if (ADI_CRYPTO_MODE_SHA == pCompute->eCipherMode) {
1263 
1264  /* Stop SHA-mode input writes one short of last 32-bit word so the DMA input interrupt
1265  can manually call PIO write function to handle SHA end flag and last write manually. */
1266 
1267 
1268  num32BitWords = pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES;
1269  if (pCompute->numInputBytesRemaining > MAX_CRYPTO_DMA_BYTES) {
1270  num32BitWords = MAX_CRYPTO_DMA_BYTES / FIFO_WIDTH_IN_BYTES;
1271  pCCD->DMASRCEND = (uint32_t)pCompute->pNextInput + sizeof(uint32_t) * (num32BitWords - 1u);
1272  }else{
1273  pCCD->DMASRCEND = (uint32_t)pCompute->pNextInput + sizeof(uint32_t) * (pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES - 2u);
1274  num32BitWords = (pCompute->numInputBytesRemaining - (pCompute->numInputBytesRemaining % sizeof(uint32_t))) / sizeof(uint32_t) - 1u; /* count - 1 */
1275  }
1276 
1277  }
1278  else
1279 #endif
1280 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1281  if (ADI_CRYPTO_MODE_HMAC == pCompute->eCipherMode) {
1282 
1283  num32BitWords = pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES;
1284  if (pCompute->numInputBytesRemaining > MAX_CRYPTO_DMA_BYTES) {
1285  num32BitWords = MAX_CRYPTO_DMA_BYTES / FIFO_WIDTH_IN_BYTES;
1286  }else{
1287  num32BitWords = pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES;
1288  }
1289  pCCD->DMASRCEND = (uint32_t)pCompute->pNextInput + FIFO_WIDTH_IN_BYTES * (num32BitWords - 1u);
1290  }
1291  else
1292 #endif
1293  {
1294  /* stop at last write end */
1295  pCCD->DMASRCEND = (uint32_t)pCompute->pNextInput + sizeof(uint32_t) * ( pCompute->numInputBytesRemaining / FIFO_WIDTH_IN_BYTES - 1u);
1296  num32BitWords = pCompute->numInputBytesRemaining / sizeof(uint32_t); /* count */
1297  }
1298 
1299  pCCD->DMADSTEND = (uint32_t)&hDevice->pDev->INBUF;
1300 
1301  /* program DMA Control Data Config register */
1302  pCCD->DMACDC =
1303  ( ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_DST_INC)
1304  | ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_SRC_INC)
1305  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1306  | ((uint32_t)ADI_DMA_RPOWER_4 << DMA_BITP_CTL_R_POWER)
1307  | (uint32_t)((num32BitWords - 1u) << DMA_BITP_CTL_N_MINUS_1)
1308  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1309  }
1310 
1311 /* don't program output DMA in SHA mode... */
1312 #if CRYPTO_SUPPORT_MODE_ANY_NON_SHA
1313 
1314  if ( (ADI_CRYPTO_MODE_SHA != pCompute->eCipherMode)
1315 #if defined (__ADUCM4x50__)
1316  && (ADI_CRYPTO_MODE_HMAC != pCompute->eCipherMode)
1317 #endif
1318  )
1319  {
1320 
1321  /* switch to OUTPUT channel */
1322  channelBit = 1u << hDevice->pDevInfo->dmaOutputChanNum;
1323 
1324  /* disable various stuff */
1325  pADI_DMA0->SRCADDR_CLR = channelBit; /* disable src endpointer decrement mode */
1326  pADI_DMA0->DSTADDR_CLR = channelBit; /* disable dst endpointer decrement mode */
1327  pADI_DMA0->EN_SET = channelBit; /* channel enable */
1328  pADI_DMA0->RMSK_CLR = channelBit; /* allow Crypto to request DMA service */
1329 
1330  pADI_DMA0->ALT_CLR = channelBit; /* activate primary descriptor */
1331  pCCD = pPrimaryCCD + hDevice->pDevInfo->dmaOutputChanNum; /* point to crypto OUTPUT descriptor */
1332 
1333 
1334  /* setup the endpoints (point to output register & last 4 bytes of output array) */
1335  pCCD->DMASRCEND = (uint32_t)&hDevice->pDev->OUTBUF;
1336  pCCD->DMADSTEND = (uint32_t)pCompute->pNextOutput + sizeof(uint32_t) * (pCompute->numOutputBytesRemaining / FIFO_WIDTH_IN_BYTES - 1u);
1337 
1338  /* program DMA Control Data Config register */
1339  num32BitWords = pCompute->numOutputBytesRemaining / sizeof(uint32_t);
1340  pCCD->DMACDC =
1341  ( ((uint32_t)ADI_DMA_INCR_4_BYTE << DMA_BITP_CTL_DST_INC)
1342  | ((uint32_t)ADI_DMA_INCR_NONE << DMA_BITP_CTL_SRC_INC)
1343  | ((uint32_t)ADI_DMA_WIDTH_4_BYTE << DMA_BITP_CTL_SRC_SIZE)
1344  | ((uint32_t)ADI_DMA_RPOWER_4 << DMA_BITP_CTL_R_POWER)
1345  | (uint32_t)((num32BitWords - 1u) << DMA_BITP_CTL_N_MINUS_1)
1346  | ((uint32_t)DMA_ENUM_CTL_CYCLE_CTL_BASIC << DMA_BITP_CTL_CYCLE_CTL) );
1347 
1348  } /* end non-SHA mode */
1349 
1350 #endif /* CRYPTO_SUPPORT_MODE_ANY_NON_SHA */
1351 }
1352 #endif /* #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1) */
1353 
1354 
1355 static void writePioInputData(ADI_CRYPTO_HANDLE const hDevice, uint32_t const status)
1356 {
1357  CRYPTO_COMPUTE* pCompute = &hDevice->Computation;
1358  uint32_t numWritable = FIFO_DEPTH - ((status & BITM_CRYPT_STAT_INWORDS) >> BITP_CRYPT_STAT_INWORDS);
1359 
1360 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1)
1361  /* always send authentication data before input payload is sent */
1362  if (0u != pCompute->numAuthBytesRemaining) {
1363 
1364  /* fill input FIFO with 32-bit authentication data */
1365  while ((0u != numWritable) && (0u != pCompute->numAuthBytesRemaining)) {
1366  hDevice->pDev->INBUF = *pCompute->pNextAuthInput;
1367  pCompute->pNextAuthInput++;
1368  pCompute->numAuthBytesRemaining -= FIFO_WIDTH_IN_BYTES;
1369  numWritable--;
1370  }
1371  } else
1372 #endif /* #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1) || (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1) */
1373  {
1374  /* no authentication data, process payload input data */
1375 
1376 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
1377  if (ADI_CRYPTO_MODE_SHA == pCompute->eCipherMode) {
1378 
1379  /* Drive up to a full "chunk" of SHA input message data.
1380  Chunk size is limited to 512-bits (64-bytes) by AES
1381  hardware compute block.
1382  */
1383 
1384  if (pCompute->numInputBytesRemaining >= SHA_CHUNK_MAX_BYTES)
1385  {
1386  /* This is the simple case, load up an entire chunk and let it go */
1387  for (uint8_t i = 0u; i < SHA_CHUNK_MAX_WORDS; i++) {
1388  hDevice->pDev->INBUF = *pCompute->pNextInput;
1389  pCompute->pNextInput++;
1390  }
1391 
1392  if(pCompute->numShaBitsRemaining >= SHA_CHUNK_MAX_BITS)
1393  pCompute->numShaBitsRemaining -= SHA_CHUNK_MAX_BITS;
1394  else
1395  pCompute->numShaBitsRemaining = 0;
1396 
1397  pCompute->numInputBytesRemaining -= SHA_CHUNK_MAX_BYTES;
1398  }
1399  else
1400  {
1401  /* The final case, we load up any bytes less than a full chunk and trigger the last word */
1402  while (FIFO_WIDTH_IN_BITS <= pCompute->numShaBitsRemaining) {
1403  hDevice->pDev->INBUF = *pCompute->pNextInput;
1404  pCompute->pNextInput++;
1405  pCompute->numShaBitsRemaining -= FIFO_WIDTH_IN_BITS;
1406  }
1407 
1408  hDevice->pDev->SHA_LAST_WORD = (pCompute->numShaBitsRemaining << BITP_CRYPT_SHA_LAST_WORD_O_BITS_VALID) | BITM_CRYPT_SHA_LAST_WORD_O_LAST_WORD;
1409 
1410  /* Last write is dummy or not, depending on remaining bit count */
1411  if (0u == pCompute->numShaBitsRemaining) {
1412  /* dummy write */
1413  hDevice->pDev->INBUF = 0u;
1414  } else {
1415  /* partial data (last remaining message data word) */
1416  hDevice->pDev->INBUF = *pCompute->pNextInput;
1417  pCompute->pNextInput++;
1418  }
1419 
1420  pCompute->numShaBitsRemaining = 0u;
1421  pCompute->numInputBytesRemaining = 0u;
1422 
1423  /* Use output bytes as a way of confirming that we are really done (can't use input bytes/bits) */
1424  pCompute->numOutputBytesRemaining -= SHA_OUTPUT_SIZE_IN_BYTES;
1425  }
1426  } /* end of SHA mode */
1427  else
1428 #endif
1429 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
1430 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1431 
1432  if (ADI_CRYPTO_MODE_HMAC == pCompute->eCipherMode) {
1433 
1434  /* Drive up to a full "chunk" of HMAC input message data.
1435  Chunk size is limited to 512-bits (64-bytes) by AES
1436  hardware compute block.
1437  */
1438 
1439  if (pCompute->numInputBytesRemaining >= HMAC_CHUNK_MAX_BYTES)
1440  {
1441  /* This is the simple case, load up an entire chunk and let it go */
1442  for (uint8_t i = 0u; i < HMAC_CHUNK_MAX_WORDS; i++) {
1443  hDevice->pDev->INBUF = *pCompute->pNextInput;
1444  pCompute->pNextInput++;
1445  }
1446 
1447  if(pCompute->numShaBitsRemaining >= HMAC_CHUNK_MAX_BITS)
1448  pCompute->numShaBitsRemaining -= HMAC_CHUNK_MAX_BITS;
1449  else
1450  pCompute->numShaBitsRemaining = 0;
1451 
1452  pCompute->numInputBytesRemaining -= HMAC_CHUNK_MAX_BYTES;
1453  }
1454  else
1455  {
1456  /* The final case, we load up any bytes less than a full chunk and trigger the last word */
1457  while (FIFO_WIDTH_IN_BITS <= pCompute->numShaBitsRemaining) {
1458  hDevice->pDev->INBUF = *pCompute->pNextInput;
1459  pCompute->pNextInput++;
1460  pCompute->numShaBitsRemaining -= FIFO_WIDTH_IN_BITS;
1461  }
1462 
1463  hDevice->pDev->SHA_LAST_WORD = (pCompute->numShaBitsRemaining << BITP_CRYPT_SHA_LAST_WORD_O_BITS_VALID) | BITM_CRYPT_SHA_LAST_WORD_O_LAST_WORD;
1464 
1465  /* Last write is dummy or not, depending on remaining bit count */
1466  if (0u == pCompute->numShaBitsRemaining) {
1467  /* dummy write */
1468  hDevice->pDev->INBUF = 0u;
1469  } else {
1470  /* partial data (last remaining message data word) */
1471  hDevice->pDev->INBUF = *pCompute->pNextInput;
1472  pCompute->pNextInput++;
1473  }
1474 
1475  pCompute->numShaBitsRemaining = 0u;
1476  pCompute->numInputBytesRemaining = 0u;
1477 
1478  /* Use output bytes as a way of confirming that we are really done (can't use input bytes/bits) */
1479  pCompute->numOutputBytesRemaining -= SHA_OUTPUT_SIZE_IN_BYTES;
1480  }
1481  } /* end of HMAC mode */
1482  else
1483 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
1484 #endif /* defined (__ADUCM4x50__) */
1485  {
1486  /* full input FIFO with normal payload write (non-SHA) */
1487  while ((0u != numWritable) && (0u != pCompute->numInputBytesRemaining)) {
1488  hDevice->pDev->INBUF = *pCompute->pNextInput;
1489  pCompute->pNextInput++;
1490  pCompute->numInputBytesRemaining -= FIFO_WIDTH_IN_BYTES;
1491  numWritable--;
1492  }
1493  }
1494  }
1495 }
1496 
1497 
1498 static void readPioOutputData(ADI_CRYPTO_HANDLE const hDevice, uint32_t const status)
1499 {
1500  CRYPTO_COMPUTE *pCompute = &hDevice->Computation;
1501  uint32_t numReadable;
1502 
1503 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1) || (defined (__ADUCM4x50__) && (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1))
1504 
1505 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1) && ((!defined (__ADUCM4x50__)) || (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 0))
1506  /* Copy the SHA output if enabled */
1507  if (pCompute->eCipherMode == ADI_CRYPTO_MODE_SHA)
1508 #elif (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 0) && defined (__ADUCM4x50__) && (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1509  /* Copy the HMAC output if enabled */
1510  if (pCompute->eCipherMode == ADI_CRYPTO_MODE_HMAC)
1511 #else
1512  /* Copy the SHA or HMAC output if enabled */
1513  if ((pCompute->eCipherMode == ADI_CRYPTO_MODE_SHA) || (pCompute->eCipherMode == ADI_CRYPTO_MODE_HMAC))
1514 #endif
1515  {
1516 #if defined (__ADUCM4x50__)
1517  if (IS_ANY_BIT_SET(status, (BITM_CRYPT_STAT_SHADONE | BITM_CRYPT_STAT_HMACDONE))) {
1518 #else
1519  if (IS_ANY_BIT_SET(status, (BITM_CRYPT_STAT_SHADONE))) {
1520 #endif
1521  /* Get 1 SHADONE per block + 1 SHADONE when we trigger the last word */
1522  if (0u == pCompute->numOutputBytesRemaining) {
1523 #if ADI_CRYPTO_SHA_OUTPUT_FORMAT == 0 /* Little Endian */
1524  pCompute->pNextOutput[0] = hDevice->pDev->SHAH7;
1525  pCompute->pNextOutput[1] = hDevice->pDev->SHAH6;
1526  pCompute->pNextOutput[2] = hDevice->pDev->SHAH5;
1527  pCompute->pNextOutput[3] = hDevice->pDev->SHAH4;
1528  pCompute->pNextOutput[4] = hDevice->pDev->SHAH3;
1529  pCompute->pNextOutput[5] = hDevice->pDev->SHAH2;
1530  pCompute->pNextOutput[6] = hDevice->pDev->SHAH1;
1531  pCompute->pNextOutput[7] = hDevice->pDev->SHAH0;
1532 #else
1533  pCompute->pNextOutput[0] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH0);
1534  pCompute->pNextOutput[1] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH1);
1535  pCompute->pNextOutput[2] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH2);
1536  pCompute->pNextOutput[3] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH3);
1537  pCompute->pNextOutput[4] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH4);
1538  pCompute->pNextOutput[5] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH5);
1539  pCompute->pNextOutput[6] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH6);
1540  pCompute->pNextOutput[7] = __ADI_BYTE_SWAP(hDevice->pDev->SHAH7);
1541 #endif
1542  }
1543  }
1544  }
1545  else
1546 #endif /* (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1) || (defined (__ADUCM4x50__) && (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)) */
1547  {
1548  /* read any ready non-SHA output from output FIFO */
1549  if (IS_ANY_BIT_SET(status, BITM_CRYPT_STAT_OUTRDY)) {
1550  numReadable = ((status & BITM_CRYPT_STAT_OUTWORDS) >> BITP_CRYPT_STAT_OUTWORDS);
1551  while ((0u != numReadable) && (0u != pCompute->numOutputBytesRemaining)) {
1552  *pCompute->pNextOutput = hDevice->pDev->OUTBUF;
1553  pCompute->pNextOutput++;
1554  pCompute->numOutputBytesRemaining -= FIFO_WIDTH_IN_BYTES;
1555  numReadable--;
1556  }
1557  }
1558  }
1559 
1560  /* if output count has gone to zero, set completion flag */
1561  if (0u == pCompute->numOutputBytesRemaining) {
1562  hDevice->bCompletion = true;
1563  }
1564 }
1565 
1566 
1567 /* Flush the Crypto input and output buffers */
1568 static void FlushInputOutputRegisters(ADI_CRYPTO_HANDLE const hDevice)
1569 {
1570  /* Set and clear the flush bits to flush the input and output buffers */
1571  SET_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_INFLUSH | BITM_CRYPT_CFG_OUTFLUSH);
1572  CLR_BITS(hDevice->pDev->CFG, BITM_CRYPT_CFG_INFLUSH | BITM_CRYPT_CFG_OUTFLUSH);
1573 }
1574 
1575 
1576 /*================ INTERRUPT HANDELING ==================*/
1577 
1578 /* native PIO-mode (non-DMA) interrupt handler */
1579 void Crypto_Int_Handler(void)
1580 {
1581  ISR_PROLOG();
1582 
1583  ADI_CRYPTO_HANDLE hDevice = CryptoDevInfo[0].hDevice;
1584  CRYPTO_COMPUTE *pCompute = &hDevice->Computation;
1585  uint32_t status = hDevice->pDev->STAT;
1586  uint32_t event;
1587 
1588  /* clear status */
1589  hDevice->pDev->STAT = status;
1590 
1591  /* check for overflow */
1592  if (IS_ANY_BIT_SET(status, BITM_CRYPT_STAT_INOVR)) {
1593 
1594  /* call user's callback */
1595  if (0u != hDevice->pfCallback) {
1596  hDevice->pfCallback(hDevice->pCBParam, ADI_CRYPTO_EVENT_STATUS_INPUT_OVERFLOW, (void *)status);
1597  }
1598 
1599  /* stop */
1600  StopCompute(hDevice);
1601 
1602  /* post the semaphore */
1603  SEM_POST(hDevice);
1604 
1605  return;
1606  }
1607 
1608  /* pull outputs (updates completion flag) */
1609  readPioOutputData(hDevice, status);
1610 
1611  if (false == hDevice->bCompletion) {
1612 
1613  /* push more inputs, but not in SHA DMA mode (except for when it's perfectly aligned block) */
1614  if ((pCompute->eCipherMode != ADI_CRYPTO_MODE_SHA) || (hDevice->bDmaEnabled == false) || (pCompute->numInputBytesRemaining == 0u))
1615  {
1616  writePioInputData(hDevice, status);
1617  }
1618 
1619  } else {
1620 
1621  /* we're done */
1622 
1623  /* dispatch to user callback if we have one */
1624  if (0u != hDevice->pfCallback) {
1625 
1626  /* check for overflow first */
1627  if (0u != (BITM_CRYPT_STAT_INOVR & status)) {
1629  } else {
1630  /* completion message depends on mode */
1631  switch (hDevice->Computation.eCipherMode) {
1632 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1)
1634 #endif
1635 #if (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1)
1637 #endif
1638 #if (ADI_CRYPTO_ENABLE_CMAC_SUPPORT == 1)
1640 #endif
1641 #if (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1)
1643 #endif
1644 #if (ADI_CRYPTO_ENABLE_ECB_SUPPORT == 1)
1646 #endif
1647 #if defined (__ADUCM4x50__) /* HMAC support is provided only in ADuCM4x50*/
1648 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1650 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
1651 #endif /* defined (__ADUCM4x50__) */
1652 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
1654 #endif
1655  default: event = ADI_CRYPTO_EVENT_STATUS_UNKNOWN; break;
1656  }
1657  }
1658 
1659  /* call user's callback and give back buffer pointer */
1660  hDevice->pfCallback(hDevice->pCBParam, event, (void*)hDevice->pUserBuffer);
1661 
1662  /* clear private copy of user buffer pointer */
1663  /* (this is done in GetBuffer in non-Callback mode) */
1664  hDevice->pUserBuffer = NULL;
1665  }
1666 
1667  /* disable interrupts */
1668  hDevice->pDev->INTEN = 0u;
1669 
1670  /* post the semaphore */
1671  SEM_POST(hDevice);
1672  }
1673 
1674  ISR_EPILOG();
1675 }
1676 
1677 
1678 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
1679 /* native DMA input interrupt handler */
1680 void DMA_AES0_IN_Int_Handler (void)
1681 {
1682  ISR_PROLOG();
1683 
1684  ADI_CRYPTO_HANDLE hDevice = CryptoDevInfo[0].hDevice;
1685  CRYPTO_COMPUTE *pCompute = &hDevice->Computation;
1686 
1687 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
1688  if (ADI_CRYPTO_MODE_SHA == pCompute->eCipherMode) {
1689 
1690  /* Update the compute structure to reflect the "post DMA" state of the transaction */
1691  uint32_t numTotalBytes = pCompute->numInputBytesRemaining;
1692  uint32_t num32BitWords = (numTotalBytes - (numTotalBytes % sizeof(uint32_t))) / sizeof(uint32_t) - 1u;
1693  if (pCompute->numInputBytesRemaining > MAX_CRYPTO_DMA_BYTES) {
1694  numTotalBytes = MAX_CRYPTO_DMA_BYTES;
1695  num32BitWords = MAX_CRYPTO_DMA_BYTES / sizeof(uint32_t);
1696  }
1697  pCompute->numInputBytesRemaining -= num32BitWords*4u;
1698  pCompute->numShaBitsRemaining -= num32BitWords*32u;
1699  pCompute->pNextInput += num32BitWords;
1700 
1701  if (8u < pCompute->numInputBytesRemaining) {
1702 
1703  /* More DMA transfers required */
1704  CLR_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1705  programDMA(hDevice);
1706  SET_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1707 
1708  }else {
1709 
1710  if ((numTotalBytes % SHA_CHUNK_MAX_BYTES) == 0u)
1711  {
1712  /* For perfect block sizes, need to write the last word WITHOUT triggering SHA_LAST_WORD */
1713  hDevice->pDev->INBUF = *pCompute->pNextInput;
1714 
1715  pCompute->numInputBytesRemaining = 0u;
1716  pCompute->numShaBitsRemaining = 0u;
1717  }
1718  else
1719  {
1720  /* Go ahead and write the remaining word, and it's okay to trigger SHA_LAST_WORD */
1721  writePioInputData(hDevice, hDevice->pDev->STAT);
1722  }
1723 
1724  }
1725  }
1726 #endif
1727 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1728  if (ADI_CRYPTO_MODE_HMAC == pCompute->eCipherMode) {
1729 
1730  /* Update the compute structure to reflect the "post DMA" state of the transaction */
1731  uint32_t numTotalBytes = pCompute->numInputBytesRemaining;
1732  uint32_t num32BitWords = numTotalBytes / FIFO_WIDTH_IN_BYTES;
1733  if (pCompute->numInputBytesRemaining > MAX_CRYPTO_DMA_BYTES) {
1734  numTotalBytes = MAX_CRYPTO_DMA_BYTES;
1735  num32BitWords = numTotalBytes / FIFO_WIDTH_IN_BYTES;
1736  }
1737  pCompute->numInputBytesRemaining -= num32BitWords * FIFO_WIDTH_IN_BYTES;
1738  pCompute->numShaBitsRemaining -= num32BitWords * FIFO_WIDTH_IN_BITS;
1739  pCompute->pNextInput += num32BitWords;
1740 
1741  if (4u < pCompute->numInputBytesRemaining) {
1742 
1743  /* More DMA transfers required */
1744  CLR_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1745  programDMA(hDevice);
1746  SET_BITS(hDevice->pDev->CFG, (BITM_CRYPT_CFG_INDMAEN));
1747  }else {
1748  /* Go ahead and write the remaining word, and it's okay to trigger SHA_LAST_WORD */
1749  writePioInputData(hDevice, hDevice->pDev->STAT);
1750  }
1751  }
1752 #endif
1753 
1754 
1755  /* defer post to output interrupt... */
1756 
1757  ISR_EPILOG();
1758 }
1759 #endif /* ADI_CRYPTO_ENABLE_DMA_SUPPORT */
1760 
1761 
1762 #if (ADI_CRYPTO_ENABLE_DMA_SUPPORT == 1)
1763 /* native DMA output interrupt handler */
1764 void DMA_AES0_OUT_Int_Handler (void)
1765 {
1766  ISR_PROLOG();
1767  ADI_CRYPTO_HANDLE hDevice = CryptoDevInfo[0].hDevice;
1768  uint32_t status = hDevice->pDev->STAT;
1769  uint32_t event;
1770 
1771  /* by the time we get here, everything should be complete */
1772 
1773  /* dispatch to user callback if we have one */
1774  if (0u != hDevice->pfCallback) {
1775 
1776  /* check for overflow first */
1777  if (0u != (BITM_CRYPT_STAT_INOVR & status)) {
1779  } else {
1780  /* completion message depends on mode */
1781  switch (hDevice->Computation.eCipherMode) {
1782 #if (ADI_CRYPTO_ENABLE_CBC_SUPPORT == 1)
1784 #endif
1785 #if (ADI_CRYPTO_ENABLE_CCM_SUPPORT == 1)
1787 #endif
1788 #if (ADI_CRYPTO_ENABLE_CMAC_SUPPORT == 1)
1790 #endif
1791 #if (ADI_CRYPTO_ENABLE_CTR_SUPPORT == 1)
1793 #endif
1794 #if (ADI_CRYPTO_ENABLE_ECB_SUPPORT == 1)
1796 #endif
1797 #if defined (__ADUCM4x50__)
1798 #if (ADI_CRYPTO_ENABLE_HMAC_SUPPORT == 1)
1800 #endif /* ADI_CRYPTO_ENABLE_HMAC_SUPPORT */
1801 #endif /* defined (__ADUCM4x50__) */
1802 #if (ADI_CRYPTO_ENABLE_SHA_SUPPORT == 1)
1804 #endif
1805  default: event = ADI_CRYPTO_EVENT_STATUS_UNKNOWN; break;
1806  }
1807  }
1808 
1809  /* call user's callback and give back buffer pointer */
1810  hDevice->pfCallback(hDevice->pCBParam, event, (void*)hDevice->pUserBuffer);
1811 
1812  /* clear private copy of user buffer pointer */
1813  /* this is done in GetBuffer in non-Callback mode */
1814  hDevice->pUserBuffer = NULL;
1815  }
1816 
1817  /* mark completion */
1818  hDevice->bCompletion = true;
1819 
1820  /* clear status */
1821  hDevice->pDev->STAT = status;
1822 
1823  /* post the semaphore */
1824  SEM_POST(hDevice);
1825 
1826  ISR_EPILOG();
1827 }
1828 #endif /* ADI_CRYPTO_ENABLE_DMA_SUPPORT */
1829 
ADI_DMA_RESULT adi_dma_RegisterCallback(DMA_CHANn_TypeDef const eChannelID, ADI_CALLBACK const pfCallback, void *const pCBParam)
Register a call-back function for a DMA channel.
Definition: adi_dma.c:232
ADI_CRYPTO_AES_BYTE_SWAP eAesByteSwap
Definition: adi_crypto.h:216
ADI_CRYPTO_CODING_MODE eCodingMode
Definition: adi_crypto.h:211
__IO uint32_t DMASRCEND
Definition: adi_dma.h:176
ADI_CRYPTO_AES_KEY_LEN
Definition: adi_crypto.h:128
ADI_CRYPTO_RESULT adi_crypto_GetBuffer(ADI_CRYPTO_HANDLE const hDevice, ADI_CRYPTO_TRANSACTION **const ppBuffer)
Get the submitted transaction buffer back from the driver.
Definition: adi_crypto.c:643
ADI_CRYPTO_AES_KEY_LEN eAesKeyLen
Definition: adi_crypto.h:219
ADI_CRYPTO_RESULT adi_crypto_RegisterCallback(ADI_CRYPTO_HANDLE const hDevice, ADI_CALLBACK const pfCallback, void *const pCBParam)
Register a user callback function.
Definition: adi_crypto.c:532
ADI_CRYPTO_RESULT adi_crypto_Enable(ADI_CRYPTO_HANDLE const hDevice, bool const bEnable)
Enable/Disable the device. Enabling the device causes the submitted buffer to be processed.
Definition: adi_crypto.c:736
#define ADI_CRYPTO_MEMORY_SIZE
Definition: adi_crypto.h:100
uint32_t * pOutputData
Definition: adi_crypto.h:229
ADI_CRYPTO_RESULT adi_crypto_Open(uint32_t const nDeviceNum, void *const pMemory, uint32_t const nMemorySize, ADI_CRYPTO_HANDLE *const phDevice)
Opens a Crypto device instance.
Definition: adi_crypto.c:395
ADI_CRYPTO_RESULT
Definition: adi_crypto.h:38
__IO uint32_t DMADSTEND
Definition: adi_dma.h:177
__IO uint32_t DMACDC
Definition: adi_dma.h:178
ADI_CRYPTO_RESULT adi_crypto_SubmitBuffer(ADI_CRYPTO_HANDLE const hDevice, ADI_CRYPTO_TRANSACTION *const pBuffer)
Submit a Crypto transaction buffer for processing.
Definition: adi_crypto.c:585
void adi_dma_Init(void)
Initialize the DMA peripheral.
Definition: adi_dma.c:155
struct __ADI_CRYPTO_DEV_DATA_TYPE * ADI_CRYPTO_HANDLE
Definition: adi_crypto.h:109
ADI_CRYPTO_RESULT adi_crypto_IsBufferAvailable(ADI_CRYPTO_HANDLE const hDevice, bool *const pbAvailable)
Peek function to know whether a submitted transaction is complete.
Definition: adi_crypto.c:697
ADI_CRYPTO_RESULT adi_crypto_Close(ADI_CRYPTO_HANDLE const hDevice)
Close the given device instance.
Definition: adi_crypto.c:480
ADI_CRYPTO_CIPHER_MODE eCipherMode
Definition: adi_crypto.h:210