1 /******************************************************************************
2 *  Filename:       aes.c
3 *
4 *  Description:    Driver for the AES functions of the crypto module
5 *
6 *  Copyright (c) 2015 - 2022, Texas Instruments Incorporated
7 *  All rights reserved.
8 *
9 *  Redistribution and use in source and binary forms, with or without
10 *  modification, are permitted provided that the following conditions are met:
11 *
12 *  1) Redistributions of source code must retain the above copyright notice,
13 *     this list of conditions and the following disclaimer.
14 *
15 *  2) Redistributions in binary form must reproduce the above copyright notice,
16 *     this list of conditions and the following disclaimer in the documentation
17 *     and/or other materials provided with the distribution.
18 *
19 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
20 *     be used to endorse or promote products derived from this software without
21 *     specific prior written permission.
22 *
23 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 *  POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************/
36 
37 #include "aes.h"
38 
39 //*****************************************************************************
40 //
41 // Handle support for DriverLib in ROM:
42 // This section will undo prototype renaming made in the header file
43 //
44 //*****************************************************************************
45 #if !defined(DOXYGEN)
46     #undef  AESStartDMAOperation
47     #define AESStartDMAOperation            NOROM_AESStartDMAOperation
48     #undef  AESSetInitializationVector
49     #define AESSetInitializationVector      NOROM_AESSetInitializationVector
50     #undef  AESWriteCCMInitializationVector
51     #define AESWriteCCMInitializationVector NOROM_AESWriteCCMInitializationVector
52     #undef  AESReadTag
53     #define AESReadTag                      NOROM_AESReadTag
54     #undef  AESVerifyTag
55     #define AESVerifyTag                    NOROM_AESVerifyTag
56     #undef  AESWriteToKeyStore
57     #define AESWriteToKeyStore              NOROM_AESWriteToKeyStore
58     #undef  AESReadFromKeyStore
59     #define AESReadFromKeyStore             NOROM_AESReadFromKeyStore
60     #undef  AESWaitForIRQFlags
61     #define AESWaitForIRQFlags              NOROM_AESWaitForIRQFlags
62     #undef  AESConfigureCCMCtrl
63     #define AESConfigureCCMCtrl             NOROM_AESConfigureCCMCtrl
64 #endif
65 
66 
67 
68 #ifndef CRYPTO_SWRESET_SW_RESET
69 /* This definition is missing in hw_crypto.h for  CC26X0 and CC13X0 devices */
70 #define CRYPTO_SWRESET_SW_RESET  0x00000001
71 #endif
72 
73 #ifndef CRYPTO_DMASWRESET_SWRES
74 /* This definition is missing in hw_crypto.h for CC26X0 and CC13X0 devices */
75 #define CRYPTO_DMASWRESET_SWRES  0x00000001
76 #endif
77 
78 #ifndef CRYPTO_DMASTAT_CH0_ACT
79 /* This definition is missing in hw_crypto.h for  CC26X0 and CC13X0 devices */
80 #define CRYPTO_DMASTAT_CH0_ACT   0x00000001
81 #endif
82 
83 #ifndef CRYPTO_DMASTAT_CH1_ACT
84 /* This definition is missing in hw_crypto.h for  CC26X0 and CC13X0 devices */
85 #define CRYPTO_DMASTAT_CH1_ACT   0x00000002
86 #endif
87 
88 //*****************************************************************************
89 //
90 // Load the initialization vector.
91 //
92 //*****************************************************************************
AESSetInitializationVector(const uint32_t * initializationVector)93 void AESSetInitializationVector(const uint32_t *initializationVector)
94 {
95     // Write initialization vector to the aes registers
96     HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0) = initializationVector[0];
97     HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1) = initializationVector[1];
98     HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2) = initializationVector[2];
99     HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3) = initializationVector[3];
100 }
101 
102 //*****************************************************************************
103 //
104 // Read the IV for Authenticated Modes (CCM or GCM) after the tag has been read.
105 //
106 //*****************************************************************************
AESReadAuthenticationModeIV(uint32_t * iv)107 void AESReadAuthenticationModeIV(uint32_t *iv)
108 {
109     /* Read the computed IV out from the hw registers */
110     iv[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESIV0);
111     iv[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESIV1);
112     iv[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESIV2);
113     /* This read will clear the saved_context_ready bit
114      * and allow the AES core to start the next operation.
115      */
116     iv[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESIV3);
117 }
118 
119 //*****************************************************************************
120 //
121 // Read the IV for Non-Authenticated Modes (CBC or CTR).
122 //
123 //*****************************************************************************
AESReadNonAuthenticationModeIV(uint32_t * iv)124 void AESReadNonAuthenticationModeIV(uint32_t *iv)
125 {
126     /* Wait until the saved context is ready */
127     while(!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) & CRYPTO_AESCTL_SAVED_CONTEXT_RDY_M));
128 
129     AESReadAuthenticationModeIV(iv);
130 }
131 
132 //*****************************************************************************
133 //
134 // Start a crypto DMA operation.
135 //
136 //*****************************************************************************
AESStartDMAOperation(const uint8_t * channel0Addr,uint32_t channel0Length,uint8_t * channel1Addr,uint32_t channel1Length)137 void AESStartDMAOperation(const uint8_t *channel0Addr, uint32_t channel0Length,  uint8_t *channel1Addr, uint32_t channel1Length)
138 {
139     if (channel0Length && channel0Addr) {
140         // We actually want to perform an operation. Clear any outstanding events.
141         HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = CRYPTO_IRQCLR_RESULT_AVAIL_M | CRYPTO_IRQEN_DMA_IN_DONE_M; // This might need AES_IRQEN_DMA_IN_DONE as well
142 
143         while(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & (CRYPTO_IRQSTAT_DMA_IN_DONE_M | CRYPTO_IRQSTAT_RESULT_AVAIL_M));
144 
145         // Configure the DMA controller - enable both DMA channels.
146         HWREGBITW(CRYPTO_BASE + CRYPTO_O_DMACH0CTL, CRYPTO_DMACH0CTL_EN_BITN) = 1;
147 
148         // Base address of the payload data in ext. memory.
149         HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0EXTADDR) = (uint32_t)channel0Addr;
150 
151         // Payload data length in bytes, equal to the cipher text length.
152         HWREG(CRYPTO_BASE + CRYPTO_O_DMACH0LEN) = channel0Length;
153     }
154 
155     if (channel1Length && channel1Addr) {
156         // Enable DMA channel 1.
157         HWREGBITW(CRYPTO_BASE + CRYPTO_O_DMACH1CTL, CRYPTO_DMACH1CTL_EN_BITN) = 1;
158 
159         // Base address of the output data buffer.
160         HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1EXTADDR) = (uint32_t)channel1Addr;
161 
162         // Output data length in bytes, equal to the cipher text length.
163         HWREG(CRYPTO_BASE + CRYPTO_O_DMACH1LEN) = channel1Length;
164     }
165 }
166 
167 //*****************************************************************************
168 //
169 // Poll the IRQ status register and return.
170 //
171 //*****************************************************************************
AESWaitForIRQFlags(uint32_t irqFlags)172 uint32_t AESWaitForIRQFlags(uint32_t irqFlags)
173 {
174     uint32_t irqTrigger = 0;
175     // Wait for the DMA operation to complete. Add a delay to make sure we are
176     // not flooding the bus with requests too much.
177     do {
178         CPUdelay(1);
179     }
180     while(!(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags & (CRYPTO_IRQSTAT_DMA_IN_DONE_M |
181                                                                 CRYPTO_IRQSTAT_RESULT_AVAIL_M |
182                                                                 CRYPTO_IRQSTAT_DMA_BUS_ERR_M |
183                                                                 CRYPTO_IRQSTAT_KEY_ST_WR_ERR_M)));
184 
185     // Save the IRQ trigger source
186     irqTrigger = HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & irqFlags;
187 
188     // Clear IRQ flags
189     HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = irqTrigger;
190 
191     return irqTrigger;
192 }
193 
194 //*****************************************************************************
195 //
196 // Transfer a key from CPU memory to a key store location.
197 //
198 //*****************************************************************************
AESWriteToKeyStore(const uint8_t * aesKey,uint32_t aesKeyLength,uint32_t keyStoreArea)199 uint32_t AESWriteToKeyStore(const uint8_t *aesKey, uint32_t aesKeyLength, uint32_t keyStoreArea)
200 {
201     // Check the arguments.
202     ASSERT((keyStoreArea == AES_KEY_AREA_0) ||
203            (keyStoreArea == AES_KEY_AREA_1) ||
204            (keyStoreArea == AES_KEY_AREA_2) ||
205            (keyStoreArea == AES_KEY_AREA_3) ||
206            (keyStoreArea == AES_KEY_AREA_4) ||
207            (keyStoreArea == AES_KEY_AREA_5) ||
208            (keyStoreArea == AES_KEY_AREA_6) ||
209            (keyStoreArea == AES_KEY_AREA_7));
210 
211     ASSERT((aesKeyLength == AES_128_KEY_LENGTH_BYTES) ||
212            (aesKeyLength == AES_192_KEY_LENGTH_BYTES) ||
213            (aesKeyLength == AES_256_KEY_LENGTH_BYTES));
214 
215     // This buffer must be declared at function scope to prevent LLVM compiler from optimizing out memcpy.
216     uint8_t paddedKey[AES_256_KEY_LENGTH_BYTES] = {0};
217     uint32_t keySize = 0;
218 
219     switch (aesKeyLength) {
220         case AES_128_KEY_LENGTH_BYTES:
221             keySize = CRYPTO_KEYSIZE_SIZE_128_BIT;
222             break;
223         case AES_192_KEY_LENGTH_BYTES:
224             keySize = CRYPTO_KEYSIZE_SIZE_192_BIT;
225             break;
226         case AES_256_KEY_LENGTH_BYTES:
227             keySize = CRYPTO_KEYSIZE_SIZE_256_BIT;
228             break;
229     }
230 
231     // Clear any previously written key at the keyLocation
232     AESInvalidateKey(keyStoreArea);
233 
234     // Disable the external interrupt to stop the interrupt form propagating
235     // from the module to the System CPU.
236     IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
237 
238     // Enable internal interrupts.
239     HWREG(CRYPTO_BASE + CRYPTO_O_IRQTYPE) = CRYPTO_IRQTYPE_LEVEL_M;
240     HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) = CRYPTO_IRQEN_DMA_IN_DONE_M | CRYPTO_IRQEN_RESULT_AVAIL_M;
241 
242     // Configure master control module.
243     HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = CRYPTO_ALGSEL_KEY_STORE;
244 
245     // Clear any outstanding events.
246     HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = (CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQCLR_RESULT_AVAIL);
247 
248     // Configure the size of keys contained within the key store
249     // Do not write to the register if the correct key size is already set.
250     // Writing to this register causes all current keys to be invalidated.
251     uint32_t keyStoreKeySize = HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE);
252     if (keySize != keyStoreKeySize) {
253         HWREG(CRYPTO_BASE + CRYPTO_O_KEYSIZE) = keySize;
254     }
255 
256     // Enable key to write (e.g. Key 0).
257     HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITEAREA) = 1 << keyStoreArea;
258 
259     if (aesKeyLength == AES_192_KEY_LENGTH_BYTES)
260     {
261         // Writing a 192-bit key to the key store RAM must be done by writing
262         // 256 bits of data with the 64 most significant bits set to zero.
263         memcpy(paddedKey, aesKey, AES_192_KEY_LENGTH_BYTES);
264 
265         AESStartDMAOperation(paddedKey, AES_256_KEY_LENGTH_BYTES, 0, 0);
266     }
267     else
268     {
269         // Total key length in bytes (16 for 1 x 128-bit key and 32 for 1 x 256-bit key).
270         AESStartDMAOperation(aesKey, aesKeyLength, 0, 0);
271     }
272 
273     // Wait for the DMA operation to complete.
274     uint32_t irqTrigger = AESWaitForIRQFlags(CRYPTO_IRQCLR_RESULT_AVAIL | CRYPTO_IRQCLR_DMA_IN_DONE | CRYPTO_IRQSTAT_DMA_BUS_ERR | CRYPTO_IRQSTAT_KEY_ST_WR_ERR);
275 
276     // Re-enable interrupts globally.
277     IntPendClear(INT_CRYPTO_RESULT_AVAIL_IRQ);
278     IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
279 
280     // If we had a bus error or the key is not in the CRYPTO_O_KEYWRITTENAREA, return an error.
281     if ((irqTrigger & (CRYPTO_IRQSTAT_DMA_BUS_ERR_M | CRYPTO_IRQSTAT_KEY_ST_WR_ERR_M)) || !(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) & (1 << keyStoreArea))) {
282         // There was an error in writing to the keyStore.
283         return AES_KEYSTORE_ERROR;
284     }
285     else {
286         return AES_SUCCESS;
287     }
288 }
289 
290 //*****************************************************************************
291 //
292 // Transfer a key from the keyStoreArea to the internal buffer of the module.
293 //
294 //*****************************************************************************
AESReadFromKeyStore(uint32_t keyStoreArea)295 uint32_t AESReadFromKeyStore(uint32_t keyStoreArea)
296 {
297     // Check the arguments.
298     ASSERT((keyStoreArea == AES_KEY_AREA_0) ||
299            (keyStoreArea == AES_KEY_AREA_1) ||
300            (keyStoreArea == AES_KEY_AREA_2) ||
301            (keyStoreArea == AES_KEY_AREA_3) ||
302            (keyStoreArea == AES_KEY_AREA_4) ||
303            (keyStoreArea == AES_KEY_AREA_5) ||
304            (keyStoreArea == AES_KEY_AREA_6) ||
305            (keyStoreArea == AES_KEY_AREA_7));
306 
307     // Check if there is a valid key in the specified keyStoreArea
308     if (!(HWREG(CRYPTO_BASE + CRYPTO_O_KEYWRITTENAREA) & (1 << keyStoreArea))) {
309         return AES_KEYSTORE_AREA_INVALID;
310     }
311 
312     // Enable keys to read (e.g. Key 0).
313     HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) = keyStoreArea;
314 
315     // Wait until key is loaded to the AES module.
316     // We cannot simply poll the IRQ status as only an error is communicated through
317     // the IRQ status and not the completion of the transfer.
318     do {
319         CPUdelay(1);
320     }
321     while((HWREG(CRYPTO_BASE + CRYPTO_O_KEYREADAREA) & CRYPTO_KEYREADAREA_BUSY_M));
322 
323     // Check for keyStore read error.
324     if((HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT) & CRYPTO_IRQSTAT_KEY_ST_RD_ERR_M)) {
325         return AES_KEYSTORE_ERROR;
326     }
327     else {
328         return AES_SUCCESS;
329     }
330 }
331 
332 //*****************************************************************************
333 //
334 // Read the tag after a completed CCM, GCM, or CBC-MAC operation.
335 //
336 //*****************************************************************************
AESReadTag(uint8_t * tag,uint32_t tagLength)337 uint32_t AESReadTag(uint8_t *tag, uint32_t tagLength)
338 {
339     // The intermediate array is used instead of a caller-provided one
340     // to enable a simple API with no unintuitive alignment or size requirements.
341     // This is a trade-off of stack-depth vs ease-of-use that came out on the
342     // ease-of-use side.
343     uint32_t computedTag[AES_BLOCK_SIZE / sizeof(uint32_t)];
344 
345     // Wait until the computed tag is ready.
346     while (!(HWREG(CRYPTO_BASE + CRYPTO_O_AESCTL) & CRYPTO_AESCTL_SAVED_CONTEXT_RDY_M));
347 
348     // Read computed tag out from the HW registers
349     // Need to read out all 128 bits in four reads to correctly clear CRYPTO_AESCTL_SAVED_CONTEXT_RDY flag
350     computedTag[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT0);
351     computedTag[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT1);
352     computedTag[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT2);
353     computedTag[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESTAGOUT3);
354 
355     memcpy(tag, computedTag, tagLength);
356 
357     return AES_SUCCESS;
358 }
359 
360 //*****************************************************************************
361 //
362 // Verify the provided tag against the computed tag after a completed CCM or
363 // GCM operation.
364 //
365 //*****************************************************************************
AESVerifyTag(const uint8_t * tag,uint32_t tagLength)366 uint32_t AESVerifyTag(const uint8_t *tag, uint32_t tagLength)
367 {
368     uint32_t resultStatus;
369     // The intermediate array is allocated on the stack to ensure users do not
370     // point the tag they provide and the one computed at the same location.
371     // That would cause memcmp to compare an array against itself. We could add
372     // a check that verifies that the arrays are not the same. If we did that and
373     // modified AESReadTag to just copy all 128 bits into a provided array,
374     // we could save 16 bytes of stack space while making the API much more
375     // complicated.
376     uint8_t computedTag[AES_BLOCK_SIZE];
377 
378     resultStatus = AESReadTag(computedTag, tagLength);
379 
380     if (resultStatus != AES_SUCCESS) {
381         return resultStatus;
382     }
383 
384     resultStatus = memcmp(computedTag, tag, tagLength);
385 
386     if (resultStatus != 0) {
387         return AES_TAG_VERIFICATION_FAILED;
388     }
389 
390     return AES_SUCCESS;
391 }
392 
393 //*****************************************************************************
394 //
395 // Configure the AES module for CCM mode
396 //
397 //*****************************************************************************
AESConfigureCCMCtrl(uint32_t nonceLength,uint32_t macLength,bool encrypt)398 void AESConfigureCCMCtrl(uint32_t nonceLength, uint32_t macLength, bool encrypt)
399 {
400     uint32_t ctrlVal = 0;
401 
402     ctrlVal = ((15 - nonceLength - 1) << CRYPTO_AESCTL_CCM_L_S);
403     if ( macLength >= 2 ) {
404         ctrlVal |= ((( macLength - 2 ) >> 1 ) << CRYPTO_AESCTL_CCM_M_S );
405     }
406     ctrlVal |= CRYPTO_AESCTL_CCM |
407                CRYPTO_AESCTL_CTR |
408                CRYPTO_AESCTL_SAVE_CONTEXT |
409                CRYPTO_AESCTL_CTR_WIDTH_128_BIT;
410     ctrlVal |= encrypt ? CRYPTO_AESCTL_DIR : 0;
411 
412     AESSetCtrl(ctrlVal);
413 }
414 
415 //*****************************************************************************
416 //
417 // Configure an IV for CCM mode of operation
418 //
419 //*****************************************************************************
AESWriteCCMInitializationVector(const uint8_t * nonce,uint32_t nonceLength)420 void AESWriteCCMInitializationVector(const uint8_t *nonce, uint32_t nonceLength)
421 {
422     union {
423         uint32_t word[4];
424         uint8_t  byte[16];
425     } initializationVector = {{0}};
426 
427     initializationVector.byte[0] = 15 - nonceLength - 1;
428 
429     memcpy(&(initializationVector.byte[1]), nonce, nonceLength);
430 
431     AESSetInitializationVector(initializationVector.word);
432 }
433 
434 //*****************************************************************************
435 //
436 // Write AES_KEY2 registers
437 //
438 //*****************************************************************************
AESWriteKey2(const uint32_t * key2)439 void AESWriteKey2(const uint32_t *key2) {
440     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY20) = key2[0];
441     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY21) = key2[1];
442     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY22) = key2[2];
443     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY23) = key2[3];
444 }
445 
446 //*****************************************************************************
447 //
448 // Write AES_KEY3 register
449 //
450 //*****************************************************************************
AESWriteKey3(const uint32_t * key3)451 void AESWriteKey3(const uint32_t *key3) {
452     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY30) = key3[0];
453     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY31) = key3[1];
454     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY32) = key3[2];
455     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY33) = key3[3];
456 }
457 
458 //*****************************************************************************
459 //
460 // Clear AES_DATA_IN registers
461 //
462 //*****************************************************************************
AESClearDataIn(void)463 void AESClearDataIn(void) {
464     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN0) = 0;
465     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN1) = 0;
466     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN2) = 0;
467     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN3) = 0;
468 }
469 
470 //*****************************************************************************
471 //
472 // Write AES_DATA_IN registers
473 //
474 //*****************************************************************************
AESWriteDataIn(const uint32_t * dataInBuffer)475 void AESWriteDataIn(const uint32_t *dataInBuffer) {
476     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN0) = dataInBuffer[0];
477     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN1) = dataInBuffer[1];
478     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN2) = dataInBuffer[2];
479     HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAIN3) = dataInBuffer[3];
480 }
481 
482 //*****************************************************************************
483 //
484 // Read AES_DATA_OUT registers
485 //
486 //*****************************************************************************
AESReadDataOut(uint32_t * dataOutBuffer)487 void AESReadDataOut(uint32_t *dataOutBuffer) {
488     dataOutBuffer[0] = HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAOUT0);
489     dataOutBuffer[1] = HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAOUT1);
490     dataOutBuffer[2] = HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAOUT2);
491     dataOutBuffer[3] = HWREG(CRYPTO_BASE + CRYPTO_O_AESDATAOUT3);
492 }
493 
494 //*****************************************************************************
495 //
496 // Clear AES_KEY2 registers
497 //
498 //*****************************************************************************
AESClearKey2(void)499 void AESClearKey2(void) {
500     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY20) = 0;
501     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY21) = 0;
502     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY22) = 0;
503     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY23) = 0;
504 }
505 
506 //*****************************************************************************
507 //
508 // Clear AES_KEY3 registers
509 //
510 //*****************************************************************************
AESClearKey3(void)511 void AESClearKey3(void) {
512     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY30) = 0;
513     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY31) = 0;
514     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY32) = 0;
515     HWREG(CRYPTO_BASE + CRYPTO_O_AESKEY33) = 0;
516 }
517 
518 
519 //*****************************************************************************
520 //
521 // Reset crypto engine
522 //
523 //*****************************************************************************
AESReset(void)524 void AESReset(void)
525 {
526     /* Soft reset routine per SafeXcel */
527     HWREG(CRYPTO_BASE + CRYPTO_O_SWRESET) = CRYPTO_SWRESET_SW_RESET;
528     AESSetCtrl(0);
529     AESSetDataLength(0);
530     AESSetAuthLength(0);
531 
532     /* Only CC26X2, CC13X2, CC26X2F6, CC13X2F6, CC26X4, and CC13X4 devices have hash support */
533     HWREG(CRYPTO_BASE + CRYPTO_O_HASHMODE) = 0;
534     HWREG(CRYPTO_BASE + CRYPTO_O_HASHINLENL) = 0;
535     /* CRYPTO_O_HASHINLENH is automatically set to 0 by HW */
536 }
537 
538 //*****************************************************************************
539 //
540 // Reset crypto DMA
541 //
542 //*****************************************************************************
AESDMAReset(void)543 void AESDMAReset(void)
544 {
545     /* Reset DMA */
546     HWREG(CRYPTO_BASE + CRYPTO_O_DMASWRESET) = CRYPTO_DMASWRESET_SWRES;
547 
548     /* Wait for DMA channels to be inactive */
549     while (HWREG(CRYPTO_BASE + CRYPTO_O_DMASTAT) &
550            (CRYPTO_DMASTAT_CH0_ACT | CRYPTO_DMASTAT_CH1_ACT));
551 }
552