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