CC26xx Driver Library
crypto.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: crypto.c
3 * Revised: 2015-05-18 15:10:12 +0200 (Mon, 18 May 2015)
4 * Revision: 43519
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 #if !defined(DOXYGEN)
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 System CPU.
108  //
109  IntDisable(INT_CRYPTO);
110 
111  //
112  // Enable internal interrupts.
113  //
117 
118  //
119  // Configure master control module.
120  //
122 
123  //
124  // Clear any outstanding events.
125  //
128 
129  //
130  // Configure key store module for 128 bit operation.
131  //
134 
135  //
136  // Enable keys to write (e.g. Key 0).
137  //
138  HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = (0x00000001 << ui32KeyLocation);
139 
140  //
141  // Enable Crypto DMA channel 0.
142  //
144 
145  //
146  // Base address of the key in ext. memory.
147  //
148  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32AesKey;
149 
150  //
151  // Total key length in bytes (e.g. 16 for 1 x 128-bit key).
152  // Writing the length of the key enables the DMA operation.
153  //
155 
156  //
157  // Wait for the DMA operation to complete.
158  //
159  do
160  {
161  CPUdelay(1);
162  }
163  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & 0x00000001));
164 
165  //
166  // Check for errors in DMA and key store.
167  //
168  if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) &
171  {
172  //
173  // Acknowledge/clear the interrupt and disable the master control.
174  //
177  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
178 
179  //
180  // Check status, if error return error code.
181  //
182  if(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) != (0x00000001 << ui32KeyLocation))
183  {
185  return (AES_KEYSTORE_READ_ERROR);
186  }
187  }
188 
189  //
190  // Return success.
191  //
193  return (AES_SUCCESS);
194 }
195 
196 //*****************************************************************************
197 //
199 //
200 //*****************************************************************************
201 uint32_t
202 CRYPTOAesEcb(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut,
203  uint32_t ui32KeyLocation, bool bEncrypt,
204  bool bIntEnable)
205 {
206  //
207  // Set current operating state of the Crypto module.
208  //
210 
211  //
212  // Enable internal interrupts.
213  //
216 
217  //
218  // Clear any outstanding interrupts.
219  //
222 
223  //
224  // If using interrupts clear any pending interrupts and enable interrupts
225  // for the Crypto module.
226  //
227  if(bIntEnable)
228  {
229  IntPendClear(INT_CRYPTO);
230  IntEnable(INT_CRYPTO);
231  }
232 
233  //
234  // Configure Master Control module.
235  //
237 
238  //
239  //
240  //
241  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
242 
243  //
244  //Wait until key is loaded to the AES module.
245  //
246  do
247  {
248  CPUdelay(1);
249  }
251 
252  //
253  // Check for Key store Read error.
254  //
256  {
257  return (AES_KEYSTORE_READ_ERROR);
258  }
259 
260  //
261  // Configure AES engine (program AES-ECB-128 encryption and no
262  // initialization vector - IV).
263  //
264  if(bEncrypt)
265  {
267  }
268  else
269  {
271  }
272 
273  //
274  // Write the length of the data.
275  //
277  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
278 
279  //
280  // Enable Crypto DMA channel 0.
281  //
283 
284  //
285  // Base address of the input data in ext. memory.
286  //
287  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn;
288 
289  //
290  // Input data length in bytes, equal to the message.
291  //
293 
294  //
295  // Enable Crypto DMA channel 1.
296  //
298 
299  //
300  // Set up the address and length of the output data.
301  //
302  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut;
304 
305  //
306  // Return success
307  //
308  return AES_SUCCESS;
309 }
310 
311 //*****************************************************************************
312 //
314 //
315 //*****************************************************************************
316 uint32_t
318 {
319  uint32_t ui32Status;
320 
321  //
322  // Get the current DMA status.
323  //
324  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
325 
326  //
327  // Check if DMA is still busy.
328  //
329  if(ui32Status & CRYPTO_DMA_BSY)
330  {
331  return (AES_DMA_BSY);
332  }
333 
334  //
335  // Check the status of the DMA operation - return error if not success.
336  //
337  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
338  {
340  return (AES_DMA_BUS_ERROR);
341  }
342 
343  //
344  // Operation successful - disable interrupt and return success.
345  //
347  IntDisable(INT_CRYPTO);
348  return (AES_SUCCESS);
349 }
350 
351 //*****************************************************************************
352 //
354 //
355 //*****************************************************************************
356 uint32_t
357 CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength ,
358  uint32_t *pui32Nonce, uint32_t *pui32PlainText,
359  uint32_t ui32PlainTextLength, uint32_t *pui32Header,
360  uint32_t ui32HeaderLength, uint32_t ui32KeyLocation,
361  uint32_t ui32FieldLength, bool bIntEnable)
362 {
363  uint32_t ui32CtrlVal;
364  uint32_t i;
365  uint32_t *pui32CipherText;
366  union {
367  uint32_t w[4];
368  uint8_t b[16];
369  } ui8InitVec;
370 
371  //
372  // Input address for the encryption engine is the same as the output.
373  //
374  pui32CipherText = pui32PlainText;
375 
376  //
377  // Set current operating state of the Crypto module.
378  //
380 
381  //
382  // Disable global interrupt, enable local interrupt and clear any pending
383  // interrupts.
384  //
385  IntDisable(INT_CRYPTO);
388 
389  //
390  // Enable internal interrupts.
391  //
395 
396  //
397  // Configure master control module for AES operation.
398  //
400 
401  //
402  // Enable keys to read (e.g. Key 0).
403  //
404  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
405 
406  //
407  // Wait until key is loaded to the AES module.
408  //
409  do
410  {
411  CPUdelay(1);
412  }
414 
415  //
416  // Check for Key store Read error.
417  //
419  {
420  return (AES_KEYSTORE_READ_ERROR);
421  }
422 
423  //
424  // Prepare the initialization vector (IV),
425  // Length of Nonce l(n) = 15 - ui32FieldLength.
426  //
427  ui8InitVec.b[0] = ui32FieldLength - 1;
428  for(i = 0; i < 12; i++)
429  {
430  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
431  }
432  if(ui32FieldLength == 2)
433  {
434  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
435  }
436  else
437  {
438  ui8InitVec.b[13] = 0;
439  }
440  ui8InitVec.b[14] = 0;
441  ui8InitVec.b[15] = 0;
442 
443  //
444  // Write initialization vector.
445  //
446  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
447  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
448  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
449  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
450 
451  //
452  // Configure AES engine.
453  //
454  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
455  if ( ui32AuthLength >= 2 ) {
456  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
457  }
458  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
459  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
460  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
461  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
462  ui32CtrlVal |= (1 << CRYPTO_AESCTL_DIR_S);
463  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
464 
465  //
466  // Write the configuration for 128 bit AES-CCM.
467  //
468  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
469 
470  //
471  // Write the length of the crypto block (plain text).
472  // Low and high part (high part is assumed to be always 0).
473  //
474  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32PlainTextLength;
475  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
476 
477  //
478  // Write the length of the header field.
479  // Also called AAD - Additional Authentication Data.
480  //
481  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
482 
483  //
484  // Check if any header information (AAD).
485  // If so configure the DMA controller to fetch the header.
486  //
487  if(ui32HeaderLength != 0)
488  {
489  //
490  // Enable DMA channel 0.
491  //
493 
494  //
495  // Register the base address of the header (AAD).
496  //
497  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
498 
499  //
500  // Header length in bytes (may be non-block size aligned).
501  //
502  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
503 
504  //
505  // Wait for completion of the header data transfer, DMA_IN_DONE.
506  //
507  do
508  {
509  CPUdelay(1);
510  }
511  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
512 
513  //
514  // Check for DMA errors.
515  //
517  {
518  return AES_DMA_BUS_ERROR;
519  }
520  }
521 
522  //
523  // Clear interrupt status.
524  //
527 
528  //
529  // Is using interrupts enable globally.
530  //
531  if(bIntEnable)
532  {
533  IntPendClear(INT_CRYPTO);
534  IntEnable(INT_CRYPTO);
535  }
536 
537  //
538  // Enable interrupts locally.
539  //
541 
542  //
543  // Perform encryption if requested.
544  //
545  if(bEncrypt)
546  {
547  //
548  // Configure the DMA controller - enable both DMA channels.
549  //
552 
553  //
554  // base address of the payload data in ext. memory.
555  //
557  (uint32_t)pui32PlainText;
558 
559  //
560  // Payload data length in bytes, equal to the plaintext length.
561  //
562  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32PlainTextLength;
563 
564  //
565  // Enable DMA channel 1
566  //
567  HWREGBITW(CRYPTO_BASE + CRYPTO_O_DMACH1CTL, CRYPTO_DMACH1CTL_EN_BITN) = 1; // Redundant (see above)?
568 
569  //
570  // Base address of the output data buffer.
571  //
573  (uint32_t)pui32CipherText;
574 
575  //
576  // Output data length in bytes, equal to the plaintext length.
577  //
578  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32PlainTextLength;
579  }
580 
581  return AES_SUCCESS;
582 }
583 
584 //*****************************************************************************
585 //
587 //
588 //*****************************************************************************
589 uint32_t
591 {
592  uint32_t ui32Status;
593 
594  //
595  // Get the current DMA status.
596  //
597  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
598 
599  //
600  // Check if DMA is still busy.
601  //
602  if(ui32Status & CRYPTO_DMA_BSY)
603  {
604  return (AES_DMA_BSY);
605  }
606 
607  //
608  // Check the status of the DMA operation - return error if not success.
609  //
610  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
611  {
613  return (AES_DMA_BUS_ERROR);
614  }
615 
616  //
617  // Operation successful - disable interrupt and return success.
618  //
619  IntDisable(INT_CRYPTO);
620  return (AES_SUCCESS);
621 }
622 
623 //*****************************************************************************
624 //
626 //
627 //*****************************************************************************
628 uint32_t
629 CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
630 {
631  uint32_t volatile ui32Tag[4];
632  uint32_t ui32Idx;
633 
634  //
635  // Result has already been copied to the output buffer by DMA
636  // Disable master control.
637  //
638  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
639 
640  //
641  // Read tag - wait for the context ready bit.
642  //
643  do
644  {
645  CPUdelay(1);
646  }
647  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
649 
650  //
651  // Read the Tag registers.
652  //
653  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
654  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
655  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
656  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
657 
658  for(ui32Idx = 0; ui32Idx < ui32TagLength ; ui32Idx++)
659  {
660  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
661  }
662 
663  //
664  // Operation successful - clear interrupt status.
665  //
669  return AES_SUCCESS;
670 }
671 
672 //*****************************************************************************
673 //
675 //
676 //*****************************************************************************
677 uint32_t
678 CRYPTOCcmInvAuthDecrypt(bool bDecrypt, uint32_t ui32AuthLength,
679  uint32_t *pui32Nonce, uint32_t *pui32CipherText,
680  uint32_t ui32CipherTextLength,
681  uint32_t *pui32Header, uint32_t ui32HeaderLength,
682  uint32_t ui32KeyLocation,
683  uint32_t ui32FieldLength, bool bIntEnable)
684 {
685  uint32_t ui32CtrlVal;
686  uint32_t i;
687  uint32_t *pui32PlainText;
688  uint32_t ui32CryptoBlockLength;
689  union {
690  uint32_t w[4];
691  uint8_t b[16];
692  } ui8InitVec;
693 
694  //
695  // Input address for the encryption engine is the same as the output.
696  //
697  pui32PlainText = pui32CipherText;
698 
699  //
700  // Set current operating state of the Crypto module.
701  //
703 
704  //
705  // Disable global interrupt, enable local interrupt and clear any pending.
706  // interrupts.
707  //
708  IntDisable(INT_CRYPTO);
711  //
712  // Enable internal interrupts.
713  //
717 
718  //
719  // Configure master control module for AES operation.
720  //
722 
723  //
724  // Enable keys to read (e.g. Key 0).
725  //
726  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
727 
728  //
729  // Wait until key is loaded to the AES module.
730  //
731  do
732  {
733  CPUdelay(1);
734  }
736 
737  //
738  // Check for Key store Read error.
739  //
741  {
742  return (AES_KEYSTORE_READ_ERROR);
743  }
744 
745  //
746  // Prepare the initialization vector (IV),
747  // Length of Nonce l(n) = 15 - ui32FieldLength.
748  //
749  ui8InitVec.b[0] = ui32FieldLength - 1;
750  for(i = 0; i < 12; i++)
751  {
752  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
753  }
754  if(ui32FieldLength == 2)
755  {
756  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
757  }
758  else
759  {
760  ui8InitVec.b[13] = 0;
761  }
762  ui8InitVec.b[14] = 0;
763  ui8InitVec.b[15] = 0;
764 
765  //
766  // Write initialization vector.
767  //
768  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
769  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
770  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
771  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
772 
773  //
774  // Configure AES engine
775  //
776  ui32CryptoBlockLength = ui32CipherTextLength - ui32AuthLength;
777  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
778  if ( ui32AuthLength >= 2 ) {
779  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
780  }
781  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
782  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
783  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
784  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
785  ui32CtrlVal |= (0 << CRYPTO_AESCTL_DIR_S);
786  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
787 
788  //
789  // Write the configuration for 128 bit AES-CCM.
790  //
791  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
792 
793  //
794  // Write the length of the crypto block (plain text).
795  // Low and high part (high part is assumed to be always 0).
796  //
797  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32CryptoBlockLength;
798  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
799 
800  //
801  // Write the length of the header field.
802  // Also called AAD - Additional Authentication Data.
803  //
804  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
805 
806  //
807  // Check if any header information (AAD).
808  // If so configure the DMA controller to fetch the header.
809  //
810  if(ui32HeaderLength != 0)
811  {
812  //
813  // Enable DMA channel 0.
814  //
816 
817  //
818  // Register the base address of the header (AAD).
819  //
820  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
821 
822  //
823  // Header length in bytes (may be non-block size aligned).
824  //
825  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
826 
827  //
828  // Wait for completion of the header data transfer, DMA_IN_DONE.
829  //
830  do
831  {
832  CPUdelay(1);
833  }
834  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
835 
836  //
837  // Check for DMA errors.
838  //
840  {
841  return AES_DMA_BUS_ERROR;
842  }
843  }
844 
845  //
846  // Clear interrupt status.
847  //
850 
851  //
852  // Is using interrupts - clear and enable globally.
853  //
854  if(bIntEnable)
855  {
856  IntPendClear(INT_CRYPTO);
857  IntEnable(INT_CRYPTO);
858  }
859 
860  //
861  // Enable internal interrupts.
862  //
865 
866  //
867  // Perform decryption if requested.
868  //
869  if(bDecrypt)
870  {
871  //
872  // Configure the DMA controller - enable both DMA channels.
873  //
875 
876  //
877  // Base address of the payload data in ext. memory.
878  //
880  (uint32_t)pui32CipherText;
881 
882  //
883  // Payload data length in bytes, equal to the cipher text length.
884  //
885  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32CryptoBlockLength;
886 
887  //
888  // Enable DMA channel 1.
889  //
891 
892  //
893  // Base address of the output data buffer.
894  //
896  (uint32_t)pui32PlainText;
897 
898  //
899  // Output data length in bytes, equal to the cipher text length.
900  //
901  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32CryptoBlockLength;
902  }
903 
904  return AES_SUCCESS;
905 }
906 
907 //*****************************************************************************
908 //
910 //
911 //*****************************************************************************
912 uint32_t
914 {
915  uint32_t ui32Status;
916 
917  //
918  // Get the current DMA status.
919  //
920  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
921 
922  //
923  // Check if DMA is still busy.
924  //
925  if(ui32Status & CRYPTO_DMA_BSY)
926  {
927  return (AES_DMA_BSY);
928  }
929 
930  //
931  // Check the status of the DMA operation - return error if not success.
932  //
933  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
934  {
936  return (AES_DMA_BUS_ERROR);
937  }
938 
939  //
940  // Operation successful - disable interrupt and return success
941  //
942  IntDisable(INT_CRYPTO);
943  return (AES_SUCCESS);
944 }
945 
946 //*****************************************************************************
947 //
949 //
950 //*****************************************************************************
951 uint32_t
952 CRYPTOCcmInvAuthDecryptResultGet(uint32_t ui32AuthLength,
953  uint32_t *pui32CipherText,
954  uint32_t ui32CipherTextLength,
955  uint32_t *pui32CcmTag)
956 {
957  uint32_t volatile ui32Tag[4];
958  uint32_t ui32TagIndex;
959  uint32_t i;
960  uint32_t ui32Idx;
961 
962  ui32TagIndex = ui32CipherTextLength - ui32AuthLength;
963 
964  //
965  // Result has already been copied to the output buffer by DMA
966  // Disable master control.
967  //
968  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
969 
970  //
971  // Read tag - wait for the context ready bit.
972  //
973  do
974  {
975  CPUdelay(1);
976  }
977  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
979 
980  //
981  // Read the Tag registers.
982  //
983  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
984  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
985  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
986  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
987 
988  for(ui32Idx = 0; ui32Idx < ui32AuthLength ; ui32Idx++)
989  {
990  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
991  }
992 
993  //
994  // Operation successful - clear interrupt status.
995  //
998 
999  //
1000  // Verify the Tag.
1001  //
1002  for(i = 0; i < ui32AuthLength; i++)
1003  {
1004  if(*((uint8_t *)pui32CcmTag + i) !=
1005  (*((uint8_t *)pui32CipherText + ui32TagIndex + i)))
1006  {
1008  }
1009  }
1010 
1012  return AES_SUCCESS;
1013 }
1014 
1015 //*****************************************************************************
1016 //
1018 //
1019 //*****************************************************************************
1020 void
1021 CRYPTODmaEnable(uint32_t ui32Channels)
1022 {
1023  //
1024  // Check the arguments.
1025  //
1026  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1027  (ui32Channels & CRYPTO_DMA_CHAN1));
1028 
1029  //
1030  // Enable the selected channels,
1031  //
1032  if(ui32Channels & CRYPTO_DMA_CHAN0)
1033  {
1035  }
1036  if(ui32Channels & CRYPTO_DMA_CHAN1)
1037  {
1039  }
1040 }
1041 
1042 //*****************************************************************************
1043 //
1045 //
1046 //*****************************************************************************
1047 void
1048 CRYPTODmaDisable(uint32_t ui32Channels)
1049 {
1050  //
1051  // Check the arguments.
1052  //
1053  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1054  (ui32Channels & CRYPTO_DMA_CHAN1));
1055 
1056  //
1057  // Enable the selected channels.
1058  //
1059  if(ui32Channels & CRYPTO_DMA_CHAN0)
1060  {
1062  }
1063  if(ui32Channels & CRYPTO_DMA_CHAN1)
1064  {
1066  }
1067 }
#define CRYPTO_AES_CCM
Definition: crypto.h:182
uint32_t CRYPTOCcmAuthEncryptStatus(void)
Check the result of an AES CCM operation.
Definition: crypto.c:590
#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:537
#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:678
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:629
#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:913
#define CRYPTO_AES_ECB
Definition: crypto.h:181
#define ASSERT(expr)
Definition: debug.h:74
#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:952
uint32_t CRYPTOAesEcbStatus(void)
Check the result of an AES ECB operation.
Definition: crypto.c:317
#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:1048
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:202
void CRYPTODmaEnable(uint32_t ui32Channels)
Enable Crypto DMA operation.
Definition: crypto.c:1021
#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:372
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt.
Definition: interrupt.c:381
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt.
Definition: interrupt.c:321
#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:357
#define CRYPTO_KEY_ST_RD_ERR
Definition: crypto.h:116