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