CC13xx Driver Library
crypto.c
Go to the documentation of this file.
1 /******************************************************************************
2 * Filename: crypto.c
3 * Revised: 2016-05-27 09:37:54 +0200 (Fri, 27 May 2016)
4 * Revision: 46519
5 *
6 * Description: Driver for the Crypto module
7 *
8 * Copyright (c) 2015 - 2016, 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 CRYPTOAesCbc
51  #define CRYPTOAesCbc NOROM_CRYPTOAesCbc
52  #undef CRYPTOAesCbcStatus
53  #define CRYPTOAesCbcStatus NOROM_CRYPTOAesCbcStatus
54  #undef CRYPTOAesEcb
55  #define CRYPTOAesEcb NOROM_CRYPTOAesEcb
56  #undef CRYPTOAesEcbStatus
57  #define CRYPTOAesEcbStatus NOROM_CRYPTOAesEcbStatus
58  #undef CRYPTOCcmAuthEncrypt
59  #define CRYPTOCcmAuthEncrypt NOROM_CRYPTOCcmAuthEncrypt
60  #undef CRYPTOCcmAuthEncryptStatus
61  #define CRYPTOCcmAuthEncryptStatus NOROM_CRYPTOCcmAuthEncryptStatus
62  #undef CRYPTOCcmAuthEncryptResultGet
63  #define CRYPTOCcmAuthEncryptResultGet NOROM_CRYPTOCcmAuthEncryptResultGet
64  #undef CRYPTOCcmInvAuthDecrypt
65  #define CRYPTOCcmInvAuthDecrypt NOROM_CRYPTOCcmInvAuthDecrypt
66  #undef CRYPTOCcmInvAuthDecryptStatus
67  #define CRYPTOCcmInvAuthDecryptStatus NOROM_CRYPTOCcmInvAuthDecryptStatus
68  #undef CRYPTOCcmInvAuthDecryptResultGet
69  #define CRYPTOCcmInvAuthDecryptResultGet NOROM_CRYPTOCcmInvAuthDecryptResultGet
70  #undef CRYPTODmaEnable
71  #define CRYPTODmaEnable NOROM_CRYPTODmaEnable
72  #undef CRYPTODmaDisable
73  #define CRYPTODmaDisable NOROM_CRYPTODmaDisable
74 #endif
75 
76 //*****************************************************************************
77 //
78 // Current AES operation initialized to None
79 //
80 //*****************************************************************************
81 volatile uint32_t g_ui32CurrentAesOp = CRYPTO_AES_NONE;
82 
83 
84 //*****************************************************************************
85 //
87 //
88 //*****************************************************************************
89 uint32_t
90 CRYPTOAesLoadKey(uint32_t *pui32AesKey,
91  uint32_t ui32KeyLocation)
92 {
93  //
94  // Check the arguments.
95  //
96  ASSERT((ui32KeyLocation == CRYPTO_KEY_AREA_0) |
97  (ui32KeyLocation == CRYPTO_KEY_AREA_1) |
98  (ui32KeyLocation == CRYPTO_KEY_AREA_2) |
99  (ui32KeyLocation == CRYPTO_KEY_AREA_3) |
100  (ui32KeyLocation == CRYPTO_KEY_AREA_4) |
101  (ui32KeyLocation == CRYPTO_KEY_AREA_5) |
102  (ui32KeyLocation == CRYPTO_KEY_AREA_6) |
103  (ui32KeyLocation == CRYPTO_KEY_AREA_7));
104 
105  //
106  // Set current operating state of the Crypto module.
107  //
109 
110  //
111  // Disable the external interrupt to stop the interrupt form propagating
112  // from the module to the System CPU.
113  //
114  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
115 
116  //
117  // Enable internal interrupts.
118  //
122 
123  //
124  // Configure master control module.
125  //
127 
128  //
129  // Clear any outstanding events.
130  //
133 
134  //
135  // Configure key store module for 128 bit operation.
136  //
139 
140  //
141  // Enable keys to write (e.g. Key 0).
142  //
143  HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = (0x00000001 << ui32KeyLocation);
144 
145  //
146  // Enable Crypto DMA channel 0.
147  //
149 
150  //
151  // Base address of the key in ext. memory.
152  //
153  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32AesKey;
154 
155  //
156  // Total key length in bytes (e.g. 16 for 1 x 128-bit key).
157  // Writing the length of the key enables the DMA operation.
158  //
160 
161  //
162  // Wait for the DMA operation to complete.
163  //
164  do
165  {
166  CPUdelay(1);
167  }
168  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & 0x00000001));
169 
170  //
171  // Check for errors in DMA and key store.
172  //
173  if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) &
176  {
177  //
178  // Acknowledge/clear the interrupt and disable the master control.
179  //
182  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
183 
184  //
185  // Check status, if error return error code.
186  //
187  if(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) != (0x00000001 << ui32KeyLocation))
188  {
190  return (AES_KEYSTORE_READ_ERROR);
191  }
192  }
193 
194  //
195  // Return success.
196  //
198  return (AES_SUCCESS);
199 }
200 
201 //*****************************************************************************
202 //
204 //
205 //*****************************************************************************
206 uint32_t
207 CRYPTOAesCbc(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut, uint32_t ui32MsgLength,
208  uint32_t *pui32Nonce, uint32_t ui32KeyLocation,
209  bool bEncrypt, bool bIntEnable)
210 {
211  uint32_t ui32CtrlVal;
212 
213  //
214  // Set current operating state of the Crypto module.
215  //
217 
218  //
219  // Enable internal interrupts.
220  //
223 
224  //
225  // Clear any outstanding interrupts.
226  //
229 
230  //
231  // Wait for interrupt lines from module to be cleared
232  //
234 
235  //
236  // If using interrupts clear any pending interrupts and enable interrupts
237  // for the Crypto module.
238  //
239  if(bIntEnable)
240  {
241  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
242  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
243  }
244 
245  //
246  // Configure Master Control module.
247  //
249 
250  //
251  //
252  //
253  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
254 
255  //
256  //Wait until key is loaded to the AES module.
257  //
258  do
259  {
260  CPUdelay(1);
261  }
263 
264  //
265  // Check for Key store Read error.
266  //
268  {
269  return (AES_KEYSTORE_READ_ERROR);
270  }
271 
272  //
273  // Write initialization vector.
274  //
275  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = pui32Nonce[0];
276  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = pui32Nonce[1];
277  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = pui32Nonce[2];
278  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = pui32Nonce[3];
279 
280  //
281  // Configure AES engine for AES-CBC with 128-bit key size.
282  //
284  if(bEncrypt)
285  {
286  ui32CtrlVal |= CRYPTO_AES128_ENCRYPT;
287  }
288  else
289  {
290  ui32CtrlVal |= CRYPTO_AES128_DECRYPT;
291  }
292  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
293 
294  //
295  // Write the length of the crypto block (plain text).
296  // Low and high part (high part is assumed to be always 0).
297  //
298  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32MsgLength;
299  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
300  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = 0;
301 
302  //
303  // Enable Crypto DMA channel 0.
304  //
306 
307  //
308  // Base address of the input data in ext. memory.
309  //
310  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn;
311 
312  //
313  // Input data length in bytes, equal to the message.
314  //
315  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32MsgLength;
316 
317  //
318  // Enable Crypto DMA channel 1.
319  //
321 
322  //
323  // Set up the address and length of the output data.
324  //
325  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut;
326  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32MsgLength;
327 
328  //
329  // Return success
330  //
331  return AES_SUCCESS;
332 }
333 
334 //*****************************************************************************
335 //
337 //
338 //*****************************************************************************
339 uint32_t
341 {
342  return(CRYPTOAesEcbStatus());
343 }
344 
345 //*****************************************************************************
346 //
348 //
349 //*****************************************************************************
350 uint32_t
351 CRYPTOAesEcb(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut,
352  uint32_t ui32KeyLocation, bool bEncrypt,
353  bool bIntEnable)
354 {
355  //
356  // Set current operating state of the Crypto module.
357  //
359 
360  //
361  // Enable internal interrupts.
362  //
365 
366  //
367  // Clear any outstanding interrupts.
368  //
371 
372  //
373  // Wait for interrupt lines from module to be cleared
374  //
376 
377  //
378  // If using interrupts clear any pending interrupts and enable interrupts
379  // for the Crypto module.
380  //
381  if(bIntEnable)
382  {
383  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
384  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
385  }
386 
387  //
388  // Configure Master Control module.
389  //
391 
392  //
393  //
394  //
395  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
396 
397  //
398  //Wait until key is loaded to the AES module.
399  //
400  do
401  {
402  CPUdelay(1);
403  }
405 
406  //
407  // Check for Key store Read error.
408  //
410  {
411  return (AES_KEYSTORE_READ_ERROR);
412  }
413 
414  //
415  // Configure AES engine (program AES-ECB-128 encryption and no
416  // initialization vector - IV).
417  //
418  if(bEncrypt)
419  {
421  }
422  else
423  {
425  }
426 
427  //
428  // Write the length of the data.
429  //
431  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
432 
433  //
434  // Enable Crypto DMA channel 0.
435  //
437 
438  //
439  // Base address of the input data in ext. memory.
440  //
441  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32MsgIn;
442 
443  //
444  // Input data length in bytes, equal to the message.
445  //
447 
448  //
449  // Enable Crypto DMA channel 1.
450  //
452 
453  //
454  // Set up the address and length of the output data.
455  //
456  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)pui32MsgOut;
458 
459  //
460  // Return success
461  //
462  return AES_SUCCESS;
463 }
464 
465 //*****************************************************************************
466 //
468 //
469 //*****************************************************************************
470 uint32_t
472 {
473  uint32_t ui32Status;
474 
475  //
476  // Get the current DMA status.
477  //
478  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
479 
480  //
481  // Check if DMA is still busy.
482  //
483  if(ui32Status & CRYPTO_DMA_BSY)
484  {
485  return (AES_DMA_BSY);
486  }
487 
488  //
489  // Check the status of the DMA operation - return error if not success.
490  //
491  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
492  {
494  return (AES_DMA_BUS_ERROR);
495  }
496 
497  //
498  // Operation successful - disable interrupt and return success.
499  //
501  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
502  return (AES_SUCCESS);
503 }
504 
505 //*****************************************************************************
506 //
508 //
509 //*****************************************************************************
510 uint32_t
511 CRYPTOCcmAuthEncrypt(bool bEncrypt, uint32_t ui32AuthLength ,
512  uint32_t *pui32Nonce, uint32_t *pui32PlainText,
513  uint32_t ui32PlainTextLength, uint32_t *pui32Header,
514  uint32_t ui32HeaderLength, uint32_t ui32KeyLocation,
515  uint32_t ui32FieldLength, bool bIntEnable)
516 {
517  uint32_t ui32CtrlVal;
518  uint32_t i;
519  uint32_t *pui32CipherText;
520  union {
521  uint32_t w[4];
522  uint8_t b[16];
523  } ui8InitVec;
524 
525  //
526  // Input address for the encryption engine is the same as the output.
527  //
528  pui32CipherText = pui32PlainText;
529 
530  //
531  // Set current operating state of the Crypto module.
532  //
534 
535  //
536  // Disable global interrupt, enable local interrupt and clear any pending
537  // interrupts.
538  //
539  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
542 
543  //
544  // Enable internal interrupts.
545  //
549 
550  //
551  // Configure master control module for AES operation.
552  //
554 
555  //
556  // Enable keys to read (e.g. Key 0).
557  //
558  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
559 
560  //
561  // Wait until key is loaded to the AES module.
562  //
563  do
564  {
565  CPUdelay(1);
566  }
568 
569  //
570  // Check for Key store Read error.
571  //
573  {
574  return (AES_KEYSTORE_READ_ERROR);
575  }
576 
577  //
578  // Prepare the initialization vector (IV),
579  // Length of Nonce l(n) = 15 - ui32FieldLength.
580  //
581  ui8InitVec.b[0] = ui32FieldLength - 1;
582  for(i = 0; i < 12; i++)
583  {
584  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
585  }
586  if(ui32FieldLength == 2)
587  {
588  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
589  }
590  else
591  {
592  ui8InitVec.b[13] = 0;
593  }
594  ui8InitVec.b[14] = 0;
595  ui8InitVec.b[15] = 0;
596 
597  //
598  // Write initialization vector.
599  //
600  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
601  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
602  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
603  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
604 
605  //
606  // Configure AES engine.
607  //
608  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
609  if ( ui32AuthLength >= 2 ) {
610  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
611  }
612  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
613  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
614  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
615  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
616  ui32CtrlVal |= (1 << CRYPTO_AESCTL_DIR_S);
617  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
618 
619  //
620  // Write the configuration for 128 bit AES-CCM.
621  //
622  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
623 
624  //
625  // Write the length of the crypto block (plain text).
626  // Low and high part (high part is assumed to be always 0).
627  //
628  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32PlainTextLength;
629  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
630 
631  //
632  // Write the length of the header field.
633  // Also called AAD - Additional Authentication Data.
634  //
635  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
636 
637  //
638  // Check if any header information (AAD).
639  // If so configure the DMA controller to fetch the header.
640  //
641  if(ui32HeaderLength != 0)
642  {
643  //
644  // Enable DMA channel 0.
645  //
647 
648  //
649  // Register the base address of the header (AAD).
650  //
651  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
652 
653  //
654  // Header length in bytes (may be non-block size aligned).
655  //
656  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
657 
658  //
659  // Wait for completion of the header data transfer, DMA_IN_DONE.
660  //
661  do
662  {
663  CPUdelay(1);
664  }
666 
667  //
668  // Check for DMA errors.
669  //
671  {
672  return AES_DMA_BUS_ERROR;
673  }
674  }
675 
676  //
677  // Clear interrupt status.
678  //
681 
682  //
683  // Wait for interrupt lines from module to be cleared
684  //
686 
687  //
688  // Disable CRYPTO_IRQEN_DMA_IN_DONE interrupt as we only
689  // want interrupt to trigger once RESULT_AVAIL occurs.
690  //
692 
693 
694  //
695  // Is using interrupts enable globally.
696  //
697  if(bIntEnable)
698  {
699  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
700  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
701  }
702 
703  //
704  // Enable interrupts locally.
705  //
707 
708  //
709  // Perform encryption if requested.
710  //
711  if(bEncrypt)
712  {
713  //
714  // Enable DMA channel 0
715  //
717 
718  //
719  // base address of the payload data in ext. memory.
720  //
722  (uint32_t)pui32PlainText;
723 
724  //
725  // Enable DMA channel 1
726  //
728 
729  //
730  // Base address of the output data buffer.
731  //
733  (uint32_t)pui32CipherText;
734 
735  //
736  // Payload data length in bytes, equal to the plaintext length.
737  //
738  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32PlainTextLength;
739  //
740  // Output data length in bytes, equal to the plaintext length.
741  //
742  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32PlainTextLength;
743  }
744 
745  return AES_SUCCESS;
746 }
747 
748 //*****************************************************************************
749 //
751 //
752 //*****************************************************************************
753 uint32_t
755 {
756  uint32_t ui32Status;
757 
758  //
759  // Get the current DMA status.
760  //
761  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
762 
763  //
764  // Check if DMA is still busy.
765  //
766  if(ui32Status & CRYPTO_DMA_BSY)
767  {
768  return (AES_DMA_BSY);
769  }
770 
771  //
772  // Check the status of the DMA operation - return error if not success.
773  //
774  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
775  {
777  return (AES_DMA_BUS_ERROR);
778  }
779 
780  //
781  // Operation successful - disable interrupt and return success.
782  //
783  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
784  return (AES_SUCCESS);
785 }
786 
787 //*****************************************************************************
788 //
790 //
791 //*****************************************************************************
792 uint32_t
793 CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
794 {
795  uint32_t volatile ui32Tag[4];
796  uint32_t ui32Idx;
797 
798  //
799  // Result has already been copied to the output buffer by DMA
800  // Disable master control.
801  //
802  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
803 
804  //
805  // Read tag - wait for the context ready bit.
806  //
807  do
808  {
809  CPUdelay(1);
810  }
811  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
813 
814  //
815  // Read the Tag registers.
816  //
817  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
818  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
819  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
820  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
821 
822  for(ui32Idx = 0; ui32Idx < ui32TagLength ; ui32Idx++)
823  {
824  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
825  }
826 
827  //
828  // Operation successful - clear interrupt status.
829  //
833  return AES_SUCCESS;
834 }
835 
836 //*****************************************************************************
837 //
839 //
840 //*****************************************************************************
841 uint32_t
842 CRYPTOCcmInvAuthDecrypt(bool bDecrypt, uint32_t ui32AuthLength,
843  uint32_t *pui32Nonce, uint32_t *pui32CipherText,
844  uint32_t ui32CipherTextLength,
845  uint32_t *pui32Header, uint32_t ui32HeaderLength,
846  uint32_t ui32KeyLocation,
847  uint32_t ui32FieldLength, bool bIntEnable)
848 {
849  uint32_t ui32CtrlVal;
850  uint32_t i;
851  uint32_t *pui32PlainText;
852  uint32_t ui32CryptoBlockLength;
853  union {
854  uint32_t w[4];
855  uint8_t b[16];
856  } ui8InitVec;
857 
858  //
859  // Input address for the encryption engine is the same as the output.
860  //
861  pui32PlainText = pui32CipherText;
862 
863  //
864  // Set current operating state of the Crypto module.
865  //
867 
868  //
869  // Disable global interrupt, enable local interrupt and clear any pending.
870  // interrupts.
871  //
872  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
875  //
876  // Enable internal interrupts.
877  //
881 
882  //
883  // Configure master control module for AES operation.
884  //
886 
887  //
888  // Enable keys to read (e.g. Key 0).
889  //
890  HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = ui32KeyLocation;
891 
892  //
893  // Wait until key is loaded to the AES module.
894  //
895  do
896  {
897  CPUdelay(1);
898  }
900 
901  //
902  // Check for Key store Read error.
903  //
905  {
906  return (AES_KEYSTORE_READ_ERROR);
907  }
908 
909  //
910  // Prepare the initialization vector (IV),
911  // Length of Nonce l(n) = 15 - ui32FieldLength.
912  //
913  ui8InitVec.b[0] = ui32FieldLength - 1;
914  for(i = 0; i < 12; i++)
915  {
916  ui8InitVec.b[i + 1] = ((uint8_t*)pui32Nonce)[i];
917  }
918  if(ui32FieldLength == 2)
919  {
920  ui8InitVec.b[13] = ((uint8_t*)pui32Nonce)[12];
921  }
922  else
923  {
924  ui8InitVec.b[13] = 0;
925  }
926  ui8InitVec.b[14] = 0;
927  ui8InitVec.b[15] = 0;
928 
929  //
930  // Write initialization vector.
931  //
932  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = ui8InitVec.w[0];
933  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = ui8InitVec.w[1];
934  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = ui8InitVec.w[2];
935  HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = ui8InitVec.w[3];
936 
937  //
938  // Configure AES engine
939  //
940  ui32CryptoBlockLength = ui32CipherTextLength - ui32AuthLength;
941  ui32CtrlVal = ((ui32FieldLength - 1) << CRYPTO_AESCTL_CCM_L_S);
942  if ( ui32AuthLength >= 2 ) {
943  ui32CtrlVal |= ((( ui32AuthLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
944  }
945  ui32CtrlVal |= CRYPTO_AESCTL_CCM;
946  ui32CtrlVal |= CRYPTO_AESCTL_CTR;
947  ui32CtrlVal |= CRYPTO_AESCTL_SAVE_CONTEXT;
948  ui32CtrlVal |= (KEY_STORE_SIZE_128 << CRYPTO_AESCTL_KEY_SIZE_S);
949  ui32CtrlVal |= (0 << CRYPTO_AESCTL_DIR_S);
950  ui32CtrlVal |= (CRYPTO_AES_CTR_128 << CRYPTO_AESCTL_CTR_WIDTH_S);
951 
952  //
953  // Write the configuration for 128 bit AES-CCM.
954  //
955  HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) = ui32CtrlVal;
956 
957  //
958  // Write the length of the crypto block (plain text).
959  // Low and high part (high part is assumed to be always 0).
960  //
961  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN0) = ui32CryptoBlockLength;
962  HWREG(CRYPTO_BASE + CRYPTO_O_AESDATALEN1) = 0;
963 
964  //
965  // Write the length of the header field.
966  // Also called AAD - Additional Authentication Data.
967  //
968  HWREG(CRYPTO_BASE + CRYPTO_O_AESAUTHLEN) = ui32HeaderLength;
969 
970  //
971  // Check if any header information (AAD).
972  // If so configure the DMA controller to fetch the header.
973  //
974  if(ui32HeaderLength != 0)
975  {
976  //
977  // Enable DMA channel 0.
978  //
980 
981  //
982  // Register the base address of the header (AAD).
983  //
984  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)pui32Header;
985 
986  //
987  // Header length in bytes (may be non-block size aligned).
988  //
989  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32HeaderLength;
990 
991  //
992  // Wait for completion of the header data transfer, DMA_IN_DONE.
993  //
994  do
995  {
996  CPUdelay(1);
997  }
999 
1000  //
1001  // Check for DMA errors.
1002  //
1004  {
1005  return AES_DMA_BUS_ERROR;
1006  }
1007  }
1008 
1009  //
1010  // Clear interrupt status.
1011  //
1014 
1015  //
1016  // Wait for interrupt lines from module to be cleared
1017  //
1019 
1020  //
1021  // Disable CRYPTO_IRQEN_DMA_IN_DONE interrupt as we only
1022  // want interrupt to trigger once RESULT_AVAIL occurs.
1023  //
1025 
1026  //
1027  // Is using interrupts - clear and enable globally.
1028  //
1029  if(bIntEnable)
1030  {
1031  IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
1032  IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
1033  }
1034 
1035  //
1036  // Enable internal interrupts.
1037  //
1040 
1041  //
1042  // Perform decryption if requested.
1043  //
1044  if(bDecrypt)
1045  {
1046  //
1047  // Configure the DMA controller - enable both DMA channels.
1048  //
1050 
1051  //
1052  // Base address of the payload data in ext. memory.
1053  //
1055  (uint32_t)pui32CipherText;
1056 
1057  //
1058  // Payload data length in bytes, equal to the cipher text length.
1059  //
1060  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = ui32CryptoBlockLength;
1061 
1062  //
1063  // Enable DMA channel 1.
1064  //
1066 
1067  //
1068  // Base address of the output data buffer.
1069  //
1071  (uint32_t)pui32PlainText;
1072 
1073  //
1074  // Output data length in bytes, equal to the cipher text length.
1075  //
1076  HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = ui32CryptoBlockLength;
1077  }
1078 
1079  return AES_SUCCESS;
1080 }
1081 
1082 //*****************************************************************************
1083 //
1085 //
1086 //*****************************************************************************
1087 uint32_t
1089 {
1090  uint32_t ui32Status;
1091 
1092  //
1093  // Get the current DMA status.
1094  //
1095  ui32Status = HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT);
1096 
1097  //
1098  // Check if DMA is still busy.
1099  //
1100  if(ui32Status & CRYPTO_DMA_BSY)
1101  {
1102  return (AES_DMA_BSY);
1103  }
1104 
1105  //
1106  // Check the status of the DMA operation - return error if not success.
1107  //
1108  if(ui32Status & CRYPTO_DMA_BUS_ERROR)
1109  {
1111  return (AES_DMA_BUS_ERROR);
1112  }
1113 
1114  //
1115  // Operation successful - disable interrupt and return success
1116  //
1117  IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
1118  return (AES_SUCCESS);
1119 }
1120 
1121 //*****************************************************************************
1122 //
1124 //
1125 //*****************************************************************************
1126 uint32_t
1127 CRYPTOCcmInvAuthDecryptResultGet(uint32_t ui32AuthLength,
1128  uint32_t *pui32CipherText,
1129  uint32_t ui32CipherTextLength,
1130  uint32_t *pui32CcmTag)
1131 {
1132  uint32_t volatile ui32Tag[4];
1133  uint32_t ui32TagIndex;
1134  uint32_t i;
1135  uint32_t ui32Idx;
1136 
1137  ui32TagIndex = ui32CipherTextLength - ui32AuthLength;
1138 
1139  //
1140  // Result has already been copied to the output buffer by DMA
1141  // Disable master control.
1142  //
1143  HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = 0x00000000;
1144 
1145  //
1146  // Read tag - wait for the context ready bit.
1147  //
1148  do
1149  {
1150  CPUdelay(1);
1151  }
1152  while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) &
1154 
1155  //
1156  // Read the Tag registers.
1157  //
1158  ui32Tag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
1159  ui32Tag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
1160  ui32Tag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
1161  ui32Tag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
1162 
1163  for(ui32Idx = 0; ui32Idx < ui32AuthLength ; ui32Idx++)
1164  {
1165  *((uint8_t*)pui32CcmTag + ui32Idx) = *((uint8_t*)ui32Tag + ui32Idx);
1166  }
1167 
1168  //
1169  // Operation successful - clear interrupt status.
1170  //
1173 
1174  //
1175  // Verify the Tag.
1176  //
1177  for(i = 0; i < ui32AuthLength; i++)
1178  {
1179  if(*((uint8_t *)pui32CcmTag + i) !=
1180  (*((uint8_t *)pui32CipherText + ui32TagIndex + i)))
1181  {
1183  }
1184  }
1185 
1187  return AES_SUCCESS;
1188 }
1189 
1190 //*****************************************************************************
1191 //
1193 //
1194 //*****************************************************************************
1195 void
1196 CRYPTODmaEnable(uint32_t ui32Channels)
1197 {
1198  //
1199  // Check the arguments.
1200  //
1201  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1202  (ui32Channels & CRYPTO_DMA_CHAN1));
1203 
1204  //
1205  // Enable the selected channels,
1206  //
1207  if(ui32Channels & CRYPTO_DMA_CHAN0)
1208  {
1210  }
1211  if(ui32Channels & CRYPTO_DMA_CHAN1)
1212  {
1214  }
1215 }
1216 
1217 //*****************************************************************************
1218 //
1220 //
1221 //*****************************************************************************
1222 void
1223 CRYPTODmaDisable(uint32_t ui32Channels)
1224 {
1225  //
1226  // Check the arguments.
1227  //
1228  ASSERT((ui32Channels & CRYPTO_DMA_CHAN0) |
1229  (ui32Channels & CRYPTO_DMA_CHAN1));
1230 
1231  //
1232  // Enable the selected channels.
1233  //
1234  if(ui32Channels & CRYPTO_DMA_CHAN0)
1235  {
1237  }
1238  if(ui32Channels & CRYPTO_DMA_CHAN1)
1239  {
1241  }
1242 }
#define CRYPTO_AES_CCM
Definition: crypto.h:184
uint32_t CRYPTOCcmAuthEncryptStatus(void)
Check the result of an AES CCM operation.
Definition: crypto.c:754
#define CRYPTO_AES_KEYL0AD
Definition: crypto.h:182
#define CRYPTO_KEY_AREA_3
Definition: crypto.h:170
#define AES_DMA_BSY
Definition: crypto.h:148
#define CRYPTO_KEY_AREA_1
Definition: crypto.h:168
#define CRYPTO_DMA_CHAN1
Definition: crypto.h:124
#define AES_KEYSTORE_READ_ERROR
Definition: crypto.h:141
#define CRYPTO_KEY_AREA_2
Definition: crypto.h:169
#define CRYPTO_DMA_BUS_ERROR
Definition: crypto.h:131
void IntPendClear(uint32_t ui32Interrupt)
Unpends an interrupt.
Definition: interrupt.c:534
uint32_t CRYPTOAesCbc(uint32_t *pui32MsgIn, uint32_t *pui32MsgOut, uint32_t ui32MsgLength, uint32_t *pui32Nonce, uint32_t ui32KeyLocation, bool bEncrypt, bool bIntEnable)
Start an AES-CBC operation (encryption or decryption).
Definition: crypto.c:207
#define CRYPTO_DMA_CHAN0
Definition: crypto.h:123
#define CRYPTO_AES_CTR_128
Definition: crypto.h:196
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:842
#define CRYPTO_AES_CBC
Definition: crypto.h:186
uint32_t CRYPTOAesLoadKey(uint32_t *pui32AesKey, uint32_t ui32KeyLocation)
Write the key into the Key Ram.
Definition: crypto.c:90
uint32_t CRYPTOCcmAuthEncryptResultGet(uint32_t ui32TagLength, uint32_t *pui32CcmTag)
Get the result of an AES-CCM operation.
Definition: crypto.c:793
volatile uint32_t g_ui32CurrentAesOp
Definition: crypto.c:81
#define CRYPTO_AES_NONE
Definition: crypto.h:181
#define KEY_STORE_SIZE_128
Definition: crypto.h:155
#define CRYPTO_AES128_ENCRYPT
Definition: crypto.h:126
#define CRYPTO_DMA_BUS_ERR
Definition: crypto.h:116
uint32_t CRYPTOCcmInvAuthDecryptStatus(void)
Checks CCM decrypt and Inverse Authentication result.
Definition: crypto.c:1088
#define CRYPTO_AES_ECB
Definition: crypto.h:183
#define ASSERT(expr)
Definition: debug.h:74
#define CRYPTO_KEY_AREA_7
Definition: crypto.h:174
#define CRYPTO_KEY_AREA_0
Definition: crypto.h:167
#define CRYPTO_KEY_AREA_5
Definition: crypto.h:172
#define CRYPTO_AES128_DECRYPT
Definition: crypto.h:127
#define CRYPTO_KEY_AREA_4
Definition: crypto.h:171
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:1127
uint32_t CRYPTOAesEcbStatus(void)
Check the result of an AES ECB operation.
Definition: crypto.c:471
#define CCM_AUTHENTICATION_FAILED
Definition: crypto.h:144
#define AES_DMA_BUS_ERROR
Definition: crypto.h:143
#define KEY_BLENGTH
Definition: crypto.h:152
#define CRYPTO_DMA_BSY
Definition: crypto.h:130
void CRYPTODmaDisable(uint32_t ui32Channels)
Disable Crypto DMA operation.
Definition: crypto.c:1223
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:351
void CRYPTODmaEnable(uint32_t ui32Channels)
Enable Crypto DMA operation.
Definition: crypto.c:1196
#define AES_ECB_LENGTH
Definition: crypto.h:106
#define AES_SUCCESS
Definition: crypto.h:140
void CPUdelay(uint32_t ui32Count)
Provide a small delay.
uint32_t CRYPTOAesCbcStatus(void)
Check the result of an AES CBC operation.
Definition: crypto.c:340
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:173
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:511
#define CRYPTO_KEY_ST_RD_ERR
Definition: crypto.h:118