X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fgeneric-2.6%2Ffiles%2Fcrypto%2Focf%2Fkirkwood%2Fcesa%2FmvCesa.c;fp=target%2Flinux%2Fgeneric-2.6%2Ffiles%2Fcrypto%2Focf%2Fkirkwood%2Fcesa%2FmvCesa.c;h=0000000000000000000000000000000000000000;hp=17ab086f079a0bb0840ba97156810ff248aaeb22;hb=da1bb88a2b900f0392b731ec47c5e1bff956fd8f;hpb=6117c04c9416b295347fb45c37e430f01df1d0d9 diff --git a/target/linux/generic-2.6/files/crypto/ocf/kirkwood/cesa/mvCesa.c b/target/linux/generic-2.6/files/crypto/ocf/kirkwood/cesa/mvCesa.c deleted file mode 100644 index 17ab086f07..0000000000 --- a/target/linux/generic-2.6/files/crypto/ocf/kirkwood/cesa/mvCesa.c +++ /dev/null @@ -1,3126 +0,0 @@ -/******************************************************************************* -Copyright (C) Marvell International Ltd. and its affiliates - -This software file (the "File") is owned and distributed by Marvell -International Ltd. and/or its affiliates ("Marvell") under the following -alternative licensing terms. Once you have made an election to distribute the -File under one of the following license alternatives, please (i) delete this -introductory statement regarding license alternatives, (ii) delete the two -license alternatives that you have not elected to use and (iii) preserve the -Marvell copyright notice above. - -******************************************************************************** -Marvell Commercial License Option - -If you received this File from Marvell and you have entered into a commercial -license agreement (a "Commercial License") with Marvell, the File is licensed -to you under the terms of the applicable Commercial License. - -******************************************************************************** -Marvell GPL License Option - -If you received this File from Marvell, you may opt to use, redistribute and/or -modify this File in accordance with the terms and conditions of the General -Public License Version 2, June 1991 (the "GPL License"), a copy of which is -available along with the File in the license.txt file or by writing to the Free -Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or -on the worldwide web at http://www.gnu.org/licenses/gpl.txt. - -THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED -WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY -DISCLAIMED. The GPL License provides additional details about this warranty -disclaimer. -******************************************************************************** -Marvell BSD License Option - -If you received this File from Marvell, you may opt to use, redistribute and/or -modify this File under the following licensing terms. -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 Marvell 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 "cesa/mvCesa.h" - -#include "ctrlEnv/mvCtrlEnvLib.h" -#undef CESA_DEBUG - - -/********** Global variables **********/ - -/* If request size is more than MV_CESA_MAX_BUF_SIZE the - * request is processed as fragmented request. - */ - -MV_CESA_STATS cesaStats; - -MV_BUF_INFO cesaSramSaBuf; -short cesaLastSid = -1; -MV_CESA_SA* pCesaSAD = NULL; -MV_U16 cesaMaxSA = 0; - -MV_CESA_REQ* pCesaReqFirst = NULL; -MV_CESA_REQ* pCesaReqLast = NULL; -MV_CESA_REQ* pCesaReqEmpty = NULL; -MV_CESA_REQ* pCesaReqProcess = NULL; -int cesaQueueDepth = 0; -int cesaReqResources = 0; - -MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL; -MV_U32 cesaCryptEngBase = 0; -void *cesaOsHandle = NULL; -#if (MV_CESA_VERSION >= 3) -MV_U32 cesaChainLength = 0; -int chainReqNum = 0; -MV_U32 chainIndex = 0; -MV_CESA_REQ* pNextActiveChain = 0; -MV_CESA_REQ* pEndCurrChain = 0; -MV_BOOL isFirstReq = MV_TRUE; -#endif - -static INLINE MV_U8* mvCesaSramAddrGet(void) -{ -#ifdef MV_CESA_NO_SRAM - return (MV_U8*)cesaSramVirtPtr; -#else - return (MV_U8*)cesaCryptEngBase; -#endif /* MV_CESA_NO_SRAM */ -} - -static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt) -{ -#ifdef MV_CESA_NO_SRAM - return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt); -#else - return (MV_ULONG)pSramVirt; -#endif /* MV_CESA_NO_SRAM */ -} - -/* Internal Function prototypes */ - -static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag, - int cryptoOffset, int ivOffset, int cryptoLength, - int macOffset, int digestOffset, int macLength, int macTotalLen, - MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc); - -static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc); - -static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf, - MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf, - int offset, int copySize, MV_BOOL skipFlush); - -static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength, - unsigned char innerIV[], unsigned char outerIV[]); - -static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA, - int macDataSize); - -static MV_CESA_COMMAND* mvCesaCtrModeInit(void); - -static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd); -static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd); -static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd); - -static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq); -static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag); - -static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset); -static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd); - -static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq, - int cryptoOffset, int macOffset, - int* pCopySize, int* pCryptoDataSize, int* pMacDataSize); -static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size); - - -/* Go to the next request in the request queue */ -static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq) -{ - if(pReq == pCesaReqLast) - return pCesaReqFirst; - - return pReq+1; -} - -#if (MV_CESA_VERSION >= 3) -/* Go to the previous request in the request queue */ -static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq) -{ - if(pReq == pCesaReqFirst) - return pCesaReqLast; - - return pReq-1; -} - -#endif - - -static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq) -{ - int frag; - -#if (MV_CESA_VERSION >= 3) - pReq->state = MV_CESA_CHAIN; -#else - pReq->state = MV_CESA_PROCESS; -#endif - cesaStats.startCount++; - - if(pReq->fragMode == MV_CESA_FRAG_NONE) - { - frag = 0; - } - else - { - frag = pReq->frags.nextFrag; - pReq->frags.nextFrag++; - } -#if (MV_CESA_VERSION >= 2) - /* Enable TDMA engine */ - MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0); - MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG, - (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst)); -#else - /* Enable IDMA engine */ - MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0); - MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0), - (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst)); -#endif /* MV_CESA_VERSION >= 2 */ - -#if defined(MV_BRIDGE_SYNC_REORDER) - mvOsBridgeReorderWA(); -#endif - - /* Start Accelerator */ - MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK); -} - - -/******************************************************************************* -* mvCesaHalInit - Initialize the CESA driver -* -* DESCRIPTION: -* This function initialize the CESA driver. -* 1) Session database -* 2) Request queue -* 4) DMA descriptor lists - one list per request. Each list -* has MV_CESA_MAX_DMA_DESC descriptors. -* -* INPUT: -* numOfSession - maximum number of supported sessions -* queueDepth - number of elements in the request queue. -* pSramBase - virtual address of Sram -* osHandle - A handle used by the OS to allocate memory for the -* module (Passed to the OS Services layer) -* -* RETURN: -* MV_OK - Success -* MV_NO_RESOURCE - Fail, can't allocate resources: -* Session database, request queue, -* DMA descriptors list, LRU cache database. -* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned. -* -*******************************************************************************/ -MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, - void *osHandle) -{ - int i, req; - MV_U32 descOffsetReg, configReg; - MV_CESA_SRAM_SA *pSramSA; - - - mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n", - numOfSession, queueDepth, pSramBase); - - cesaOsHandle = osHandle; - /* Create Session database */ - pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession); - if(pCesaSAD == NULL) - { - mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n", - sizeof(MV_CESA_SA)*numOfSession, numOfSession); - mvCesaFinish(); - return MV_NO_RESOURCE; - } - memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession); - cesaMaxSA = numOfSession; - - /* Allocate imag of sramSA in the DRAM */ - cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession + - CPU_D_CACHE_LINE_SIZE; - - cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize, - &cesaSramSaBuf.bufPhysAddr, - &cesaSramSaBuf.memHandle); - - if(cesaSramSaBuf.bufVirtPtr == NULL) - { - mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n", - cesaSramSaBuf.bufSize); - mvCesaFinish(); - return MV_NO_RESOURCE; - } - memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize); - pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr, - CPU_D_CACHE_LINE_SIZE); - for(i=0; i= 3) - cesaChainLength = MAX_CESA_CHAIN_LENGTH; -#endif - /* pSramBase must be 8 byte aligned */ - if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) ) - { - mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n", - pSramBase); - mvCesaFinish(); - return MV_NOT_ALIGNED; - } - cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase; - - cesaCryptEngBase = cryptEngBase; - - /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/ - - /* Clear registers */ - MV_REG_WRITE( MV_CESA_CFG_REG, 0); - MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0); - MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0); - - /* Initialize DMA descriptor lists for all requests in Request queue */ - descOffsetReg = configReg = 0; - for(req=0; reqcesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS + - CPU_D_CACHE_LINE_SIZE; - - pReq->cesaDescBuf.bufVirtPtr = - mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize, - &pReq->cesaDescBuf.bufPhysAddr, - &pReq->cesaDescBuf.memHandle); - - if(pReq->cesaDescBuf.bufVirtPtr == NULL) - { - mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n", - req, pReq->cesaDescBuf.bufSize); - mvCesaFinish(); - return MV_NO_RESOURCE; - } - memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize); - pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr, - CPU_D_CACHE_LINE_SIZE); - - pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS + - CPU_D_CACHE_LINE_SIZE; - - pReq->dmaDescBuf.bufVirtPtr = - mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize, - &pReq->dmaDescBuf.bufPhysAddr, - &pReq->dmaDescBuf.memHandle); - - if(pReq->dmaDescBuf.bufVirtPtr == NULL) - { - mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n", - req, pReq->dmaDescBuf.bufSize); - mvCesaFinish(); - return MV_NO_RESOURCE; - } - memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize); - pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr, - CPU_D_CACHE_LINE_SIZE); - - for(frag=0; fragdma[frag]; - - pDma->pDmaFirst = pDmaDesc; - pDma->pDmaLast = NULL; - - for(i=0; ipDmaFirst[i].phyNextDescPtr = - MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1])); - } - pDma->pDmaFirst[i].phyNextDescPtr = 0; - mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC)); - - pDmaDesc += MV_CESA_MAX_DMA_DESC; - } - } - /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/ - descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet()); - MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg); - - configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK); -#if (MV_CESA_VERSION >= 3) - configReg |= MV_CESA_CFG_CHAIN_MODE_MASK; -#endif - -#if (MV_CESA_VERSION >= 2) - /* Initialize TDMA engine */ - MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE); - MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0); - MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0); -#else - /* Initialize IDMA #0 engine */ - MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0); - MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0); - MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0); - MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE -#ifdef MV_CPU_LE - | ICCHR_DESC_BYTE_SWAP_EN -#endif - ); - /* Clear Cause Byte of IDMA channel to be used */ - MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0)); - MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE); -#endif /* (MV_CESA_VERSION >= 2) */ - - /* Set CESA configuration registers */ - MV_REG_WRITE( MV_CESA_CFG_REG, configReg); - mvCesaDebugStatsClear(); - - return MV_OK; -} - -/******************************************************************************* -* mvCesaFinish - Shutdown the CESA driver -* -* DESCRIPTION: -* This function shutdown the CESA driver and free all allocted resources. -* -* INPUT: None -* -* RETURN: -* MV_OK - Success -* Other - Fail -* -*******************************************************************************/ -MV_STATUS mvCesaFinish (void) -{ - int req; - MV_CESA_REQ* pReq; - - mvOsPrintf("mvCesaFinish: \n"); - - cesaSramVirtPtr = NULL; - - /* Free all resources: DMA list, etc. */ - for(req=0; reqdmaDescBuf.bufVirtPtr != NULL) - { - mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize, - pReq->dmaDescBuf.bufPhysAddr, - pReq->dmaDescBuf.bufVirtPtr, - pReq->dmaDescBuf.memHandle); - } - if(pReq->cesaDescBuf.bufVirtPtr != NULL) - { - mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize, - pReq->cesaDescBuf.bufPhysAddr, - pReq->cesaDescBuf.bufVirtPtr, - pReq->cesaDescBuf.memHandle); - } - } -#if (MV_CESA_VERSION < 2) - MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0); -#endif /* (MV_CESA_VERSION < 2) */ - - /* Free request queue */ - if(pCesaReqFirst != NULL) - { - mvOsFree(pCesaReqFirst); - pCesaReqFirst = pCesaReqLast = NULL; - pCesaReqEmpty = pCesaReqProcess = NULL; - cesaQueueDepth = cesaReqResources = 0; - } - /* Free SA database */ - if(pCesaSAD != NULL) - { - mvOsFree(pCesaSAD); - pCesaSAD = NULL; - cesaMaxSA = 0; - } - MV_REG_WRITE( MV_CESA_CFG_REG, 0); - MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0); - MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0); - - return MV_OK; -} - -/******************************************************************************* -* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode -* -* DESCRIPTION: -* This function set IV value using by Crypto algorithms in CBC mode. -* Each channel has its own IV value. -* This function gets IV value from the caller. If no IV value passed from -* the caller or only part of IV passed, the function will init the rest part -* of IV value (or the whole IV) by random value. -* -* INPUT: -* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL -* the function will generate random IV value. -* int ivSize - size (in bytes) of IV provided by user. If ivSize is -* smaller than maximum IV size, the function will complete -* IV by random value. -* -* RETURN: -* MV_OK - Success -* Other - Fail -* -*******************************************************************************/ -MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize) -{ - MV_U8* pSramIV; -#if defined(MV646xx) - mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n"); -#endif - pSramIV = cesaSramVirtPtr->cryptoIV; - if(ivSize > MV_CESA_MAX_IV_LENGTH) - { - mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize); - ivSize = MV_CESA_MAX_IV_LENGTH; - } - if(pIV != NULL) - { - memcpy(pSramIV, pIV, ivSize); - ivSize = MV_CESA_MAX_IV_LENGTH - ivSize; - pSramIV += ivSize; - } - - while(ivSize > 0) - { - int size, mv_random = mvOsRand(); - - size = MV_MIN(ivSize, sizeof(mv_random)); - memcpy(pSramIV, (void*)&mv_random, size); - - pSramIV += size; - ivSize -= size; - } -/* - mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV, - MV_CESA_MAX_IV_LENGTH); - mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV, - MV_CESA_MAX_IV_LENGTH); -*/ - return MV_OK; -} - -/******************************************************************************* -* mvCesaSessionOpen - Open new uni-directional crypto session -* -* DESCRIPTION: -* This function open new session. -* -* INPUT: -* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters -* -* OUTPUT: -* short *pSid - session ID, should be used for all future -* requests over this session. -* -* RETURN: -* MV_OK - Session opend successfully. -* MV_FULL - All sessions are in use, no free place in -* SA database. -* MV_BAD_PARAM - One of session input parameters is invalid. -* -*******************************************************************************/ -MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid) -{ - short sid; - MV_U32 config = 0; - int digestSize; - - cesaStats.openedCount++; - - /* Find free entry in SAD */ - for(sid=0; sidoperation >= MV_CESA_MAX_OPERATION) - { - mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n", - pSession->operation); - return MV_BAD_PARAM; - } - config |= (pSession->operation << MV_CESA_OPERATION_OFFSET); - - if( (pSession->direction != MV_CESA_DIR_ENCODE) && - (pSession->direction != MV_CESA_DIR_DECODE) ) - { - mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n", - pSession->direction); - return MV_BAD_PARAM; - } - config |= (pSession->direction << MV_CESA_DIRECTION_BIT); - /* Clear SA entry */ - /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */ - - /* Check AUTH parameters and update SA entry */ - if(pSession->operation != MV_CESA_CRYPTO_ONLY) - { - /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */ - if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) || - (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) ) - { - if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH) - { - mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n", - pSession->macKeyLength); - return MV_BAD_PARAM; - } - mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength, - pCesaSAD[sid].pSramSA->macInnerIV, - pCesaSAD[sid].pSramSA->macOuterIV); - pCesaSAD[sid].macKeyLength = pSession->macKeyLength; - } - switch(pSession->macMode) - { - case MV_CESA_MAC_MD5: - case MV_CESA_MAC_HMAC_MD5: - digestSize = MV_CESA_MD5_DIGEST_SIZE; - break; - - case MV_CESA_MAC_SHA1: - case MV_CESA_MAC_HMAC_SHA1: - digestSize = MV_CESA_SHA1_DIGEST_SIZE; - break; - - default: - mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n", - pSession->macMode); - return MV_BAD_PARAM; - } - config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET); - - /* Supported digest sizes: MD5 - 16 bytes (128 bits), */ - /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */ - if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12)) - { - mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n", - pSession->digestSize); - mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n"); - return MV_BAD_PARAM; - } - pCesaSAD[sid].digestSize = pSession->digestSize; - - if(pCesaSAD[sid].digestSize == 12) - { - /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */ - config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT); - } - } - - /* Check CRYPTO parameters and update SA entry */ - if(pSession->operation != MV_CESA_MAC_ONLY) - { - switch(pSession->cryptoAlgorithm) - { - case MV_CESA_CRYPTO_DES: - pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH; - pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE; - break; - - case MV_CESA_CRYPTO_3DES: - pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH; - pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE; - /* Only EDE mode is supported */ - config |= (MV_CESA_CRYPTO_3DES_EDE << - MV_CESA_CRYPTO_3DES_MODE_BIT); - break; - - case MV_CESA_CRYPTO_AES: - switch(pSession->cryptoKeyLength) - { - case 16: - pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH; - config |= (MV_CESA_CRYPTO_AES_KEY_128 << - MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET); - break; - - case 24: - pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH; - config |= (MV_CESA_CRYPTO_AES_KEY_192 << - MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET); - break; - - case 32: - default: - pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH; - config |= (MV_CESA_CRYPTO_AES_KEY_256 << - MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET); - break; - } - pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE; - break; - - default: - mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n", - pSession->cryptoAlgorithm); - return MV_BAD_PARAM; - } - config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET); - - if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength) - { - mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n", - pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength); - return MV_BAD_PARAM; - } - - /* Copy Crypto key */ - if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) && - (pSession->direction == MV_CESA_DIR_DECODE)) - { - /* Crypto Key for AES decode is computed from original key material */ - /* and depend on cryptoKeyLength (128/192/256 bits) */ - aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey, - pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8); - } - else - { - /*panic("mvCesaSessionOpen2");*/ - memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey, - pCesaSAD[sid].cryptoKeyLength); - - } - - switch(pSession->cryptoMode) - { - case MV_CESA_CRYPTO_ECB: - pCesaSAD[sid].cryptoIvSize = 0; - break; - - case MV_CESA_CRYPTO_CBC: - pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize; - break; - - case MV_CESA_CRYPTO_CTR: - /* Supported only for AES algorithm */ - if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES) - { - mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n"); - return MV_BAD_PARAM; - } - pCesaSAD[sid].cryptoIvSize = 0; - pCesaSAD[sid].ctrMode = 1; - /* Replace to ECB mode for HW */ - pSession->cryptoMode = MV_CESA_CRYPTO_ECB; - break; - - default: - mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n", - pSession->cryptoMode); - return MV_BAD_PARAM; - } - - config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT); - } - pCesaSAD[sid].config = config; - - mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA)); - if(pSid != NULL) - *pSid = sid; - - pCesaSAD[sid].valid = 1; - return MV_OK; -} - -/******************************************************************************* -* mvCesaSessionClose - Close active crypto session -* -* DESCRIPTION: -* This function closes existing session -* -* INPUT: -* short sid - Unique identifier of the session to be closed -* -* RETURN: -* MV_OK - Session closed successfully. -* MV_BAD_PARAM - Session identifier is out of valid range. -* MV_NOT_FOUND - There is no active session with such ID. -* -*******************************************************************************/ -MV_STATUS mvCesaSessionClose(short sid) -{ - cesaStats.closedCount++; - - if(sid >= cesaMaxSA) - { - mvOsPrintf("CESA Error: sid (%d) is too big\n", sid); - return MV_BAD_PARAM; - } - if(pCesaSAD[sid].valid == 0) - { - mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid); - return MV_NOT_FOUND; - } - if(cesaLastSid == sid) - cesaLastSid = -1; - - pCesaSAD[sid].valid = 0; - return MV_OK; -} - -/******************************************************************************* -* mvCesaAction - Perform crypto operation -* -* DESCRIPTION: -* This function set new CESA request FIFO queue for further HW processing. -* The function checks request parameters before set new request to the queue. -* If one of the CESA channels is ready for processing the request will be -* passed to HW. When request processing is finished the CESA interrupt will -* be generated by HW. The caller should call mvCesaReadyGet() function to -* complete request processing and get result. -* -* INPUT: -* MV_CESA_COMMAND *pCmd - pointer to new CESA request. -* It includes pointers to Source and Destination -* buffers, session identifier get from -* mvCesaSessionOpen() function, pointer to caller -* private data and all needed crypto parameters. -* -* RETURN: -* MV_OK - request successfully added to request queue -* and will be processed. -* MV_NO_MORE - request successfully added to request queue and will -* be processed, but request queue became Full and next -* request will not be accepted. -* MV_NO_RESOURCE - request queue is FULL and the request can not -* be processed. -* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is -* failed. Request can not be processed. -* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed -* as one request and should be splitted for two requests: -* CRYPTO_ONLY and MAC_ONLY. -* MV_BAD_PARAM - One of the request parameters is out of valid range. -* The request can not be processed. -* -*******************************************************************************/ -MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd) -{ - MV_STATUS status; - MV_CESA_REQ* pReq = pCesaReqEmpty; - int sid = pCmd->sessionId; - MV_CESA_SA* pSA = &pCesaSAD[sid]; -#if (MV_CESA_VERSION >= 3) - MV_CESA_REQ* pFromReq; - MV_CESA_REQ* pToReq; -#endif - cesaStats.reqCount++; - - /* Check that the request queue is not FULL */ - if(cesaReqResources == 0) - return MV_NO_RESOURCE; - - if( (sid >= cesaMaxSA) || (!pSA->valid) ) - { - mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid); - return MV_BAD_PARAM; - } - pSA->count++; - - if(pSA->ctrMode) - { - /* AES in CTR mode can't be mixed with Authentication */ - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n"); - return MV_NOT_ALLOWED; - } - /* All other request parameters should not be checked because key stream */ - /* (not user data) processed by AES HW engine */ - pReq->pOrgCmd = pCmd; - /* Allocate temporary pCmd structure for Key stream */ - pCmd = mvCesaCtrModeInit(); - if(pCmd == NULL) - return MV_OUT_OF_CPU_MEM; - - /* Prepare Key stream */ - mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd); - pReq->fixOffset = 0; - } - else - { - /* Check request parameters and calculae fixOffset */ - status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset); - if(status != MV_OK) - { - return status; - } - } - pReq->pCmd = pCmd; - - /* Check if the packet need fragmentation */ - if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) ) - { - /* request size is smaller than single buffer size */ - pReq->fragMode = MV_CESA_FRAG_NONE; - - /* Prepare NOT fragmented packets */ - status = mvCesaReqProcess(pReq); - if(status != MV_OK) - { - mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n", - pReq, status); - } -#if (MV_CESA_VERSION >= 3) - pReq->frags.numFrag = 1; -#endif - } - else - { - MV_U8 frag = 0; - - /* request size is larger than buffer size - needs fragmentation */ - - /* Check restrictions for processing fragmented packets */ - status = mvCesaFragParamCheck(pSA, pCmd); - if(status != MV_OK) - return status; - - pReq->fragMode = MV_CESA_FRAG_FIRST; - pReq->frags.nextFrag = 0; - - /* Prepare Process Fragmented packets */ - while(pReq->fragMode != MV_CESA_FRAG_LAST) - { - if(frag >= MV_CESA_MAX_REQ_FRAGS) - { - mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag); - return MV_OUT_OF_CPU_MEM; - } - status = mvCesaFragReqProcess(pReq, frag); - if(status == MV_OK) { -#if (MV_CESA_VERSION >= 3) - if(frag) { - pReq->dma[frag-1].pDmaLast->phyNextDescPtr = - MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst)); - mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC)); - } -#endif - frag++; - } - } - pReq->frags.numFrag = frag; -#if (MV_CESA_VERSION >= 3) - if(chainReqNum) { - chainReqNum += pReq->frags.numFrag; - if(chainReqNum >= MAX_CESA_CHAIN_LENGTH) - chainReqNum = MAX_CESA_CHAIN_LENGTH; - } -#endif - } - - pReq->state = MV_CESA_PENDING; - - pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq); - cesaReqResources -= 1; - -/* #ifdef CESA_DEBUG */ - if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount) - cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources); -/* #endif CESA_DEBUG */ - - cesaLastSid = sid; - -#if (MV_CESA_VERSION >= 3) - /* Are we within chain bounderies and follows the first request ? */ - if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) { - if(chainIndex) { - pFromReq = MV_CESA_REQ_PREV_PTR(pReq); - pToReq = pReq; - pReq->state = MV_CESA_CHAIN; - /* assume concatenating is possible */ - pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr = - MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst)); - mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC)); - - /* align active & next pointers */ - if(pNextActiveChain->state != MV_CESA_PENDING) - pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq); - } - else { /* we have only one chain, start new one */ - chainReqNum = 0; - chainIndex++; - /* align active & next pointers */ - if(pNextActiveChain->state != MV_CESA_PENDING) - pEndCurrChain = pNextActiveChain = pReq; - } - } - else { - /* In case we concatenate full chain */ - if(chainReqNum == MAX_CESA_CHAIN_LENGTH) { - chainIndex++; - if(pNextActiveChain->state != MV_CESA_PENDING) - pEndCurrChain = pNextActiveChain = pReq; - chainReqNum = 0; - } - - pReq = pCesaReqProcess; - if(pReq->state == MV_CESA_PENDING) { - pNextActiveChain = pReq; - pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq); - /* Start Process new request */ - mvCesaReqProcessStart(pReq); - } - } - - chainReqNum++; - - if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage)) - cesaStats.maxChainUsage = chainReqNum; - -#else - - /* Check status of CESA channels and process requests if possible */ - pReq = pCesaReqProcess; - if(pReq->state == MV_CESA_PENDING) - { - /* Start Process new request */ - mvCesaReqProcessStart(pReq); - } -#endif - /* If request queue became FULL - return MV_NO_MORE */ - if(cesaReqResources == 0) - return MV_NO_MORE; - - return MV_OK; - -} - -/******************************************************************************* -* mvCesaReadyGet - Get crypto request that processing is finished -* -* DESCRIPTION: -* This function complete request processing and return ready request to -* caller. To don't miss interrupts the caller must call this function -* while MV_OK or MV_TERMINATE values returned. -* -* INPUT: -* MV_U32 chanMap - map of CESA channels finished thier job -* accordingly with CESA Cause register. -* MV_CESA_RESULT* pResult - pointer to structure contains information -* about ready request. It includes pointer to -* user private structure "pReqPrv", session identifier -* for this request "sessionId" and return code. -* Return code set to MV_FAIL if calculated digest value -* on decode direction is different than digest value -* in the packet. -* -* RETURN: -* MV_OK - Success, ready request is returned. -* MV_NOT_READY - Next request is not ready yet. New interrupt will -* be generated for futher request processing. -* MV_EMPTY - There is no more request for processing. -* MV_BUSY - Fragmented request is not ready yet. -* MV_TERMINATE - Call this function once more to complete processing -* of fragmented request. -* -*******************************************************************************/ -MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult) -{ - MV_STATUS status, readyStatus = MV_NOT_READY; - MV_U32 statusReg; - MV_CESA_REQ* pReq; - MV_CESA_SA* pSA; - -#if (MV_CESA_VERSION >= 3) - if(isFirstReq == MV_TRUE) { - if(chainIndex == 0) - chainReqNum = 0; - - isFirstReq = MV_FALSE; - - if(pNextActiveChain->state == MV_CESA_PENDING) { - /* Start request Process */ - mvCesaReqProcessStart(pNextActiveChain); - pEndCurrChain = pNextActiveChain; - if(chainIndex > 0) - chainIndex--; - /* Update pNextActiveChain to next chain head */ - while(pNextActiveChain->state == MV_CESA_CHAIN) - pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain); - } - } - - /* Check if there are more processed requests - can we remove pEndCurrChain ??? */ - if(pCesaReqProcess == pEndCurrChain) { - isFirstReq = MV_TRUE; - pEndCurrChain = pNextActiveChain; -#else - if(pCesaReqProcess->state != MV_CESA_PROCESS) { -#endif - return MV_EMPTY; - } - -#ifdef CESA_DEBUG - statusReg = MV_REG_READ(MV_CESA_STATUS_REG); - if( statusReg & MV_CESA_STATUS_ACTIVE_MASK ) - { - mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg); - cesaStats.notReadyCount++; - return MV_NOT_READY; - } -#endif /* CESA_DEBUG */ - - cesaStats.readyCount++; - - pReq = pCesaReqProcess; - pSA = &pCesaSAD[pReq->pCmd->sessionId]; - - pResult->retCode = MV_OK; - if(pReq->fragMode != MV_CESA_FRAG_NONE) - { - MV_U8* pNewDigest; - int frag; -#if (MV_CESA_VERSION >= 3) - pReq->frags.nextFrag = 1; - while(pReq->frags.nextFrag <= pReq->frags.numFrag) { -#endif - frag = (pReq->frags.nextFrag - 1); - - /* Restore DMA descriptor list */ - pReq->dma[frag].pDmaLast->phyNextDescPtr = - MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1])); - pReq->dma[frag].pDmaLast = NULL; - - /* Special processing for finished fragmented request */ - if(pReq->frags.nextFrag >= pReq->frags.numFrag) - { - mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize); - - /* Fragmented packet is ready */ - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize; - - if(macDataSize != 0) - { - /* Calculate all other blocks by SW */ - mvCesaFragAuthComplete(pReq, pSA, macDataSize); - } - - /* Copy new digest from SRAM to the Destination buffer */ - pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset; - status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst, - pReq->pCmd->digestOffset, pSA->digestSize); - - /* For decryption: Compare new digest value with original one */ - if((pSA->config & MV_CESA_DIRECTION_MASK) == - (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) - { - if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0) - { -/* - mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n", - chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG)); -*/ - /* Signiture verification is failed */ - pResult->retCode = MV_FAIL; - } - } - } - readyStatus = MV_OK; - } -#if (MV_CESA_VERSION >= 3) - pReq->frags.nextFrag++; - } -#endif - } - else - { - mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize); - - /* Restore DMA descriptor list */ - pReq->dma[0].pDmaLast->phyNextDescPtr = - MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1])); - pReq->dma[0].pDmaLast = NULL; - if( ((pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) && - ((pSA->config & MV_CESA_DIRECTION_MASK) == - (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) ) - { - /* For AUTH on decode : Check Digest result in Status register */ - statusReg = MV_REG_READ(MV_CESA_STATUS_REG); - if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK) - { -/* - mvOsPrintf("Digest error: chan=%d, status = 0x%x\n", - chan, statusReg); -*/ - /* Signiture verification is failed */ - pResult->retCode = MV_FAIL; - } - } - readyStatus = MV_OK; - } - - if(readyStatus == MV_OK) - { - /* If Request is ready - Prepare pResult structure */ - pResult->pReqPrv = pReq->pCmd->pReqPrv; - pResult->sessionId = pReq->pCmd->sessionId; - - pReq->state = MV_CESA_IDLE; - pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq); - cesaReqResources++; - - if(pSA->ctrMode) - { - /* For AES CTR mode - complete processing and free allocated resources */ - mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd); - mvCesaCtrModeFinish(pReq->pCmd); - pReq->pOrgCmd = NULL; - } - } - -#if (MV_CESA_VERSION < 3) - if(pCesaReqProcess->state == MV_CESA_PROCESS) - { - /* Start request Process */ - mvCesaReqProcessStart(pCesaReqProcess); - if(readyStatus == MV_NOT_READY) - readyStatus = MV_BUSY; - } - else if(pCesaReqProcess != pCesaReqEmpty) - { - /* Start process new request from the queue */ - mvCesaReqProcessStart(pCesaReqProcess); - } -#endif - return readyStatus; -} - -/***************** Functions to work with CESA_MBUF structure ******************/ - -/******************************************************************************* -* mvCesaMbufOffset - Locate offset in the Mbuf structure -* -* DESCRIPTION: -* This function locates offset inside Multi-Bufeer structure. -* It get fragment number and place in the fragment where the offset -* is located. -* -* -* INPUT: -* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure -* int offset - Offset from the beginning of the data presented by -* the Mbuf structure. -* -* OUTPUT: -* int* pBufOffset - Offset from the beginning of the fragment where -* the offset is located. -* -* RETURN: -* int - Number of fragment, where the offset is located\ -* -*******************************************************************************/ -int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset) -{ - int frag = 0; - - while(offset > 0) - { - if(frag >= pMbuf->numFrags) - { - mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n", - frag, pMbuf->numFrags); - return MV_INVALID; - } - if(offset < pMbuf->pFrags[frag].bufSize) - { - break; - } - offset -= pMbuf->pFrags[frag].bufSize; - frag++; - } - if(pBufOffset != NULL) - *pBufOffset = offset; - - return frag; -} - -/******************************************************************************* -* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer -* -* DESCRIPTION: -* -* -* INPUT: -* MV_U8* pDstBuf - Pointer to continuous buffer, where data is -* copied to. -* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is -* copied from. -* int offset - Offset in the Mbuf structure where located first -* byte of data should be copied. -* int size - Size of data should be copied -* -* RETURN: -* MV_OK - Success, all data is copied successfully. -* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range. -* No data is copied. -* MV_EMPTY - Multi-buffer structure has not enough data to copy -* Data from the offset to end of Mbuf data is copied. -* -*******************************************************************************/ -MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf, - int offset, int size) -{ - int frag, fragOffset, bufSize; - MV_U8* pBuf; - - if(size == 0) - return MV_OK; - - frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset); - if(frag == MV_INVALID) - { - mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset); - return MV_OUT_OF_RANGE; - } - - bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset; - pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset; - while(MV_TRUE) - { - if(size <= bufSize) - { - memcpy(pDstBuf, pBuf, size); - return MV_OK; - } - memcpy(pDstBuf, pBuf, bufSize); - size -= bufSize; - frag++; - pDstBuf += bufSize; - if(frag >= pSrcMbuf->numFrags) - break; - - bufSize = pSrcMbuf->pFrags[frag].bufSize; - pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr; - } - mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n", - size); - return MV_EMPTY; -} - -/******************************************************************************* -* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure -* -* DESCRIPTION: -* -* -* INPUT: -* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is -* copied from. -* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is -* copied to. -* int offset - Offset in the Mbuf structure where located first -* byte of data should be copied. -* int size - Size of data should be copied -* -* RETURN: -* MV_OK - Success, all data is copied successfully. -* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range. -* No data is copied. -* MV_FULL - Multi-buffer structure has not enough place to copy -* all data. Data from the offset to end of Mbuf data -* is copied. -* -*******************************************************************************/ -MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf, - int offset, int size) -{ - int frag, fragOffset, bufSize; - MV_U8* pBuf; - - if(size == 0) - return MV_OK; - - frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset); - if(frag == MV_INVALID) - { - mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset); - return MV_OUT_OF_RANGE; - } - - bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset; - pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset; - while(MV_TRUE) - { - if(size <= bufSize) - { - memcpy(pBuf, pSrcBuf, size); - return MV_OK; - } - memcpy(pBuf, pSrcBuf, bufSize); - size -= bufSize; - frag++; - pSrcBuf += bufSize; - if(frag >= pDstMbuf->numFrags) - break; - - bufSize = pDstMbuf->pFrags[frag].bufSize; - pBuf = pDstMbuf->pFrags[frag].bufVirtPtr; - } - mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n", - size); - return MV_FULL; -} - -/******************************************************************************* -* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure -* -* DESCRIPTION: -* -* -* INPUT: -* -* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is -* copied to. -* int dstMbufOffset - Offset in the dstMbuf structure where first byte -* of data should be copied to. -* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is -* copied from. -* int srcMbufOffset - Offset in the srcMbuf structure where first byte -* of data should be copied from. -* int size - Size of data should be copied -* -* RETURN: -* MV_OK - Success, all data is copied successfully. -* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of -* srcMbuf or dstMbuf structure correspondently. -* No data is copied. -* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy -* all data. Partial data is copied -* -*******************************************************************************/ -MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset, - MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size) -{ - int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset; - int copySize; - MV_U8 *pSrc, *pDst; - - if(size == 0) - return MV_OK; - - srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset); - if(srcFrag == MV_INVALID) - { - mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset); - return MV_OUT_OF_RANGE; - } - pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset; - srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset; - - dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset); - if(dstFrag == MV_INVALID) - { - mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset); - return MV_OUT_OF_RANGE; - } - pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset; - dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset; - - while(size > 0) - { - copySize = MV_MIN(srcSize, dstSize); - if(size <= copySize) - { - memcpy(pDst, pSrc, size); - return MV_OK; - } - memcpy(pDst, pSrc, copySize); - size -= copySize; - srcSize -= copySize; - dstSize -= copySize; - - if(srcSize == 0) - { - srcFrag++; - if(srcFrag >= pMbufSrc->numFrags) - break; - - pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr; - srcSize = pMbufSrc->pFrags[srcFrag].bufSize; - } - - if(dstSize == 0) - { - dstFrag++; - if(dstFrag >= pMbufDst->numFrags) - break; - - pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr; - dstSize = pMbufDst->pFrags[dstFrag].bufSize; - } - } - mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n", - size); - - return MV_BAD_SIZE; -} - -static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size) -{ - int frag, fragOffset, bufSize; - MV_U8* pBuf; - - if(size == 0) - return MV_OK; - - frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset); - if(frag == MV_INVALID) - { - mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset); - return MV_OUT_OF_RANGE; - } - - bufSize = pMbuf->pFrags[frag].bufSize - fragOffset; - pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset; - while(MV_TRUE) - { - if(size <= bufSize) - { - mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size); - return MV_OK; - } - - mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize); - size -= bufSize; - frag++; - if(frag >= pMbuf->numFrags) - break; - - bufSize = pMbuf->pFrags[frag].bufSize; - pBuf = pMbuf->pFrags[frag].bufVirtPtr; - } - mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n", - __FUNCTION__, size); - return MV_FULL; -} - - -/*************************************** Local Functions ******************************/ - -/******************************************************************************* -* mvCesaFragReqProcess - Process fragmented request -* -* DESCRIPTION: -* This function processes a fragment of fragmented request (First, Middle or Last) -* -* -* INPUT: -* MV_CESA_REQ* pReq - Pointer to the request in the request queue. -* -* RETURN: -* MV_OK - The fragment is successfully passed to HW for processing. -* MV_TERMINATE - Means, that HW finished its work on this packet and no more -* interrupts will be generated for this request. -* Function mvCesaReadyGet() must be called to complete request -* processing and get request result. -* -*******************************************************************************/ -static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag) -{ - int i, copySize, cryptoDataSize, macDataSize, sid; - int cryptoIvOffset, digestOffset; - MV_U32 config; - MV_CESA_COMMAND* pCmd = pReq->pCmd; - MV_CESA_SA* pSA; - MV_CESA_MBUF* pMbuf; - MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst; - MV_U8* pSramBuf = cesaSramVirtPtr->buf; - int macTotalLen = 0; - int fixOffset, cryptoOffset, macOffset; - - cesaStats.fragCount++; - - sid = pReq->pCmd->sessionId; - - pSA = &pCesaSAD[sid]; - - cryptoIvOffset = digestOffset = 0; - i = macDataSize = 0; - cryptoDataSize = 0; - - /* First fragment processing */ - if(pReq->fragMode == MV_CESA_FRAG_FIRST) - { - /* pReq->frags monitors processing of fragmented request between fragments */ - pReq->frags.bufOffset = 0; - pReq->frags.cryptoSize = 0; - pReq->frags.macSize = 0; - - config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET); - - /* fixOffset can be not equal to zero only for FIRST fragment */ - fixOffset = pReq->fixOffset; - /* For FIRST fragment crypto and mac offsets are taken from pCmd */ - cryptoOffset = pCmd->cryptoOffset; - macOffset = pCmd->macOffset; - - copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset; - - /* Find fragment size: Must meet all requirements for CRYPTO and MAC - * cryptoDataSize - size of data will be encrypted/decrypted in this fragment - * macDataSize - size of data will be signed/verified in this fragment - * copySize - size of data will be copied from srcMbuf to SRAM and - * back to dstMbuf for this fragment - */ - mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset, - ©Size, &cryptoDataSize, &macDataSize); - - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) - { - /* CryptoIV special processing */ - if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) == - (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) ) - { - /* In CBC mode for encode direction when IV from user */ - if( (pCmd->ivFromUser) && - ((pSA->config & MV_CESA_DIRECTION_MASK) == - (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) ) - { - - /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer, - * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place - * in the buffer to SRAM IVPointer - */ - i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i], - MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush); - } - - /* Special processing when IV is not located in the first fragment */ - if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize)) - { - /* Prepare dummy place for cryptoIV in SRAM */ - cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet(); - - /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */ - if((pSA->config & MV_CESA_DIRECTION_MASK) == - (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) - { - i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i], - MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush); - } - else - { - /* For Encryption when IV is NOT from User: */ - /* Copy IV from SRAM to buffer (pCmd->ivOffset) */ - if(pCmd->ivFromUser == 0) - { - /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */ - i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i], - MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush); - } - } - } - else - { - cryptoIvOffset = pCmd->ivOffset; - } - } - } - - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - /* MAC digest special processing on Decode direction */ - if((pSA->config & MV_CESA_DIRECTION_MASK) == - (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) - { - /* Save digest from pCmd->digestOffset */ - mvCesaCopyFromMbuf(pReq->frags.orgDigest, - pCmd->pSrc, pCmd->digestOffset, pSA->digestSize); - - /* If pCmd->digestOffset is not located on the first */ - if(pCmd->digestOffset > (copySize - pSA->digestSize)) - { - MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE]; - - /* Set zeros to pCmd->digestOffset (DRAM) */ - memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE); - mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize); - - /* Prepare dummy place for digest in SRAM */ - digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet(); - } - else - { - digestOffset = pCmd->digestOffset; - } - } - } - /* Update SA in SRAM */ - if(cesaLastSid != sid) - { - mvCesaSramSaUpdate(sid, &pDmaDesc[i]); - i++; - } - - pReq->fragMode = MV_CESA_FRAG_MIDDLE; - } - else - { - /* Continue fragment */ - fixOffset = 0; - cryptoOffset = 0; - macOffset = 0; - if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf)) - { - /* Last fragment */ - config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET); - pReq->fragMode = MV_CESA_FRAG_LAST; - copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset; - - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - macDataSize = pCmd->macLength - pReq->frags.macSize; - - /* If pCmd->digestOffset is not located on last fragment */ - if(pCmd->digestOffset < pReq->frags.bufOffset) - { - /* Prepare dummy place for digest in SRAM */ - digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet(); - } - else - { - digestOffset = pCmd->digestOffset - pReq->frags.bufOffset; - } - pReq->frags.newDigestOffset = digestOffset; - macTotalLen = pCmd->macLength; - - /* HW can't calculate the Digest correctly for fragmented packets - * in the following cases: - * - MV88F5182 || - * - MV88F5181L when total macLength more that 16 Kbytes || - * - total macLength more that 64 Kbytes - */ - if( (mvCtrlModelGet() == MV_5182_DEV_ID) || - ( (mvCtrlModelGet() == MV_5181_DEV_ID) && - (mvCtrlRevGet() >= MV_5181L_A0_REV) && - (pCmd->macLength >= (1 << 14)) ) ) - { - return MV_TERMINATE; - } - } - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize; - } - - /* cryptoIvOffset - don't care */ - } - else - { - /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */ - if( (mvCtrlModelGet() == MV_5182_DEV_ID) && - (((pSA->config & MV_CESA_MAC_MODE_MASK) == - (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) || - ((pSA->config & MV_CESA_MAC_MODE_MASK) == - (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) ) - { - pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet(); - pReq->fragMode = MV_CESA_FRAG_LAST; - - return MV_TERMINATE; - } - /* Middle fragment */ - config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET); - copySize = sizeof(cesaSramVirtPtr->buf); - /* digestOffset and cryptoIvOffset - don't care */ - - /* Find fragment size */ - mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset, - ©Size, &cryptoDataSize, &macDataSize); - } - } - /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/ - pMbuf = pCmd->pSrc; - i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i], - MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush); - - /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */ - mvCesaSramDescrBuild(config, frag, - cryptoOffset + fixOffset, cryptoIvOffset + fixOffset, - cryptoDataSize, macOffset + fixOffset, - digestOffset + fixOffset, macDataSize, macTotalLen, - pReq, &pDmaDesc[i]); - i++; - - /* Add special descriptor Ownership for CPU */ - pDmaDesc[i].byteCnt = 0; - pDmaDesc[i].phySrcAdd = 0; - pDmaDesc[i].phyDestAdd = 0; - i++; - - /********* Prepare DMA descriptors to copy from SRAM to pDst *********/ - pMbuf = pCmd->pDst; - i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i], - MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush); - - /* Next field of Last DMA descriptor must be NULL */ - pDmaDesc[i-1].phyNextDescPtr = 0; - pReq->dma[frag].pDmaLast = &pDmaDesc[i-1]; - mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst, - i*sizeof(MV_DMA_DESC)); - - /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/ - - pReq->frags.bufOffset += copySize; - pReq->frags.cryptoSize += cryptoDataSize; - pReq->frags.macSize += macDataSize; - - return MV_OK; -} - - -/******************************************************************************* -* mvCesaReqProcess - Process regular (Non-fragmented) request -* -* DESCRIPTION: -* This function processes the whole (not fragmented) request -* -* INPUT: -* MV_CESA_REQ* pReq - Pointer to the request in the request queue. -* -* RETURN: -* MV_OK - The request is successfully passed to HW for processing. -* Other - Failure. The request will not be processed -* -*******************************************************************************/ -static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq) -{ - MV_CESA_MBUF *pMbuf; - MV_DMA_DESC *pDmaDesc; - MV_U8 *pSramBuf; - int sid, i, fixOffset; - MV_CESA_SA *pSA; - MV_CESA_COMMAND *pCmd = pReq->pCmd; - - cesaStats.procCount++; - - sid = pCmd->sessionId; - pSA = &pCesaSAD[sid]; - pDmaDesc = pReq->dma[0].pDmaFirst; - pSramBuf = cesaSramVirtPtr->buf; - fixOffset = pReq->fixOffset; - -/* - mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n", - sid, pSA, pDmaDesc, pSramBuf); -*/ - i = 0; - - /* Crypto IV Special processing in CBC mode for Encryption direction */ - if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) && - ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) && - ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) && - (pCmd->ivFromUser) ) - { - /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer, - * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place - * in the buffer to SRAM IVPointer - */ - i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i], - MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush); - } - - /* Update SA in SRAM */ - if(cesaLastSid != sid) - { - mvCesaSramSaUpdate(sid, &pDmaDesc[i]); - i++; - } - - /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/ - pMbuf = pCmd->pSrc; - i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i], - MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush); - - /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */ - mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset, - pCmd->ivOffset + fixOffset, pCmd->cryptoLength, - pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset, - pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]); - i++; - - /* Add special descriptor Ownership for CPU */ - pDmaDesc[i].byteCnt = 0; - pDmaDesc[i].phySrcAdd = 0; - pDmaDesc[i].phyDestAdd = 0; - i++; - - /********* Prepare DMA descriptors to copy from SRAM to pDst *********/ - pMbuf = pCmd->pDst; - i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i], - MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush); - - /* Next field of Last DMA descriptor must be NULL */ - pDmaDesc[i-1].phyNextDescPtr = 0; - pReq->dma[0].pDmaLast = &pDmaDesc[i-1]; - mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC)); - - return MV_OK; -} - - -/******************************************************************************* -* mvCesaSramDescrBuild - Set CESA descriptor in SRAM -* -* DESCRIPTION: -* This function builds CESA descriptor in SRAM from all Command parameters -* -* -* INPUT: -* int chan - CESA channel uses the descriptor -* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure -* int cryptoOffset - Offset from the beginning of SRAM buffer where -* data for encryption/decription is started. -* int ivOffset - Offset of crypto IV from the SRAM base. Valid only -* for first fragment. -* int cryptoLength - Size (in bytes) of data for encryption/descryption -* operation on this fragment. -* int macOffset - Offset from the beginning of SRAM buffer where -* data for Authentication is started -* int digestOffset - Offset from the beginning of SRAM buffer where -* digest is located. Valid for first and last fragments. -* int macLength - Size (in bytes) of data for Authentication -* operation on this fragment. -* int macTotalLen - Toatl size (in bytes) of data for Authentication -* operation on the whole request (packet). Valid for -* last fragment only. -* -* RETURN: None -* -*******************************************************************************/ -static void mvCesaSramDescrBuild(MV_U32 config, int frag, - int cryptoOffset, int ivOffset, int cryptoLength, - int macOffset, int digestOffset, int macLength, - int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc) -{ - MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag]; - MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc; - MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet()); - - pCesaDesc->config = MV_32BIT_LE(config); - - if( (config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - /* word 1 */ - pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset); - pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset); - /* word 2 */ - pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength); - /* word 3 */ - pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey - - mvCesaSramAddrGet())); - /* word 4 */ - pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV - - mvCesaSramAddrGet())); - pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset); - } - - if( (config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - /* word 5 */ - pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset); - pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen); - - /* word 6 */ - pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset); - pCesaDesc->macDataLen = MV_16BIT_LE(macLength); - - /* word 7 */ - pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV - - mvCesaSramAddrGet())); - pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV - - mvCesaSramAddrGet())); - } - /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */ - pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc)); - pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc)); - pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31); - - /* flush Source buffer */ - mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC)); -} - -/******************************************************************************* -* mvCesaSramSaUpdate - Move required SA information to SRAM if needed. -* -* DESCRIPTION: -* Copy to SRAM values of the required SA. -* -* -* INPUT: -* short sid - Session ID needs SRAM Cache update -* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to -* copy SA values from DRAM to SRAM. -* -* RETURN: -* MV_OK - Cache entry for this SA copied to SRAM. -* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM -* -*******************************************************************************/ -static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc) -{ - MV_CESA_SA *pSA = &pCesaSAD[sid]; - - /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */ - pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31); - pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA)); - pDmaDesc->phyDestAdd = - MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA)); - - /* Source buffer is already flushed during OpenSession*/ - /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/ -} - -/******************************************************************************* -* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by -* Mbuf structure from DRAM to SRAM -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request -* data in DRAM -* MV_U8* pSramBuf - pointer to buffer in SRAM where data should -* be copied to. -* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy. -* The function set number of DMA descriptors needed -* to copy the copySize bytes from Mbuf. -* MV_BOOL isToMbuf - Copy direction. -* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM. -* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer. -* int offset - Offset in the Mbuf structure that copy should be -* started from. -* int copySize - Size of data should be copied. -* -* RETURN: -* int - number of DMA descriptors used for the copy. -* -*******************************************************************************/ -#ifndef MV_NETBSD -static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf, - MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf, - int offset, int copySize, MV_BOOL skipFlush) -{ - int bufOffset, bufSize, size, frag, i; - MV_U8* pBuf; - - i = 0; - - /* Calculate start place for copy: fragment number and offset in the fragment */ - frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset); - bufSize = pMbuf->pFrags[frag].bufSize - bufOffset; - pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset; - - /* Size accumulate total copy size */ - size = 0; - - /* Create DMA lists to copy mBuf from pSrc to SRAM */ - while(size < copySize) - { - /* Find copy size for each DMA descriptor */ - bufSize = MV_MIN(bufSize, (copySize - size)); - pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31); - if(isToMbuf) - { - pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf)); - pDmaDesc[i].phySrcAdd = - MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size))); - /* invalidate the buffer */ - if(skipFlush == MV_FALSE) - mvOsCacheInvalidate(NULL, pBuf, bufSize); - } - else - { - pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf)); - pDmaDesc[i].phyDestAdd = - MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size))); - /* flush the buffer */ - if(skipFlush == MV_FALSE) - mvOsCacheFlush(NULL, pBuf, bufSize); - } - - /* Count number of used DMA descriptors */ - i++; - size += bufSize; - - /* go to next fragment in the Mbuf */ - frag++; - pBuf = pMbuf->pFrags[frag].bufVirtPtr; - bufSize = pMbuf->pFrags[frag].bufSize; - } - return i; -} -#else /* MV_NETBSD */ -static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf, - MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf, - int offset, int copySize, MV_BOOL skipFlush) -{ - int bufOffset, bufSize, thisSize, size, frag, i; - MV_ULONG bufPhys, sramPhys; - MV_U8* pBuf; - - /* - * Calculate start place for copy: fragment number and offset in - * the fragment - */ - frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset); - - /* - * Get SRAM physical address only once. We can update it in-place - * as we build the descriptor chain. - */ - sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf); - - /* - * 'size' accumulates total copy size, 'i' counts desccriptors. - */ - size = i = 0; - - /* Create DMA lists to copy mBuf from pSrc to SRAM */ - while (size < copySize) { - /* - * Calculate # of bytes to copy from the current fragment, - * and the pointer to the start of data - */ - bufSize = pMbuf->pFrags[frag].bufSize - bufOffset; - pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset; - bufOffset = 0; /* First frag may be non-zero */ - frag++; - - /* - * As long as there is data in the current fragment... - */ - while (bufSize > 0) { - /* - * Ensure we don't cross an MMU page boundary. - * XXX: This is NetBSD-specific, but it is a - * quick and dirty way to fix the problem. - * A true HAL would rely on the OS-specific - * driver to do this... - */ - thisSize = PAGE_SIZE - - (((MV_ULONG)pBuf) & (PAGE_SIZE - 1)); - thisSize = MV_MIN(bufSize, thisSize); - /* - * Make sure we don't copy more than requested - */ - if (thisSize > (copySize - size)) { - thisSize = copySize - size; - bufSize = 0; - } - - /* - * Physicall address of this fragment - */ - bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf)); - - /* - * Set up the descriptor - */ - pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31); - if(isToMbuf) { - pDmaDesc[i].phyDestAdd = bufPhys; - pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys); - /* invalidate the buffer */ - if(skipFlush == MV_FALSE) - mvOsCacheInvalidate(NULL, pBuf, thisSize); - } else { - pDmaDesc[i].phySrcAdd = bufPhys; - pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys); - /* flush the buffer */ - if(skipFlush == MV_FALSE) - mvOsCacheFlush(NULL, pBuf, thisSize); - } - - pDmaDesc[i].phyNextDescPtr = - MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1]))); - - /* flush the DMA desc */ - mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC)); - - /* Update state */ - bufSize -= thisSize; - sramPhys += thisSize; - pBuf += thisSize; - size += thisSize; - i++; - } - } - - return i; -} -#endif /* MV_NETBSD */ -/******************************************************************************* -* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key -* -* DESCRIPTION: -* This function calculate Inner and Outer values used for HMAC algorithm. -* This operation allows improve performance fro the whole HMAC processing. -* -* INPUT: -* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1. -* unsigned char key[] - Pointer to HMAC key. -* int keyLength - Size of HMAC key (maximum 64 bytes) -* -* OUTPUT: -* unsigned char innerIV[] - HASH(key^inner) -* unsigned char outerIV[] - HASH(key^outter) -* -* RETURN: None -* -*******************************************************************************/ -static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength, - unsigned char innerIV[], unsigned char outerIV[]) -{ - unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH]; - unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH]; - int i, digestSize = 0; -#if defined(MV_CPU_LE) || defined(MV_PPC) - MV_U32 swapped32, val32, *pVal32; -#endif - for(i=0; ipFrags[frag].bufVirtPtr + fragOffset; - size = pMbuf->pFrags[frag].bufSize - fragOffset; - - /* Complete Inner part */ - while(macLeftSize > 0) - { - if(macLeftSize <= size) - { - mvSHA1Update(&ctx, pData, macLeftSize); - break; - } - mvSHA1Update(&ctx, pData, size); - macLeftSize -= size; - frag++; - pData = pMbuf->pFrags[frag].bufVirtPtr; - size = pMbuf->pFrags[frag].bufSize; - } - mvSHA1Final(pDigest, &ctx); -/* - mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n", - pOuterIV, macLeftSize, macTotalSize); - mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1); -*/ - - if(pOuterIV != NULL) - { - /* If HMAC - Complete Outer part */ - for(i=0; ipFrags[frag].bufVirtPtr + fragOffset; - size = pMbuf->pFrags[frag].bufSize - fragOffset; - - /* Complete Inner part */ - while(macLeftSize > 0) - { - if(macLeftSize <= size) - { - mvMD5Update(&ctx, pData, macLeftSize); - break; - } - mvMD5Update(&ctx, pData, size); - macLeftSize -= size; - frag++; - pData = pMbuf->pFrags[frag].bufVirtPtr; - size = pMbuf->pFrags[frag].bufSize; - } - mvMD5Final(pDigest, &ctx); - -/* - mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n", - pOuterIV, macLeftSize, macTotalSize); - mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1); -*/ - if(pOuterIV != NULL) - { - /* Complete Outer part */ - for(i=0; ipCmd; - MV_U8* pDigest; - MV_CESA_MAC_MODE macMode; - MV_U8* pOuterIV = NULL; - - /* Copy data from Source fragment to Destination */ - if(pCmd->pSrc != pCmd->pDst) - { - mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset, - pCmd->pSrc, pReq->frags.bufOffset, macDataSize); - } - -/* - mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize); - mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize); -*/ - pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset); - - macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET; -/* - mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n", - macDataSize, pCmd->macLength, pCmd->digestOffset, macMode); -*/ - switch(macMode) - { - case MV_CESA_MAC_HMAC_MD5: - pOuterIV = pSA->pSramSA->macOuterIV; - - case MV_CESA_MAC_MD5: - mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV, - macDataSize, pCmd->macLength, pDigest); - break; - - case MV_CESA_MAC_HMAC_SHA1: - pOuterIV = pSA->pSramSA->macOuterIV; - - case MV_CESA_MAC_SHA1: - mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV, - macDataSize, pCmd->macLength, pDigest); - break; - - default: - mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode); - return MV_BAD_PARAM; - } - return MV_OK; -} - -/******************************************************************************* -* mvCesaCtrModeInit - -* -* DESCRIPTION: -* -* -* INPUT: NONE -* -* -* RETURN: -* MV_CESA_COMMAND* -* -*******************************************************************************/ -static MV_CESA_COMMAND* mvCesaCtrModeInit(void) -{ - MV_CESA_MBUF *pMbuf; - MV_U8 *pBuf; - MV_CESA_COMMAND *pCmd; - - pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) + - sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100); - if(pBuf == NULL) - { - mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n", - sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) ); - return NULL; - } - pCmd = (MV_CESA_COMMAND*)pBuf; - pBuf += sizeof(MV_CESA_COMMAND); - - pMbuf = (MV_CESA_MBUF*)pBuf; - pBuf += sizeof(MV_CESA_MBUF); - - pMbuf->pFrags = (MV_BUF_INFO*)pBuf; - - pMbuf->numFrags = 1; - pCmd->pSrc = pMbuf; - pCmd->pDst = pMbuf; -/* - mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n", - pCmd, pCmd->pSrc, pCmd->pDst, - pMbuf->pFrags); -*/ - return pCmd; -} - -/******************************************************************************* -* mvCesaCtrModePrepare - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd) -{ - MV_CESA_MBUF *pMbuf; - MV_U8 *pBuf, *pIV; - MV_U32 counter, *pCounter; - int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE); -/* - mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n", - pCmd, pCmd->pSrc, pCmd->pDst, - pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst); -*/ - pMbuf = pCtrModeCmd->pSrc; - - /* Allocate buffer for Key stream */ - pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize, - &pMbuf->pFrags[0].bufPhysAddr, - &pMbuf->pFrags[0].memHandle); - if(pBuf == NULL) - { - mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize); - return MV_OUT_OF_CPU_MEM; - } - memset(pBuf, 0, cryptoSize); - mvOsCacheFlush(NULL, pBuf, cryptoSize); - - pMbuf->pFrags[0].bufVirtPtr = pBuf; - pMbuf->mbufSize = cryptoSize; - pMbuf->pFrags[0].bufSize = cryptoSize; - - pCtrModeCmd->pReqPrv = pCmd->pReqPrv; - pCtrModeCmd->sessionId = pCmd->sessionId; - - /* ivFromUser and ivOffset are don't care */ - pCtrModeCmd->cryptoOffset = 0; - pCtrModeCmd->cryptoLength = cryptoSize; - - /* digestOffset, macOffset and macLength are don't care */ - - mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE); - pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter))); - counter = *pCounter; - counter = MV_32BIT_BE(counter); - pIV = pBuf; - cryptoSize -= MV_CESA_AES_BLOCK_SIZE; - - /* fill key stream */ - while(cryptoSize > 0) - { - pBuf += MV_CESA_AES_BLOCK_SIZE; - memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter)); - pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter))); - counter++; - *pCounter = MV_32BIT_BE(counter); - cryptoSize -= MV_CESA_AES_BLOCK_SIZE; - } - - return MV_OK; -} - -/******************************************************************************* -* mvCesaCtrModeComplete - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd) -{ - int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize; - int cryptoSize = pCmd->cryptoLength; - MV_U8 *pSrc, *pDst, *pKey; - MV_STATUS status = MV_OK; -/* - mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n", - pCmd, pCmd->pSrc, pCmd->pDst, - pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst); -*/ - /* XOR source data with key stream to destination data */ - pKey = pCmd->pDst->pFrags[0].bufVirtPtr; - keyOffset = 0; - - if( (pOrgCmd->pSrc != pOrgCmd->pDst) && - (pOrgCmd->cryptoOffset > 0) ) - { - /* Copy Prefix from source buffer to destination buffer */ - - status = mvCesaMbufCopy(pOrgCmd->pDst, 0, - pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset); -/* - status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc, - 0, pOrgCmd->cryptoOffset); - status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst, - 0, pOrgCmd->cryptoOffset); -*/ - } - - srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset); - pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr; - srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize; - - dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset); - pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr; - dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize; - - while(cryptoSize > 0) - { - pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]); - - cryptoSize--; - dstOffset++; - srcOffset++; - keyOffset++; - - if(srcOffset >= srcSize) - { - srcFrag++; - srcOffset = 0; - pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr; - srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize; - } - - if(dstOffset >= dstSize) - { - dstFrag++; - dstOffset = 0; - pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr; - dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize; - } - } - - if(pOrgCmd->pSrc != pOrgCmd->pDst) - { - /* Copy Suffix from source buffer to destination buffer */ - srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength; - - if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0) - { - status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset, - pOrgCmd->pSrc, srcOffset, - pOrgCmd->pDst->mbufSize - srcOffset); - } - -/* - status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc, - srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset); - status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst, - srcOffset, pOrgCmd->pDst->mbufSize - srcOffset); -*/ - } - - /* Free buffer used for Key stream */ - mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize, - pCmd->pDst->pFrags[0].bufPhysAddr, - pCmd->pDst->pFrags[0].bufVirtPtr, - pCmd->pDst->pFrags[0].memHandle); - - return MV_OK; -} - -/******************************************************************************* -* mvCesaCtrModeFinish - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_COMMAND* pCmd -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd) -{ - mvOsFree(pCmd); -} - -/******************************************************************************* -* mvCesaParamCheck - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, - MV_U8* pFixOffset) -{ - MV_U8 fixOffset = 0xFF; - - /* Check AUTH operation parameters */ - if( ((pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) ) - { - /* MAC offset should be at least 4 byte aligned */ - if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) ) - { - mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n", - pCmd->macOffset); - return MV_BAD_PARAM; - } - /* Digest offset must be 4 byte aligned */ - if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) ) - { - mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n", - pCmd->digestOffset); - return MV_BAD_PARAM; - } - /* In addition all offsets should be the same alignment: 8 or 4 */ - if(fixOffset == 0xFF) - { - fixOffset = (pCmd->macOffset % 8); - } - else - { - if( (pCmd->macOffset % 8) != fixOffset) - { - mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n", - pCmd->macOffset, fixOffset); - return MV_BAD_PARAM; - } - } - if( (pCmd->digestOffset % 8) != fixOffset) - { - mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n", - pCmd->digestOffset, fixOffset); - return MV_BAD_PARAM; - } - } - /* Check CRYPTO operation parameters */ - if( ((pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) ) - { - /* CryptoOffset should be at least 4 byte aligned */ - if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) ) - { - mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n", - pCmd->cryptoOffset); - return MV_BAD_PARAM; - } - /* cryptoLength should be the whole number of blocks */ - if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) ) - { - mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n", - pCmd->cryptoLength, pSA->cryptoBlockSize); - return MV_BAD_PARAM; - } - if(fixOffset == 0xFF) - { - fixOffset = (pCmd->cryptoOffset % 8); - } - else - { - /* In addition all offsets should be the same alignment: 8 or 4 */ - if( (pCmd->cryptoOffset % 8) != fixOffset) - { - mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n", - pCmd->cryptoOffset, fixOffset); - return MV_BAD_PARAM; - } - } - - /* check for CBC mode */ - if(pSA->cryptoIvSize > 0) - { - /* cryptoIV must not be part of CryptoLength */ - if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) && - (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) ) - { - mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n", - pCmd->ivOffset, pCmd->macOffset, pCmd->macLength); - return MV_BAD_PARAM; - } - - /* ivOffset must be 4 byte aligned */ - if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) ) - { - mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n", - pCmd->ivOffset); - return MV_BAD_PARAM; - } - /* In addition all offsets should be the same alignment: 8 or 4 */ - if( (pCmd->ivOffset % 8) != fixOffset) - { - mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n", - pCmd->ivOffset, fixOffset); - return MV_BAD_PARAM; - } - } - } - return MV_OK; -} - -/******************************************************************************* -* mvCesaFragParamCheck - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd) -{ - int offset; - - if( ((pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) ) - { - /* macOffset must be less that SRAM buffer size */ - if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE)) - { - mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n", - pCmd->macOffset); - return MV_BAD_PARAM; - } - /* macOffset+macSize must be more than mbufSize - SRAM buffer size */ - if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) || - ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >= - sizeof(cesaSramVirtPtr->buf)) ) - { - mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n", - pCmd->macLength, pCmd->pSrc->mbufSize); - return MV_BAD_PARAM; - } - } - - if( ((pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) ) - { - /* cryptoOffset must be less that SRAM buffer size */ - /* 4 for possible fixOffset */ - if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) - { - mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n", - pCmd->cryptoOffset); - return MV_BAD_PARAM; - } - - /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */ - if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) || - ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >= - (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) ) - { - mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n", - pCmd->cryptoLength, pCmd->pSrc->mbufSize); - return MV_BAD_PARAM; - } - } - - /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */ - if( ((pSA->config & MV_CESA_OPERATION_MASK) == - (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) || - ((pSA->config & MV_CESA_OPERATION_MASK) == - (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) ) - { - if( (mvCtrlModelGet() == MV_5182_DEV_ID) || - ( (mvCtrlModelGet() == MV_5181_DEV_ID) && - (mvCtrlRevGet() >= MV_5181L_A0_REV) && - (pCmd->macLength >= (1 << 14)) ) ) - { - return MV_NOT_ALLOWED; - } - - /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */ - if(pCmd->cryptoOffset > pCmd->macOffset) - { - offset = pCmd->cryptoOffset - pCmd->macOffset; - } - else - { - offset = pCmd->macOffset - pCmd->cryptoOffset; - } - - if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) ) - { -/* - mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n", - pSA->cryptoBlockSize); -*/ - return MV_NOT_ALLOWED; - } - /* Digest must not be part of CryptoLength */ - if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) && - (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) ) - { -/* - mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n", - pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength); -*/ - return MV_NOT_ALLOWED; - } - } - return MV_OK; -} - -/******************************************************************************* -* mvCesaFragSizeFind - -* -* DESCRIPTION: -* -* -* INPUT: -* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, -* int cryptoOffset, int macOffset, -* -* OUTPUT: -* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize -* -* RETURN: -* MV_STATUS -* -*******************************************************************************/ -static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq, - int cryptoOffset, int macOffset, - int* pCopySize, int* pCryptoDataSize, int* pMacDataSize) -{ - MV_CESA_COMMAND *pCmd = pReq->pCmd; - int cryptoDataSize, macDataSize, copySize; - - cryptoDataSize = macDataSize = 0; - copySize = *pCopySize; - - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - cryptoDataSize = MV_MIN( (copySize - cryptoOffset), - (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) ); - - /* cryptoSize for each fragment must be the whole number of blocksSize */ - if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) ) - { - cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize); - copySize = cryptoOffset + cryptoDataSize; - } - } - if( (pSA->config & MV_CESA_OPERATION_MASK) != - (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) - { - macDataSize = MV_MIN( (copySize - macOffset), - (pCmd->macLength - (pReq->frags.macSize + 1))); - - /* macSize for each fragment (except last) must be the whole number of blocksSize */ - if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) ) - { - macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE); - copySize = macOffset + macDataSize; - } - cryptoDataSize = copySize - cryptoOffset; - } - *pCopySize = copySize; - - if(pCryptoDataSize != NULL) - *pCryptoDataSize = cryptoDataSize; - - if(pMacDataSize != NULL) - *pMacDataSize = macDataSize; -}