1 /*
2 * Copyright (c) 2015-2019, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <stdint.h>
34 #include <stdbool.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*
39 * By default disable both asserts and log for this module.
40 * This must be done before DebugP.h is included.
41 */
42 #ifndef DebugP_ASSERT_ENABLED
43 #define DebugP_ASSERT_ENABLED 0
44 #endif
45 #ifndef DebugP_LOG_ENABLED
46 #define DebugP_LOG_ENABLED 0
47 #endif
48
49 #include <ti/drivers/dpl/DebugP.h>
50 #include <ti/drivers/dpl/ClockP.h>
51 #include <ti/drivers/dpl/HwiP.h>
52 #include <ti/drivers/dpl/SemaphoreP.h>
53
54 #include <ti/drivers/Power.h>
55 #include <ti/drivers/power/PowerCC32XX.h>
56
57 #include <ti/drivers/crypto/CryptoCC32XX.h>
58 #include <ti/drivers/cryptoutils/utils/CryptoUtils.h>
59
60 #include <ti/devices/cc32xx/inc/hw_types.h>
61 #include <ti/devices/cc32xx/inc/hw_ints.h>
62 #include <ti/devices/cc32xx/inc/hw_memmap.h>
63 #include <ti/devices/cc32xx/inc/hw_shamd5.h>
64 #include <ti/devices/cc32xx/driverlib/rom.h>
65 #include <ti/devices/cc32xx/driverlib/rom_map.h>
66 #include <ti/devices/cc32xx/driverlib/aes.h>
67 #include <ti/devices/cc32xx/driverlib/des.h>
68 #include <ti/devices/cc32xx/driverlib/shamd5.h>
69 #include <ti/devices/cc32xx/driverlib/prcm.h>
70
71
72 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_MD5 16
73 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA1 20
74 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA224 28
75 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256 32
76
77 #define CryptoCC32XX_CONTEXT_READY_MAX_COUNTER 1000
78
79 #define CryptoCC32XX_SHAMD5GetSignatureSize(_mode) ((_mode == SHAMD5_ALGO_MD5) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_MD5: \
80 (_mode == SHAMD5_ALGO_SHA1) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA1: \
81 (_mode == SHAMD5_ALGO_SHA224) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA224: \
82 (_mode == SHAMD5_ALGO_SHA256) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256:0)
83
84 #define SHAMD5_SIGNATURE_MAX_LEN CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256
85 typedef int8_t CryptoCC32XX_SHAMD5Signature[SHAMD5_SIGNATURE_MAX_LEN];
86
87 typedef struct {
88 /*! Crypto Peripheral's interrupt handler */
89 HwiP_Fxn hwiIntFxn;
90 /*! Crypto Peripheral's interrupt vector */
91 uint32_t intNum;
92 /*! Crypto Peripheral's interrupt priority */
93 uint32_t intPriority;
94 } CryptoCC32XX_HwiP;
95
96 /* Prototypes */
97 int32_t CryptoCC32XX_aesProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t* pInBuff, uint16_t inLen, uint8_t* pOutBuff , CryptoCC32XX_EncryptParams* pParams);
98 int32_t CryptoCC32XX_desProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t* pInBuff, uint16_t inLen, uint8_t* pOutBuff , CryptoCC32XX_EncryptParams* pParams);
99 int32_t CryptoCC32XX_shamd5Process(uint32_t cryptoMode , uint8_t* pBuff, uint32_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams* pParams);
100 void CryptoCC32XX_aesIntHandler(void);
101 void CryptoCC32XX_desIntHandler(void);
102 void CryptoCC32XX_shamd5IntHandler(void);
103 HwiP_Handle CryptoCC32XX_register(CryptoCC32XX_Handle handle, CryptoCC32XX_HwiP *hwiP);
104 void CryptoCC32XX_unregister(HwiP_Handle handle);
105
106
107 /* Crypto CC32XX interrupts implementation */
108 CryptoCC32XX_HwiP CryptoCC32XX_HwiPTable[] = {
109 { (HwiP_Fxn)CryptoCC32XX_aesIntHandler, INT_AES, (~0) }, /* AES */
110 { (HwiP_Fxn)CryptoCC32XX_desIntHandler, INT_DES, (~0) }, /* DES */
111 { (HwiP_Fxn)CryptoCC32XX_shamd5IntHandler, INT_SHA, (~0) } /* SHAMD5 */
112 };
113
114 /* Crypto AES key size to Crypto CC32XX AES key size */
115 #define CryptoCC32XX_getAesKeySize(_keySize) ( \
116 (_keySize == CryptoCC32XX_AES_KEY_SIZE_128BIT)? AES_CFG_KEY_SIZE_128BIT: \
117 (_keySize == CryptoCC32XX_AES_KEY_SIZE_192BIT)? AES_CFG_KEY_SIZE_192BIT: \
118 (_keySize == CryptoCC32XX_AES_KEY_SIZE_256BIT)? AES_CFG_KEY_SIZE_256BIT: \
119 CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED)
120
121 /* Crypto DES key size to Crypto CC32XX DES key size */
122 #define CryptoCC32XX_getDesKeySize(_keySize) ( \
123 (_keySize == CryptoCC32XX_DES_KEY_SIZE_SINGLE)? DES_CFG_SINGLE: \
124 (_keySize == CryptoCC32XX_DES_KEY_SIZE_TRIPLE)? DES_CFG_TRIPLE: \
125 CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED)
126
127 /* Crypto method to Crypto CC32XX mode */
128 #define CryptoCC32XX_getMode(_method) ( \
129 (_method == CryptoCC32XX_AES_ECB)? AES_CFG_MODE_ECB: \
130 (_method == CryptoCC32XX_AES_CBC)? AES_CFG_MODE_CBC: \
131 (_method == CryptoCC32XX_AES_CTR)? AES_CFG_MODE_CTR: \
132 (_method == CryptoCC32XX_AES_ICM)? AES_CFG_MODE_ICM: \
133 (_method == CryptoCC32XX_AES_CFB)? AES_CFG_MODE_CFB: \
134 (_method == CryptoCC32XX_AES_GCM)? AES_CFG_MODE_GCM_HY0CALC: \
135 (_method == CryptoCC32XX_AES_CCM)? AES_CFG_MODE_CCM: \
136 (_method == CryptoCC32XX_DES_ECB)? DES_CFG_MODE_ECB: \
137 (_method == CryptoCC32XX_DES_CBC)? DES_CFG_MODE_CBC: \
138 (_method == CryptoCC32XX_DES_CFB)? DES_CFG_MODE_CFB: \
139 (_method == CryptoCC32XX_HMAC_MD5)? SHAMD5_ALGO_MD5: \
140 (_method == CryptoCC32XX_HMAC_SHA1)? SHAMD5_ALGO_SHA1: \
141 (_method == CryptoCC32XX_HMAC_SHA224)? SHAMD5_ALGO_SHA224: \
142 (_method == CryptoCC32XX_HMAC_SHA256)? SHAMD5_ALGO_SHA256: \
143 CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED)
144
145
146 /* global variables for the interrupt handles */
147 static volatile bool g_bAESReadyFlag;
148 static volatile bool g_bDESReadyFlag;
149 static volatile bool g_bSHAMD5ReadyFlag;
150
151 /* Externs */
152 extern const CryptoCC32XX_Config CryptoCC32XX_config[];
153 extern const uint8_t CryptoCC32XX_count;
154
155
156 /*
157 * ======== CryptoCC32XX_close ========
158 */
CryptoCC32XX_close(CryptoCC32XX_Handle handle)159 void CryptoCC32XX_close(CryptoCC32XX_Handle handle)
160 {
161 uintptr_t key;
162 CryptoCC32XX_Object *object = handle->object;
163 int32_t type;
164
165 /* Mask Crypto interrupts */
166
167
168 /* Power off the Crypto module */
169 Power_releaseDependency(PowerCC32XX_PERIPH_DTHE);
170
171 for (type = 0; type < CryptoCC32XX_MAX_TYPES;type++)
172 {
173 if (object->sem[type] != NULL)
174 {
175 SemaphoreP_delete(object->sem[type]);
176 }
177 if (object->hwiHandle[type] != NULL)
178 {
179 CryptoCC32XX_unregister(object->hwiHandle[type]);
180 }
181 }
182
183 /* Mark the module as available */
184 key = HwiP_disable();
185
186 object->isOpen = false;
187
188 HwiP_restore(key);
189
190 return;
191 }
192
193
194 /*
195 * ======== CryptoCC32XX_init ========
196 */
CryptoCC32XX_init(void)197 void CryptoCC32XX_init(void)
198 {
199 }
200
201 /*
202 * ======== CryptoCC32XX_open ========
203 */
CryptoCC32XX_open(uint32_t index,uint32_t types)204 CryptoCC32XX_Handle CryptoCC32XX_open(uint32_t index, uint32_t types)
205 {
206 CryptoCC32XX_Handle handle;
207 uintptr_t key;
208 CryptoCC32XX_Object *object;
209 SemaphoreP_Params semParams;
210 int32_t type;
211
212
213 if (index >= CryptoCC32XX_count)
214 {
215 return (NULL);
216 }
217
218 /* Get handle for this driver instance */
219 handle = (CryptoCC32XX_Handle)&(CryptoCC32XX_config[index]);
220 object = handle->object;
221
222 /* Determine if the device index was already opened */
223 key = HwiP_disable();
224 if(object->isOpen == true)
225 {
226 HwiP_restore(key);
227 return (NULL);
228 }
229
230 /* Mark the handle as being used */
231 object->isOpen = true;
232 HwiP_restore(key);
233
234 /* Power on the Crypto module */
235 Power_setDependency(PowerCC32XX_PERIPH_DTHE);
236 MAP_PRCMPeripheralReset(PRCM_DTHE);
237
238 /* create the semaphore for each crypto type*/
239 SemaphoreP_Params_init(&semParams);
240 semParams.mode = SemaphoreP_Mode_BINARY;
241 for (type=0 ;type < CryptoCC32XX_MAX_TYPES; type++)
242 {
243 if ((types & (1<<type)) != 0)
244 {
245 object->sem[type] = SemaphoreP_create(1, &semParams);
246 if (object->sem[type] == NULL)
247 {
248 CryptoCC32XX_close(handle);
249 return (NULL);
250 }
251 /* interrupt handler */
252 object->hwiHandle[type] = CryptoCC32XX_register(handle,&CryptoCC32XX_HwiPTable[type]);
253 if (object->hwiHandle[type] == NULL)
254 {
255 CryptoCC32XX_close(handle);
256 return (NULL);
257 }
258 }
259 else
260 {
261 object->sem[type] = NULL;
262 }
263 }
264 /* Return the address of the handle */
265 return (handle);
266 }
267
268 /*
269 * ======== CryptoCC32XX_HmacParams_init ========
270 */
CryptoCC32XX_HmacParams_init(CryptoCC32XX_HmacParams * params)271 void CryptoCC32XX_HmacParams_init(CryptoCC32XX_HmacParams *params)
272 {
273 memset(params, 0, sizeof(CryptoCC32XX_HmacParams));
274 params->first = 1;
275 /* All supported hashing algorithms block size are equal, set one as default */
276 params->blockSize = CryptoCC32XX_SHA256_BLOCK_SIZE;
277 }
278
279 /*
280 * ======== CryptoCC32XX_encrypt ========
281 */
CryptoCC32XX_encrypt(CryptoCC32XX_Handle handle,CryptoCC32XX_EncryptMethod method,void * pInBuff,size_t inLen,void * pOutBuff,size_t * outLen,CryptoCC32XX_EncryptParams * pParams)282 int32_t CryptoCC32XX_encrypt(CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method , void *pInBuff, size_t inLen, void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams)
283 {
284 CryptoCC32XX_Object *object = handle->object;
285 uint8_t cryptoType = method >> 8;
286 uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method);
287 int32_t status = CryptoCC32XX_STATUS_ERROR;
288 /* Convert crypto type bitwise to index */
289 uint8_t cryptoIndex = cryptoType >> 1;
290
291 /* check semaphore created */
292 if (object->sem[cryptoIndex] == NULL)
293 {
294 return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED;
295 }
296 /* get the semaphore */
297 if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex],
298 SemaphoreP_WAIT_FOREVER))
299 {
300 switch (cryptoType)
301 {
302 case CryptoCC32XX_AES:
303 status = CryptoCC32XX_aesProcess(cryptoMode , AES_CFG_DIR_ENCRYPT, pInBuff, inLen, pOutBuff , pParams);
304 break;
305 case CryptoCC32XX_DES:
306 status = CryptoCC32XX_desProcess(cryptoMode , DES_CFG_DIR_ENCRYPT, pInBuff, inLen, pOutBuff , pParams);
307 break;
308 default:
309 break;
310 }
311
312 /* release the semaphore */
313 SemaphoreP_post(object->sem[cryptoIndex]);
314 }
315 return status;
316 }
317
318 /*
319 * ======== CryptoCC32XX_decrypt ========
320 */
CryptoCC32XX_decrypt(CryptoCC32XX_Handle handle,CryptoCC32XX_EncryptMethod method,void * pInBuff,size_t inLen,void * pOutBuff,size_t * outLen,CryptoCC32XX_EncryptParams * pParams)321 int32_t CryptoCC32XX_decrypt(CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method , void *pInBuff, size_t inLen, void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams)
322 {
323 CryptoCC32XX_Object *object = handle->object;
324 uint8_t cryptoType = method >> 8;
325 uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method);
326 int32_t status = CryptoCC32XX_STATUS_ERROR;
327 /* Convert crypto type bitwise to index */
328 uint8_t cryptoIndex = cryptoType >> 1;
329
330 /* check semaphore created */
331 if (object->sem[cryptoIndex] == NULL)
332 {
333 return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED;
334 }
335 /* get the semaphore */
336 if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex],
337 SemaphoreP_WAIT_FOREVER))
338 {
339 switch (cryptoType)
340 {
341 case CryptoCC32XX_AES:
342 status = CryptoCC32XX_aesProcess(cryptoMode , AES_CFG_DIR_DECRYPT, pInBuff, inLen, pOutBuff , pParams);
343 break;
344 case CryptoCC32XX_DES:
345 status = CryptoCC32XX_desProcess(cryptoMode , DES_CFG_DIR_DECRYPT, pInBuff, inLen, pOutBuff , pParams);
346 break;
347 default:
348 break;
349 }
350 /* release the semaphore */
351 SemaphoreP_post(object->sem[cryptoIndex]);
352 }
353 return status;
354 }
355
356
357 /*
358 * ======== CryptoCC32XX_sign ========
359 */
CryptoCC32XX_sign(CryptoCC32XX_Handle handle,CryptoCC32XX_HmacMethod method,void * pBuff,size_t len,uint8_t * pSignature,CryptoCC32XX_HmacParams * pParams)360 int32_t CryptoCC32XX_sign(CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method , void *pBuff, size_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams)
361 {
362 CryptoCC32XX_Object *object = handle->object;
363 uint8_t cryptoType = CryptoCC32XX_HMAC;
364 uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method);
365 int32_t status = CryptoCC32XX_STATUS_ERROR;
366 /* Convert crypto type bitwise to index */
367 uint8_t cryptoIndex = cryptoType >> 1;
368
369 /* check semaphore created */
370 if (object->sem[cryptoIndex] == NULL)
371 {
372 return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED;
373 }
374 /* get the semaphore */
375 if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex],
376 SemaphoreP_WAIT_FOREVER))
377 {
378 switch (cryptoType)
379 {
380 case CryptoCC32XX_HMAC:
381 status = CryptoCC32XX_shamd5Process(cryptoMode , pBuff, len, pSignature , pParams);
382 break;
383 default:
384 break;
385 }
386 /* release the semaphore */
387 SemaphoreP_post(object->sem[cryptoIndex]);
388 }
389 return status;
390 }
391
392 /*
393 * ======== CryptoCC32XX_verify ========
394 */
CryptoCC32XX_verify(CryptoCC32XX_Handle handle,CryptoCC32XX_HmacMethod method,void * pBuff,size_t len,uint8_t * pSignature,CryptoCC32XX_HmacParams * pParams)395 int32_t CryptoCC32XX_verify(CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method , void *pBuff, size_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams)
396 {
397 CryptoCC32XX_Object *object = handle->object;
398 uint8_t cryptoType = CryptoCC32XX_HMAC;
399 uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method);
400 int32_t status = CryptoCC32XX_STATUS_ERROR;
401 uint16_t shamd5SignatureSize;
402 CryptoCC32XX_SHAMD5Signature shamd5Signature;
403 /* Convert crypto type bitwise to index */
404 uint8_t cryptoIndex = cryptoType >> 1;
405
406 /* check semaphore created */
407 if (object->sem[cryptoIndex] == NULL)
408 {
409 return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED;
410 }
411 /* get the semaphore */
412 if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex],
413 SemaphoreP_WAIT_FOREVER))
414 {
415 switch (cryptoType)
416 {
417 case CryptoCC32XX_HMAC:
418 shamd5SignatureSize = CryptoCC32XX_SHAMD5GetSignatureSize(cryptoMode);
419 if (shamd5SignatureSize > 0)
420 {
421 if (pParams->moreData == 0)
422 {
423 /* save the received signature */
424 memcpy(shamd5Signature,pSignature,shamd5SignatureSize);
425 }
426 /* calculate the signature */
427 status = CryptoCC32XX_shamd5Process(cryptoMode , pBuff, len, pSignature , pParams);
428 /* compare the calculated signature to the received signature */
429 if (status == CryptoCC32XX_STATUS_SUCCESS)
430 {
431 if (pParams->moreData == 0)
432 {
433 if (CryptoUtils_buffersMatch(shamd5Signature, pSignature, shamd5SignatureSize) != true)
434 {
435 status = CryptoCC32XX_STATUS_ERROR_VERIFY;
436 }
437 }
438 }
439 }
440 break;
441 default:
442 break;
443 }
444 /* release the semaphore */
445 SemaphoreP_post(object->sem[cryptoIndex]);
446 }
447 return status;
448 }
449
450 /*
451 * ======== CryptoCC32XX_shamd5Process ========
452 */
CryptoCC32XX_shamd5Process(uint32_t cryptoMode,uint8_t * pBuff,uint32_t len,uint8_t * pSignature,CryptoCC32XX_HmacParams * pParams)453 int32_t CryptoCC32XX_shamd5Process(uint32_t cryptoMode , uint8_t *pBuff, uint32_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams)
454 {
455 int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER;
456 uint32_t blockComplementLen = 0;
457 uint32_t newLen = 0;
458 uint32_t copyLen = 0;
459 uint32_t totalLen = 0;
460 uint32_t blockRemainder = 0;
461 /*
462 Step1: Enable Interrupts
463 Step2: Wait for Context Ready Interrupt
464 Step3: Set the Configuration Parameters (Hash Algorithm)
465 Step4: Set Key
466 Step5: Start Hash Generation
467 */
468
469 if((pBuff == NULL) || (0 == len))
470 {
471 return CryptoCC32XX_STATUS_ERROR;
472 }
473
474 /* Clear the flag */
475 g_bSHAMD5ReadyFlag = false;
476
477 /* Enable interrupts. */
478 MAP_SHAMD5IntEnable(SHAMD5_BASE, SHAMD5_INT_CONTEXT_READY |
479 SHAMD5_INT_PARTHASH_READY |
480 SHAMD5_INT_INPUT_READY |
481 SHAMD5_INT_OUTPUT_READY);
482
483 /* Wait for the context ready flag. */
484 while ((!g_bSHAMD5ReadyFlag) && (count > 0))
485 {
486 count --;
487 }
488 if (count == 0)
489 {
490 return CryptoCC32XX_STATUS_ERROR;
491 }
492
493 if (pParams->moreData == 1)
494 {
495 /* Less than block size available. Copy the received data to the internal buffer and return */
496 if((pParams->buffLen + len) < pParams->blockSize)
497 {
498 memcpy(&pParams->buff[pParams->buffLen], pBuff, len);
499 pParams->buffLen += len;
500 return CryptoCC32XX_STATUS_SUCCESS;
501 }
502
503 if(pParams->first)
504 {
505 /* If Keyed Hashing is used, set Key */
506 if (pParams->pKey != NULL)
507 {
508 MAP_SHAMD5HMACKeySet(SHAMD5_BASE, pParams->pKey);
509 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 0, 1, 0);
510 }
511 else
512 {
513 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 1, 0, 0, 0);
514 }
515
516 /* Will write data in this iteration. Unset first */
517 pParams->first = 0;
518 }
519 else
520 {
521 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 0, 0, 0);
522 /* Write the intermediate digest and count in case it isn't the first round */
523 SHAMD5ResultWrite(SHAMD5_BASE, pParams->innerDigest);
524 SHAMD5WriteDigestCount(SHAMD5_BASE, pParams->digestCount);
525 }
526 }
527 else
528 {
529 if(pParams->first)
530 {
531 /* If Keyed Hashing is used, set Key */
532 if (pParams->pKey != NULL)
533 {
534 MAP_SHAMD5HMACKeySet(SHAMD5_BASE, pParams->pKey);
535 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 1, 1);
536 }
537 else
538 {
539 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 1, 1, 0, 0);
540 }
541 }
542 else
543 {
544 /* Write the intermediate digest and count in case it isn't the first round */
545 SHAMD5ResultWrite(SHAMD5_BASE, pParams->innerDigest);
546 SHAMD5WriteDigestCount(SHAMD5_BASE, pParams->digestCount);
547 if (pParams->pKey != NULL)
548 {
549 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 0, 1);
550 }
551 else
552 {
553 MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 0, 0);
554 }
555
556 /* This is the last iteration for the requested calculation */
557 /* Set the first flag to 1 (initial value) for next calculations */
558 pParams->first = 1;
559 }
560 }
561
562 /* Set the length of the data that will be written to the SHA module in this iteration */
563 /* In case it isn't the last iteration, it has to be an integer multiple of block size */
564 if (pParams->moreData)
565 {
566 totalLen = ((pParams->buffLen + len) / pParams->blockSize) * pParams->blockSize;
567 }
568 else
569 {
570 totalLen = pParams->buffLen + len;
571 }
572 SHAMD5DataLengthSet(SHAMD5_BASE, totalLen);
573
574 /* In case there is data in the internal buffer, complement to a block size (if the length is sufficient) and write */
575 if (pParams->buffLen)
576 {
577 blockComplementLen = pParams->blockSize - pParams->buffLen;
578 /* Copy to the internal buffer */
579 /* The length to copy is the minimum between the block complement and the data length */
580 copyLen = len < blockComplementLen ? len : blockComplementLen;
581 memcpy(&pParams->buff[pParams->buffLen], pBuff, copyLen);
582 pParams->buffLen += copyLen;
583
584 /* If buffLen is smaller than block size this must be the last iteration */
585 /* Write and set the buffer and buffer length to zero */
586 SHAMD5DataWriteMultiple(SHAMD5_BASE, pParams->buff, pParams->buffLen);
587 pParams->buffLen = 0;
588 memset(pParams->buff, 0, sizeof(pParams->buff));
589 }
590
591 /* If data length is greater than block complement, write the rest of the data */
592 if (len > blockComplementLen)
593 {
594 newLen= len - blockComplementLen;
595 pBuff += blockComplementLen;
596 }
597
598 if (pParams->moreData)
599 {
600 /* Remaining length is smaller than block size - Save data to the internal buffer */
601 if (newLen < pParams->blockSize)
602 {
603 memcpy(&pParams->buff[pParams->buffLen], pBuff, newLen);
604 pParams->buffLen = newLen;
605 }
606 /* Remaining length is greater than block size - write blocks and save remainder to the internal buffer */
607 else
608 {
609 blockRemainder = newLen % pParams->blockSize;
610 newLen -= blockRemainder;
611 SHAMD5DataWriteMultiple(SHAMD5_BASE, pBuff, newLen);
612
613 if (blockRemainder)
614 {
615 pBuff += newLen;
616 memcpy(&pParams->buff[pParams->buffLen], pBuff, blockRemainder);
617 pParams->buffLen += blockRemainder;
618 }
619 }
620 }
621 else
622 {
623 /* Last iteration, write all the data */
624 if (newLen)
625 {
626 SHAMD5DataWriteMultiple(SHAMD5_BASE, pBuff, newLen);
627 }
628 }
629
630 /* Wait for the output to be ready */
631 while((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) == 0)
632 {
633 }
634
635 /* Read the result */
636 if (pParams->moreData == 1)
637 {
638 /* Read the digest and count to an internal parameter (will be used in the next iteration) */
639 MAP_SHAMD5ResultRead(SHAMD5_BASE, pParams->innerDigest);
640 SHAMD5ReadDigestCount(SHAMD5_BASE, &(pParams->digestCount));
641 }
642 else
643 {
644 /* Read the final digest result to an outer pointer */
645 MAP_SHAMD5ResultRead(SHAMD5_BASE, pSignature);
646 }
647
648 return CryptoCC32XX_STATUS_SUCCESS;
649 }
650
651 /*
652 * ======== CryptoCC32XX_aesProcess ========
653 */
CryptoCC32XX_aesProcess(uint32_t cryptoMode,uint32_t cryptoDirection,uint8_t * pInBuff,uint16_t inLen,uint8_t * pOutBuff,CryptoCC32XX_EncryptParams * pParams)654 int32_t CryptoCC32XX_aesProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t *pInBuff, uint16_t inLen, uint8_t *pOutBuff , CryptoCC32XX_EncryptParams *pParams)
655 {
656 int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER;
657 /*
658 Step1: Enable Interrupts
659 Step2: Wait for Context Ready Interrupt
660 Step3: Set the Configuration Parameters (Direction,AES Mode and Key Size)
661 Step4: Set the Initialization Vector
662 Step5: Write Key
663 Step6: Start the Crypt Process
664 */
665
666 /* Clear the flag. */
667 g_bAESReadyFlag = false;
668
669 /* Enable all interrupts. */
670 MAP_AESIntEnable(AES_BASE, AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT);
671
672 /* Wait for the context in flag, the flag will be set in the Interrupt handler. */
673 while((!g_bAESReadyFlag) && (count > 0))
674 {
675 count --;
676 }
677 if (count == 0)
678 {
679 return CryptoCC32XX_STATUS_ERROR;
680 }
681
682 /* Configure the AES module with direction (encryption or decryption) and */
683 /* the key size. */
684 MAP_AESConfigSet(AES_BASE, cryptoDirection | cryptoMode | CryptoCC32XX_getAesKeySize(pParams->aes.keySize));
685
686 /* Write the initial value registers if needed, depends on the mode. */
687 if ((cryptoMode == AES_CFG_MODE_CBC) || (cryptoMode == AES_CFG_MODE_CFB) ||
688 (cryptoMode == AES_CFG_MODE_CTR) || (cryptoMode == AES_CFG_MODE_ICM) ||
689 (cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC))
690 {
691 MAP_AESIVSet(AES_BASE, pParams->aes.pIV);
692 }
693
694
695 /* Write key1. */
696 MAP_AESKey1Set(AES_BASE, (uint8_t *)pParams->aes.pKey,CryptoCC32XX_getAesKeySize(pParams->aes.keySize));
697
698 /* Write key2. */
699 if (cryptoMode == AES_CFG_MODE_CCM)
700 {
701 MAP_AESKey2Set(AES_BASE, pParams->aes.aadParams.input.pKey2, CryptoCC32XX_getAesKeySize(pParams->aes.aadParams.input.key2Size));
702 }
703
704 /* Start Crypt Process */
705 if ((cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC))
706 {
707 MAP_AESDataProcessAE(AES_BASE, (uint8_t *)(pInBuff+(pParams->aes.aadParams.input.len)), pOutBuff ,inLen, pInBuff, pParams->aes.aadParams.input.len, pParams->aes.aadParams.tag);
708
709 }
710 else
711 {
712 MAP_AESDataProcess(AES_BASE, pInBuff, pOutBuff, inLen);
713 }
714
715 /* Read the initial value registers if needed, depends on the mode. */
716 if ((cryptoMode == AES_CFG_MODE_CBC) || (cryptoMode == AES_CFG_MODE_CFB) ||
717 (cryptoMode == AES_CFG_MODE_CTR) || (cryptoMode == AES_CFG_MODE_ICM) ||
718 (cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC))
719 {
720 MAP_AESIVGet(AES_BASE, pParams->aes.pIV);
721 }
722
723 return CryptoCC32XX_STATUS_SUCCESS;
724
725 }
726
727 /*
728 * ======== CryptoCC32XX_desProcess ========
729 */
CryptoCC32XX_desProcess(uint32_t cryptoMode,uint32_t cryptoDirection,uint8_t * pInBuff,uint16_t inLen,uint8_t * pOutBuff,CryptoCC32XX_EncryptParams * pParams)730 int32_t CryptoCC32XX_desProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t *pInBuff, uint16_t inLen, uint8_t *pOutBuff , CryptoCC32XX_EncryptParams *pParams)
731 {
732 int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER;
733
734 /*
735 Step1: Enable Interrupts
736 Step2: Wait for Context Ready Interrupt
737 Step3: Set the Configuration Parameters (Direction,AES Mode)
738 Step4: Set the Initialization Vector
739 Step5: Write Key
740 Step6: Start the Crypt Process
741 */
742
743 /* Clear the flag. */
744 g_bDESReadyFlag = false;
745
746 /* Enable all interrupts. */
747 MAP_DESIntEnable(DES_BASE, DES_INT_CONTEXT_IN | DES_INT_DATA_IN | DES_INT_DATA_OUT);
748
749 /* Wait for the context in flag. */
750 while((!g_bDESReadyFlag) && (count > 0))
751 {
752 count --;
753 }
754 if (count == 0)
755 {
756 return CryptoCC32XX_STATUS_ERROR;
757 }
758
759 /* Configure the DES module. */
760 MAP_DESConfigSet(DES_BASE, cryptoDirection | cryptoMode | CryptoCC32XX_getDesKeySize(pParams->des.keySize));
761
762 /* Set the key. */
763 MAP_DESKeySet(DES_BASE, (uint8_t *)pParams->des.pKey);
764
765 /* Write the initial value registers if needed. */
766 if((cryptoMode & DES_CFG_MODE_CBC) || (cryptoMode & DES_CFG_MODE_CFB))
767 {
768 MAP_DESIVSet(DES_BASE, pParams->des.pIV);
769 }
770
771 MAP_DESDataProcess(DES_BASE, pInBuff, pOutBuff,inLen);
772 return CryptoCC32XX_STATUS_SUCCESS;
773 }
774
775
776 /*
777 * ======== CryptoCC32XX_aesIntHandler ========
778 */
CryptoCC32XX_aesIntHandler(void)779 void CryptoCC32XX_aesIntHandler(void)
780 {
781 uint32_t uiIntStatus;
782
783 /* Read the AES masked interrupt status. */
784 uiIntStatus = MAP_AESIntStatus(AES_BASE, true);
785
786 /* Set Different flags depending on the interrupt source. */
787 if(uiIntStatus & AES_INT_CONTEXT_IN)
788 {
789 MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_IN);
790 g_bAESReadyFlag = true;
791 }
792 if(uiIntStatus & AES_INT_DATA_IN)
793 {
794 MAP_AESIntDisable(AES_BASE, AES_INT_DATA_IN);
795 }
796 if(uiIntStatus & AES_INT_CONTEXT_OUT)
797 {
798 MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_OUT);
799 }
800 if(uiIntStatus & AES_INT_DATA_OUT)
801 {
802 MAP_AESIntDisable(AES_BASE, AES_INT_DATA_OUT);
803 }
804 }
805
806 /*
807 * ======== CryptoCC32XX_desIntHandler ========
808 */
CryptoCC32XX_desIntHandler(void)809 void CryptoCC32XX_desIntHandler(void)
810 {
811 uint32_t ui32IntStatus;
812
813 /* Read the DES masked interrupt status. */
814 ui32IntStatus = MAP_DESIntStatus(DES_BASE, true);
815
816 /* set flags depending on the interrupt source. */
817 if(ui32IntStatus & DES_INT_CONTEXT_IN)
818 {
819 MAP_DESIntDisable(DES_BASE, DES_INT_CONTEXT_IN);
820 g_bDESReadyFlag = true;
821 }
822 if(ui32IntStatus & DES_INT_DATA_IN)
823 {
824 MAP_DESIntDisable(DES_BASE, DES_INT_DATA_IN);
825 }
826 if(ui32IntStatus & DES_INT_DATA_OUT)
827 {
828 MAP_DESIntDisable(DES_BASE, DES_INT_DATA_OUT);
829 }
830 }
831
832 /*
833 * ======== CryptoCC32XX_shamd5IntHandler ========
834 */
CryptoCC32XX_shamd5IntHandler(void)835 void CryptoCC32XX_shamd5IntHandler(void)
836 {
837 uint32_t ui32IntStatus;
838
839 /* Read the SHA/MD5 masked interrupt status. */
840 ui32IntStatus = MAP_SHAMD5IntStatus(SHAMD5_BASE, true);
841
842 if(ui32IntStatus & SHAMD5_INT_CONTEXT_READY)
843 {
844 MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_CONTEXT_READY);
845 g_bSHAMD5ReadyFlag = true;
846 }
847 if(ui32IntStatus & SHAMD5_INT_PARTHASH_READY)
848 {
849 MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_PARTHASH_READY);
850 }
851 if(ui32IntStatus & SHAMD5_INT_INPUT_READY)
852 {
853 MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_INPUT_READY);
854 }
855 if(ui32IntStatus & SHAMD5_INT_OUTPUT_READY)
856 {
857 MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_OUTPUT_READY);
858 }
859 }
860
861 /*
862 * ======== CryptoCC32XX_register ========
863 */
CryptoCC32XX_register(CryptoCC32XX_Handle handle,CryptoCC32XX_HwiP * hwiP)864 HwiP_Handle CryptoCC32XX_register(CryptoCC32XX_Handle handle, CryptoCC32XX_HwiP *hwiP)
865 {
866 HwiP_Params hwiParams;
867 HwiP_Handle hwiHandle = NULL;
868
869 if (hwiP->hwiIntFxn != NULL)
870 {
871 /* Create Hwi object for this CryptoCC32XX peripheral. */
872 HwiP_Params_init(&hwiParams);
873 hwiParams.arg = (uintptr_t)handle;
874 hwiParams.priority = hwiP->intPriority;
875 hwiHandle = HwiP_create(hwiP->intNum, hwiP->hwiIntFxn,&hwiParams);
876 }
877 return hwiHandle;
878 }
879
880 /*
881 * ======== CryptoCC32XX_unregister ========
882 */
CryptoCC32XX_unregister(HwiP_Handle handle)883 void CryptoCC32XX_unregister(HwiP_Handle handle)
884 {
885 if (handle != NULL)
886 {
887 /* Delete Hwi object */
888 HwiP_delete(handle);
889 }
890 }
891