CC26xx Driver Library
crypto.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: crypto.c
3 * Revised: 2016-04-07 15:04:05 +0200 (Thu, 07 Apr 2016)
4 * Revision: 46052
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_RESULT_AVAIL_IRQ);
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  // Wait for interrupt lines from module to be cleared
225  //
227 
228  //
229  // If using interrupts clear any pending interrupts and enable interrupts
230  // for the Crypto module.
231  //
232  if(bIntEnable)
233  {
234  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
235  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
236  }
237 
238  //
239  // Configure Master Control module.
240  //
242 
243  //
244  //
245  //
246  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
247 
248  //
249  //Wait until key is loaded to the AES module.
250  //
251  do
252  {
253  CPUdelay(1);
254  }
256 
257  //
258  // Check for Key store Read error.
259  //
261  {
262  return (AES_KEYSTORE_READ_ERROR);
263  }
264 
265  //
266  // Configure AES engine (program AES-ECB-128 encryption and no
267  // initialization vector - IV).
268  //
269  if(bEncrypt)
270  {
272  }
273  else
274  {
276  }
277 
278  //
279  // Write the length of the data.
280  //
282  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
283 
284  //
285  // Enable Crypto DMA channel 0.
286  //
288 
289  //
290  // Base address of the input data in ext. memory.
291  //
292  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn;
293 
294  //
295  // Input data length in bytes, equal to the message.
296  //
298 
299  //
300  // Enable Crypto DMA channel 1.
301  //
303 
304  //
305  // Set up the address and length of the output data.
306  //
307  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut;
309 
310  //
311  // Return success
312  //
313  return AES_SUCCESS;
314 }
315 
316 //*****************************************************************************
317 //
319 //
320 //*****************************************************************************
321 uint32_t
323 {
324  uint32_t ui32Status;
325 
326  //
327  // Get the current DMA status.
328  //
329  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
330 
331  //
332  // Check if DMA is still busy.
333  //
334  if(ui32Status & CRYPTO_DMA_BSY)
335  {
336  return (AES_DMA_BSY);
337  }
338 
339  //
340  // Check the status of the DMA operation - return error if not success.
341  //
342  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
343  {
345  return (AES_DMA_BUS_ERROR);
346  }
347 
348  //
349  // Operation successful - disable interrupt and return success.
350  //
352  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
353  return (AES_SUCCESS);
354 }
355 
356 //*****************************************************************************
357 //
359 //
360 //*****************************************************************************
361 uint32_t
362 CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength ,
363  uint32_t *pui32Nonce, uint32_t *pui32PlainText,
364  uint32_t ui32PlainTextLength, uint32_t *pui32Header,
365  uint32_t ui32HeaderLength, uint32_t ui32KeyLocation,
366  uint32_t ui32FieldLength, bool bIntEnable)
367 {
368  uint32_t ui32CtrlVal;
369  uint32_t i;
370  uint32_t *pui32CipherText;
371  union {
372  uint32_t w[4];
373  uint8_t b[16];
374  } ui8InitVec;
375 
376  //
377  // Input address for the encryption engine is the same as the output.
378  //
379  pui32CipherText = pui32PlainText;
380 
381  //
382  // Set current operating state of the Crypto module.
383  //
385 
386  //
387  // Disable global interrupt, enable local interrupt and clear any pending
388  // interrupts.
389  //
390  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
393 
394  //
395  // Enable internal interrupts.
396  //
400 
401  //
402  // Configure master control module for AES operation.
403  //
405 
406  //
407  // Enable keys to read (e.g. Key 0).
408  //
409  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
410 
411  //
412  // Wait until key is loaded to the AES module.
413  //
414  do
415  {
416  CPUdelay(1);
417  }
419 
420  //
421  // Check for Key store Read error.
422  //
424  {
425  return (AES_KEYSTORE_READ_ERROR);
426  }
427 
428  //
429  // Prepare the initialization vector (IV),
430  // Length of Nonce l(n) = 15 - ui32FieldLength.
431  //
432  ui8InitVec.b[0] = ui32FieldLength - 1;
433  for(i = 0; i < 12; i++)
434  {
435  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
436  }
437  if(ui32FieldLength == 2)
438  {
439  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
440  }
441  else
442  {
443  ui8InitVec.b[13] = 0;
444  }
445  ui8InitVec.b[14] = 0;
446  ui8InitVec.b[15] = 0;
447 
448  //
449  // Write initialization vector.
450  //
451  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
452  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
453  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
454  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
455 
456  //
457  // Configure AES engine.
458  //
459  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
460  if ( ui32AuthLength >= 2 ) {
461  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
462  }
463  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
464  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
465  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
466  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
467  ui32CtrlVal |= (1 << CRYPTO_AESCTL_DIR_S);
468  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
469 
470  //
471  // Write the configuration for 128 bit AES-CCM.
472  //
473  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
474 
475  //
476  // Write the length of the crypto block (plain text).
477  // Low and high part (high part is assumed to be always 0).
478  //
479  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32PlainTextLength;
480  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
481 
482  //
483  // Write the length of the header field.
484  // Also called AAD - Additional Authentication Data.
485  //
486  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
487 
488  //
489  // Check if any header information (AAD).
490  // If so configure the DMA controller to fetch the header.
491  //
492  if(ui32HeaderLength != 0)
493  {
494  //
495  // Enable DMA channel 0.
496  //
498 
499  //
500  // Register the base address of the header (AAD).
501  //
502  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
503 
504  //
505  // Header length in bytes (may be non-block size aligned).
506  //
507  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
508 
509  //
510  // Wait for completion of the header data transfer, DMA_IN_DONE.
511  //
512  do
513  {
514  CPUdelay(1);
515  }
516  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
517 
518  //
519  // Check for DMA errors.
520  //
522  {
523  return AES_DMA_BUS_ERROR;
524  }
525  }
526 
527  //
528  // Clear interrupt status.
529  //
532 
533  //
534  // Wait for interrupt lines from module to be cleared
535  //
537 
538  //
539  // Disable CRYPTO_IRQEN_DMA_IN_DONE interrupt as we only
540  // want interrupt to trigger once RESULT_AVAIL occurs.
541  //
543 
544 
545  //
546  // Is using interrupts enable globally.
547  //
548  if(bIntEnable)
549  {
550  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
551  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
552  }
553 
554  //
555  // Enable interrupts locally.
556  //
558 
559  //
560  // Perform encryption if requested.
561  //
562  if(bEncrypt)
563  {
564  //
565  // Enable DMA channel 0
566  //
568 
569  //
570  // base address of the payload data in ext. memory.
571  //
573  (uint32_t)pui32PlainText;
574 
575  //
576  // Enable DMA channel 1
577  //
579 
580  //
581  // Base address of the output data buffer.
582  //
584  (uint32_t)pui32CipherText;
585 
586  //
587  // Payload data length in bytes, equal to the plaintext length.
588  //
589  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32PlainTextLength;
590  //
591  // Output data length in bytes, equal to the plaintext length.
592  //
593  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32PlainTextLength;
594  }
595 
596  return AES_SUCCESS;
597 }
598 
599 //*****************************************************************************
600 //
602 //
603 //*****************************************************************************
604 uint32_t
606 {
607  uint32_t ui32Status;
608 
609  //
610  // Get the current DMA status.
611  //
612  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
613 
614  //
615  // Check if DMA is still busy.
616  //
617  if(ui32Status & CRYPTO_DMA_BSY)
618  {
619  return (AES_DMA_BSY);
620  }
621 
622  //
623  // Check the status of the DMA operation - return error if not success.
624  //
625  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
626  {
628  return (AES_DMA_BUS_ERROR);
629  }
630 
631  //
632  // Operation successful - disable interrupt and return success.
633  //
634  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
635  return (AES_SUCCESS);
636 }
637 
638 //*****************************************************************************
639 //
641 //
642 //*****************************************************************************
643 uint32_t
644 CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
645 {
646  uint32_t volatile ui32Tag[4];
647  uint32_t ui32Idx;
648 
649  //
650  // Result has already been copied to the output buffer by DMA
651  // Disable master control.
652  //
653  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
654 
655  //
656  // Read tag - wait for the context ready bit.
657  //
658  do
659  {
660  CPUdelay(1);
661  }
662  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
664 
665  //
666  // Read the Tag registers.
667  //
668  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
669  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
670  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
671  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
672 
673  for(ui32Idx = 0; ui32Idx < ui32TagLength ; ui32Idx++)
674  {
675  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
676  }
677 
678  //
679  // Operation successful - clear interrupt status.
680  //
684  return AES_SUCCESS;
685 }
686 
687 //*****************************************************************************
688 //
690 //
691 //*****************************************************************************
692 uint32_t
693 CRYPTOCcmInvAuthDecrypt(bool bDecrypt, uint32_t ui32AuthLength,
694  uint32_t *pui32Nonce, uint32_t *pui32CipherText,
695  uint32_t ui32CipherTextLength,
696  uint32_t *pui32Header, uint32_t ui32HeaderLength,
697  uint32_t ui32KeyLocation,
698  uint32_t ui32FieldLength, bool bIntEnable)
699 {
700  uint32_t ui32CtrlVal;
701  uint32_t i;
702  uint32_t *pui32PlainText;
703  uint32_t ui32CryptoBlockLength;
704  union {
705  uint32_t w[4];
706  uint8_t b[16];
707  } ui8InitVec;
708 
709  //
710  // Input address for the encryption engine is the same as the output.
711  //
712  pui32PlainText = pui32CipherText;
713 
714  //
715  // Set current operating state of the Crypto module.
716  //
718 
719  //
720  // Disable global interrupt, enable local interrupt and clear any pending.
721  // interrupts.
722  //
723  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
726  //
727  // Enable internal interrupts.
728  //
732 
733  //
734  // Configure master control module for AES operation.
735  //
737 
738  //
739  // Enable keys to read (e.g. Key 0).
740  //
741  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
742 
743  //
744  // Wait until key is loaded to the AES module.
745  //
746  do
747  {
748  CPUdelay(1);
749  }
751 
752  //
753  // Check for Key store Read error.
754  //
756  {
757  return (AES_KEYSTORE_READ_ERROR);
758  }
759 
760  //
761  // Prepare the initialization vector (IV),
762  // Length of Nonce l(n) = 15 - ui32FieldLength.
763  //
764  ui8InitVec.b[0] = ui32FieldLength - 1;
765  for(i = 0; i < 12; i++)
766  {
767  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
768  }
769  if(ui32FieldLength == 2)
770  {
771  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
772  }
773  else
774  {
775  ui8InitVec.b[13] = 0;
776  }
777  ui8InitVec.b[14] = 0;
778  ui8InitVec.b[15] = 0;
779 
780  //
781  // Write initialization vector.
782  //
783  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
784  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
785  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
786  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
787 
788  //
789  // Configure AES engine
790  //
791  ui32CryptoBlockLength = ui32CipherTextLength - ui32AuthLength;
792  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
793  if ( ui32AuthLength >= 2 ) {
794  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
795  }
796  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
797  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
798  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
799  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
800  ui32CtrlVal |= (0 << CRYPTO_AESCTL_DIR_S);
801  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
802 
803  //
804  // Write the configuration for 128 bit AES-CCM.
805  //
806  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
807 
808  //
809  // Write the length of the crypto block (plain text).
810  // Low and high part (high part is assumed to be always 0).
811  //
812  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32CryptoBlockLength;
813  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
814 
815  //
816  // Write the length of the header field.
817  // Also called AAD - Additional Authentication Data.
818  //
819  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
820 
821  //
822  // Check if any header information (AAD).
823  // If so configure the DMA controller to fetch the header.
824  //
825  if(ui32HeaderLength != 0)
826  {
827  //
828  // Enable DMA channel 0.
829  //
831 
832  //
833  // Register the base address of the header (AAD).
834  //
835  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
836 
837  //
838  // Header length in bytes (may be non-block size aligned).
839  //
840  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
841 
842  //
843  // Wait for completion of the header data transfer, DMA_IN_DONE.
844  //
845  do
846  {
847  CPUdelay(1);
848  }
849  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_DMA_IN_DONE));
850 
851  //
852  // Check for DMA errors.
853  //
855  {
856  return AES_DMA_BUS_ERROR;
857  }
858  }
859 
860  //
861  // Clear interrupt status.
862  //
865 
866  //
867  // Wait for interrupt lines from module to be cleared
868  //
870 
871  //
872  // Disable CRYPTO_IRQEN_DMA_IN_DONE interrupt as we only
873  // want interrupt to trigger once RESULT_AVAIL occurs.
874  //
876 
877  //
878  // Is using interrupts - clear and enable globally.
879  //
880  if(bIntEnable)
881  {
882  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
883  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
884  }
885 
886  //
887  // Enable internal interrupts.
888  //
891 
892  //
893  // Perform decryption if requested.
894  //
895  if(bDecrypt)
896  {
897  //
898  // Configure the DMA controller - enable both DMA channels.
899  //
901 
902  //
903  // Base address of the payload data in ext. memory.
904  //
906  (uint32_t)pui32CipherText;
907 
908  //
909  // Payload data length in bytes, equal to the cipher text length.
910  //
911  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32CryptoBlockLength;
912 
913  //
914  // Enable DMA channel 1.
915  //
917 
918  //
919  // Base address of the output data buffer.
920  //
922  (uint32_t)pui32PlainText;
923 
924  //
925  // Output data length in bytes, equal to the cipher text length.
926  //
927  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32CryptoBlockLength;
928  }
929 
930  return AES_SUCCESS;
931 }
932 
933 //*****************************************************************************
934 //
936 //
937 //*****************************************************************************
938 uint32_t
940 {
941  uint32_t ui32Status;
942 
943  //
944  // Get the current DMA status.
945  //
946  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
947 
948  //
949  // Check if DMA is still busy.
950  //
951  if(ui32Status & CRYPTO_DMA_BSY)
952  {
953  return (AES_DMA_BSY);
954  }
955 
956  //
957  // Check the status of the DMA operation - return error if not success.
958  //
959  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
960  {
962  return (AES_DMA_BUS_ERROR);
963  }
964 
965  //
966  // Operation successful - disable interrupt and return success
967  //
968  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
969  return (AES_SUCCESS);
970 }
971 
972 //*****************************************************************************
973 //
975 //
976 //*****************************************************************************
977 uint32_t
978 CRYPTOCcmInvAuthDecryptResultGet(uint32_t ui32AuthLength,
979  uint32_t *pui32CipherText,
980  uint32_t ui32CipherTextLength,
981  uint32_t *pui32CcmTag)
982 {
983  uint32_t volatile ui32Tag[4];
984  uint32_t ui32TagIndex;
985  uint32_t i;
986  uint32_t ui32Idx;
987 
988  ui32TagIndex = ui32CipherTextLength - ui32AuthLength;
989 
990  //
991  // Result has already been copied to the output buffer by DMA
992  // Disable master control.
993  //
994  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
995 
996  //
997  // Read tag - wait for the context ready bit.
998  //
999  do
1000  {
1001  CPUdelay(1);
1002  }
1003  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
1005 
1006  //
1007  // Read the Tag registers.
1008  //
1009  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
1010  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
1011  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
1012  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
1013 
1014  for(ui32Idx = 0; ui32Idx < ui32AuthLength ; ui32Idx++)
1015  {
1016  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
1017  }
1018 
1019  //
1020  // Operation successful - clear interrupt status.
1021  //
1024 
1025  //
1026  // Verify the Tag.
1027  //
1028  for(i = 0; i < ui32AuthLength; i++)
1029  {
1030  if(*((uint8_t *)pui32CcmTag + i) !=
1031  (*((uint8_t *)pui32CipherText + ui32TagIndex + i)))
1032  {
1034  }
1035  }
1036 
1038  return AES_SUCCESS;
1039 }
1040 
1041 //*****************************************************************************
1042 //
1044 //
1045 //*****************************************************************************
1046 void
1047 CRYPTODmaEnable(uint32_t ui32Channels)
1048 {
1049  //
1050  // Check the arguments.
1051  //
1052  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1053  (ui32Channels & CRYPTO_DMA_CHAN1));
1054 
1055  //
1056  // Enable the selected channels,
1057  //
1058  if(ui32Channels & CRYPTO_DMA_CHAN0)
1059  {
1061  }
1062  if(ui32Channels & CRYPTO_DMA_CHAN1)
1063  {
1065  }
1066 }
1067 
1068 //*****************************************************************************
1069 //
1071 //
1072 //*****************************************************************************
1073 void
1074 CRYPTODmaDisable(uint32_t ui32Channels)
1075 {
1076  //
1077  // Check the arguments.
1078  //
1079  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1080  (ui32Channels & CRYPTO_DMA_CHAN1));
1081 
1082  //
1083  // Enable the selected channels.
1084  //
1085  if(ui32Channels & CRYPTO_DMA_CHAN0)
1086  {
1088  }
1089  if(ui32Channels & CRYPTO_DMA_CHAN1)
1090  {
1092  }
1093 }
#define CRYPTO_AES_CCM
Definition: crypto.h:182
uint32_t CRYPTOCcmAuthEncryptStatus(void)
Check the result of an AES CCM operation.
Definition: crypto.c:605
#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:534
#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:693
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:644
#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:939
#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:978
uint32_t CRYPTOAesEcbStatus(void)
Check the result of an AES ECB operation.
Definition: crypto.c:322
#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:1074
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:1047
#define AES_ECB_LENGTH
Definition: crypto.h:104
#define AES_SUCCESS
Definition: crypto.h:138
void CPUdelay(uint32_t ui32Count)
Provide a small delay.
void IntDisable(uint32_t ui32Interrupt)
Disables an interrupt.
Definition: interrupt.c:378
void IntEnable(uint32_t ui32Interrupt)
Enables an interrupt.
Definition: interrupt.c:318
#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:362
#define CRYPTO_KEY_ST_RD_ERR
Definition: crypto.h:116