/* * Copyright (c) 2015-2019, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include /* * By default disable both asserts and log for this module. * This must be done before DebugP.h is included. */ #ifndef DebugP_ASSERT_ENABLED #define DebugP_ASSERT_ENABLED 0 #endif #ifndef DebugP_LOG_ENABLED #define DebugP_LOG_ENABLED 0 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_MD5 16 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA1 20 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA224 28 #define CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256 32 #define CryptoCC32XX_CONTEXT_READY_MAX_COUNTER 1000 #define CryptoCC32XX_SHAMD5GetSignatureSize(_mode) ((_mode == SHAMD5_ALGO_MD5) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_MD5: \ (_mode == SHAMD5_ALGO_SHA1) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA1: \ (_mode == SHAMD5_ALGO_SHA224) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA224: \ (_mode == SHAMD5_ALGO_SHA256) ? CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256:0) #define SHAMD5_SIGNATURE_MAX_LEN CryptoCC32XX_SHAMD5_SIGNATURE_LEN_SHA256 typedef int8_t CryptoCC32XX_SHAMD5Signature[SHAMD5_SIGNATURE_MAX_LEN]; typedef struct { /*! Crypto Peripheral's interrupt handler */ HwiP_Fxn hwiIntFxn; /*! Crypto Peripheral's interrupt vector */ uint32_t intNum; /*! Crypto Peripheral's interrupt priority */ uint32_t intPriority; } CryptoCC32XX_HwiP; /* Prototypes */ int32_t CryptoCC32XX_aesProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t* pInBuff, uint16_t inLen, uint8_t* pOutBuff , CryptoCC32XX_EncryptParams* pParams); int32_t CryptoCC32XX_desProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t* pInBuff, uint16_t inLen, uint8_t* pOutBuff , CryptoCC32XX_EncryptParams* pParams); int32_t CryptoCC32XX_shamd5Process(uint32_t cryptoMode , uint8_t* pBuff, uint32_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams* pParams); void CryptoCC32XX_aesIntHandler(void); void CryptoCC32XX_desIntHandler(void); void CryptoCC32XX_shamd5IntHandler(void); HwiP_Handle CryptoCC32XX_register(CryptoCC32XX_Handle handle, CryptoCC32XX_HwiP *hwiP); void CryptoCC32XX_unregister(HwiP_Handle handle); /* Crypto CC32XX interrupts implementation */ CryptoCC32XX_HwiP CryptoCC32XX_HwiPTable[] = { { (HwiP_Fxn)CryptoCC32XX_aesIntHandler, INT_AES, (~0) }, /* AES */ { (HwiP_Fxn)CryptoCC32XX_desIntHandler, INT_DES, (~0) }, /* DES */ { (HwiP_Fxn)CryptoCC32XX_shamd5IntHandler, INT_SHA, (~0) } /* SHAMD5 */ }; /* Crypto AES key size to Crypto CC32XX AES key size */ #define CryptoCC32XX_getAesKeySize(_keySize) ( \ (_keySize == CryptoCC32XX_AES_KEY_SIZE_128BIT)? AES_CFG_KEY_SIZE_128BIT: \ (_keySize == CryptoCC32XX_AES_KEY_SIZE_192BIT)? AES_CFG_KEY_SIZE_192BIT: \ (_keySize == CryptoCC32XX_AES_KEY_SIZE_256BIT)? AES_CFG_KEY_SIZE_256BIT: \ CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED) /* Crypto DES key size to Crypto CC32XX DES key size */ #define CryptoCC32XX_getDesKeySize(_keySize) ( \ (_keySize == CryptoCC32XX_DES_KEY_SIZE_SINGLE)? DES_CFG_SINGLE: \ (_keySize == CryptoCC32XX_DES_KEY_SIZE_TRIPLE)? DES_CFG_TRIPLE: \ CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED) /* Crypto method to Crypto CC32XX mode */ #define CryptoCC32XX_getMode(_method) ( \ (_method == CryptoCC32XX_AES_ECB)? AES_CFG_MODE_ECB: \ (_method == CryptoCC32XX_AES_CBC)? AES_CFG_MODE_CBC: \ (_method == CryptoCC32XX_AES_CTR)? AES_CFG_MODE_CTR: \ (_method == CryptoCC32XX_AES_ICM)? AES_CFG_MODE_ICM: \ (_method == CryptoCC32XX_AES_CFB)? AES_CFG_MODE_CFB: \ (_method == CryptoCC32XX_AES_GCM)? AES_CFG_MODE_GCM_HY0CALC: \ (_method == CryptoCC32XX_AES_CCM)? AES_CFG_MODE_CCM: \ (_method == CryptoCC32XX_DES_ECB)? DES_CFG_MODE_ECB: \ (_method == CryptoCC32XX_DES_CBC)? DES_CFG_MODE_CBC: \ (_method == CryptoCC32XX_DES_CFB)? DES_CFG_MODE_CFB: \ (_method == CryptoCC32XX_HMAC_MD5)? SHAMD5_ALGO_MD5: \ (_method == CryptoCC32XX_HMAC_SHA1)? SHAMD5_ALGO_SHA1: \ (_method == CryptoCC32XX_HMAC_SHA224)? SHAMD5_ALGO_SHA224: \ (_method == CryptoCC32XX_HMAC_SHA256)? SHAMD5_ALGO_SHA256: \ CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED) /* global variables for the interrupt handles */ static volatile bool g_bAESReadyFlag; static volatile bool g_bDESReadyFlag; static volatile bool g_bSHAMD5ReadyFlag; /* Externs */ extern const CryptoCC32XX_Config CryptoCC32XX_config[]; extern const uint8_t CryptoCC32XX_count; /* * ======== CryptoCC32XX_close ======== */ void CryptoCC32XX_close(CryptoCC32XX_Handle handle) { uintptr_t key; CryptoCC32XX_Object *object = handle->object; int32_t type; /* Mask Crypto interrupts */ /* Power off the Crypto module */ Power_releaseDependency(PowerCC32XX_PERIPH_DTHE); for (type = 0; type < CryptoCC32XX_MAX_TYPES;type++) { if (object->sem[type] != NULL) { SemaphoreP_delete(object->sem[type]); } if (object->hwiHandle[type] != NULL) { CryptoCC32XX_unregister(object->hwiHandle[type]); } } /* Mark the module as available */ key = HwiP_disable(); object->isOpen = false; HwiP_restore(key); return; } /* * ======== CryptoCC32XX_init ======== */ void CryptoCC32XX_init(void) { } /* * ======== CryptoCC32XX_open ======== */ CryptoCC32XX_Handle CryptoCC32XX_open(uint32_t index, uint32_t types) { CryptoCC32XX_Handle handle; uintptr_t key; CryptoCC32XX_Object *object; SemaphoreP_Params semParams; int32_t type; if (index >= CryptoCC32XX_count) { return (NULL); } /* Get handle for this driver instance */ handle = (CryptoCC32XX_Handle)&(CryptoCC32XX_config[index]); object = handle->object; /* Determine if the device index was already opened */ key = HwiP_disable(); if(object->isOpen == true) { HwiP_restore(key); return (NULL); } /* Mark the handle as being used */ object->isOpen = true; HwiP_restore(key); /* Power on the Crypto module */ Power_setDependency(PowerCC32XX_PERIPH_DTHE); MAP_PRCMPeripheralReset(PRCM_DTHE); /* create the semaphore for each crypto type*/ SemaphoreP_Params_init(&semParams); semParams.mode = SemaphoreP_Mode_BINARY; for (type=0 ;type < CryptoCC32XX_MAX_TYPES; type++) { if ((types & (1<sem[type] = SemaphoreP_create(1, &semParams); if (object->sem[type] == NULL) { CryptoCC32XX_close(handle); return (NULL); } /* interrupt handler */ object->hwiHandle[type] = CryptoCC32XX_register(handle,&CryptoCC32XX_HwiPTable[type]); if (object->hwiHandle[type] == NULL) { CryptoCC32XX_close(handle); return (NULL); } } else { object->sem[type] = NULL; } } /* Return the address of the handle */ return (handle); } /* * ======== CryptoCC32XX_HmacParams_init ======== */ void CryptoCC32XX_HmacParams_init(CryptoCC32XX_HmacParams *params) { memset(params, 0, sizeof(CryptoCC32XX_HmacParams)); params->first = 1; /* All supported hashing algorithms block size are equal, set one as default */ params->blockSize = CryptoCC32XX_SHA256_BLOCK_SIZE; } /* * ======== CryptoCC32XX_encrypt ======== */ int32_t CryptoCC32XX_encrypt(CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method , void *pInBuff, size_t inLen, void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams) { CryptoCC32XX_Object *object = handle->object; uint8_t cryptoType = method >> 8; uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method); int32_t status = CryptoCC32XX_STATUS_ERROR; /* Convert crypto type bitwise to index */ uint8_t cryptoIndex = cryptoType >> 1; /* check semaphore created */ if (object->sem[cryptoIndex] == NULL) { return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED; } /* get the semaphore */ if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex], SemaphoreP_WAIT_FOREVER)) { switch (cryptoType) { case CryptoCC32XX_AES: status = CryptoCC32XX_aesProcess(cryptoMode , AES_CFG_DIR_ENCRYPT, pInBuff, inLen, pOutBuff , pParams); break; case CryptoCC32XX_DES: status = CryptoCC32XX_desProcess(cryptoMode , DES_CFG_DIR_ENCRYPT, pInBuff, inLen, pOutBuff , pParams); break; default: break; } /* release the semaphore */ SemaphoreP_post(object->sem[cryptoIndex]); } return status; } /* * ======== CryptoCC32XX_decrypt ======== */ int32_t CryptoCC32XX_decrypt(CryptoCC32XX_Handle handle, CryptoCC32XX_EncryptMethod method , void *pInBuff, size_t inLen, void *pOutBuff , size_t *outLen , CryptoCC32XX_EncryptParams *pParams) { CryptoCC32XX_Object *object = handle->object; uint8_t cryptoType = method >> 8; uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method); int32_t status = CryptoCC32XX_STATUS_ERROR; /* Convert crypto type bitwise to index */ uint8_t cryptoIndex = cryptoType >> 1; /* check semaphore created */ if (object->sem[cryptoIndex] == NULL) { return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED; } /* get the semaphore */ if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex], SemaphoreP_WAIT_FOREVER)) { switch (cryptoType) { case CryptoCC32XX_AES: status = CryptoCC32XX_aesProcess(cryptoMode , AES_CFG_DIR_DECRYPT, pInBuff, inLen, pOutBuff , pParams); break; case CryptoCC32XX_DES: status = CryptoCC32XX_desProcess(cryptoMode , DES_CFG_DIR_DECRYPT, pInBuff, inLen, pOutBuff , pParams); break; default: break; } /* release the semaphore */ SemaphoreP_post(object->sem[cryptoIndex]); } return status; } /* * ======== CryptoCC32XX_sign ======== */ int32_t CryptoCC32XX_sign(CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method , void *pBuff, size_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams) { CryptoCC32XX_Object *object = handle->object; uint8_t cryptoType = CryptoCC32XX_HMAC; uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method); int32_t status = CryptoCC32XX_STATUS_ERROR; /* Convert crypto type bitwise to index */ uint8_t cryptoIndex = cryptoType >> 1; /* check semaphore created */ if (object->sem[cryptoIndex] == NULL) { return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED; } /* get the semaphore */ if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex], SemaphoreP_WAIT_FOREVER)) { switch (cryptoType) { case CryptoCC32XX_HMAC: status = CryptoCC32XX_shamd5Process(cryptoMode , pBuff, len, pSignature , pParams); break; default: break; } /* release the semaphore */ SemaphoreP_post(object->sem[cryptoIndex]); } return status; } /* * ======== CryptoCC32XX_verify ======== */ int32_t CryptoCC32XX_verify(CryptoCC32XX_Handle handle, CryptoCC32XX_HmacMethod method , void *pBuff, size_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams) { CryptoCC32XX_Object *object = handle->object; uint8_t cryptoType = CryptoCC32XX_HMAC; uint32_t cryptoMode = CryptoCC32XX_getMode((uint32_t)method); int32_t status = CryptoCC32XX_STATUS_ERROR; uint16_t shamd5SignatureSize; CryptoCC32XX_SHAMD5Signature shamd5Signature; /* Convert crypto type bitwise to index */ uint8_t cryptoIndex = cryptoType >> 1; /* check semaphore created */ if (object->sem[cryptoIndex] == NULL) { return CryptoCC32XX_STATUS_ERROR_NOT_SUPPORTED; } /* get the semaphore */ if (SemaphoreP_OK == SemaphoreP_pend(object->sem[cryptoIndex], SemaphoreP_WAIT_FOREVER)) { switch (cryptoType) { case CryptoCC32XX_HMAC: shamd5SignatureSize = CryptoCC32XX_SHAMD5GetSignatureSize(cryptoMode); if (shamd5SignatureSize > 0) { if (pParams->moreData == 0) { /* save the received signature */ memcpy(shamd5Signature,pSignature,shamd5SignatureSize); } /* calculate the signature */ status = CryptoCC32XX_shamd5Process(cryptoMode , pBuff, len, pSignature , pParams); /* compare the calculated signature to the received signature */ if (status == CryptoCC32XX_STATUS_SUCCESS) { if (pParams->moreData == 0) { if (CryptoUtils_buffersMatch(shamd5Signature, pSignature, shamd5SignatureSize) != true) { status = CryptoCC32XX_STATUS_ERROR_VERIFY; } } } } break; default: break; } /* release the semaphore */ SemaphoreP_post(object->sem[cryptoIndex]); } return status; } /* * ======== CryptoCC32XX_shamd5Process ======== */ int32_t CryptoCC32XX_shamd5Process(uint32_t cryptoMode , uint8_t *pBuff, uint32_t len, uint8_t *pSignature, CryptoCC32XX_HmacParams *pParams) { int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER; uint32_t blockComplementLen = 0; uint32_t newLen = 0; uint32_t copyLen = 0; uint32_t totalLen = 0; uint32_t blockRemainder = 0; /* Step1: Enable Interrupts Step2: Wait for Context Ready Interrupt Step3: Set the Configuration Parameters (Hash Algorithm) Step4: Set Key Step5: Start Hash Generation */ if((pBuff == NULL) || (0 == len)) { return CryptoCC32XX_STATUS_ERROR; } /* Clear the flag */ g_bSHAMD5ReadyFlag = false; /* Enable interrupts. */ MAP_SHAMD5IntEnable(SHAMD5_BASE, SHAMD5_INT_CONTEXT_READY | SHAMD5_INT_PARTHASH_READY | SHAMD5_INT_INPUT_READY | SHAMD5_INT_OUTPUT_READY); /* Wait for the context ready flag. */ while ((!g_bSHAMD5ReadyFlag) && (count > 0)) { count --; } if (count == 0) { return CryptoCC32XX_STATUS_ERROR; } if (pParams->moreData == 1) { /* Less than block size available. Copy the received data to the internal buffer and return */ if((pParams->buffLen + len) < pParams->blockSize) { memcpy(&pParams->buff[pParams->buffLen], pBuff, len); pParams->buffLen += len; return CryptoCC32XX_STATUS_SUCCESS; } if(pParams->first) { /* If Keyed Hashing is used, set Key */ if (pParams->pKey != NULL) { MAP_SHAMD5HMACKeySet(SHAMD5_BASE, pParams->pKey); MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 0, 1, 0); } else { MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 1, 0, 0, 0); } /* Will write data in this iteration. Unset first */ pParams->first = 0; } else { MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 0, 0, 0); /* Write the intermediate digest and count in case it isn't the first round */ SHAMD5ResultWrite(SHAMD5_BASE, pParams->innerDigest); SHAMD5WriteDigestCount(SHAMD5_BASE, pParams->digestCount); } } else { if(pParams->first) { /* If Keyed Hashing is used, set Key */ if (pParams->pKey != NULL) { MAP_SHAMD5HMACKeySet(SHAMD5_BASE, pParams->pKey); MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 1, 1); } else { MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 1, 1, 0, 0); } } else { /* Write the intermediate digest and count in case it isn't the first round */ SHAMD5ResultWrite(SHAMD5_BASE, pParams->innerDigest); SHAMD5WriteDigestCount(SHAMD5_BASE, pParams->digestCount); if (pParams->pKey != NULL) { MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 0, 1); } else { MAP_SHAMD5ConfigSet(SHAMD5_BASE, cryptoMode, 0, 1, 0, 0); } /* This is the last iteration for the requested calculation */ /* Set the first flag to 1 (initial value) for next calculations */ pParams->first = 1; } } /* Set the length of the data that will be written to the SHA module in this iteration */ /* In case it isn't the last iteration, it has to be an integer multiple of block size */ if (pParams->moreData) { totalLen = ((pParams->buffLen + len) / pParams->blockSize) * pParams->blockSize; } else { totalLen = pParams->buffLen + len; } SHAMD5DataLengthSet(SHAMD5_BASE, totalLen); /* In case there is data in the internal buffer, complement to a block size (if the length is sufficient) and write */ if (pParams->buffLen) { blockComplementLen = pParams->blockSize - pParams->buffLen; /* Copy to the internal buffer */ /* The length to copy is the minimum between the block complement and the data length */ copyLen = len < blockComplementLen ? len : blockComplementLen; memcpy(&pParams->buff[pParams->buffLen], pBuff, copyLen); pParams->buffLen += copyLen; /* If buffLen is smaller than block size this must be the last iteration */ /* Write and set the buffer and buffer length to zero */ SHAMD5DataWriteMultiple(SHAMD5_BASE, pParams->buff, pParams->buffLen); pParams->buffLen = 0; memset(pParams->buff, 0, sizeof(pParams->buff)); } /* If data length is greater than block complement, write the rest of the data */ if (len > blockComplementLen) { newLen= len - blockComplementLen; pBuff += blockComplementLen; } if (pParams->moreData) { /* Remaining length is smaller than block size - Save data to the internal buffer */ if (newLen < pParams->blockSize) { memcpy(&pParams->buff[pParams->buffLen], pBuff, newLen); pParams->buffLen = newLen; } /* Remaining length is greater than block size - write blocks and save remainder to the internal buffer */ else { blockRemainder = newLen % pParams->blockSize; newLen -= blockRemainder; SHAMD5DataWriteMultiple(SHAMD5_BASE, pBuff, newLen); if (blockRemainder) { pBuff += newLen; memcpy(&pParams->buff[pParams->buffLen], pBuff, blockRemainder); pParams->buffLen += blockRemainder; } } } else { /* Last iteration, write all the data */ if (newLen) { SHAMD5DataWriteMultiple(SHAMD5_BASE, pBuff, newLen); } } /* Wait for the output to be ready */ while((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) == 0) { } /* Read the result */ if (pParams->moreData == 1) { /* Read the digest and count to an internal parameter (will be used in the next iteration) */ MAP_SHAMD5ResultRead(SHAMD5_BASE, pParams->innerDigest); SHAMD5ReadDigestCount(SHAMD5_BASE, &(pParams->digestCount)); } else { /* Read the final digest result to an outer pointer */ MAP_SHAMD5ResultRead(SHAMD5_BASE, pSignature); } return CryptoCC32XX_STATUS_SUCCESS; } /* * ======== CryptoCC32XX_aesProcess ======== */ int32_t CryptoCC32XX_aesProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t *pInBuff, uint16_t inLen, uint8_t *pOutBuff , CryptoCC32XX_EncryptParams *pParams) { int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER; /* Step1: Enable Interrupts Step2: Wait for Context Ready Interrupt Step3: Set the Configuration Parameters (Direction,AES Mode and Key Size) Step4: Set the Initialization Vector Step5: Write Key Step6: Start the Crypt Process */ /* Clear the flag. */ g_bAESReadyFlag = false; /* Enable all interrupts. */ MAP_AESIntEnable(AES_BASE, AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT); /* Wait for the context in flag, the flag will be set in the Interrupt handler. */ while((!g_bAESReadyFlag) && (count > 0)) { count --; } if (count == 0) { return CryptoCC32XX_STATUS_ERROR; } /* Configure the AES module with direction (encryption or decryption) and */ /* the key size. */ MAP_AESConfigSet(AES_BASE, cryptoDirection | cryptoMode | CryptoCC32XX_getAesKeySize(pParams->aes.keySize)); /* Write the initial value registers if needed, depends on the mode. */ if ((cryptoMode == AES_CFG_MODE_CBC) || (cryptoMode == AES_CFG_MODE_CFB) || (cryptoMode == AES_CFG_MODE_CTR) || (cryptoMode == AES_CFG_MODE_ICM) || (cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC)) { MAP_AESIVSet(AES_BASE, pParams->aes.pIV); } /* Write key1. */ MAP_AESKey1Set(AES_BASE, (uint8_t *)pParams->aes.pKey,CryptoCC32XX_getAesKeySize(pParams->aes.keySize)); /* Write key2. */ if (cryptoMode == AES_CFG_MODE_CCM) { MAP_AESKey2Set(AES_BASE, pParams->aes.aadParams.input.pKey2, CryptoCC32XX_getAesKeySize(pParams->aes.aadParams.input.key2Size)); } /* Start Crypt Process */ if ((cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC)) { MAP_AESDataProcessAE(AES_BASE, (uint8_t *)(pInBuff+(pParams->aes.aadParams.input.len)), pOutBuff ,inLen, pInBuff, pParams->aes.aadParams.input.len, pParams->aes.aadParams.tag); } else { MAP_AESDataProcess(AES_BASE, pInBuff, pOutBuff, inLen); } /* Read the initial value registers if needed, depends on the mode. */ if ((cryptoMode == AES_CFG_MODE_CBC) || (cryptoMode == AES_CFG_MODE_CFB) || (cryptoMode == AES_CFG_MODE_CTR) || (cryptoMode == AES_CFG_MODE_ICM) || (cryptoMode == AES_CFG_MODE_CCM) || (cryptoMode == AES_CFG_MODE_GCM_HY0CALC)) { MAP_AESIVGet(AES_BASE, pParams->aes.pIV); } return CryptoCC32XX_STATUS_SUCCESS; } /* * ======== CryptoCC32XX_desProcess ======== */ int32_t CryptoCC32XX_desProcess(uint32_t cryptoMode , uint32_t cryptoDirection, uint8_t *pInBuff, uint16_t inLen, uint8_t *pOutBuff , CryptoCC32XX_EncryptParams *pParams) { int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER; /* Step1: Enable Interrupts Step2: Wait for Context Ready Interrupt Step3: Set the Configuration Parameters (Direction,AES Mode) Step4: Set the Initialization Vector Step5: Write Key Step6: Start the Crypt Process */ /* Clear the flag. */ g_bDESReadyFlag = false; /* Enable all interrupts. */ MAP_DESIntEnable(DES_BASE, DES_INT_CONTEXT_IN | DES_INT_DATA_IN | DES_INT_DATA_OUT); /* Wait for the context in flag. */ while((!g_bDESReadyFlag) && (count > 0)) { count --; } if (count == 0) { return CryptoCC32XX_STATUS_ERROR; } /* Configure the DES module. */ MAP_DESConfigSet(DES_BASE, cryptoDirection | cryptoMode | CryptoCC32XX_getDesKeySize(pParams->des.keySize)); /* Set the key. */ MAP_DESKeySet(DES_BASE, (uint8_t *)pParams->des.pKey); /* Write the initial value registers if needed. */ if((cryptoMode & DES_CFG_MODE_CBC) || (cryptoMode & DES_CFG_MODE_CFB)) { MAP_DESIVSet(DES_BASE, pParams->des.pIV); } MAP_DESDataProcess(DES_BASE, pInBuff, pOutBuff,inLen); return CryptoCC32XX_STATUS_SUCCESS; } /* * ======== CryptoCC32XX_aesIntHandler ======== */ void CryptoCC32XX_aesIntHandler(void) { uint32_t uiIntStatus; /* Read the AES masked interrupt status. */ uiIntStatus = MAP_AESIntStatus(AES_BASE, true); /* Set Different flags depending on the interrupt source. */ if(uiIntStatus & AES_INT_CONTEXT_IN) { MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_IN); g_bAESReadyFlag = true; } if(uiIntStatus & AES_INT_DATA_IN) { MAP_AESIntDisable(AES_BASE, AES_INT_DATA_IN); } if(uiIntStatus & AES_INT_CONTEXT_OUT) { MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_OUT); } if(uiIntStatus & AES_INT_DATA_OUT) { MAP_AESIntDisable(AES_BASE, AES_INT_DATA_OUT); } } /* * ======== CryptoCC32XX_desIntHandler ======== */ void CryptoCC32XX_desIntHandler(void) { uint32_t ui32IntStatus; /* Read the DES masked interrupt status. */ ui32IntStatus = MAP_DESIntStatus(DES_BASE, true); /* set flags depending on the interrupt source. */ if(ui32IntStatus & DES_INT_CONTEXT_IN) { MAP_DESIntDisable(DES_BASE, DES_INT_CONTEXT_IN); g_bDESReadyFlag = true; } if(ui32IntStatus & DES_INT_DATA_IN) { MAP_DESIntDisable(DES_BASE, DES_INT_DATA_IN); } if(ui32IntStatus & DES_INT_DATA_OUT) { MAP_DESIntDisable(DES_BASE, DES_INT_DATA_OUT); } } /* * ======== CryptoCC32XX_shamd5IntHandler ======== */ void CryptoCC32XX_shamd5IntHandler(void) { uint32_t ui32IntStatus; /* Read the SHA/MD5 masked interrupt status. */ ui32IntStatus = MAP_SHAMD5IntStatus(SHAMD5_BASE, true); if(ui32IntStatus & SHAMD5_INT_CONTEXT_READY) { MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_CONTEXT_READY); g_bSHAMD5ReadyFlag = true; } if(ui32IntStatus & SHAMD5_INT_PARTHASH_READY) { MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_PARTHASH_READY); } if(ui32IntStatus & SHAMD5_INT_INPUT_READY) { MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_INPUT_READY); } if(ui32IntStatus & SHAMD5_INT_OUTPUT_READY) { MAP_SHAMD5IntDisable(SHAMD5_BASE, SHAMD5_INT_OUTPUT_READY); } } /* * ======== CryptoCC32XX_register ======== */ HwiP_Handle CryptoCC32XX_register(CryptoCC32XX_Handle handle, CryptoCC32XX_HwiP *hwiP) { HwiP_Params hwiParams; HwiP_Handle hwiHandle = NULL; if (hwiP->hwiIntFxn != NULL) { /* Create Hwi object for this CryptoCC32XX peripheral. */ HwiP_Params_init(&hwiParams); hwiParams.arg = (uintptr_t)handle; hwiParams.priority = hwiP->intPriority; hwiHandle = HwiP_create(hwiP->intNum, hwiP->hwiIntFxn,&hwiParams); } return hwiHandle; } /* * ======== CryptoCC32XX_unregister ======== */ void CryptoCC32XX_unregister(HwiP_Handle handle) { if (handle != NULL) { /* Delete Hwi object */ HwiP_delete(handle); } }