1 /*******************************************************************************
2 Copyright (C) Marvell International Ltd. and its affiliates
4 This software file (the "File") is owned and distributed by Marvell
5 International Ltd. and/or its affiliates ("Marvell") under the following
6 alternative licensing terms. Once you have made an election to distribute the
7 File under one of the following license alternatives, please (i) delete this
8 introductory statement regarding license alternatives, (ii) delete the two
9 license alternatives that you have not elected to use and (iii) preserve the
10 Marvell copyright notice above.
12 ********************************************************************************
13 Marvell Commercial License Option
15 If you received this File from Marvell and you have entered into a commercial
16 license agreement (a "Commercial License") with Marvell, the File is licensed
17 to you under the terms of the applicable Commercial License.
19 ********************************************************************************
20 Marvell GPL License Option
22 If you received this File from Marvell, you may opt to use, redistribute and/or
23 modify this File in accordance with the terms and conditions of the General
24 Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25 available along with the File in the license.txt file or by writing to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27 on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
29 THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31 DISCLAIMED. The GPL License provides additional details about this warranty
33 ********************************************************************************
34 Marvell BSD License Option
36 If you received this File from Marvell, you may opt to use, redistribute and/or
37 modify this File under the following licensing terms.
38 Redistribution and use in source and binary forms, with or without modification,
39 are permitted provided that the following conditions are met:
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
44 * Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
48 * Neither the name of Marvell nor the names of its contributors may be
49 used to endorse or promote products derived from this software without
50 specific prior written permission.
52 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 *******************************************************************************/
65 #include "cesa/mvCesa.h"
67 #include "ctrlEnv/mvCtrlEnvLib.h"
71 /********** Global variables **********/
73 /* If request size is more than MV_CESA_MAX_BUF_SIZE the
74 * request is processed as fragmented request.
77 MV_CESA_STATS cesaStats
;
79 MV_BUF_INFO cesaSramSaBuf
;
80 short cesaLastSid
= -1;
81 MV_CESA_SA
* pCesaSAD
= NULL
;
84 MV_CESA_REQ
* pCesaReqFirst
= NULL
;
85 MV_CESA_REQ
* pCesaReqLast
= NULL
;
86 MV_CESA_REQ
* pCesaReqEmpty
= NULL
;
87 MV_CESA_REQ
* pCesaReqProcess
= NULL
;
88 int cesaQueueDepth
= 0;
89 int cesaReqResources
= 0;
91 MV_CESA_SRAM_MAP
* cesaSramVirtPtr
= NULL
;
92 MV_U32 cesaCryptEngBase
= 0;
93 void *cesaOsHandle
= NULL
;
94 #if (MV_CESA_VERSION >= 3)
95 MV_U32 cesaChainLength
= 0;
97 MV_U32 chainIndex
= 0;
98 MV_CESA_REQ
* pNextActiveChain
= 0;
99 MV_CESA_REQ
* pEndCurrChain
= 0;
100 MV_BOOL isFirstReq
= MV_TRUE
;
103 static INLINE MV_U8
* mvCesaSramAddrGet(void)
105 #ifdef MV_CESA_NO_SRAM
106 return (MV_U8
*)cesaSramVirtPtr
;
108 return (MV_U8
*)cesaCryptEngBase
;
109 #endif /* MV_CESA_NO_SRAM */
112 static INLINE MV_ULONG
mvCesaSramVirtToPhys(void* pDev
, MV_U8
* pSramVirt
)
114 #ifdef MV_CESA_NO_SRAM
115 return (MV_ULONG
)mvOsIoVirtToPhy(NULL
, pSramVirt
);
117 return (MV_ULONG
)pSramVirt
;
118 #endif /* MV_CESA_NO_SRAM */
121 /* Internal Function prototypes */
123 static INLINE
void mvCesaSramDescrBuild(MV_U32 config
, int frag
,
124 int cryptoOffset
, int ivOffset
, int cryptoLength
,
125 int macOffset
, int digestOffset
, int macLength
, int macTotalLen
,
126 MV_CESA_REQ
*pCesaReq
, MV_DMA_DESC
* pDmaDesc
);
128 static INLINE
void mvCesaSramSaUpdate(short sid
, MV_DMA_DESC
*pDmaDesc
);
130 static INLINE
int mvCesaDmaCopyPrepare(MV_CESA_MBUF
* pMbuf
, MV_U8
* pSramBuf
,
131 MV_DMA_DESC
* pDmaDesc
, MV_BOOL isToMbuf
,
132 int offset
, int copySize
, MV_BOOL skipFlush
);
134 static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode
, unsigned char key
[], int keyLength
,
135 unsigned char innerIV
[], unsigned char outerIV
[]);
137 static MV_STATUS
mvCesaFragAuthComplete(MV_CESA_REQ
* pReq
, MV_CESA_SA
* pSA
,
140 static MV_CESA_COMMAND
* mvCesaCtrModeInit(void);
142 static MV_STATUS
mvCesaCtrModePrepare(MV_CESA_COMMAND
*pCtrModeCmd
, MV_CESA_COMMAND
*pCmd
);
143 static MV_STATUS
mvCesaCtrModeComplete(MV_CESA_COMMAND
*pOrgCmd
, MV_CESA_COMMAND
*pCmd
);
144 static void mvCesaCtrModeFinish(MV_CESA_COMMAND
*pCmd
);
146 static INLINE MV_STATUS
mvCesaReqProcess(MV_CESA_REQ
* pReq
);
147 static MV_STATUS
mvCesaFragReqProcess(MV_CESA_REQ
* pReq
, MV_U8 frag
);
149 static INLINE MV_STATUS
mvCesaParamCheck(MV_CESA_SA
* pSA
, MV_CESA_COMMAND
*pCmd
, MV_U8
* pFixOffset
);
150 static INLINE MV_STATUS
mvCesaFragParamCheck(MV_CESA_SA
* pSA
, MV_CESA_COMMAND
*pCmd
);
152 static INLINE
void mvCesaFragSizeFind(MV_CESA_SA
* pSA
, MV_CESA_REQ
* pReq
,
153 int cryptoOffset
, int macOffset
,
154 int* pCopySize
, int* pCryptoDataSize
, int* pMacDataSize
);
155 static MV_STATUS
mvCesaMbufCacheUnmap(MV_CESA_MBUF
* pMbuf
, int offset
, int size
);
158 /* Go to the next request in the request queue */
159 static INLINE MV_CESA_REQ
* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ
* pReq
)
161 if(pReq
== pCesaReqLast
)
162 return pCesaReqFirst
;
167 #if (MV_CESA_VERSION >= 3)
168 /* Go to the previous request in the request queue */
169 static INLINE MV_CESA_REQ
* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ
* pReq
)
171 if(pReq
== pCesaReqFirst
)
180 static INLINE
void mvCesaReqProcessStart(MV_CESA_REQ
* pReq
)
184 #if (MV_CESA_VERSION >= 3)
185 pReq
->state
= MV_CESA_CHAIN
;
187 pReq
->state
= MV_CESA_PROCESS
;
189 cesaStats
.startCount
++;
191 if(pReq
->fragMode
== MV_CESA_FRAG_NONE
)
197 frag
= pReq
->frags
.nextFrag
;
198 pReq
->frags
.nextFrag
++;
200 #if (MV_CESA_VERSION >= 2)
201 /* Enable TDMA engine */
202 MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG
, 0);
203 MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG
,
204 (MV_U32
)mvCesaVirtToPhys(&pReq
->dmaDescBuf
, pReq
->dma
[frag
].pDmaFirst
));
206 /* Enable IDMA engine */
207 MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
208 MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
209 (MV_U32
)mvCesaVirtToPhys(&pReq
->dmaDescBuf
, pReq
->dma
[frag
].pDmaFirst
));
210 #endif /* MV_CESA_VERSION >= 2 */
212 #if defined(MV_BRIDGE_SYNC_REORDER)
213 mvOsBridgeReorderWA();
216 /* Start Accelerator */
217 MV_REG_WRITE(MV_CESA_CMD_REG
, MV_CESA_CMD_CHAN_ENABLE_MASK
);
221 /*******************************************************************************
222 * mvCesaHalInit - Initialize the CESA driver
225 * This function initialize the CESA driver.
226 * 1) Session database
228 * 4) DMA descriptor lists - one list per request. Each list
229 * has MV_CESA_MAX_DMA_DESC descriptors.
232 * numOfSession - maximum number of supported sessions
233 * queueDepth - number of elements in the request queue.
234 * pSramBase - virtual address of Sram
235 * osHandle - A handle used by the OS to allocate memory for the
236 * module (Passed to the OS Services layer)
240 * MV_NO_RESOURCE - Fail, can't allocate resources:
241 * Session database, request queue,
242 * DMA descriptors list, LRU cache database.
243 * MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
245 *******************************************************************************/
246 MV_STATUS
mvCesaHalInit (int numOfSession
, int queueDepth
, char* pSramBase
, MV_U32 cryptEngBase
,
250 MV_U32 descOffsetReg
, configReg
;
251 MV_CESA_SRAM_SA
*pSramSA
;
254 mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
255 numOfSession
, queueDepth
, pSramBase
);
257 cesaOsHandle
= osHandle
;
258 /* Create Session database */
259 pCesaSAD
= mvOsMalloc(sizeof(MV_CESA_SA
)*numOfSession
);
262 mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
263 sizeof(MV_CESA_SA
)*numOfSession
, numOfSession
);
265 return MV_NO_RESOURCE
;
267 memset(pCesaSAD
, 0, sizeof(MV_CESA_SA
)*numOfSession
);
268 cesaMaxSA
= numOfSession
;
270 /* Allocate imag of sramSA in the DRAM */
271 cesaSramSaBuf
.bufSize
= sizeof(MV_CESA_SRAM_SA
)*numOfSession
+
272 CPU_D_CACHE_LINE_SIZE
;
274 cesaSramSaBuf
.bufVirtPtr
= mvOsIoCachedMalloc(osHandle
,cesaSramSaBuf
.bufSize
,
275 &cesaSramSaBuf
.bufPhysAddr
,
276 &cesaSramSaBuf
.memHandle
);
278 if(cesaSramSaBuf
.bufVirtPtr
== NULL
)
280 mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
281 cesaSramSaBuf
.bufSize
);
283 return MV_NO_RESOURCE
;
285 memset(cesaSramSaBuf
.bufVirtPtr
, 0, cesaSramSaBuf
.bufSize
);
286 pSramSA
= (MV_CESA_SRAM_SA
*)MV_ALIGN_UP((MV_ULONG
)cesaSramSaBuf
.bufVirtPtr
,
287 CPU_D_CACHE_LINE_SIZE
);
288 for(i
=0; i
<numOfSession
; i
++)
290 pCesaSAD
[i
].pSramSA
= &pSramSA
[i
];
293 /* Create request queue */
294 pCesaReqFirst
= mvOsMalloc(sizeof(MV_CESA_REQ
)*queueDepth
);
295 if(pCesaReqFirst
== NULL
)
297 mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
298 sizeof(MV_CESA_REQ
)*queueDepth
, queueDepth
);
300 return MV_NO_RESOURCE
;
302 memset(pCesaReqFirst
, 0, sizeof(MV_CESA_REQ
)*queueDepth
);
303 pCesaReqEmpty
= pCesaReqFirst
;
304 pCesaReqLast
= pCesaReqFirst
+ (queueDepth
-1);
305 pCesaReqProcess
= pCesaReqEmpty
;
306 cesaQueueDepth
= queueDepth
;
307 cesaReqResources
= queueDepth
;
308 #if (MV_CESA_VERSION >= 3)
309 cesaChainLength
= MAX_CESA_CHAIN_LENGTH
;
311 /* pSramBase must be 8 byte aligned */
312 if( MV_IS_NOT_ALIGN((MV_ULONG
)pSramBase
, 8) )
314 mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
317 return MV_NOT_ALIGNED
;
319 cesaSramVirtPtr
= (MV_CESA_SRAM_MAP
*)pSramBase
;
321 cesaCryptEngBase
= cryptEngBase
;
323 /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
325 /* Clear registers */
326 MV_REG_WRITE( MV_CESA_CFG_REG
, 0);
327 MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG
, 0);
328 MV_REG_WRITE( MV_CESA_ISR_MASK_REG
, 0);
330 /* Initialize DMA descriptor lists for all requests in Request queue */
331 descOffsetReg
= configReg
= 0;
332 for(req
=0; req
<queueDepth
; req
++)
336 MV_DMA_DESC
* pDmaDesc
;
338 pReq
= &pCesaReqFirst
[req
];
340 pReq
->cesaDescBuf
.bufSize
= sizeof(MV_CESA_DESC
)*MV_CESA_MAX_REQ_FRAGS
+
341 CPU_D_CACHE_LINE_SIZE
;
343 pReq
->cesaDescBuf
.bufVirtPtr
=
344 mvOsIoCachedMalloc(osHandle
,pReq
->cesaDescBuf
.bufSize
,
345 &pReq
->cesaDescBuf
.bufPhysAddr
,
346 &pReq
->cesaDescBuf
.memHandle
);
348 if(pReq
->cesaDescBuf
.bufVirtPtr
== NULL
)
350 mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
351 req
, pReq
->cesaDescBuf
.bufSize
);
353 return MV_NO_RESOURCE
;
355 memset(pReq
->cesaDescBuf
.bufVirtPtr
, 0, pReq
->cesaDescBuf
.bufSize
);
356 pReq
->pCesaDesc
= (MV_CESA_DESC
*)MV_ALIGN_UP((MV_ULONG
)pReq
->cesaDescBuf
.bufVirtPtr
,
357 CPU_D_CACHE_LINE_SIZE
);
359 pReq
->dmaDescBuf
.bufSize
= sizeof(MV_DMA_DESC
)*MV_CESA_MAX_DMA_DESC
*MV_CESA_MAX_REQ_FRAGS
+
360 CPU_D_CACHE_LINE_SIZE
;
362 pReq
->dmaDescBuf
.bufVirtPtr
=
363 mvOsIoCachedMalloc(osHandle
,pReq
->dmaDescBuf
.bufSize
,
364 &pReq
->dmaDescBuf
.bufPhysAddr
,
365 &pReq
->dmaDescBuf
.memHandle
);
367 if(pReq
->dmaDescBuf
.bufVirtPtr
== NULL
)
369 mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
370 req
, pReq
->dmaDescBuf
.bufSize
);
372 return MV_NO_RESOURCE
;
374 memset(pReq
->dmaDescBuf
.bufVirtPtr
, 0, pReq
->dmaDescBuf
.bufSize
);
375 pDmaDesc
= (MV_DMA_DESC
*)MV_ALIGN_UP((MV_ULONG
)pReq
->dmaDescBuf
.bufVirtPtr
,
376 CPU_D_CACHE_LINE_SIZE
);
378 for(frag
=0; frag
<MV_CESA_MAX_REQ_FRAGS
; frag
++)
380 MV_CESA_DMA
* pDma
= &pReq
->dma
[frag
];
382 pDma
->pDmaFirst
= pDmaDesc
;
383 pDma
->pDmaLast
= NULL
;
385 for(i
=0; i
<MV_CESA_MAX_DMA_DESC
-1; i
++)
387 /* link all DMA descriptors together */
388 pDma
->pDmaFirst
[i
].phyNextDescPtr
=
389 MV_32BIT_LE(mvCesaVirtToPhys(&pReq
->dmaDescBuf
, &pDmaDesc
[i
+1]));
391 pDma
->pDmaFirst
[i
].phyNextDescPtr
= 0;
392 mvOsCacheFlush(NULL
, &pDma
->pDmaFirst
[0], MV_CESA_MAX_DMA_DESC
*sizeof(MV_DMA_DESC
));
394 pDmaDesc
+= MV_CESA_MAX_DMA_DESC
;
397 /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
398 descOffsetReg
= (MV_U16
)((MV_U8
*)&cesaSramVirtPtr
->desc
- mvCesaSramAddrGet());
399 MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG
, descOffsetReg
);
401 configReg
|= (MV_CESA_CFG_WAIT_DMA_MASK
| MV_CESA_CFG_ACT_DMA_MASK
);
402 #if (MV_CESA_VERSION >= 3)
403 configReg
|= MV_CESA_CFG_CHAIN_MODE_MASK
;
406 #if (MV_CESA_VERSION >= 2)
407 /* Initialize TDMA engine */
408 MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG
, MV_CESA_TDMA_CTRL_VALUE
);
409 MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG
, 0);
410 MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG
, 0);
412 /* Initialize IDMA #0 engine */
413 MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
414 MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
415 MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
416 MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
418 | ICCHR_DESC_BYTE_SWAP_EN
421 /* Clear Cause Byte of IDMA channel to be used */
422 MV_REG_WRITE( IDMA_CAUSE_REG
, ~ICICR_CAUSE_MASK_ALL(0));
423 MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE
);
424 #endif /* (MV_CESA_VERSION >= 2) */
426 /* Set CESA configuration registers */
427 MV_REG_WRITE( MV_CESA_CFG_REG
, configReg
);
428 mvCesaDebugStatsClear();
433 /*******************************************************************************
434 * mvCesaFinish - Shutdown the CESA driver
437 * This function shutdown the CESA driver and free all allocted resources.
445 *******************************************************************************/
446 MV_STATUS
mvCesaFinish (void)
451 mvOsPrintf("mvCesaFinish: \n");
453 cesaSramVirtPtr
= NULL
;
455 /* Free all resources: DMA list, etc. */
456 for(req
=0; req
<cesaQueueDepth
; req
++)
458 pReq
= &pCesaReqFirst
[req
];
459 if(pReq
->dmaDescBuf
.bufVirtPtr
!= NULL
)
461 mvOsIoCachedFree(cesaOsHandle
,pReq
->dmaDescBuf
.bufSize
,
462 pReq
->dmaDescBuf
.bufPhysAddr
,
463 pReq
->dmaDescBuf
.bufVirtPtr
,
464 pReq
->dmaDescBuf
.memHandle
);
466 if(pReq
->cesaDescBuf
.bufVirtPtr
!= NULL
)
468 mvOsIoCachedFree(cesaOsHandle
,pReq
->cesaDescBuf
.bufSize
,
469 pReq
->cesaDescBuf
.bufPhysAddr
,
470 pReq
->cesaDescBuf
.bufVirtPtr
,
471 pReq
->cesaDescBuf
.memHandle
);
474 #if (MV_CESA_VERSION < 2)
475 MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
476 #endif /* (MV_CESA_VERSION < 2) */
478 /* Free request queue */
479 if(pCesaReqFirst
!= NULL
)
481 mvOsFree(pCesaReqFirst
);
482 pCesaReqFirst
= pCesaReqLast
= NULL
;
483 pCesaReqEmpty
= pCesaReqProcess
= NULL
;
484 cesaQueueDepth
= cesaReqResources
= 0;
486 /* Free SA database */
493 MV_REG_WRITE( MV_CESA_CFG_REG
, 0);
494 MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG
, 0);
495 MV_REG_WRITE( MV_CESA_ISR_MASK_REG
, 0);
500 /*******************************************************************************
501 * mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
504 * This function set IV value using by Crypto algorithms in CBC mode.
505 * Each channel has its own IV value.
506 * This function gets IV value from the caller. If no IV value passed from
507 * the caller or only part of IV passed, the function will init the rest part
508 * of IV value (or the whole IV) by random value.
511 * MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
512 * the function will generate random IV value.
513 * int ivSize - size (in bytes) of IV provided by user. If ivSize is
514 * smaller than maximum IV size, the function will complete
515 * IV by random value.
521 *******************************************************************************/
522 MV_STATUS
mvCesaCryptoIvSet(MV_U8
* pIV
, int ivSize
)
526 mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
528 pSramIV
= cesaSramVirtPtr
->cryptoIV
;
529 if(ivSize
> MV_CESA_MAX_IV_LENGTH
)
531 mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize
);
532 ivSize
= MV_CESA_MAX_IV_LENGTH
;
536 memcpy(pSramIV
, pIV
, ivSize
);
537 ivSize
= MV_CESA_MAX_IV_LENGTH
- ivSize
;
543 int size
, mv_random
= mvOsRand();
545 size
= MV_MIN(ivSize
, sizeof(mv_random
));
546 memcpy(pSramIV
, (void*)&mv_random
, size
);
552 mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
553 MV_CESA_MAX_IV_LENGTH);
554 mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
555 MV_CESA_MAX_IV_LENGTH);
560 /*******************************************************************************
561 * mvCesaSessionOpen - Open new uni-directional crypto session
564 * This function open new session.
567 * MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
570 * short *pSid - session ID, should be used for all future
571 * requests over this session.
574 * MV_OK - Session opend successfully.
575 * MV_FULL - All sessions are in use, no free place in
577 * MV_BAD_PARAM - One of session input parameters is invalid.
579 *******************************************************************************/
580 MV_STATUS
mvCesaSessionOpen(MV_CESA_OPEN_SESSION
*pSession
, short* pSid
)
586 cesaStats
.openedCount
++;
588 /* Find free entry in SAD */
589 for(sid
=0; sid
<cesaMaxSA
; sid
++)
591 if(pCesaSAD
[sid
].valid
== 0)
598 mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
602 /* Check Input parameters for Open session */
603 if (pSession
->operation
>= MV_CESA_MAX_OPERATION
)
605 mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
606 pSession
->operation
);
609 config
|= (pSession
->operation
<< MV_CESA_OPERATION_OFFSET
);
611 if( (pSession
->direction
!= MV_CESA_DIR_ENCODE
) &&
612 (pSession
->direction
!= MV_CESA_DIR_DECODE
) )
614 mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
615 pSession
->direction
);
618 config
|= (pSession
->direction
<< MV_CESA_DIRECTION_BIT
);
620 /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
622 /* Check AUTH parameters and update SA entry */
623 if(pSession
->operation
!= MV_CESA_CRYPTO_ONLY
)
625 /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
626 if( (pSession
->macMode
== MV_CESA_MAC_HMAC_MD5
) ||
627 (pSession
->macMode
== MV_CESA_MAC_HMAC_SHA1
) )
629 if(pSession
->macKeyLength
> MV_CESA_MAX_MAC_KEY_LENGTH
)
631 mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
632 pSession
->macKeyLength
);
635 mvCesaHmacIvGet(pSession
->macMode
, pSession
->macKey
, pSession
->macKeyLength
,
636 pCesaSAD
[sid
].pSramSA
->macInnerIV
,
637 pCesaSAD
[sid
].pSramSA
->macOuterIV
);
638 pCesaSAD
[sid
].macKeyLength
= pSession
->macKeyLength
;
640 switch(pSession
->macMode
)
642 case MV_CESA_MAC_MD5
:
643 case MV_CESA_MAC_HMAC_MD5
:
644 digestSize
= MV_CESA_MD5_DIGEST_SIZE
;
647 case MV_CESA_MAC_SHA1
:
648 case MV_CESA_MAC_HMAC_SHA1
:
649 digestSize
= MV_CESA_SHA1_DIGEST_SIZE
;
653 mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
657 config
|= (pSession
->macMode
<< MV_CESA_MAC_MODE_OFFSET
);
659 /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
660 /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
661 if( (pSession
->digestSize
!= digestSize
) && (pSession
->digestSize
!= 12))
663 mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
664 pSession
->digestSize
);
665 mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
668 pCesaSAD
[sid
].digestSize
= pSession
->digestSize
;
670 if(pCesaSAD
[sid
].digestSize
== 12)
672 /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
673 config
|= (MV_CESA_MAC_DIGEST_96B
<< MV_CESA_MAC_DIGEST_SIZE_BIT
);
677 /* Check CRYPTO parameters and update SA entry */
678 if(pSession
->operation
!= MV_CESA_MAC_ONLY
)
680 switch(pSession
->cryptoAlgorithm
)
682 case MV_CESA_CRYPTO_DES
:
683 pCesaSAD
[sid
].cryptoKeyLength
= MV_CESA_DES_KEY_LENGTH
;
684 pCesaSAD
[sid
].cryptoBlockSize
= MV_CESA_DES_BLOCK_SIZE
;
687 case MV_CESA_CRYPTO_3DES
:
688 pCesaSAD
[sid
].cryptoKeyLength
= MV_CESA_3DES_KEY_LENGTH
;
689 pCesaSAD
[sid
].cryptoBlockSize
= MV_CESA_DES_BLOCK_SIZE
;
690 /* Only EDE mode is supported */
691 config
|= (MV_CESA_CRYPTO_3DES_EDE
<<
692 MV_CESA_CRYPTO_3DES_MODE_BIT
);
695 case MV_CESA_CRYPTO_AES
:
696 switch(pSession
->cryptoKeyLength
)
699 pCesaSAD
[sid
].cryptoKeyLength
= MV_CESA_AES_128_KEY_LENGTH
;
700 config
|= (MV_CESA_CRYPTO_AES_KEY_128
<<
701 MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET
);
705 pCesaSAD
[sid
].cryptoKeyLength
= MV_CESA_AES_192_KEY_LENGTH
;
706 config
|= (MV_CESA_CRYPTO_AES_KEY_192
<<
707 MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET
);
712 pCesaSAD
[sid
].cryptoKeyLength
= MV_CESA_AES_256_KEY_LENGTH
;
713 config
|= (MV_CESA_CRYPTO_AES_KEY_256
<<
714 MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET
);
717 pCesaSAD
[sid
].cryptoBlockSize
= MV_CESA_AES_BLOCK_SIZE
;
721 mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
722 pSession
->cryptoAlgorithm
);
725 config
|= (pSession
->cryptoAlgorithm
<< MV_CESA_CRYPTO_ALG_OFFSET
);
727 if(pSession
->cryptoKeyLength
!= pCesaSAD
[sid
].cryptoKeyLength
)
729 mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
730 pSession
->cryptoKeyLength
, pCesaSAD
[sid
].cryptoKeyLength
);
734 /* Copy Crypto key */
735 if( (pSession
->cryptoAlgorithm
== MV_CESA_CRYPTO_AES
) &&
736 (pSession
->direction
== MV_CESA_DIR_DECODE
))
738 /* Crypto Key for AES decode is computed from original key material */
739 /* and depend on cryptoKeyLength (128/192/256 bits) */
740 aesMakeKey(pCesaSAD
[sid
].pSramSA
->cryptoKey
, pSession
->cryptoKey
,
741 pSession
->cryptoKeyLength
*8, MV_CESA_AES_BLOCK_SIZE
*8);
745 /*panic("mvCesaSessionOpen2");*/
746 memcpy(pCesaSAD
[sid
].pSramSA
->cryptoKey
, pSession
->cryptoKey
,
747 pCesaSAD
[sid
].cryptoKeyLength
);
751 switch(pSession
->cryptoMode
)
753 case MV_CESA_CRYPTO_ECB
:
754 pCesaSAD
[sid
].cryptoIvSize
= 0;
757 case MV_CESA_CRYPTO_CBC
:
758 pCesaSAD
[sid
].cryptoIvSize
= pCesaSAD
[sid
].cryptoBlockSize
;
761 case MV_CESA_CRYPTO_CTR
:
762 /* Supported only for AES algorithm */
763 if(pSession
->cryptoAlgorithm
!= MV_CESA_CRYPTO_AES
)
765 mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
768 pCesaSAD
[sid
].cryptoIvSize
= 0;
769 pCesaSAD
[sid
].ctrMode
= 1;
770 /* Replace to ECB mode for HW */
771 pSession
->cryptoMode
= MV_CESA_CRYPTO_ECB
;
775 mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
776 pSession
->cryptoMode
);
780 config
|= (pSession
->cryptoMode
<< MV_CESA_CRYPTO_MODE_BIT
);
782 pCesaSAD
[sid
].config
= config
;
784 mvOsCacheFlush(NULL
, pCesaSAD
[sid
].pSramSA
, sizeof(MV_CESA_SRAM_SA
));
788 pCesaSAD
[sid
].valid
= 1;
792 /*******************************************************************************
793 * mvCesaSessionClose - Close active crypto session
796 * This function closes existing session
799 * short sid - Unique identifier of the session to be closed
802 * MV_OK - Session closed successfully.
803 * MV_BAD_PARAM - Session identifier is out of valid range.
804 * MV_NOT_FOUND - There is no active session with such ID.
806 *******************************************************************************/
807 MV_STATUS
mvCesaSessionClose(short sid
)
809 cesaStats
.closedCount
++;
813 mvOsPrintf("CESA Error: sid (%d) is too big\n", sid
);
816 if(pCesaSAD
[sid
].valid
== 0)
818 mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid
);
821 if(cesaLastSid
== sid
)
824 pCesaSAD
[sid
].valid
= 0;
828 /*******************************************************************************
829 * mvCesaAction - Perform crypto operation
832 * This function set new CESA request FIFO queue for further HW processing.
833 * The function checks request parameters before set new request to the queue.
834 * If one of the CESA channels is ready for processing the request will be
835 * passed to HW. When request processing is finished the CESA interrupt will
836 * be generated by HW. The caller should call mvCesaReadyGet() function to
837 * complete request processing and get result.
840 * MV_CESA_COMMAND *pCmd - pointer to new CESA request.
841 * It includes pointers to Source and Destination
842 * buffers, session identifier get from
843 * mvCesaSessionOpen() function, pointer to caller
844 * private data and all needed crypto parameters.
847 * MV_OK - request successfully added to request queue
848 * and will be processed.
849 * MV_NO_MORE - request successfully added to request queue and will
850 * be processed, but request queue became Full and next
851 * request will not be accepted.
852 * MV_NO_RESOURCE - request queue is FULL and the request can not
854 * MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
855 * failed. Request can not be processed.
856 * MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
857 * as one request and should be splitted for two requests:
858 * CRYPTO_ONLY and MAC_ONLY.
859 * MV_BAD_PARAM - One of the request parameters is out of valid range.
860 * The request can not be processed.
862 *******************************************************************************/
863 MV_STATUS
mvCesaAction (MV_CESA_COMMAND
*pCmd
)
866 MV_CESA_REQ
* pReq
= pCesaReqEmpty
;
867 int sid
= pCmd
->sessionId
;
868 MV_CESA_SA
* pSA
= &pCesaSAD
[sid
];
869 #if (MV_CESA_VERSION >= 3)
870 MV_CESA_REQ
* pFromReq
;
873 cesaStats
.reqCount
++;
875 /* Check that the request queue is not FULL */
876 if(cesaReqResources
== 0)
877 return MV_NO_RESOURCE
;
879 if( (sid
>= cesaMaxSA
) || (!pSA
->valid
) )
881 mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid
);
888 /* AES in CTR mode can't be mixed with Authentication */
889 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
890 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
892 mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
893 return MV_NOT_ALLOWED
;
895 /* All other request parameters should not be checked because key stream */
896 /* (not user data) processed by AES HW engine */
897 pReq
->pOrgCmd
= pCmd
;
898 /* Allocate temporary pCmd structure for Key stream */
899 pCmd
= mvCesaCtrModeInit();
901 return MV_OUT_OF_CPU_MEM
;
903 /* Prepare Key stream */
904 mvCesaCtrModePrepare(pCmd
, pReq
->pOrgCmd
);
909 /* Check request parameters and calculae fixOffset */
910 status
= mvCesaParamCheck(pSA
, pCmd
, &pReq
->fixOffset
);
918 /* Check if the packet need fragmentation */
919 if(pCmd
->pSrc
->mbufSize
<= sizeof(cesaSramVirtPtr
->buf
) )
921 /* request size is smaller than single buffer size */
922 pReq
->fragMode
= MV_CESA_FRAG_NONE
;
924 /* Prepare NOT fragmented packets */
925 status
= mvCesaReqProcess(pReq
);
928 mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
931 #if (MV_CESA_VERSION >= 3)
932 pReq
->frags
.numFrag
= 1;
939 /* request size is larger than buffer size - needs fragmentation */
941 /* Check restrictions for processing fragmented packets */
942 status
= mvCesaFragParamCheck(pSA
, pCmd
);
946 pReq
->fragMode
= MV_CESA_FRAG_FIRST
;
947 pReq
->frags
.nextFrag
= 0;
949 /* Prepare Process Fragmented packets */
950 while(pReq
->fragMode
!= MV_CESA_FRAG_LAST
)
952 if(frag
>= MV_CESA_MAX_REQ_FRAGS
)
954 mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag
);
955 return MV_OUT_OF_CPU_MEM
;
957 status
= mvCesaFragReqProcess(pReq
, frag
);
958 if(status
== MV_OK
) {
959 #if (MV_CESA_VERSION >= 3)
961 pReq
->dma
[frag
-1].pDmaLast
->phyNextDescPtr
=
962 MV_32BIT_LE(mvCesaVirtToPhys(&pReq
->dmaDescBuf
, pReq
->dma
[frag
].pDmaFirst
));
963 mvOsCacheFlush(NULL
, pReq
->dma
[frag
-1].pDmaLast
, sizeof(MV_DMA_DESC
));
969 pReq
->frags
.numFrag
= frag
;
970 #if (MV_CESA_VERSION >= 3)
972 chainReqNum
+= pReq
->frags
.numFrag
;
973 if(chainReqNum
>= MAX_CESA_CHAIN_LENGTH
)
974 chainReqNum
= MAX_CESA_CHAIN_LENGTH
;
979 pReq
->state
= MV_CESA_PENDING
;
981 pCesaReqEmpty
= MV_CESA_REQ_NEXT_PTR(pReq
);
982 cesaReqResources
-= 1;
984 /* #ifdef CESA_DEBUG */
985 if( (cesaQueueDepth
- cesaReqResources
) > cesaStats
.maxReqCount
)
986 cesaStats
.maxReqCount
= (cesaQueueDepth
- cesaReqResources
);
987 /* #endif CESA_DEBUG */
991 #if (MV_CESA_VERSION >= 3)
992 /* Are we within chain bounderies and follows the first request ? */
993 if((chainReqNum
> 0) && (chainReqNum
< MAX_CESA_CHAIN_LENGTH
)) {
995 pFromReq
= MV_CESA_REQ_PREV_PTR(pReq
);
997 pReq
->state
= MV_CESA_CHAIN
;
998 /* assume concatenating is possible */
999 pFromReq
->dma
[pFromReq
->frags
.numFrag
-1].pDmaLast
->phyNextDescPtr
=
1000 MV_32BIT_LE(mvCesaVirtToPhys(&pToReq
->dmaDescBuf
, pToReq
->dma
[0].pDmaFirst
));
1001 mvOsCacheFlush(NULL
, pFromReq
->dma
[pFromReq
->frags
.numFrag
-1].pDmaLast
, sizeof(MV_DMA_DESC
));
1003 /* align active & next pointers */
1004 if(pNextActiveChain
->state
!= MV_CESA_PENDING
)
1005 pEndCurrChain
= pNextActiveChain
= MV_CESA_REQ_NEXT_PTR(pReq
);
1007 else { /* we have only one chain, start new one */
1010 /* align active & next pointers */
1011 if(pNextActiveChain
->state
!= MV_CESA_PENDING
)
1012 pEndCurrChain
= pNextActiveChain
= pReq
;
1016 /* In case we concatenate full chain */
1017 if(chainReqNum
== MAX_CESA_CHAIN_LENGTH
) {
1019 if(pNextActiveChain
->state
!= MV_CESA_PENDING
)
1020 pEndCurrChain
= pNextActiveChain
= pReq
;
1024 pReq
= pCesaReqProcess
;
1025 if(pReq
->state
== MV_CESA_PENDING
) {
1026 pNextActiveChain
= pReq
;
1027 pEndCurrChain
= MV_CESA_REQ_NEXT_PTR(pReq
);
1028 /* Start Process new request */
1029 mvCesaReqProcessStart(pReq
);
1035 if((chainIndex
< MAX_CESA_CHAIN_LENGTH
) && (chainReqNum
> cesaStats
.maxChainUsage
))
1036 cesaStats
.maxChainUsage
= chainReqNum
;
1040 /* Check status of CESA channels and process requests if possible */
1041 pReq
= pCesaReqProcess
;
1042 if(pReq
->state
== MV_CESA_PENDING
)
1044 /* Start Process new request */
1045 mvCesaReqProcessStart(pReq
);
1048 /* If request queue became FULL - return MV_NO_MORE */
1049 if(cesaReqResources
== 0)
1056 /*******************************************************************************
1057 * mvCesaReadyGet - Get crypto request that processing is finished
1060 * This function complete request processing and return ready request to
1061 * caller. To don't miss interrupts the caller must call this function
1062 * while MV_OK or MV_TERMINATE values returned.
1065 * MV_U32 chanMap - map of CESA channels finished thier job
1066 * accordingly with CESA Cause register.
1067 * MV_CESA_RESULT* pResult - pointer to structure contains information
1068 * about ready request. It includes pointer to
1069 * user private structure "pReqPrv", session identifier
1070 * for this request "sessionId" and return code.
1071 * Return code set to MV_FAIL if calculated digest value
1072 * on decode direction is different than digest value
1076 * MV_OK - Success, ready request is returned.
1077 * MV_NOT_READY - Next request is not ready yet. New interrupt will
1078 * be generated for futher request processing.
1079 * MV_EMPTY - There is no more request for processing.
1080 * MV_BUSY - Fragmented request is not ready yet.
1081 * MV_TERMINATE - Call this function once more to complete processing
1082 * of fragmented request.
1084 *******************************************************************************/
1085 MV_STATUS
mvCesaReadyGet(MV_CESA_RESULT
* pResult
)
1087 MV_STATUS status
, readyStatus
= MV_NOT_READY
;
1092 #if (MV_CESA_VERSION >= 3)
1093 if(isFirstReq
== MV_TRUE
) {
1097 isFirstReq
= MV_FALSE
;
1099 if(pNextActiveChain
->state
== MV_CESA_PENDING
) {
1100 /* Start request Process */
1101 mvCesaReqProcessStart(pNextActiveChain
);
1102 pEndCurrChain
= pNextActiveChain
;
1105 /* Update pNextActiveChain to next chain head */
1106 while(pNextActiveChain
->state
== MV_CESA_CHAIN
)
1107 pNextActiveChain
= MV_CESA_REQ_NEXT_PTR(pNextActiveChain
);
1111 /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
1112 if(pCesaReqProcess
== pEndCurrChain
) {
1113 isFirstReq
= MV_TRUE
;
1114 pEndCurrChain
= pNextActiveChain
;
1116 if(pCesaReqProcess
->state
!= MV_CESA_PROCESS
) {
1122 statusReg
= MV_REG_READ(MV_CESA_STATUS_REG
);
1123 if( statusReg
& MV_CESA_STATUS_ACTIVE_MASK
)
1125 mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg
);
1126 cesaStats
.notReadyCount
++;
1127 return MV_NOT_READY
;
1129 #endif /* CESA_DEBUG */
1131 cesaStats
.readyCount
++;
1133 pReq
= pCesaReqProcess
;
1134 pSA
= &pCesaSAD
[pReq
->pCmd
->sessionId
];
1136 pResult
->retCode
= MV_OK
;
1137 if(pReq
->fragMode
!= MV_CESA_FRAG_NONE
)
1141 #if (MV_CESA_VERSION >= 3)
1142 pReq
->frags
.nextFrag
= 1;
1143 while(pReq
->frags
.nextFrag
<= pReq
->frags
.numFrag
) {
1145 frag
= (pReq
->frags
.nextFrag
- 1);
1147 /* Restore DMA descriptor list */
1148 pReq
->dma
[frag
].pDmaLast
->phyNextDescPtr
=
1149 MV_32BIT_LE(mvCesaVirtToPhys(&pReq
->dmaDescBuf
, &pReq
->dma
[frag
].pDmaLast
[1]));
1150 pReq
->dma
[frag
].pDmaLast
= NULL
;
1152 /* Special processing for finished fragmented request */
1153 if(pReq
->frags
.nextFrag
>= pReq
->frags
.numFrag
)
1155 mvCesaMbufCacheUnmap(pReq
->pCmd
->pDst
, 0, pReq
->pCmd
->pDst
->mbufSize
);
1157 /* Fragmented packet is ready */
1158 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1159 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1161 int macDataSize
= pReq
->pCmd
->macLength
- pReq
->frags
.macSize
;
1163 if(macDataSize
!= 0)
1165 /* Calculate all other blocks by SW */
1166 mvCesaFragAuthComplete(pReq
, pSA
, macDataSize
);
1169 /* Copy new digest from SRAM to the Destination buffer */
1170 pNewDigest
= cesaSramVirtPtr
->buf
+ pReq
->frags
.newDigestOffset
;
1171 status
= mvCesaCopyToMbuf(pNewDigest
, pReq
->pCmd
->pDst
,
1172 pReq
->pCmd
->digestOffset
, pSA
->digestSize
);
1174 /* For decryption: Compare new digest value with original one */
1175 if((pSA
->config
& MV_CESA_DIRECTION_MASK
) ==
1176 (MV_CESA_DIR_DECODE
<< MV_CESA_DIRECTION_BIT
))
1178 if( memcmp(pNewDigest
, pReq
->frags
.orgDigest
, pSA
->digestSize
) != 0)
1181 mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
1182 chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
1184 /* Signiture verification is failed */
1185 pResult
->retCode
= MV_FAIL
;
1189 readyStatus
= MV_OK
;
1191 #if (MV_CESA_VERSION >= 3)
1192 pReq
->frags
.nextFrag
++;
1198 mvCesaMbufCacheUnmap(pReq
->pCmd
->pDst
, 0, pReq
->pCmd
->pDst
->mbufSize
);
1200 /* Restore DMA descriptor list */
1201 pReq
->dma
[0].pDmaLast
->phyNextDescPtr
=
1202 MV_32BIT_LE(mvCesaVirtToPhys(&pReq
->dmaDescBuf
, &pReq
->dma
[0].pDmaLast
[1]));
1203 pReq
->dma
[0].pDmaLast
= NULL
;
1204 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1205 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) ) &&
1206 ((pSA
->config
& MV_CESA_DIRECTION_MASK
) ==
1207 (MV_CESA_DIR_DECODE
<< MV_CESA_DIRECTION_BIT
)) )
1209 /* For AUTH on decode : Check Digest result in Status register */
1210 statusReg
= MV_REG_READ(MV_CESA_STATUS_REG
);
1211 if(statusReg
& MV_CESA_STATUS_DIGEST_ERR_MASK
)
1214 mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
1217 /* Signiture verification is failed */
1218 pResult
->retCode
= MV_FAIL
;
1221 readyStatus
= MV_OK
;
1224 if(readyStatus
== MV_OK
)
1226 /* If Request is ready - Prepare pResult structure */
1227 pResult
->pReqPrv
= pReq
->pCmd
->pReqPrv
;
1228 pResult
->sessionId
= pReq
->pCmd
->sessionId
;
1230 pReq
->state
= MV_CESA_IDLE
;
1231 pCesaReqProcess
= MV_CESA_REQ_NEXT_PTR(pReq
);
1236 /* For AES CTR mode - complete processing and free allocated resources */
1237 mvCesaCtrModeComplete(pReq
->pOrgCmd
, pReq
->pCmd
);
1238 mvCesaCtrModeFinish(pReq
->pCmd
);
1239 pReq
->pOrgCmd
= NULL
;
1243 #if (MV_CESA_VERSION < 3)
1244 if(pCesaReqProcess
->state
== MV_CESA_PROCESS
)
1246 /* Start request Process */
1247 mvCesaReqProcessStart(pCesaReqProcess
);
1248 if(readyStatus
== MV_NOT_READY
)
1249 readyStatus
= MV_BUSY
;
1251 else if(pCesaReqProcess
!= pCesaReqEmpty
)
1253 /* Start process new request from the queue */
1254 mvCesaReqProcessStart(pCesaReqProcess
);
1260 /***************** Functions to work with CESA_MBUF structure ******************/
1262 /*******************************************************************************
1263 * mvCesaMbufOffset - Locate offset in the Mbuf structure
1266 * This function locates offset inside Multi-Bufeer structure.
1267 * It get fragment number and place in the fragment where the offset
1272 * MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
1273 * int offset - Offset from the beginning of the data presented by
1274 * the Mbuf structure.
1277 * int* pBufOffset - Offset from the beginning of the fragment where
1278 * the offset is located.
1281 * int - Number of fragment, where the offset is located\
1283 *******************************************************************************/
1284 int mvCesaMbufOffset(MV_CESA_MBUF
* pMbuf
, int offset
, int* pBufOffset
)
1290 if(frag
>= pMbuf
->numFrags
)
1292 mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
1293 frag
, pMbuf
->numFrags
);
1296 if(offset
< pMbuf
->pFrags
[frag
].bufSize
)
1300 offset
-= pMbuf
->pFrags
[frag
].bufSize
;
1303 if(pBufOffset
!= NULL
)
1304 *pBufOffset
= offset
;
1309 /*******************************************************************************
1310 * mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
1316 * MV_U8* pDstBuf - Pointer to continuous buffer, where data is
1318 * MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
1320 * int offset - Offset in the Mbuf structure where located first
1321 * byte of data should be copied.
1322 * int size - Size of data should be copied
1325 * MV_OK - Success, all data is copied successfully.
1326 * MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
1327 * No data is copied.
1328 * MV_EMPTY - Multi-buffer structure has not enough data to copy
1329 * Data from the offset to end of Mbuf data is copied.
1331 *******************************************************************************/
1332 MV_STATUS
mvCesaCopyFromMbuf(MV_U8
* pDstBuf
, MV_CESA_MBUF
* pSrcMbuf
,
1333 int offset
, int size
)
1335 int frag
, fragOffset
, bufSize
;
1341 frag
= mvCesaMbufOffset(pSrcMbuf
, offset
, &fragOffset
);
1342 if(frag
== MV_INVALID
)
1344 mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset
);
1345 return MV_OUT_OF_RANGE
;
1348 bufSize
= pSrcMbuf
->pFrags
[frag
].bufSize
- fragOffset
;
1349 pBuf
= pSrcMbuf
->pFrags
[frag
].bufVirtPtr
+ fragOffset
;
1354 memcpy(pDstBuf
, pBuf
, size
);
1357 memcpy(pDstBuf
, pBuf
, bufSize
);
1361 if(frag
>= pSrcMbuf
->numFrags
)
1364 bufSize
= pSrcMbuf
->pFrags
[frag
].bufSize
;
1365 pBuf
= pSrcMbuf
->pFrags
[frag
].bufVirtPtr
;
1367 mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
1372 /*******************************************************************************
1373 * mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
1379 * MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
1381 * MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
1383 * int offset - Offset in the Mbuf structure where located first
1384 * byte of data should be copied.
1385 * int size - Size of data should be copied
1388 * MV_OK - Success, all data is copied successfully.
1389 * MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
1390 * No data is copied.
1391 * MV_FULL - Multi-buffer structure has not enough place to copy
1392 * all data. Data from the offset to end of Mbuf data
1395 *******************************************************************************/
1396 MV_STATUS
mvCesaCopyToMbuf(MV_U8
* pSrcBuf
, MV_CESA_MBUF
* pDstMbuf
,
1397 int offset
, int size
)
1399 int frag
, fragOffset
, bufSize
;
1405 frag
= mvCesaMbufOffset(pDstMbuf
, offset
, &fragOffset
);
1406 if(frag
== MV_INVALID
)
1408 mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset
);
1409 return MV_OUT_OF_RANGE
;
1412 bufSize
= pDstMbuf
->pFrags
[frag
].bufSize
- fragOffset
;
1413 pBuf
= pDstMbuf
->pFrags
[frag
].bufVirtPtr
+ fragOffset
;
1418 memcpy(pBuf
, pSrcBuf
, size
);
1421 memcpy(pBuf
, pSrcBuf
, bufSize
);
1425 if(frag
>= pDstMbuf
->numFrags
)
1428 bufSize
= pDstMbuf
->pFrags
[frag
].bufSize
;
1429 pBuf
= pDstMbuf
->pFrags
[frag
].bufVirtPtr
;
1431 mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
1436 /*******************************************************************************
1437 * mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
1444 * MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
1446 * int dstMbufOffset - Offset in the dstMbuf structure where first byte
1447 * of data should be copied to.
1448 * MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
1450 * int srcMbufOffset - Offset in the srcMbuf structure where first byte
1451 * of data should be copied from.
1452 * int size - Size of data should be copied
1455 * MV_OK - Success, all data is copied successfully.
1456 * MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
1457 * srcMbuf or dstMbuf structure correspondently.
1458 * No data is copied.
1459 * MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
1460 * all data. Partial data is copied
1462 *******************************************************************************/
1463 MV_STATUS
mvCesaMbufCopy(MV_CESA_MBUF
* pMbufDst
, int dstMbufOffset
,
1464 MV_CESA_MBUF
* pMbufSrc
, int srcMbufOffset
, int size
)
1466 int srcFrag
, dstFrag
, srcSize
, dstSize
, srcOffset
, dstOffset
;
1473 srcFrag
= mvCesaMbufOffset(pMbufSrc
, srcMbufOffset
, &srcOffset
);
1474 if(srcFrag
== MV_INVALID
)
1476 mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset
);
1477 return MV_OUT_OF_RANGE
;
1479 pSrc
= pMbufSrc
->pFrags
[srcFrag
].bufVirtPtr
+ srcOffset
;
1480 srcSize
= pMbufSrc
->pFrags
[srcFrag
].bufSize
- srcOffset
;
1482 dstFrag
= mvCesaMbufOffset(pMbufDst
, dstMbufOffset
, &dstOffset
);
1483 if(dstFrag
== MV_INVALID
)
1485 mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset
);
1486 return MV_OUT_OF_RANGE
;
1488 pDst
= pMbufDst
->pFrags
[dstFrag
].bufVirtPtr
+ dstOffset
;
1489 dstSize
= pMbufDst
->pFrags
[dstFrag
].bufSize
- dstOffset
;
1493 copySize
= MV_MIN(srcSize
, dstSize
);
1494 if(size
<= copySize
)
1496 memcpy(pDst
, pSrc
, size
);
1499 memcpy(pDst
, pSrc
, copySize
);
1501 srcSize
-= copySize
;
1502 dstSize
-= copySize
;
1507 if(srcFrag
>= pMbufSrc
->numFrags
)
1510 pSrc
= pMbufSrc
->pFrags
[srcFrag
].bufVirtPtr
;
1511 srcSize
= pMbufSrc
->pFrags
[srcFrag
].bufSize
;
1517 if(dstFrag
>= pMbufDst
->numFrags
)
1520 pDst
= pMbufDst
->pFrags
[dstFrag
].bufVirtPtr
;
1521 dstSize
= pMbufDst
->pFrags
[dstFrag
].bufSize
;
1524 mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
1530 static MV_STATUS
mvCesaMbufCacheUnmap(MV_CESA_MBUF
* pMbuf
, int offset
, int size
)
1532 int frag
, fragOffset
, bufSize
;
1538 frag
= mvCesaMbufOffset(pMbuf
, offset
, &fragOffset
);
1539 if(frag
== MV_INVALID
)
1541 mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset
);
1542 return MV_OUT_OF_RANGE
;
1545 bufSize
= pMbuf
->pFrags
[frag
].bufSize
- fragOffset
;
1546 pBuf
= pMbuf
->pFrags
[frag
].bufVirtPtr
+ fragOffset
;
1551 mvOsCacheUnmap(NULL
, mvOsIoVirtToPhy(NULL
, pBuf
), size
);
1555 mvOsCacheUnmap(NULL
, mvOsIoVirtToPhy(NULL
, pBuf
), bufSize
);
1558 if(frag
>= pMbuf
->numFrags
)
1561 bufSize
= pMbuf
->pFrags
[frag
].bufSize
;
1562 pBuf
= pMbuf
->pFrags
[frag
].bufVirtPtr
;
1564 mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
1565 __FUNCTION__
, size
);
1570 /*************************************** Local Functions ******************************/
1572 /*******************************************************************************
1573 * mvCesaFragReqProcess - Process fragmented request
1576 * This function processes a fragment of fragmented request (First, Middle or Last)
1580 * MV_CESA_REQ* pReq - Pointer to the request in the request queue.
1583 * MV_OK - The fragment is successfully passed to HW for processing.
1584 * MV_TERMINATE - Means, that HW finished its work on this packet and no more
1585 * interrupts will be generated for this request.
1586 * Function mvCesaReadyGet() must be called to complete request
1587 * processing and get request result.
1589 *******************************************************************************/
1590 static MV_STATUS
mvCesaFragReqProcess(MV_CESA_REQ
* pReq
, MV_U8 frag
)
1592 int i
, copySize
, cryptoDataSize
, macDataSize
, sid
;
1593 int cryptoIvOffset
, digestOffset
;
1595 MV_CESA_COMMAND
* pCmd
= pReq
->pCmd
;
1597 MV_CESA_MBUF
* pMbuf
;
1598 MV_DMA_DESC
* pDmaDesc
= pReq
->dma
[frag
].pDmaFirst
;
1599 MV_U8
* pSramBuf
= cesaSramVirtPtr
->buf
;
1600 int macTotalLen
= 0;
1601 int fixOffset
, cryptoOffset
, macOffset
;
1603 cesaStats
.fragCount
++;
1605 sid
= pReq
->pCmd
->sessionId
;
1607 pSA
= &pCesaSAD
[sid
];
1609 cryptoIvOffset
= digestOffset
= 0;
1610 i
= macDataSize
= 0;
1613 /* First fragment processing */
1614 if(pReq
->fragMode
== MV_CESA_FRAG_FIRST
)
1616 /* pReq->frags monitors processing of fragmented request between fragments */
1617 pReq
->frags
.bufOffset
= 0;
1618 pReq
->frags
.cryptoSize
= 0;
1619 pReq
->frags
.macSize
= 0;
1621 config
= pSA
->config
| (MV_CESA_FRAG_FIRST
<< MV_CESA_FRAG_MODE_OFFSET
);
1623 /* fixOffset can be not equal to zero only for FIRST fragment */
1624 fixOffset
= pReq
->fixOffset
;
1625 /* For FIRST fragment crypto and mac offsets are taken from pCmd */
1626 cryptoOffset
= pCmd
->cryptoOffset
;
1627 macOffset
= pCmd
->macOffset
;
1629 copySize
= sizeof(cesaSramVirtPtr
->buf
) - pReq
->fixOffset
;
1631 /* Find fragment size: Must meet all requirements for CRYPTO and MAC
1632 * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
1633 * macDataSize - size of data will be signed/verified in this fragment
1634 * copySize - size of data will be copied from srcMbuf to SRAM and
1635 * back to dstMbuf for this fragment
1637 mvCesaFragSizeFind(pSA
, pReq
, cryptoOffset
, macOffset
,
1638 ©Size
, &cryptoDataSize
, &macDataSize
);
1640 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1641 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
))
1643 /* CryptoIV special processing */
1644 if( (pSA
->config
& MV_CESA_CRYPTO_MODE_MASK
) ==
1645 (MV_CESA_CRYPTO_CBC
<< MV_CESA_CRYPTO_MODE_BIT
) )
1647 /* In CBC mode for encode direction when IV from user */
1648 if( (pCmd
->ivFromUser
) &&
1649 ((pSA
->config
& MV_CESA_DIRECTION_MASK
) ==
1650 (MV_CESA_DIR_ENCODE
<< MV_CESA_DIRECTION_BIT
)) )
1653 /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
1654 * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
1655 * in the buffer to SRAM IVPointer
1657 i
+= mvCesaDmaCopyPrepare(pCmd
->pSrc
, cesaSramVirtPtr
->cryptoIV
, &pDmaDesc
[i
],
1658 MV_FALSE
, pCmd
->ivOffset
, pSA
->cryptoIvSize
, pCmd
->skipFlush
);
1661 /* Special processing when IV is not located in the first fragment */
1662 if(pCmd
->ivOffset
> (copySize
- pSA
->cryptoIvSize
))
1664 /* Prepare dummy place for cryptoIV in SRAM */
1665 cryptoIvOffset
= cesaSramVirtPtr
->tempCryptoIV
- mvCesaSramAddrGet();
1667 /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
1668 if((pSA
->config
& MV_CESA_DIRECTION_MASK
) ==
1669 (MV_CESA_DIR_DECODE
<< MV_CESA_DIRECTION_BIT
))
1671 i
+= mvCesaDmaCopyPrepare(pCmd
->pSrc
, cesaSramVirtPtr
->tempCryptoIV
, &pDmaDesc
[i
],
1672 MV_FALSE
, pCmd
->ivOffset
, pSA
->cryptoIvSize
, pCmd
->skipFlush
);
1676 /* For Encryption when IV is NOT from User: */
1677 /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
1678 if(pCmd
->ivFromUser
== 0)
1680 /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
1681 i
+= mvCesaDmaCopyPrepare(pCmd
->pSrc
, cesaSramVirtPtr
->cryptoIV
, &pDmaDesc
[i
],
1682 MV_TRUE
, pCmd
->ivOffset
, pSA
->cryptoIvSize
, pCmd
->skipFlush
);
1688 cryptoIvOffset
= pCmd
->ivOffset
;
1693 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1694 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1696 /* MAC digest special processing on Decode direction */
1697 if((pSA
->config
& MV_CESA_DIRECTION_MASK
) ==
1698 (MV_CESA_DIR_DECODE
<< MV_CESA_DIRECTION_BIT
))
1700 /* Save digest from pCmd->digestOffset */
1701 mvCesaCopyFromMbuf(pReq
->frags
.orgDigest
,
1702 pCmd
->pSrc
, pCmd
->digestOffset
, pSA
->digestSize
);
1704 /* If pCmd->digestOffset is not located on the first */
1705 if(pCmd
->digestOffset
> (copySize
- pSA
->digestSize
))
1707 MV_U8 digestZero
[MV_CESA_MAX_DIGEST_SIZE
];
1709 /* Set zeros to pCmd->digestOffset (DRAM) */
1710 memset(digestZero
, 0, MV_CESA_MAX_DIGEST_SIZE
);
1711 mvCesaCopyToMbuf(digestZero
, pCmd
->pSrc
, pCmd
->digestOffset
, pSA
->digestSize
);
1713 /* Prepare dummy place for digest in SRAM */
1714 digestOffset
= cesaSramVirtPtr
->tempDigest
- mvCesaSramAddrGet();
1718 digestOffset
= pCmd
->digestOffset
;
1722 /* Update SA in SRAM */
1723 if(cesaLastSid
!= sid
)
1725 mvCesaSramSaUpdate(sid
, &pDmaDesc
[i
]);
1729 pReq
->fragMode
= MV_CESA_FRAG_MIDDLE
;
1733 /* Continue fragment */
1737 if( (pCmd
->pSrc
->mbufSize
- pReq
->frags
.bufOffset
) <= sizeof(cesaSramVirtPtr
->buf
))
1740 config
= pSA
->config
| (MV_CESA_FRAG_LAST
<< MV_CESA_FRAG_MODE_OFFSET
);
1741 pReq
->fragMode
= MV_CESA_FRAG_LAST
;
1742 copySize
= pCmd
->pSrc
->mbufSize
- pReq
->frags
.bufOffset
;
1744 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1745 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1747 macDataSize
= pCmd
->macLength
- pReq
->frags
.macSize
;
1749 /* If pCmd->digestOffset is not located on last fragment */
1750 if(pCmd
->digestOffset
< pReq
->frags
.bufOffset
)
1752 /* Prepare dummy place for digest in SRAM */
1753 digestOffset
= cesaSramVirtPtr
->tempDigest
- mvCesaSramAddrGet();
1757 digestOffset
= pCmd
->digestOffset
- pReq
->frags
.bufOffset
;
1759 pReq
->frags
.newDigestOffset
= digestOffset
;
1760 macTotalLen
= pCmd
->macLength
;
1762 /* HW can't calculate the Digest correctly for fragmented packets
1763 * in the following cases:
1765 * - MV88F5181L when total macLength more that 16 Kbytes ||
1766 * - total macLength more that 64 Kbytes
1768 if( (mvCtrlModelGet() == MV_5182_DEV_ID
) ||
1769 ( (mvCtrlModelGet() == MV_5181_DEV_ID
) &&
1770 (mvCtrlRevGet() >= MV_5181L_A0_REV
) &&
1771 (pCmd
->macLength
>= (1 << 14)) ) )
1773 return MV_TERMINATE
;
1776 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
1777 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1779 cryptoDataSize
= pCmd
->cryptoLength
- pReq
->frags
.cryptoSize
;
1782 /* cryptoIvOffset - don't care */
1786 /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
1787 if( (mvCtrlModelGet() == MV_5182_DEV_ID
) &&
1788 (((pSA
->config
& MV_CESA_MAC_MODE_MASK
) ==
1789 (MV_CESA_MAC_MD5
<< MV_CESA_MAC_MODE_OFFSET
)) ||
1790 ((pSA
->config
& MV_CESA_MAC_MODE_MASK
) ==
1791 (MV_CESA_MAC_SHA1
<< MV_CESA_MAC_MODE_OFFSET
))) )
1793 pReq
->frags
.newDigestOffset
= cesaSramVirtPtr
->tempDigest
- mvCesaSramAddrGet();
1794 pReq
->fragMode
= MV_CESA_FRAG_LAST
;
1796 return MV_TERMINATE
;
1798 /* Middle fragment */
1799 config
= pSA
->config
| (MV_CESA_FRAG_MIDDLE
<< MV_CESA_FRAG_MODE_OFFSET
);
1800 copySize
= sizeof(cesaSramVirtPtr
->buf
);
1801 /* digestOffset and cryptoIvOffset - don't care */
1803 /* Find fragment size */
1804 mvCesaFragSizeFind(pSA
, pReq
, cryptoOffset
, macOffset
,
1805 ©Size
, &cryptoDataSize
, &macDataSize
);
1808 /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
1810 i
+= mvCesaDmaCopyPrepare(pMbuf
, pSramBuf
+ fixOffset
, &pDmaDesc
[i
],
1811 MV_FALSE
, pReq
->frags
.bufOffset
, copySize
, pCmd
->skipFlush
);
1813 /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
1814 mvCesaSramDescrBuild(config
, frag
,
1815 cryptoOffset
+ fixOffset
, cryptoIvOffset
+ fixOffset
,
1816 cryptoDataSize
, macOffset
+ fixOffset
,
1817 digestOffset
+ fixOffset
, macDataSize
, macTotalLen
,
1818 pReq
, &pDmaDesc
[i
]);
1821 /* Add special descriptor Ownership for CPU */
1822 pDmaDesc
[i
].byteCnt
= 0;
1823 pDmaDesc
[i
].phySrcAdd
= 0;
1824 pDmaDesc
[i
].phyDestAdd
= 0;
1827 /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
1829 i
+= mvCesaDmaCopyPrepare(pMbuf
, pSramBuf
+ fixOffset
, &pDmaDesc
[i
],
1830 MV_TRUE
, pReq
->frags
.bufOffset
, copySize
, pCmd
->skipFlush
);
1832 /* Next field of Last DMA descriptor must be NULL */
1833 pDmaDesc
[i
-1].phyNextDescPtr
= 0;
1834 pReq
->dma
[frag
].pDmaLast
= &pDmaDesc
[i
-1];
1835 mvOsCacheFlush(NULL
, pReq
->dma
[frag
].pDmaFirst
,
1836 i
*sizeof(MV_DMA_DESC
));
1838 /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
1840 pReq
->frags
.bufOffset
+= copySize
;
1841 pReq
->frags
.cryptoSize
+= cryptoDataSize
;
1842 pReq
->frags
.macSize
+= macDataSize
;
1848 /*******************************************************************************
1849 * mvCesaReqProcess - Process regular (Non-fragmented) request
1852 * This function processes the whole (not fragmented) request
1855 * MV_CESA_REQ* pReq - Pointer to the request in the request queue.
1858 * MV_OK - The request is successfully passed to HW for processing.
1859 * Other - Failure. The request will not be processed
1861 *******************************************************************************/
1862 static MV_STATUS
mvCesaReqProcess(MV_CESA_REQ
* pReq
)
1864 MV_CESA_MBUF
*pMbuf
;
1865 MV_DMA_DESC
*pDmaDesc
;
1867 int sid
, i
, fixOffset
;
1869 MV_CESA_COMMAND
*pCmd
= pReq
->pCmd
;
1871 cesaStats
.procCount
++;
1873 sid
= pCmd
->sessionId
;
1874 pSA
= &pCesaSAD
[sid
];
1875 pDmaDesc
= pReq
->dma
[0].pDmaFirst
;
1876 pSramBuf
= cesaSramVirtPtr
->buf
;
1877 fixOffset
= pReq
->fixOffset
;
1880 mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
1881 sid, pSA, pDmaDesc, pSramBuf);
1885 /* Crypto IV Special processing in CBC mode for Encryption direction */
1886 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) != (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
)) &&
1887 ((pSA
->config
& MV_CESA_CRYPTO_MODE_MASK
) == (MV_CESA_CRYPTO_CBC
<< MV_CESA_CRYPTO_MODE_BIT
)) &&
1888 ((pSA
->config
& MV_CESA_DIRECTION_MASK
) == (MV_CESA_DIR_ENCODE
<< MV_CESA_DIRECTION_BIT
)) &&
1889 (pCmd
->ivFromUser
) )
1891 /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
1892 * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
1893 * in the buffer to SRAM IVPointer
1895 i
+= mvCesaDmaCopyPrepare(pCmd
->pSrc
, cesaSramVirtPtr
->cryptoIV
, &pDmaDesc
[i
],
1896 MV_FALSE
, pCmd
->ivOffset
, pSA
->cryptoIvSize
, pCmd
->skipFlush
);
1899 /* Update SA in SRAM */
1900 if(cesaLastSid
!= sid
)
1902 mvCesaSramSaUpdate(sid
, &pDmaDesc
[i
]);
1906 /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
1908 i
+= mvCesaDmaCopyPrepare(pMbuf
, pSramBuf
+ fixOffset
, &pDmaDesc
[i
],
1909 MV_FALSE
, 0, pMbuf
->mbufSize
, pCmd
->skipFlush
);
1911 /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
1912 mvCesaSramDescrBuild(pSA
->config
, 0, pCmd
->cryptoOffset
+ fixOffset
,
1913 pCmd
->ivOffset
+ fixOffset
, pCmd
->cryptoLength
,
1914 pCmd
->macOffset
+ fixOffset
, pCmd
->digestOffset
+ fixOffset
,
1915 pCmd
->macLength
, pCmd
->macLength
, pReq
, &pDmaDesc
[i
]);
1918 /* Add special descriptor Ownership for CPU */
1919 pDmaDesc
[i
].byteCnt
= 0;
1920 pDmaDesc
[i
].phySrcAdd
= 0;
1921 pDmaDesc
[i
].phyDestAdd
= 0;
1924 /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
1926 i
+= mvCesaDmaCopyPrepare(pMbuf
, pSramBuf
+ fixOffset
, &pDmaDesc
[i
],
1927 MV_TRUE
, 0, pMbuf
->mbufSize
, pCmd
->skipFlush
);
1929 /* Next field of Last DMA descriptor must be NULL */
1930 pDmaDesc
[i
-1].phyNextDescPtr
= 0;
1931 pReq
->dma
[0].pDmaLast
= &pDmaDesc
[i
-1];
1932 mvOsCacheFlush(NULL
, pReq
->dma
[0].pDmaFirst
, i
*sizeof(MV_DMA_DESC
));
1938 /*******************************************************************************
1939 * mvCesaSramDescrBuild - Set CESA descriptor in SRAM
1942 * This function builds CESA descriptor in SRAM from all Command parameters
1946 * int chan - CESA channel uses the descriptor
1947 * MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
1948 * int cryptoOffset - Offset from the beginning of SRAM buffer where
1949 * data for encryption/decription is started.
1950 * int ivOffset - Offset of crypto IV from the SRAM base. Valid only
1951 * for first fragment.
1952 * int cryptoLength - Size (in bytes) of data for encryption/descryption
1953 * operation on this fragment.
1954 * int macOffset - Offset from the beginning of SRAM buffer where
1955 * data for Authentication is started
1956 * int digestOffset - Offset from the beginning of SRAM buffer where
1957 * digest is located. Valid for first and last fragments.
1958 * int macLength - Size (in bytes) of data for Authentication
1959 * operation on this fragment.
1960 * int macTotalLen - Toatl size (in bytes) of data for Authentication
1961 * operation on the whole request (packet). Valid for
1962 * last fragment only.
1966 *******************************************************************************/
1967 static void mvCesaSramDescrBuild(MV_U32 config
, int frag
,
1968 int cryptoOffset
, int ivOffset
, int cryptoLength
,
1969 int macOffset
, int digestOffset
, int macLength
,
1970 int macTotalLen
, MV_CESA_REQ
* pReq
, MV_DMA_DESC
* pDmaDesc
)
1972 MV_CESA_DESC
* pCesaDesc
= &pReq
->pCesaDesc
[frag
];
1973 MV_CESA_DESC
* pSramDesc
= pSramDesc
= &cesaSramVirtPtr
->desc
;
1974 MV_U16 sramBufOffset
= (MV_U16
)((MV_U8
*)cesaSramVirtPtr
->buf
- mvCesaSramAddrGet());
1976 pCesaDesc
->config
= MV_32BIT_LE(config
);
1978 if( (config
& MV_CESA_OPERATION_MASK
) !=
1979 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1982 pCesaDesc
->cryptoSrcOffset
= MV_16BIT_LE(sramBufOffset
+ cryptoOffset
);
1983 pCesaDesc
->cryptoDstOffset
= MV_16BIT_LE(sramBufOffset
+ cryptoOffset
);
1985 pCesaDesc
->cryptoDataLen
= MV_16BIT_LE(cryptoLength
);
1987 pCesaDesc
->cryptoKeyOffset
= MV_16BIT_LE((MV_U16
)(cesaSramVirtPtr
->sramSA
.cryptoKey
-
1988 mvCesaSramAddrGet()));
1990 pCesaDesc
->cryptoIvOffset
= MV_16BIT_LE((MV_U16
)(cesaSramVirtPtr
->cryptoIV
-
1991 mvCesaSramAddrGet()));
1992 pCesaDesc
->cryptoIvBufOffset
= MV_16BIT_LE(sramBufOffset
+ ivOffset
);
1995 if( (config
& MV_CESA_OPERATION_MASK
) !=
1996 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
1999 pCesaDesc
->macSrcOffset
= MV_16BIT_LE(sramBufOffset
+ macOffset
);
2000 pCesaDesc
->macTotalLen
= MV_16BIT_LE(macTotalLen
);
2003 pCesaDesc
->macDigestOffset
= MV_16BIT_LE(sramBufOffset
+ digestOffset
);
2004 pCesaDesc
->macDataLen
= MV_16BIT_LE(macLength
);
2007 pCesaDesc
->macInnerIvOffset
= MV_16BIT_LE((MV_U16
)(cesaSramVirtPtr
->sramSA
.macInnerIV
-
2008 mvCesaSramAddrGet()));
2009 pCesaDesc
->macOuterIvOffset
= MV_16BIT_LE((MV_U16
)(cesaSramVirtPtr
->sramSA
.macOuterIV
-
2010 mvCesaSramAddrGet()));
2012 /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
2013 pDmaDesc
->phySrcAdd
= MV_32BIT_LE(mvCesaVirtToPhys(&pReq
->cesaDescBuf
, pCesaDesc
));
2014 pDmaDesc
->phyDestAdd
= MV_32BIT_LE(mvCesaSramVirtToPhys(NULL
, (MV_U8
*)pSramDesc
));
2015 pDmaDesc
->byteCnt
= MV_32BIT_LE(sizeof(MV_CESA_DESC
) | BIT31
);
2017 /* flush Source buffer */
2018 mvOsCacheFlush(NULL
, pCesaDesc
, sizeof(MV_CESA_DESC
));
2021 /*******************************************************************************
2022 * mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
2025 * Copy to SRAM values of the required SA.
2029 * short sid - Session ID needs SRAM Cache update
2030 * MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
2031 * copy SA values from DRAM to SRAM.
2034 * MV_OK - Cache entry for this SA copied to SRAM.
2035 * MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
2037 *******************************************************************************/
2038 static INLINE
void mvCesaSramSaUpdate(short sid
, MV_DMA_DESC
*pDmaDesc
)
2040 MV_CESA_SA
*pSA
= &pCesaSAD
[sid
];
2042 /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
2043 pDmaDesc
->byteCnt
= MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA
) | BIT31
);
2044 pDmaDesc
->phySrcAdd
= MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf
, pSA
->pSramSA
));
2045 pDmaDesc
->phyDestAdd
=
2046 MV_32BIT_LE(mvCesaSramVirtToPhys(NULL
, (MV_U8
*)&cesaSramVirtPtr
->sramSA
));
2048 /* Source buffer is already flushed during OpenSession*/
2049 /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
2052 /*******************************************************************************
2053 * mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
2054 * Mbuf structure from DRAM to SRAM
2060 * MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
2062 * MV_U8* pSramBuf - pointer to buffer in SRAM where data should
2064 * MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
2065 * The function set number of DMA descriptors needed
2066 * to copy the copySize bytes from Mbuf.
2067 * MV_BOOL isToMbuf - Copy direction.
2068 * MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
2069 * MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
2070 * int offset - Offset in the Mbuf structure that copy should be
2072 * int copySize - Size of data should be copied.
2075 * int - number of DMA descriptors used for the copy.
2077 *******************************************************************************/
2079 static INLINE
int mvCesaDmaCopyPrepare(MV_CESA_MBUF
* pMbuf
, MV_U8
* pSramBuf
,
2080 MV_DMA_DESC
* pDmaDesc
, MV_BOOL isToMbuf
,
2081 int offset
, int copySize
, MV_BOOL skipFlush
)
2083 int bufOffset
, bufSize
, size
, frag
, i
;
2088 /* Calculate start place for copy: fragment number and offset in the fragment */
2089 frag
= mvCesaMbufOffset(pMbuf
, offset
, &bufOffset
);
2090 bufSize
= pMbuf
->pFrags
[frag
].bufSize
- bufOffset
;
2091 pBuf
= pMbuf
->pFrags
[frag
].bufVirtPtr
+ bufOffset
;
2093 /* Size accumulate total copy size */
2096 /* Create DMA lists to copy mBuf from pSrc to SRAM */
2097 while(size
< copySize
)
2099 /* Find copy size for each DMA descriptor */
2100 bufSize
= MV_MIN(bufSize
, (copySize
- size
));
2101 pDmaDesc
[i
].byteCnt
= MV_32BIT_LE(bufSize
| BIT31
);
2104 pDmaDesc
[i
].phyDestAdd
= MV_32BIT_LE(mvOsIoVirtToPhy(NULL
, pBuf
));
2105 pDmaDesc
[i
].phySrcAdd
=
2106 MV_32BIT_LE(mvCesaSramVirtToPhys(NULL
, (pSramBuf
+ size
)));
2107 /* invalidate the buffer */
2108 if(skipFlush
== MV_FALSE
)
2109 mvOsCacheInvalidate(NULL
, pBuf
, bufSize
);
2113 pDmaDesc
[i
].phySrcAdd
= MV_32BIT_LE(mvOsIoVirtToPhy(NULL
, pBuf
));
2114 pDmaDesc
[i
].phyDestAdd
=
2115 MV_32BIT_LE(mvCesaSramVirtToPhys(NULL
, (pSramBuf
+ size
)));
2116 /* flush the buffer */
2117 if(skipFlush
== MV_FALSE
)
2118 mvOsCacheFlush(NULL
, pBuf
, bufSize
);
2121 /* Count number of used DMA descriptors */
2125 /* go to next fragment in the Mbuf */
2127 pBuf
= pMbuf
->pFrags
[frag
].bufVirtPtr
;
2128 bufSize
= pMbuf
->pFrags
[frag
].bufSize
;
2132 #else /* MV_NETBSD */
2133 static int mvCesaDmaCopyPrepare(MV_CESA_MBUF
* pMbuf
, MV_U8
* pSramBuf
,
2134 MV_DMA_DESC
* pDmaDesc
, MV_BOOL isToMbuf
,
2135 int offset
, int copySize
, MV_BOOL skipFlush
)
2137 int bufOffset
, bufSize
, thisSize
, size
, frag
, i
;
2138 MV_ULONG bufPhys
, sramPhys
;
2142 * Calculate start place for copy: fragment number and offset in
2145 frag
= mvCesaMbufOffset(pMbuf
, offset
, &bufOffset
);
2148 * Get SRAM physical address only once. We can update it in-place
2149 * as we build the descriptor chain.
2151 sramPhys
= mvCesaSramVirtToPhys(NULL
, pSramBuf
);
2154 * 'size' accumulates total copy size, 'i' counts desccriptors.
2158 /* Create DMA lists to copy mBuf from pSrc to SRAM */
2159 while (size
< copySize
) {
2161 * Calculate # of bytes to copy from the current fragment,
2162 * and the pointer to the start of data
2164 bufSize
= pMbuf
->pFrags
[frag
].bufSize
- bufOffset
;
2165 pBuf
= pMbuf
->pFrags
[frag
].bufVirtPtr
+ bufOffset
;
2166 bufOffset
= 0; /* First frag may be non-zero */
2170 * As long as there is data in the current fragment...
2172 while (bufSize
> 0) {
2174 * Ensure we don't cross an MMU page boundary.
2175 * XXX: This is NetBSD-specific, but it is a
2176 * quick and dirty way to fix the problem.
2177 * A true HAL would rely on the OS-specific
2178 * driver to do this...
2180 thisSize
= PAGE_SIZE
-
2181 (((MV_ULONG
)pBuf
) & (PAGE_SIZE
- 1));
2182 thisSize
= MV_MIN(bufSize
, thisSize
);
2184 * Make sure we don't copy more than requested
2186 if (thisSize
> (copySize
- size
)) {
2187 thisSize
= copySize
- size
;
2192 * Physicall address of this fragment
2194 bufPhys
= MV_32BIT_LE(mvOsIoVirtToPhy(NULL
, pBuf
));
2197 * Set up the descriptor
2199 pDmaDesc
[i
].byteCnt
= MV_32BIT_LE(thisSize
| BIT31
);
2201 pDmaDesc
[i
].phyDestAdd
= bufPhys
;
2202 pDmaDesc
[i
].phySrcAdd
= MV_32BIT_LE(sramPhys
);
2203 /* invalidate the buffer */
2204 if(skipFlush
== MV_FALSE
)
2205 mvOsCacheInvalidate(NULL
, pBuf
, thisSize
);
2207 pDmaDesc
[i
].phySrcAdd
= bufPhys
;
2208 pDmaDesc
[i
].phyDestAdd
= MV_32BIT_LE(sramPhys
);
2209 /* flush the buffer */
2210 if(skipFlush
== MV_FALSE
)
2211 mvOsCacheFlush(NULL
, pBuf
, thisSize
);
2214 pDmaDesc
[i
].phyNextDescPtr
=
2215 MV_32BIT_LE(mvOsIoVirtToPhy(NULL
,(&pDmaDesc
[i
+1])));
2217 /* flush the DMA desc */
2218 mvOsCacheFlush(NULL
, &pDmaDesc
[i
], sizeof(MV_DMA_DESC
));
2221 bufSize
-= thisSize
;
2222 sramPhys
+= thisSize
;
2231 #endif /* MV_NETBSD */
2232 /*******************************************************************************
2233 * mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
2236 * This function calculate Inner and Outer values used for HMAC algorithm.
2237 * This operation allows improve performance fro the whole HMAC processing.
2240 * MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
2241 * unsigned char key[] - Pointer to HMAC key.
2242 * int keyLength - Size of HMAC key (maximum 64 bytes)
2245 * unsigned char innerIV[] - HASH(key^inner)
2246 * unsigned char outerIV[] - HASH(key^outter)
2250 *******************************************************************************/
2251 static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode
, unsigned char key
[], int keyLength
,
2252 unsigned char innerIV
[], unsigned char outerIV
[])
2254 unsigned char inner
[MV_CESA_MAX_MAC_KEY_LENGTH
];
2255 unsigned char outer
[MV_CESA_MAX_MAC_KEY_LENGTH
];
2256 int i
, digestSize
= 0;
2257 #if defined(MV_CPU_LE) || defined(MV_PPC)
2258 MV_U32 swapped32
, val32
, *pVal32
;
2260 for(i
=0; i
<keyLength
; i
++)
2262 inner
[i
] = 0x36 ^ key
[i
];
2263 outer
[i
] = 0x5c ^ key
[i
];
2266 for(i
=keyLength
; i
<MV_CESA_MAX_MAC_KEY_LENGTH
; i
++)
2271 if(macMode
== MV_CESA_MAC_HMAC_MD5
)
2276 mvMD5Update(&ctx
, inner
, MV_CESA_MAX_MAC_KEY_LENGTH
);
2278 memcpy(innerIV
, ctx
.buf
, MV_CESA_MD5_DIGEST_SIZE
);
2279 memset(&ctx
, 0, sizeof(ctx
));
2282 mvMD5Update(&ctx
, outer
, MV_CESA_MAX_MAC_KEY_LENGTH
);
2283 memcpy(outerIV
, ctx
.buf
, MV_CESA_MD5_DIGEST_SIZE
);
2284 memset(&ctx
, 0, sizeof(ctx
));
2285 digestSize
= MV_CESA_MD5_DIGEST_SIZE
;
2287 else if(macMode
== MV_CESA_MAC_HMAC_SHA1
)
2292 mvSHA1Update(&ctx
, inner
, MV_CESA_MAX_MAC_KEY_LENGTH
);
2293 memcpy(innerIV
, ctx
.state
, MV_CESA_SHA1_DIGEST_SIZE
);
2294 memset(&ctx
, 0, sizeof(ctx
));
2297 mvSHA1Update(&ctx
, outer
, MV_CESA_MAX_MAC_KEY_LENGTH
);
2298 memcpy(outerIV
, ctx
.state
, MV_CESA_SHA1_DIGEST_SIZE
);
2299 memset(&ctx
, 0, sizeof(ctx
));
2300 digestSize
= MV_CESA_SHA1_DIGEST_SIZE
;
2304 mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode
);
2306 #if defined(MV_CPU_LE) || defined(MV_PPC)
2307 /* 32 bits Swap of Inner and Outer values */
2308 pVal32
= (MV_U32
*)innerIV
;
2309 for(i
=0; i
<digestSize
/4; i
++)
2312 swapped32
= MV_BYTE_SWAP_32BIT(val32
);
2313 *pVal32
= swapped32
;
2316 pVal32
= (MV_U32
*)outerIV
;
2317 for(i
=0; i
<digestSize
/4; i
++)
2320 swapped32
= MV_BYTE_SWAP_32BIT(val32
);
2321 *pVal32
= swapped32
;
2324 #endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
2328 /*******************************************************************************
2329 * mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
2335 * MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
2336 * for SHA1 is placed.
2337 * int offset - Offset in the Mbuf structure where
2338 * unprocessed data for SHA1 is started.
2339 * MV_U8* pOuterIV - Pointer to OUTER for this session.
2340 * If pOuterIV==NULL - MAC mode is HASH_SHA1
2341 * If pOuterIV!=NULL - MAC mode is HMAC_SHA1
2342 * int macLeftSize - Size of unprocessed data for SHA1.
2343 * int macTotalSize - Total size of data for SHA1 in the
2344 * request (processed + unprocessed)
2347 * MV_U8* pDigest - Pointer to place where calculated Digest will
2352 *******************************************************************************/
2353 static void mvCesaFragSha1Complete(MV_CESA_MBUF
* pMbuf
, int offset
,
2354 MV_U8
* pOuterIV
, int macLeftSize
,
2355 int macTotalSize
, MV_U8
* pDigest
)
2359 int i
, frag
, fragOffset
, size
;
2361 /* Read temporary Digest from HW */
2362 for(i
=0; i
<MV_CESA_SHA1_DIGEST_SIZE
/4; i
++)
2364 ctx
.state
[i
] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i
));
2366 /* Initialize MV_SHA1_CTX structure */
2367 memset(ctx
.buffer
, 0, 64);
2368 /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
2369 /* so count[1] is always 0 */
2370 ctx
.count
[0] = ((macTotalSize
- macLeftSize
) * 8);
2373 /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
2374 if(pOuterIV
!= NULL
)
2375 ctx
.count
[0] += (64 * 8);
2377 /* Get place of unprocessed data in the Mbuf structure */
2378 frag
= mvCesaMbufOffset(pMbuf
, offset
, &fragOffset
);
2379 if(frag
== MV_INVALID
)
2381 mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset
);
2385 pData
= pMbuf
->pFrags
[frag
].bufVirtPtr
+ fragOffset
;
2386 size
= pMbuf
->pFrags
[frag
].bufSize
- fragOffset
;
2388 /* Complete Inner part */
2389 while(macLeftSize
> 0)
2391 if(macLeftSize
<= size
)
2393 mvSHA1Update(&ctx
, pData
, macLeftSize
);
2396 mvSHA1Update(&ctx
, pData
, size
);
2397 macLeftSize
-= size
;
2399 pData
= pMbuf
->pFrags
[frag
].bufVirtPtr
;
2400 size
= pMbuf
->pFrags
[frag
].bufSize
;
2402 mvSHA1Final(pDigest
, &ctx
);
2404 mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
2405 pOuterIV, macLeftSize, macTotalSize);
2406 mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
2409 if(pOuterIV
!= NULL
)
2411 /* If HMAC - Complete Outer part */
2412 for(i
=0; i
<MV_CESA_SHA1_DIGEST_SIZE
/4; i
++)
2414 #if defined(MV_CPU_LE) || defined(MV_ARM)
2415 ctx
.state
[i
] = MV_BYTE_SWAP_32BIT(((MV_U32
*)pOuterIV
)[i
]);
2417 ctx
.state
[i
] = ((MV_U32
*)pOuterIV
)[i
];
2420 memset(ctx
.buffer
, 0, 64);
2422 ctx
.count
[0] = 64*8;
2424 mvSHA1Update(&ctx
, pDigest
, MV_CESA_SHA1_DIGEST_SIZE
);
2425 mvSHA1Final(pDigest
, &ctx
);
2429 /*******************************************************************************
2430 * mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
2436 * MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
2437 * for SHA1 is placed.
2438 * int offset - Offset in the Mbuf structure where
2439 * unprocessed data for MD5 is started.
2440 * MV_U8* pOuterIV - Pointer to OUTER for this session.
2441 * If pOuterIV==NULL - MAC mode is HASH_MD5
2442 * If pOuterIV!=NULL - MAC mode is HMAC_MD5
2443 * int macLeftSize - Size of unprocessed data for MD5.
2444 * int macTotalSize - Total size of data for MD5 in the
2445 * request (processed + unprocessed)
2448 * MV_U8* pDigest - Pointer to place where calculated Digest will
2453 *******************************************************************************/
2454 static void mvCesaFragMd5Complete(MV_CESA_MBUF
* pMbuf
, int offset
,
2455 MV_U8
* pOuterIV
, int macLeftSize
,
2456 int macTotalSize
, MV_U8
* pDigest
)
2460 int i
, frag
, fragOffset
, size
;
2462 /* Read temporary Digest from HW */
2463 for(i
=0; i
<MV_CESA_MD5_DIGEST_SIZE
/4; i
++)
2465 ctx
.buf
[i
] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i
));
2467 memset(ctx
.in
, 0, 64);
2469 /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
2470 /* so count[1] is always 0 */
2471 ctx
.bits
[0] = ((macTotalSize
- macLeftSize
) * 8);
2474 /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
2475 if(pOuterIV
!= NULL
)
2476 ctx
.bits
[0] += (64 * 8);
2478 frag
= mvCesaMbufOffset(pMbuf
, offset
, &fragOffset
);
2479 if(frag
== MV_INVALID
)
2481 mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset
);
2485 pData
= pMbuf
->pFrags
[frag
].bufVirtPtr
+ fragOffset
;
2486 size
= pMbuf
->pFrags
[frag
].bufSize
- fragOffset
;
2488 /* Complete Inner part */
2489 while(macLeftSize
> 0)
2491 if(macLeftSize
<= size
)
2493 mvMD5Update(&ctx
, pData
, macLeftSize
);
2496 mvMD5Update(&ctx
, pData
, size
);
2497 macLeftSize
-= size
;
2499 pData
= pMbuf
->pFrags
[frag
].bufVirtPtr
;
2500 size
= pMbuf
->pFrags
[frag
].bufSize
;
2502 mvMD5Final(pDigest
, &ctx
);
2505 mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
2506 pOuterIV, macLeftSize, macTotalSize);
2507 mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
2509 if(pOuterIV
!= NULL
)
2511 /* Complete Outer part */
2512 for(i
=0; i
<MV_CESA_MD5_DIGEST_SIZE
/4; i
++)
2514 #if defined(MV_CPU_LE) || defined(MV_ARM)
2515 ctx
.buf
[i
] = MV_BYTE_SWAP_32BIT(((MV_U32
*)pOuterIV
)[i
]);
2517 ctx
.buf
[i
] = ((MV_U32
*)pOuterIV
)[i
];
2520 memset(ctx
.in
, 0, 64);
2524 mvMD5Update(&ctx
, pDigest
, MV_CESA_MD5_DIGEST_SIZE
);
2525 mvMD5Final(pDigest
, &ctx
);
2529 /*******************************************************************************
2530 * mvCesaFragAuthComplete -
2536 * MV_CESA_REQ* pReq,
2543 *******************************************************************************/
2544 static MV_STATUS
mvCesaFragAuthComplete(MV_CESA_REQ
* pReq
, MV_CESA_SA
* pSA
,
2547 MV_CESA_COMMAND
* pCmd
= pReq
->pCmd
;
2549 MV_CESA_MAC_MODE macMode
;
2550 MV_U8
* pOuterIV
= NULL
;
2552 /* Copy data from Source fragment to Destination */
2553 if(pCmd
->pSrc
!= pCmd
->pDst
)
2555 mvCesaMbufCopy(pCmd
->pDst
, pReq
->frags
.bufOffset
,
2556 pCmd
->pSrc
, pReq
->frags
.bufOffset
, macDataSize
);
2560 mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
2561 mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
2563 pDigest
= (mvCesaSramAddrGet() + pReq
->frags
.newDigestOffset
);
2565 macMode
= (pSA
->config
& MV_CESA_MAC_MODE_MASK
) >> MV_CESA_MAC_MODE_OFFSET
;
2567 mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
2568 macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
2572 case MV_CESA_MAC_HMAC_MD5
:
2573 pOuterIV
= pSA
->pSramSA
->macOuterIV
;
2575 case MV_CESA_MAC_MD5
:
2576 mvCesaFragMd5Complete(pCmd
->pDst
, pReq
->frags
.bufOffset
, pOuterIV
,
2577 macDataSize
, pCmd
->macLength
, pDigest
);
2580 case MV_CESA_MAC_HMAC_SHA1
:
2581 pOuterIV
= pSA
->pSramSA
->macOuterIV
;
2583 case MV_CESA_MAC_SHA1
:
2584 mvCesaFragSha1Complete(pCmd
->pDst
, pReq
->frags
.bufOffset
, pOuterIV
,
2585 macDataSize
, pCmd
->macLength
, pDigest
);
2589 mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode
);
2590 return MV_BAD_PARAM
;
2595 /*******************************************************************************
2596 * mvCesaCtrModeInit -
2607 *******************************************************************************/
2608 static MV_CESA_COMMAND
* mvCesaCtrModeInit(void)
2610 MV_CESA_MBUF
*pMbuf
;
2612 MV_CESA_COMMAND
*pCmd
;
2614 pBuf
= mvOsMalloc(sizeof(MV_CESA_COMMAND
) +
2615 sizeof(MV_CESA_MBUF
) + sizeof(MV_BUF_INFO
) + 100);
2618 mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
2619 sizeof(MV_CESA_COMMAND
) + sizeof(MV_CESA_MBUF
) + sizeof(MV_BUF_INFO
) );
2622 pCmd
= (MV_CESA_COMMAND
*)pBuf
;
2623 pBuf
+= sizeof(MV_CESA_COMMAND
);
2625 pMbuf
= (MV_CESA_MBUF
*)pBuf
;
2626 pBuf
+= sizeof(MV_CESA_MBUF
);
2628 pMbuf
->pFrags
= (MV_BUF_INFO
*)pBuf
;
2630 pMbuf
->numFrags
= 1;
2634 mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
2635 pCmd, pCmd->pSrc, pCmd->pDst,
2641 /*******************************************************************************
2642 * mvCesaCtrModePrepare -
2648 * MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
2653 *******************************************************************************/
2654 static MV_STATUS
mvCesaCtrModePrepare(MV_CESA_COMMAND
*pCtrModeCmd
, MV_CESA_COMMAND
*pCmd
)
2656 MV_CESA_MBUF
*pMbuf
;
2658 MV_U32 counter
, *pCounter
;
2659 int cryptoSize
= MV_ALIGN_UP(pCmd
->cryptoLength
, MV_CESA_AES_BLOCK_SIZE
);
2661 mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
2662 pCmd, pCmd->pSrc, pCmd->pDst,
2663 pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
2665 pMbuf
= pCtrModeCmd
->pSrc
;
2667 /* Allocate buffer for Key stream */
2668 pBuf
= mvOsIoCachedMalloc(cesaOsHandle
,cryptoSize
,
2669 &pMbuf
->pFrags
[0].bufPhysAddr
,
2670 &pMbuf
->pFrags
[0].memHandle
);
2673 mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize
);
2674 return MV_OUT_OF_CPU_MEM
;
2676 memset(pBuf
, 0, cryptoSize
);
2677 mvOsCacheFlush(NULL
, pBuf
, cryptoSize
);
2679 pMbuf
->pFrags
[0].bufVirtPtr
= pBuf
;
2680 pMbuf
->mbufSize
= cryptoSize
;
2681 pMbuf
->pFrags
[0].bufSize
= cryptoSize
;
2683 pCtrModeCmd
->pReqPrv
= pCmd
->pReqPrv
;
2684 pCtrModeCmd
->sessionId
= pCmd
->sessionId
;
2686 /* ivFromUser and ivOffset are don't care */
2687 pCtrModeCmd
->cryptoOffset
= 0;
2688 pCtrModeCmd
->cryptoLength
= cryptoSize
;
2690 /* digestOffset, macOffset and macLength are don't care */
2692 mvCesaCopyFromMbuf(pBuf
, pCmd
->pSrc
, pCmd
->ivOffset
, MV_CESA_AES_BLOCK_SIZE
);
2693 pCounter
= (MV_U32
*)(pBuf
+ (MV_CESA_AES_BLOCK_SIZE
- sizeof(counter
)));
2694 counter
= *pCounter
;
2695 counter
= MV_32BIT_BE(counter
);
2697 cryptoSize
-= MV_CESA_AES_BLOCK_SIZE
;
2699 /* fill key stream */
2700 while(cryptoSize
> 0)
2702 pBuf
+= MV_CESA_AES_BLOCK_SIZE
;
2703 memcpy(pBuf
, pIV
, MV_CESA_AES_BLOCK_SIZE
- sizeof(counter
));
2704 pCounter
= (MV_U32
*)(pBuf
+ (MV_CESA_AES_BLOCK_SIZE
- sizeof(counter
)));
2706 *pCounter
= MV_32BIT_BE(counter
);
2707 cryptoSize
-= MV_CESA_AES_BLOCK_SIZE
;
2713 /*******************************************************************************
2714 * mvCesaCtrModeComplete -
2720 * MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
2725 *******************************************************************************/
2726 static MV_STATUS
mvCesaCtrModeComplete(MV_CESA_COMMAND
*pOrgCmd
, MV_CESA_COMMAND
*pCmd
)
2728 int srcFrag
, dstFrag
, srcOffset
, dstOffset
, keyOffset
, srcSize
, dstSize
;
2729 int cryptoSize
= pCmd
->cryptoLength
;
2730 MV_U8
*pSrc
, *pDst
, *pKey
;
2731 MV_STATUS status
= MV_OK
;
2733 mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
2734 pCmd, pCmd->pSrc, pCmd->pDst,
2735 pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
2737 /* XOR source data with key stream to destination data */
2738 pKey
= pCmd
->pDst
->pFrags
[0].bufVirtPtr
;
2741 if( (pOrgCmd
->pSrc
!= pOrgCmd
->pDst
) &&
2742 (pOrgCmd
->cryptoOffset
> 0) )
2744 /* Copy Prefix from source buffer to destination buffer */
2746 status
= mvCesaMbufCopy(pOrgCmd
->pDst
, 0,
2747 pOrgCmd
->pSrc
, 0, pOrgCmd
->cryptoOffset
);
2749 status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
2750 0, pOrgCmd->cryptoOffset);
2751 status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
2752 0, pOrgCmd->cryptoOffset);
2756 srcFrag
= mvCesaMbufOffset(pOrgCmd
->pSrc
, pOrgCmd
->cryptoOffset
, &srcOffset
);
2757 pSrc
= pOrgCmd
->pSrc
->pFrags
[srcFrag
].bufVirtPtr
;
2758 srcSize
= pOrgCmd
->pSrc
->pFrags
[srcFrag
].bufSize
;
2760 dstFrag
= mvCesaMbufOffset(pOrgCmd
->pDst
, pOrgCmd
->cryptoOffset
, &dstOffset
);
2761 pDst
= pOrgCmd
->pDst
->pFrags
[dstFrag
].bufVirtPtr
;
2762 dstSize
= pOrgCmd
->pDst
->pFrags
[dstFrag
].bufSize
;
2764 while(cryptoSize
> 0)
2766 pDst
[dstOffset
] = (pSrc
[srcOffset
] ^ pKey
[keyOffset
]);
2773 if(srcOffset
>= srcSize
)
2777 pSrc
= pOrgCmd
->pSrc
->pFrags
[srcFrag
].bufVirtPtr
;
2778 srcSize
= pOrgCmd
->pSrc
->pFrags
[srcFrag
].bufSize
;
2781 if(dstOffset
>= dstSize
)
2785 pDst
= pOrgCmd
->pDst
->pFrags
[dstFrag
].bufVirtPtr
;
2786 dstSize
= pOrgCmd
->pDst
->pFrags
[dstFrag
].bufSize
;
2790 if(pOrgCmd
->pSrc
!= pOrgCmd
->pDst
)
2792 /* Copy Suffix from source buffer to destination buffer */
2793 srcOffset
= pOrgCmd
->cryptoOffset
+ pOrgCmd
->cryptoLength
;
2795 if( (pOrgCmd
->pDst
->mbufSize
- srcOffset
) > 0)
2797 status
= mvCesaMbufCopy(pOrgCmd
->pDst
, srcOffset
,
2798 pOrgCmd
->pSrc
, srcOffset
,
2799 pOrgCmd
->pDst
->mbufSize
- srcOffset
);
2803 status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
2804 srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
2805 status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
2806 srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
2810 /* Free buffer used for Key stream */
2811 mvOsIoCachedFree(cesaOsHandle
,pCmd
->pDst
->pFrags
[0].bufSize
,
2812 pCmd
->pDst
->pFrags
[0].bufPhysAddr
,
2813 pCmd
->pDst
->pFrags
[0].bufVirtPtr
,
2814 pCmd
->pDst
->pFrags
[0].memHandle
);
2819 /*******************************************************************************
2820 * mvCesaCtrModeFinish -
2826 * MV_CESA_COMMAND* pCmd
2831 *******************************************************************************/
2832 static void mvCesaCtrModeFinish(MV_CESA_COMMAND
* pCmd
)
2837 /*******************************************************************************
2838 * mvCesaParamCheck -
2844 * MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
2849 *******************************************************************************/
2850 static MV_STATUS
mvCesaParamCheck(MV_CESA_SA
* pSA
, MV_CESA_COMMAND
*pCmd
,
2853 MV_U8 fixOffset
= 0xFF;
2855 /* Check AUTH operation parameters */
2856 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) !=
2857 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
)) )
2859 /* MAC offset should be at least 4 byte aligned */
2860 if( MV_IS_NOT_ALIGN(pCmd
->macOffset
, 4) )
2862 mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
2864 return MV_BAD_PARAM
;
2866 /* Digest offset must be 4 byte aligned */
2867 if( MV_IS_NOT_ALIGN(pCmd
->digestOffset
, 4) )
2869 mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
2870 pCmd
->digestOffset
);
2871 return MV_BAD_PARAM
;
2873 /* In addition all offsets should be the same alignment: 8 or 4 */
2874 if(fixOffset
== 0xFF)
2876 fixOffset
= (pCmd
->macOffset
% 8);
2880 if( (pCmd
->macOffset
% 8) != fixOffset
)
2882 mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
2883 pCmd
->macOffset
, fixOffset
);
2884 return MV_BAD_PARAM
;
2887 if( (pCmd
->digestOffset
% 8) != fixOffset
)
2889 mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
2890 pCmd
->digestOffset
, fixOffset
);
2891 return MV_BAD_PARAM
;
2894 /* Check CRYPTO operation parameters */
2895 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) !=
2896 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
)) )
2898 /* CryptoOffset should be at least 4 byte aligned */
2899 if( MV_IS_NOT_ALIGN(pCmd
->cryptoOffset
, 4) )
2901 mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
2902 pCmd
->cryptoOffset
);
2903 return MV_BAD_PARAM
;
2905 /* cryptoLength should be the whole number of blocks */
2906 if( MV_IS_NOT_ALIGN(pCmd
->cryptoLength
, pSA
->cryptoBlockSize
) )
2908 mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
2909 pCmd
->cryptoLength
, pSA
->cryptoBlockSize
);
2910 return MV_BAD_PARAM
;
2912 if(fixOffset
== 0xFF)
2914 fixOffset
= (pCmd
->cryptoOffset
% 8);
2918 /* In addition all offsets should be the same alignment: 8 or 4 */
2919 if( (pCmd
->cryptoOffset
% 8) != fixOffset
)
2921 mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
2922 pCmd
->cryptoOffset
, fixOffset
);
2923 return MV_BAD_PARAM
;
2927 /* check for CBC mode */
2928 if(pSA
->cryptoIvSize
> 0)
2930 /* cryptoIV must not be part of CryptoLength */
2931 if( ((pCmd
->ivOffset
+ pSA
->cryptoIvSize
) > pCmd
->cryptoOffset
) &&
2932 (pCmd
->ivOffset
< (pCmd
->cryptoOffset
+ pCmd
->cryptoLength
)) )
2934 mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
2935 pCmd
->ivOffset
, pCmd
->macOffset
, pCmd
->macLength
);
2936 return MV_BAD_PARAM
;
2939 /* ivOffset must be 4 byte aligned */
2940 if( MV_IS_NOT_ALIGN(pCmd
->ivOffset
, 4) )
2942 mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
2944 return MV_BAD_PARAM
;
2946 /* In addition all offsets should be the same alignment: 8 or 4 */
2947 if( (pCmd
->ivOffset
% 8) != fixOffset
)
2949 mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
2950 pCmd
->ivOffset
, fixOffset
);
2951 return MV_BAD_PARAM
;
2958 /*******************************************************************************
2959 * mvCesaFragParamCheck -
2965 * MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
2970 *******************************************************************************/
2971 static MV_STATUS
mvCesaFragParamCheck(MV_CESA_SA
* pSA
, MV_CESA_COMMAND
*pCmd
)
2975 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) !=
2976 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
)) )
2978 /* macOffset must be less that SRAM buffer size */
2979 if(pCmd
->macOffset
> (sizeof(cesaSramVirtPtr
->buf
) - MV_CESA_AUTH_BLOCK_SIZE
))
2981 mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
2983 return MV_BAD_PARAM
;
2985 /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
2986 if( ((pCmd
->macOffset
+ pCmd
->macLength
) > pCmd
->pSrc
->mbufSize
) ||
2987 ((pCmd
->pSrc
->mbufSize
- (pCmd
->macOffset
+ pCmd
->macLength
)) >=
2988 sizeof(cesaSramVirtPtr
->buf
)) )
2990 mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
2991 pCmd
->macLength
, pCmd
->pSrc
->mbufSize
);
2992 return MV_BAD_PARAM
;
2996 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) !=
2997 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
)) )
2999 /* cryptoOffset must be less that SRAM buffer size */
3000 /* 4 for possible fixOffset */
3001 if( (pCmd
->cryptoOffset
+ 4) > (sizeof(cesaSramVirtPtr
->buf
) - pSA
->cryptoBlockSize
))
3003 mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
3004 pCmd
->cryptoOffset
);
3005 return MV_BAD_PARAM
;
3008 /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
3009 if( ((pCmd
->cryptoOffset
+ pCmd
->cryptoLength
) > pCmd
->pSrc
->mbufSize
) ||
3010 ((pCmd
->pSrc
->mbufSize
- (pCmd
->cryptoOffset
+ pCmd
->cryptoLength
)) >=
3011 (sizeof(cesaSramVirtPtr
->buf
) - pSA
->cryptoBlockSize
)) )
3013 mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
3014 pCmd
->cryptoLength
, pCmd
->pSrc
->mbufSize
);
3015 return MV_BAD_PARAM
;
3019 /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
3020 if( ((pSA
->config
& MV_CESA_OPERATION_MASK
) ==
3021 (MV_CESA_MAC_THEN_CRYPTO
<< MV_CESA_OPERATION_OFFSET
)) ||
3022 ((pSA
->config
& MV_CESA_OPERATION_MASK
) ==
3023 (MV_CESA_CRYPTO_THEN_MAC
<< MV_CESA_OPERATION_OFFSET
)) )
3025 if( (mvCtrlModelGet() == MV_5182_DEV_ID
) ||
3026 ( (mvCtrlModelGet() == MV_5181_DEV_ID
) &&
3027 (mvCtrlRevGet() >= MV_5181L_A0_REV
) &&
3028 (pCmd
->macLength
>= (1 << 14)) ) )
3030 return MV_NOT_ALLOWED
;
3033 /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
3034 if(pCmd
->cryptoOffset
> pCmd
->macOffset
)
3036 offset
= pCmd
->cryptoOffset
- pCmd
->macOffset
;
3040 offset
= pCmd
->macOffset
- pCmd
->cryptoOffset
;
3043 if( MV_IS_NOT_ALIGN(offset
, pSA
->cryptoBlockSize
) )
3046 mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
3047 pSA->cryptoBlockSize);
3049 return MV_NOT_ALLOWED
;
3051 /* Digest must not be part of CryptoLength */
3052 if( ((pCmd
->digestOffset
+ pSA
->digestSize
) > pCmd
->cryptoOffset
) &&
3053 (pCmd
->digestOffset
< (pCmd
->cryptoOffset
+ pCmd
->cryptoLength
)) )
3056 mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
3057 pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
3059 return MV_NOT_ALLOWED
;
3065 /*******************************************************************************
3066 * mvCesaFragSizeFind -
3072 * MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
3073 * int cryptoOffset, int macOffset,
3076 * int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
3081 *******************************************************************************/
3082 static void mvCesaFragSizeFind(MV_CESA_SA
* pSA
, MV_CESA_REQ
* pReq
,
3083 int cryptoOffset
, int macOffset
,
3084 int* pCopySize
, int* pCryptoDataSize
, int* pMacDataSize
)
3086 MV_CESA_COMMAND
*pCmd
= pReq
->pCmd
;
3087 int cryptoDataSize
, macDataSize
, copySize
;
3089 cryptoDataSize
= macDataSize
= 0;
3090 copySize
= *pCopySize
;
3092 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
3093 (MV_CESA_MAC_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
3095 cryptoDataSize
= MV_MIN( (copySize
- cryptoOffset
),
3096 (pCmd
->cryptoLength
- (pReq
->frags
.cryptoSize
+ 1)) );
3098 /* cryptoSize for each fragment must be the whole number of blocksSize */
3099 if( MV_IS_NOT_ALIGN(cryptoDataSize
, pSA
->cryptoBlockSize
) )
3101 cryptoDataSize
= MV_ALIGN_DOWN(cryptoDataSize
, pSA
->cryptoBlockSize
);
3102 copySize
= cryptoOffset
+ cryptoDataSize
;
3105 if( (pSA
->config
& MV_CESA_OPERATION_MASK
) !=
3106 (MV_CESA_CRYPTO_ONLY
<< MV_CESA_OPERATION_OFFSET
) )
3108 macDataSize
= MV_MIN( (copySize
- macOffset
),
3109 (pCmd
->macLength
- (pReq
->frags
.macSize
+ 1)));
3111 /* macSize for each fragment (except last) must be the whole number of blocksSize */
3112 if( MV_IS_NOT_ALIGN(macDataSize
, MV_CESA_AUTH_BLOCK_SIZE
) )
3114 macDataSize
= MV_ALIGN_DOWN(macDataSize
, MV_CESA_AUTH_BLOCK_SIZE
);
3115 copySize
= macOffset
+ macDataSize
;
3117 cryptoDataSize
= copySize
- cryptoOffset
;
3119 *pCopySize
= copySize
;
3121 if(pCryptoDataSize
!= NULL
)
3122 *pCryptoDataSize
= cryptoDataSize
;
3124 if(pMacDataSize
!= NULL
)
3125 *pMacDataSize
= macDataSize
;