CC26xx Driver Library
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
crypto.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: crypto.c
3 * Revised: 2015-01-13 16:59:55 +0100 (ti, 13 jan 2015)
4 * Revision: 42365
5 *
6 * Description: Driver for the Crypto module
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38 
39 #include <driverlib/crypto.h>
40 
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #ifndef DRIVERLIB_GENERATE_ROM
48  #undef CRYPTOAesLoadKey
49  #define CRYPTOAesLoadKey NOROM_CRYPTOAesLoadKey
50  #undef CRYPTOAesEcb
51  #define CRYPTOAesEcb NOROM_CRYPTOAesEcb
52  #undef CRYPTOAesEcbStatus
53  #define CRYPTOAesEcbStatus NOROM_CRYPTOAesEcbStatus
54  #undef CRYPTOCcmAuthEncrypt
55  #define CRYPTOCcmAuthEncrypt NOROM_CRYPTOCcmAuthEncrypt
56  #undef CRYPTOCcmAuthEncryptStatus
57  #define CRYPTOCcmAuthEncryptStatus NOROM_CRYPTOCcmAuthEncryptStatus
58  #undef CRYPTOCcmAuthEncryptResultGet
59  #define CRYPTOCcmAuthEncryptResultGet NOROM_CRYPTOCcmAuthEncryptResultGet
60  #undef CRYPTOCcmInvAuthDecrypt
61  #define CRYPTOCcmInvAuthDecrypt NOROM_CRYPTOCcmInvAuthDecrypt
62  #undef CRYPTOCcmInvAuthDecryptStatus
63  #define CRYPTOCcmInvAuthDecryptStatus NOROM_CRYPTOCcmInvAuthDecryptStatus
64  #undef CRYPTOCcmInvAuthDecryptResultGet
65  #define CRYPTOCcmInvAuthDecryptResultGet NOROM_CRYPTOCcmInvAuthDecryptResultGet
66  #undef CRYPTODmaEnable
67  #define CRYPTODmaEnable NOROM_CRYPTODmaEnable
68  #undef CRYPTODmaDisable
69  #define CRYPTODmaDisable NOROM_CRYPTODmaDisable
70 #endif
71 
72 //*****************************************************************************
73 //
74 // Current AES operation initialized to None
75 //
76 //*****************************************************************************
77 volatile uint32_t g_ui32CurrentAesOp = CRYPTO_AES_NONE;
78 
79 //*****************************************************************************
80 //
82 //
83 //*****************************************************************************
84 uint32_t
85 CRYPTOAesLoadKey(uint32_t *pui32AesKey,
86  uint32_t ui32KeyLocation)
87 {
88  //
89  // Check the arguments.
90  //
91  ASSERT((ui32KeyLocation == CRYPTO_KEY_AREA_0) |
92  (ui32KeyLocation == CRYPTO_KEY_AREA_1) |
93  (ui32KeyLocation == CRYPTO_KEY_AREA_2) |
94  (ui32KeyLocation == CRYPTO_KEY_AREA_3) |
95  (ui32KeyLocation == CRYPTO_KEY_AREA_4) |
96  (ui32KeyLocation == CRYPTO_KEY_AREA_5) |
97  (ui32KeyLocation == CRYPTO_KEY_AREA_6) |
98  (ui32KeyLocation == CRYPTO_KEY_AREA_7));
99 
100  //
101  // Set current operating state of the Crypto module.
102  //
104 
105  //
106  // Disable the external interrupt to stop the interrupt form propagating
107  // from the module to the CM3.
108  //
109  IntDisable(INT_CRYPTO);
110 
111  //
112  // Enable internal interrupts.
113  //
117 
118  //
119  // Configure master control module.
120  //
123 
124  //
125  // Clear any outstanding events.
126  //
129 
130  //
131  // Configure key store module for 128 bit operation.
132  //
135 
136  //
137  // Enable keys to write (e.g. Key 0).
138  //
139  HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = (0x00000001 << ui32KeyLocation);
140 
141  //
142  // Enable Crypto DMA channel 0.
143  //
145 
146  //
147  // Base address of the key in ext. memory.
148  //
149  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32AesKey;
150 
151  //
152  // Total key length in bytes (e.g. 16 for 1 x 128-bit key).
153  // Writing the length of the key enables the DMA operation.
154  //
156 
157  //
158  // Wait for the DMA operation to complete.
159  //
160  do
161  {
162  CPUdelay(1);
163  }
164  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & 0x00000001));
165 
166  //
167  // Check for errors in DMA and key store.
168  //
169  if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) &
172  {
173  //
174  // Acknowledge/clear the interrupt and disable the master control.
175  //
178  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
179 
180  //
181  // Check status, if error return error code.
182  //
183  if(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) != (0x00000001 << ui32KeyLocation))
184  {
186  return (AES_KEYSTORE_READ_ERROR);
187  }
188  }
189 
190  //
191  // Return success.
192  //
194  return (AES_SUCCESS);
195 }
196 
197 //*****************************************************************************
198 //
200 //
201 //*****************************************************************************
202 uint32_t
203 CRYPTOAesEcb(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut,
204  uint32_t ui32KeyLocation, bool bEncrypt,
205  bool bIntEnable)
206 {
207  //
208  // Set current operating state of the Crypto module.
209  //
211 
212  //
213  // Enable internal interrupts.
214  //
217 
218  //
219  // Clear any outstanding interrupts.
220  //
223 
224  //
225  // If using interrupts clear any pending interrupts and enable interrupts
226  // for the Crypto module.
227  //
228  if(bIntEnable)
229  {
230  IntPendClear(INT_CRYPTO);
231  IntEnable(INT_CRYPTO);
232  }
233 
234  //
235  // Configure Master Control module.
236  //
238 
239  //
240  //
241  //
242  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
243 
244  //
245  //Wait until key is loaded to the AES module.
246  //
247  do
248  {
249  CPUdelay(1);
250  }
252 
253  //
254  // Check for Key store Read error.
255  //
257  {
258  return (AES_KEYSTORE_READ_ERROR);
259  }
260 
261  //
262  // Configure AES engine (program AES-ECB-128 encryption and no
263  // initialization vector - IV).
264  //
265  if(bEncrypt)
266  {
268  }
269  else
270  {
272  }
273 
274  //
275  // Write the length of the data.
276  //
278  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
279 
280  //
281  // Enable Crypto DMA channel 0.
282  //
284 
285  //
286  // Base address of the input data in ext. memory.
287  //
288  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn;
289 
290  //
291  // Input data length in bytes, equal to the message.
292  //
294 
295  //
296  // Enable Crypto DMA channel 1.
297  //
299 
300  //
301  // Setup the address and length of the output data.
302  //
303  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut;
305 
306  //
307  // Return success
308  //
309  return AES_SUCCESS;
310 }
311 
312 //*****************************************************************************
313 //
315 //
316 //*****************************************************************************
317 uint32_t
319 {
320  uint32_t ui32Status;
321 
322  //
323  // Get the current DMA status.
324  //
325  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
326 
327  //
328  // Check if DMA is still busy.
329  //
330  if(ui32Status & CRYPTO_DMA_BSY)
331  {
332  return (AES_DMA_BSY);
333  }
334 
335  //
336  // Check the status of the DMA operation - return error if not success.
337  //
338  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
339  {
341  return (AES_DMA_BUS_ERROR);
342  }
343 
344  //
345  // Operation successfull - disable interrupt and return success.
346  //
348  IntDisable(INT_CRYPTO);
349  return (AES_SUCCESS);
350 }
351 
352 //*****************************************************************************
353 //
355 //
356 //*****************************************************************************
357 uint32_t
358 CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength ,
359  uint32_t *pui32Nonce, uint32_t *pui32PlainText,
360  uint32_t ui32PlainTextLength, uint32_t *pui32Header,
361  uint32_t ui32HeaderLength, uint32_t ui32KeyLocation,
362  uint32_t ui32FieldLength, bool bIntEnable)
363 {
364  uint8_t ui8InitVec[16];
365  uint32_t ui32CtrlVal;
366  uint32_t i;
367  uint32_t *pui32CipherText;
368 
369  //
370  // Input address for the encryption engine is the same as the output.
371  //
372  pui32CipherText = pui32PlainText;
373 
374  //
375  // Set current operating state of the Crypto module.
376  //
378 
379  //
380  // Disable global interrupt, enable local interrupt and clear any pending
381  // interrupts.
382  //
383  IntDisable(INT_CRYPTO);
386 
387  //
388  // Enable internal interrupts.
389  //
393 
394  //
395  // Configure master control module for AES operation.
396  //
398 
399  //
400  // Enable keys to read (e.g. Key 0).
401  //
402  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
403 
404  //
405  // Wait until key is loaded to the AES module.
406  //
407  do
408  {
409  CPUdelay(1);
410  }
412 
413  //
414  // Check for Key store Read error.
415  //
417  {
418  return (AES_KEYSTORE_READ_ERROR);
419  }
420 
421  //
422  // Prepare the initialization vector (IV),
423  // Length of Nonce l(n) = 15 - ui32FieldLength.
424  //
425  ui8InitVec[0] = ui32FieldLength - 1;
426  for(i = 0; i < 12; i++)
427  {
428  ui8InitVec[i + 1] = ((uint8_t*)pui32Nonce)[i];
429  }
430  if(ui32FieldLength == 2)
431  {
432  ui8InitVec[13] = ((uint8_t*)pui32Nonce)[12];
433  }
434  else
435  {
436  ui8InitVec[13] = 0;
437  }
438  ui8InitVec[14] = 0;
439  ui8InitVec[15] = 0;
440 
441  //
442  // Write initialization vector.
443  //
444  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ((uint32_t *)&ui8InitVec)[0];
445  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ((uint32_t *)&ui8InitVec)[1];
446  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ((uint32_t *)&ui8InitVec)[2];
447  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ((uint32_t *)&ui8InitVec)[3];
448 
449  //
450  // Configure AES engine.
451  //
452  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
453  ui32CtrlVal |= (((ui32AuthLength - 2) >> 1) << CRYPTO_AESCTL_CCM_M_S);
454  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
455  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
456  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
457  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
458  ui32CtrlVal |= (1 << CRYPTO_AESCTL_DIR_S);
459  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
460 
461  //
462  // Write the configuration for 128 bit AES-CCM.
463  //
464  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
465 
466  //
467  // Write the length of the crypto block (plain text).
468  // Low and high part (high part is assumed to be always 0).
469  //
470  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32PlainTextLength;
471  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
472 
473  //
474  // Write the length of the header field.
475  // Also called AAD - Additional Authentication Data.
476  //
477  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
478 
479  //
480  // Check if any header information (AAD).
481  // If so configure the DMA controller to fetch the header.
482  //
483  if(ui32HeaderLength != 0)
484  {
485  //
486  // Enable DMA channel 0.
487  //
489 
490  //
491  // Register the base address of the header (AAD).
492  //
493  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
494 
495  //
496  // Header length in bytes (may be non-block size aligned).
497  //
498  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
499 
500  //
501  // Wait for completion of the header data transfer, DMA_IN_DONE.
502  //
503  do
504  {
505  CPUdelay(1);
506  }
507  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
508 
509  //
510  // Check for DMA errors.
511  //
513  {
514  return AES_DMA_BUS_ERROR;
515  }
516  }
517 
518  //
519  // Clear interrupt status.
520  //
523 
524  //
525  // Is using interrupts enable globally.
526  //
527  if(bIntEnable)
528  {
529  IntPendClear(INT_CRYPTO);
530  IntEnable(INT_CRYPTO);
531  }
532 
533  //
534  // Enable interrupts locally.
535  //
537 
538  //
539  // Perform encryption if requested.
540  //
541  if(bEncrypt)
542  {
543  //
544  // Configure the DMA controller - enable both DMA channels.
545  //
548 
549  //
550  // base address of the payload data in ext. memory.
551  //
553  (uint32_t)pui32PlainText;
554 
555  //
556  // Payload data length in bytes, equal to the plaintext length.
557  //
558  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32PlainTextLength;
559 
560  //
561  // Enable DMA channel 1
562  //
564 
565  //
566  // Base address of the output data buffer.
567  //
569  (uint32_t)pui32CipherText;
570 
571  //
572  // Output data length in bytes, equal to the plaintext length.
573  //
574  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32PlainTextLength;
575  }
576 
577  return AES_SUCCESS;
578 }
579 
580 //*****************************************************************************
581 //
583 //
584 //*****************************************************************************
585 uint32_t
587 {
588  uint32_t ui32Status;
589 
590  //
591  // Get the current DMA status.
592  //
593  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
594 
595  //
596  // Check if DMA is still busy.
597  //
598  if(ui32Status & CRYPTO_DMA_BSY)
599  {
600  return (AES_DMA_BSY);
601  }
602 
603  //
604  // Check the status of the DMA operation - return error if not success.
605  //
606  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
607  {
609  return (AES_DMA_BUS_ERROR);
610  }
611 
612  //
613  // Operation successfull - disable interrupt and return success.
614  //
615  IntDisable(INT_CRYPTO);
616  return (AES_SUCCESS);
617 }
618 
619 //*****************************************************************************
620 //
622 //
623 //*****************************************************************************
624 uint32_t
625 CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
626 {
627  uint32_t volatile ui32Tag[4];
628  uint32_t ui32Idx;
629 
630  //
631  // Result has already been copied to the output buffer by DMA
632  // Disable master control.
633  //
634  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
635 
636  //
637  // Read tag - wait for the context ready bit.
638  //
639  do
640  {
641  CPUdelay(1);
642  }
643  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
645 
646  //
647  // Read the Tag registers.
648  //
649  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
650  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
651  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
652  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
653 
654  for(ui32Idx = 0; ui32Idx < ui32TagLength ; ui32Idx++)
655  {
656  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
657  }
658 
659  //
660  // Operation successfull - clear interrupt status.
661  //
665  return AES_SUCCESS;
666 }
667 
668 //*****************************************************************************
669 //
671 //
672 //*****************************************************************************
673 uint32_t
674 CRYPTOCcmInvAuthDecrypt(bool bDecrypt, uint32_t ui32AuthLength,
675  uint32_t *pui32Nonce, uint32_t *pui32CipherText,
676  uint32_t ui32CipherTextLength,
677  uint32_t *pui32Header, uint32_t ui32HeaderLength,
678  uint32_t ui32KeyLocation,
679  uint32_t ui32FieldLength, bool bIntEnable)
680 {
681  uint8_t ui8InitVec[16];
682  uint32_t ui32CtrlVal;
683  uint32_t i;
684  uint32_t *pui32PlainText;
685  uint32_t ui32CryptoBlockLength;
686 
687  //
688  // Input address for the encryption engine is the same as the output.
689  //
690  pui32PlainText = pui32CipherText;
691 
692  //
693  // Set current operating state of the Crypto module.
694  //
696 
697  //
698  // Disable global interrupt, enable local interrupt and clear any pending.
699  // interrupts.
700  //
701  IntDisable(INT_CRYPTO);
704  //
705  // Enable internal interrupts.
706  //
710 
711  //
712  // Configure master control module for AES operation.
713  //
715 
716  //
717  // Enable keys to read (e.g. Key 0).
718  //
719  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
720 
721  //
722  // Wait until key is loaded to the AES module.
723  //
724  do
725  {
726  CPUdelay(1);
727  }
729 
730  //
731  // Check for Key store Read error.
732  //
734  {
735  return (AES_KEYSTORE_READ_ERROR);
736  }
737 
738  //
739  // Prepare the initialization vector (IV),
740  // Length of Nonce l(n) = 15 - ui32FieldLength.
741  //
742  ui8InitVec[0] = ui32FieldLength - 1;
743  for(i = 0; i < 12; i++)
744  {
745  ui8InitVec[i + 1] = ((uint8_t*)pui32Nonce)[i];
746  }
747  if(ui32FieldLength == 2)
748  {
749  ui8InitVec[13] = ((uint8_t*)pui32Nonce)[12];
750  }
751  else
752  {
753  ui8InitVec[13] = 0;
754  }
755  ui8InitVec[14] = 0;
756  ui8InitVec[15] = 0;
757 
758  //
759  // Write initialization vector.
760  //
761  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ((uint32_t *)&ui8InitVec)[0];
762  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ((uint32_t *)&ui8InitVec)[1];
763  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ((uint32_t *)&ui8InitVec)[2];
764  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ((uint32_t *)&ui8InitVec)[3];
765 
766  //
767  // Configure AES engine
768  //
769  ui32CryptoBlockLength = ui32CipherTextLength - ui32AuthLength;
770  ui32AuthLength = ui32AuthLength < 2 ? 0 : ((ui32AuthLength - 2) >> 1);
771  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
772  ui32CtrlVal |= (ui32AuthLength << CRYPTO_AESCTL_CCM_M_S);
773  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
774  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
775  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
776  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
777  ui32CtrlVal |= (0 << CRYPTO_AESCTL_DIR_S);
778  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
779 
780  //
781  // Write the configuration for 128 bit AES-CCM.
782  //
783  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
784 
785  //
786  // Write the length of the crypto block (plain text).
787  // Low and high part (high part is assumed to be always 0).
788  //
789  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32CryptoBlockLength;
790  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
791 
792  //
793  // Write the length of the header field.
794  // Also called AAD - Additional Authentication Data.
795  //
796  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
797 
798  //
799  // Check if any header information (AAD).
800  // If so configure the DMA controller to fetch the header.
801  //
802  if(ui32HeaderLength != 0)
803  {
804  //
805  // Enable DMA channel 0.
806  //
808 
809  //
810  // Register the base address of the header (AAD).
811  //
812  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
813 
814  //
815  // Header length in bytes (may be non-block size aligned).
816  //
817  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
818 
819  //
820  // Wait for completion of the header data transfer, DMA_IN_DONE.
821  //
822  do
823  {
824  CPUdelay(1);
825  }
826  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
827 
828  //
829  // Check for DMA errors.
830  //
832  {
833  return AES_DMA_BUS_ERROR;
834  }
835  }
836 
837  //
838  // Clear interrupt status.
839  //
842 
843  //
844  // Is using interrupts - clear and enable globally.
845  //
846  if(bIntEnable)
847  {
848  IntPendClear(INT_CRYPTO);
849  IntEnable(INT_CRYPTO);
850  }
851 
852  //
853  // Enable internal interrupts.
854  //
857 
858  //
859  // Perform decryption if requested.
860  //
861  if(bDecrypt)
862  {
863  //
864  // Configure the DMA controller - enable both DMA channels.
865  //
867 
868  //
869  // Base address of the payload data in ext. memory.
870  //
872  (uint32_t)pui32CipherText;
873 
874  //
875  // Payload data length in bytes, equal to the cipher text length.
876  //
877  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32CryptoBlockLength;
878 
879  //
880  // Enable DMA channel 1.
881  //
883 
884  //
885  // Base address of the output data buffer.
886  //
888  (uint32_t)pui32PlainText;
889 
890  //
891  // Output data length in bytes, equal to the cipher text length.
892  //
893  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32CryptoBlockLength;
894  }
895 
896  return AES_SUCCESS;
897 }
898 
899 //*****************************************************************************
900 //
902 //
903 //*****************************************************************************
904 uint32_t
906 {
907  uint32_t ui32Status;
908 
909  //
910  // Get the current DMA status.
911  //
912  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
913 
914  //
915  // Check if DMA is still busy.
916  //
917  if(ui32Status & CRYPTO_DMA_BSY)
918  {
919  return (AES_DMA_BSY);
920  }
921 
922  //
923  // Check the status of the DMA operation - return error if not success.
924  //
925  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
926  {
928  return (AES_DMA_BUS_ERROR);
929  }
930 
931  //
932  // Operation successfull - disable interrupt and return success
933  //
934  IntDisable(INT_CRYPTO);
935  return (AES_SUCCESS);
936 }
937 
938 //*****************************************************************************
939 //
941 //
942 //*****************************************************************************
943 uint32_t
944 CRYPTOCcmInvAuthDecryptResultGet(uint32_t ui32AuthLength,
945  uint32_t *pui32CipherText,
946  uint32_t ui32CipherTextLength,
947  uint32_t *pui32CcmTag)
948 {
949  uint32_t volatile ui32Tag[4];
950  uint32_t ui32TagIndex;
951  uint32_t i;
952  uint32_t ui32Idx;
953 
954  ui32TagIndex = ui32CipherTextLength - ui32AuthLength;
955 
956  //
957  // Result has already been copied to the output buffer by DMA
958  // Disable master control.
959  //
960  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
961 
962  //
963  // Read tag - wait for the context ready bit.
964  //
965  do
966  {
967  CPUdelay(1);
968  }
969  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
971 
972  //
973  // Read the Tag registers.
974  //
975  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
976  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
977  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
978  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
979 
980  for(ui32Idx = 0; ui32Idx < ui32AuthLength ; ui32Idx++)
981  {
982  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
983  }
984 
985  //
986  // Operation successfull - clear interrupt status.
987  //
990 
991  //
992  // Verify the Tag.
993  //
994  for(i = 0; i < ui32AuthLength; i++)
995  {
996  if(*((uint8_t *)pui32CcmTag + i) !=
997  (*((uint8_t *)pui32CipherText + ui32TagIndex + i)))
998  {
1000  }
1001  }
1002 
1004  return AES_SUCCESS;
1005 }
1006 
1007 //*****************************************************************************
1008 //
1010 //
1011 //*****************************************************************************
1012 void
1013 CRYPTODmaEnable(uint32_t ui32Channels)
1014 {
1015  //
1016  // Check the arguments.
1017  //
1018  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1019  (ui32Channels & CRYPTO_DMA_CHAN1));
1020 
1021  //
1022  // Enable the selected channels,
1023  //
1024  if(ui32Channels & CRYPTO_DMA_CHAN0)
1025  {
1027  }
1028  if(ui32Channels & CRYPTO_DMA_CHAN1)
1029  {
1031  }
1032 }
1033 
1034 //*****************************************************************************
1035 //
1037 //
1038 //*****************************************************************************
1039 void
1040 CRYPTODmaDisable(uint32_t ui32Channels)
1041 {
1042  //
1043  // Check the arguments.
1044  //
1045  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1046  (ui32Channels & CRYPTO_DMA_CHAN1));
1047 
1048  //
1049  // Enable the selected channels.
1050  //
1051  if(ui32Channels & CRYPTO_DMA_CHAN0)
1052  {
1054  }
1055  if(ui32Channels & CRYPTO_DMA_CHAN1)
1056  {
1058  }
1059 }
#define CRYPTO_AES_CCM
Definition: crypto.h:182
uint32_t CRYPTOCcmAuthEncryptStatus(void)
Check the result of an AES CCM operation.
Definition: crypto.c:586
#define CRYPTO_RESULT_RDY
Definition: crypto.h:113
#define CRYPTO_AES_KEYL0AD
Definition: crypto.h:180
#define CRYPTO_KEY_AREA_3
Definition: crypto.h:168
#define AES_DMA_BSY
Definition: crypto.h:146
#define CRYPTO_KEY_AREA_1
Definition: crypto.h:166
#define CRYPTO_DMA_CHAN1
Definition: crypto.h:122
#define AES_KEYSTORE_READ_ERROR
Definition: crypto.h:139
#define CRYPTO_KEY_AREA_2
Definition: crypto.h:167
#define CRYPTO_DMA_BUS_ERROR
Definition: crypto.h:129
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:539
#define CRYPTO_DMA_CHAN0
Definition: crypto.h:121
#define CRYPTO_AES_CTR_128
Definition: crypto.h:193
uint32_t CRYPTOCcmInvAuthDecrypt(bool bDecrypt, uint32_t ui32AuthLength, uint32_t *pui32Nonce, uint32_t *pui32CipherText, uint32_t ui32CipherTextLength, uint32_t *pui32Header, uint32_t ui32HeaderLength, uint32_t ui32KeyLocation, uint32_t ui32FieldLength, bool bIntEnable)
Start a CCM Decryption and Inverse Authentication operation.
Definition: crypto.c:674
#define ASSERT(expr)
Definition: debug.h:65
uint32_t CRYPTOAesLoadKey(uint32_t *pui32AesKey, uint32_t ui32KeyLocation)
Write the key into the Key Ram.
Definition: crypto.c:85
uint32_t CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
Get the result of an AES-CCM operation.
Definition: crypto.c:625
#define CRYPTO_DMA_IN_DONE
Definition: crypto.h:112
volatile uint32_t g_ui32CurrentAesOp
Definition: crypto.c:77
#define CRYPTO_AES_NONE
Definition: crypto.h:179
#define KEY_STORE_SIZE_128
Definition: crypto.h:153
#define CRYPTO_AES128_ENCRYPT
Definition: crypto.h:124
#define CRYPTO_DMA_BUS_ERR
Definition: crypto.h:114
uint32_t CRYPTOCcmInvAuthDecryptStatus(void)
Checks CCM decrypt and Inverse Authentication result.
Definition: crypto.c:905
#define CRYPTO_AES_ECB
Definition: crypto.h:181
#define CRYPTO_KEY_AREA_7
Definition: crypto.h:172
#define CRYPTO_KEY_AREA_0
Definition: crypto.h:165
#define CRYPTO_KEY_AREA_5
Definition: crypto.h:170
#define CRYPTO_INT_LEVEL
Definition: crypto.h:118
#define CRYPTO_AES128_DECRYPT
Definition: crypto.h:125
#define CRYPTO_KEY_AREA_4
Definition: crypto.h:169
uint32_t CRYPTOCcmInvAuthDecryptResultGet(uint32_t ui32AuthLength, uint32_t *pui32CipherText, uint32_t ui32CipherTextLength, uint32_t *pui32CcmTag)
Get the result of the CCM operation.
Definition: crypto.c:944
uint32_t CRYPTOAesEcbStatus(void)
Check the result of an AES ECB operation.
Definition: crypto.c:318
#define CCM_AUTHENTICATION_FAILED
Definition: crypto.h:142
#define AES_DMA_BUS_ERROR
Definition: crypto.h:141
#define KEY_BLENGTH
Definition: crypto.h:150
#define CRYPTO_DMA_BSY
Definition: crypto.h:128
void CRYPTODmaDisable(uint32_t ui32Channels)
Disable Crypto DMA operation.
Definition: crypto.c:1040
uint32_t CRYPTOAesEcb(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut, uint32_t ui32KeyLocation, bool bEncrypt, bool bIntEnable)
Start an AES-ECB operation (encryption or decryption).
Definition: crypto.c:203
void CRYPTODmaEnable(uint32_t ui32Channels)
Enable Crypto DMA operation.
Definition: crypto.c:1013
#define AES_ECB_LENGTH
Definition: crypto.h:104
#define AES_SUCCESS
Definition: crypto.h:138
void CPUdelay(uint32_t ui32Count)
Provide a small delay.
Definition: cpu.c:402
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt.
Definition: interrupt.c:383
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt.
Definition: interrupt.c:323
#define CRYPTO_KEY_AREA_6
Definition: crypto.h:171
uint32_t CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength, uint32_t *pui32Nonce, uint32_t *pui32PlainText, uint32_t ui32PlainTextLength, uint32_t *pui32Header, uint32_t ui32HeaderLength, uint32_t ui32KeyLocation, uint32_t ui32FieldLength, bool bIntEnable)
Start CCM operation.
Definition: crypto.c:358
#define CRYPTO_KEY_ST_RD_ERR
Definition: crypto.h:116