CC26xx Driver Library |

- Main Page
- Related Pages
- CC26xx APIs
- Register Descriptions
- Online Resources

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