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