embeddedsw/lib/sw_services/xilsecure/src/xsecure_aes.c
Sarat Chand Savitala a01d2a94ac sw_services:xilsecure: Fix to avoid clearing of AES key
Clearing the CSU_AES_KEY_CLEAR register to avoid clearing of AES key.

Signed-off-by: Sarat Chand Savitala <saratcha@xilinx.com>
2015-06-19 17:57:08 +05:30

696 lines
21 KiB
C
Executable file

/******************************************************************************
*
* (c) Copyright 2013 Xilinx, Inc. All rights reserved.
*
* This file contains confidential and proprietary information of Xilinx, Inc.
* and is protected under U.S. and international copyright and other
* intellectual property laws.
*
* DISCLAIMER
* This disclaimer is not a license and does not grant any rights to the
* materials distributed herewith. Except as otherwise provided in a valid
* license issued to you by Xilinx, and to the maximum extent permitted by
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE
* and (2) Xilinx shall not be liable (whether in contract or tort, including
* negligence, or under any other theory of liability) for any loss or damage
* of any kind or nature related to, arising under or in connection with these
* materials, including for any direct, or any indirect, special, incidental,
* or consequential loss or damage (including loss of data, profits, goodwill,
* or any type of loss or damage suffered as a result of any action brought by
* a third party) even if such damage or loss was reasonably foreseeable or
* Xilinx had been advised of the possibility of the same.
*
* CRITICAL APPLICATIONS
* Xilinx products are not designed or intended to be fail-safe, or for use in
* any application requiring fail-safe performance, such as life-support or
* safety devices or systems, Class III medical devices, nuclear facilities,
* applications related to the deployment of airbags, or any other applications
* that could lead to death, personal injury, or severe property or
* environmental damage (individually and collectively, "Critical
* Applications"). Customer assumes the sole risk and liability of any use of
* Xilinx products in Critical Applications, subject only to applicable laws
* and regulations governing limitations on product liability.
*
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
* AT ALL TIMES.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xsecure_aes.c
*
* This file contains the implementation of the interface functions for AES
* driver. Refer to the header file xsecure_aes.h for more detailed information.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- -------------------------------------------------------
* 1.00 ba 09/10/2014 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xsecure_aes.h"
/************************** Function Prototypes ******************************/
/************************** Function Definitions *****************************/
/*****************************************************************************/
/**
*
* Waits for AES completion for keyload.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
* @param CsuDmaPtr is the pointer to the XCsuDma instance.
* @param KeySel is the key source for decryption, can be KUP or device key
* @param Iv is pointer to the Initialization Vector for decryption
* @param Key is the pointer to Aes decryption key in case KUP key is used
* Pass Null if device key is to be used
*
* @return XST_SUCCESS if initialization was successful.
*
* @note None
*
******************************************************************************/
s32 XSecure_AesInitialize(XSecure_Aes *InstancePtr, XCsuDma *CsuDmaPtr,
u32 KeySel, u32* Iv, u32* Key)
{
/* Assert validates the input arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(CsuDmaPtr != NULL);
Xil_AssertNonvoid(Iv != NULL);
InstancePtr->BaseAddress = XSECURE_CSU_AES_BASE;
InstancePtr->CsuDmaPtr = CsuDmaPtr;
InstancePtr->KeySel = KeySel;
InstancePtr->Iv = Iv;
/*
* Clarify if Aes block expects IV in big or small endian, swap
* endianness of Iv likewise
*/
InstancePtr->Key = Key;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* Waits for AES completion for keyload.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
*
* @return None
*
* @note None
*
******************************************************************************/
static void XSecure_AesWaitKeyLoad(XSecure_Aes *InstancePtr)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
volatile u32 Status;
do {
Status = XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_STS_OFFSET);
} while (!((u32)Status & XSECURE_CSU_AES_STS_KEY_INIT_DONE));
}
/*****************************************************************************/
/**
*
* Waits for AES completion.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
*
* @return None
*
* @note None
******************************************************************************/
static void XSecure_AesWaitForDone(XSecure_Aes *InstancePtr)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
volatile u32 Status;
do {
Status = XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_STS_OFFSET);
} while ((u32)Status & XSECURE_CSU_AES_STS_AES_BUSY);
}
/*****************************************************************************/
/**
*
* Reset the AES engine.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
*
* @return None
*
* @note None
*
******************************************************************************/
void XSecure_AesReset(XSecure_Aes *InstancePtr)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_RESET_OFFSET, XSECURE_CSU_AES_RESET);
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_RESET_OFFSET, 0x0U);
//replaced mb here
}
/*****************************************************************************/
/**
*
* Reset the AES key storage registers.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
*
* @return None
*
* @note None
*
******************************************************************************/
void XSecure_AesKeyZero(XSecure_Aes *InstancePtr)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
volatile u32 Status;
Status = XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_CLR_OFFSET);
Status |= InstancePtr->KeySel;
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_CLR_OFFSET, (u32)Status);
Status &= ~InstancePtr->KeySel;
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_CLR_OFFSET, (u32)Status);
do {
Status = XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_STS_OFFSET);
} while ((InstancePtr->KeySel << 8) == ((u32)Status &
(InstancePtr->KeySel << 8)));
}
/*****************************************************************************/
/**
*
* Configures and load AES key from selected key source.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
*
* @return None
*
* @note None
*
******************************************************************************/
void XSecure_AesKeySelNLoad(XSecure_Aes *InstancePtr)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
if(InstancePtr->KeySel == XSECURE_CSU_AES_KEY_SRC_DEV)
{
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_SRC_OFFSET, XSECURE_CSU_AES_KEY_SRC_DEV);
}
else
{
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_SRC_OFFSET,
XSECURE_CSU_AES_KEY_SRC_KUP);
}
/* Trig loading of key. */
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_LOAD_OFFSET,
XSECURE_CSU_AES_KEY_LOAD);
/* Wait for AES key loading.*/
XSecure_AesWaitKeyLoad(InstancePtr);
}
/*****************************************************************************/
/**
*
* Function for doing encryption using h/w AES engine.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
* @param Dst is pointer to location where encrypted output will
* be written.
* @param Src is pointer to input data for encryption.
* @param Len is the size of input data in bytes
*
* @return None
*
* @note None
*
******************************************************************************/
void XSecure_AesEncrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src,
u32 Len)
{
/* Assert validates the input arguments */
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(Dst != NULL);
Xil_AssertVoid(Src != NULL);
Xil_AssertVoid(Len != (u32)0x0);
u32 SssCfg = 0U;
/* Configure the SSS for AES.*/
u32 SssDma = XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC_AES);
u32 SssAes = XSecure_SssInputAes(XSECURE_CSU_SSS_SRC_SRC_DMA);
SssCfg = SssDma|SssAes ;
XSecure_SssSetup(SssCfg);
/* Configure the AES for Encryption.*/
XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_CFG_OFFSET,
XSECURE_CSU_AES_CFG_ENC);
/* Start the message.*/
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_START_MSG_OFFSET,
XSECURE_CSU_AES_START_MSG);
/* Push IV into the AES engine.*/
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
(u64)InstancePtr->Iv,
XSECURE_SECURE_GCM_TAG_SIZE/4U, 0);
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL);
/* Configure the CSU DMA Tx/Rx.*/
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL, (u64) Dst,
(Len + XSECURE_SECURE_GCM_TAG_SIZE)/4U, 0);
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, (u64) Src,
XSECURE_SECURE_GCM_TAG_SIZE/4U, 1);
/**
* Wait for Dst/Src DMA done.
*/
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL);
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL);
/* Wait for AES encryption completion.*/
XSecure_AesWaitForDone(InstancePtr);
}
/*****************************************************************************/
/**
*
* Function for doing decryption using h/w AES engine.
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
* @param Dst is pointer to location where encrypted data will be written
* @param Src is pointer to input data for encryption.
* @param Tag is pointer to the GCM tag used for authentication
* @param Len is the length of the output data expected after decryption.
* @param Flag denotes whether the block is Secure header or data block
*
* @return returns 1 if GCM tag matching was successful
*
* @note None
*
******************************************************************************/
static u32 XSecure_AesDecryptBlk(XSecure_Aes *InstancePtr, u8 *Dst,
const u8 *Src, const u8 *Tag, u32 Len, u32 Flag)
{
/* Assert validates the input arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(Dst != NULL);
Xil_AssertNonvoid(Src != NULL);
Xil_AssertNonvoid(Tag != NULL);
volatile u32 Status = 0U;
/* Start the message. */
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_START_MSG_OFFSET,
XSECURE_CSU_AES_START_MSG);
/* Push IV into the AES engine. */
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
(u64)InstancePtr->Iv, XSECURE_SECURE_GCM_TAG_SIZE/4U, 0);
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL);
/* Acknowledge the transfer has completed */
XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
XCSUDMA_IXR_DONE_MASK);
/* Enable CSU DMA Src channel for byte swapping.*/
XCsuDma_Configure ConfigurValues = {0};
XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
&ConfigurValues);
ConfigurValues.EndianType = 1U;
XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
&ConfigurValues);
if(Flag)
{
/*
* This means we are decrypting Block of the boot image.
* Enable CSU DMA Dst channel for byte swapping.
*/
XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
&ConfigurValues);
ConfigurValues.EndianType = 1U;
XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
&ConfigurValues);
/* Configure the CSU DMA Tx/Rx for the incoming Block. */
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
(u64)Dst, Len/4U, 0);
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
(u64)Src, Len/4U, 0);
/* Wait for the Dst DMA completion. */
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL);
/* Acknowledge the transfers has completed */
XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
XCSUDMA_IXR_DONE_MASK);
XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
XCSUDMA_IXR_DONE_MASK);
/* Disble CSU DMA Dst channel for byte swapping. */
XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
&ConfigurValues);
ConfigurValues.EndianType = 0U;
XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_DST_CHANNEL,
&ConfigurValues);
/*
* Configure AES engine to push decrypted Key and IV in the
* block to the CSU KEY and IV registers.
*/
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KUP_WR_OFFSET,
XSECURE_CSU_AES_IV_WR | XSECURE_CSU_AES_KUP_WR);
}
else
{
/*
* This means we are decrypting the Secure header.
* Configure AES engine to push decrypted IV in the Secure
* header to the CSU IV register.
*/
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KUP_WR_OFFSET,
XSECURE_CSU_AES_IV_WR | XSECURE_CSU_AES_KUP_WR);
}
/* Push the Secure header/footer for decrypting next blocks KEY and IV. */
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
(u64)(Src + Len), XSECURE_SECURE_HDR_SIZE/4U, 1);
/* Wait for the Src DMA completion. */
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL);
/* Acknowledge the transfer has completed */
XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
XCSUDMA_IXR_DONE_MASK);
/* Restore Key write register to 0. */
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KUP_WR_OFFSET, 0x0);
/* Push the GCM tag. */
XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, (u64)Tag,
XSECURE_SECURE_GCM_TAG_SIZE/4U, 0);
/* Wait for the Src DMA completion. */
XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL);
/* Acknowledge the transfer has completed */
XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
XCSUDMA_IXR_DONE_MASK);
/* Disable CSU DMA Src channel for byte swapping. */
XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
&ConfigurValues);
ConfigurValues.EndianType = 0U;
XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
&ConfigurValues);
/* Wait for AES Decryption completion. */
XSecure_AesWaitForDone(InstancePtr);
/* Get the AES status to know if GCM check passed. */
Status = XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_STS_OFFSET) &
XSECURE_CSU_AES_STS_GCM_TAG_OK;
return !!Status;
}
/*****************************************************************************/
/**
*
* This function will handle the AES-GCM Decryption.
*
* The Multiple key(a.k.a Key Rolling) or Single key
* Encrypted images will have the same format,
* such that it will have the following:
*
* Secure header --> Dummy AES Key of 32byte +
* Block 0 IV of 12byte +
* DLC for Block 0 of 4byte +
* GCM tag of 16byte(Un-Enc).
* Block N --> Boot Image Data for Block N of n size +
* Block N+1 AES key of 32byte +
* Block N+1 IV of 12byte +
* GCM tag for Block N of 16byte(Un-Enc).
*
* The Secure header and Block 0 will be decrypted using
* Device key or user provide key.
* If more than 1 blocks are found then the key and IV
* obtained from previous block will be used for decryption
*
*
* 1> Read the 1st 64bytes and decrypt 48 bytes using
* the selected Device key.
* 2> Decrypt the 0th block using the IV + Size from step 2
* and selected device key.
* 3> After decryption we will get decrypted data+KEY+IV+Blk
* Size so store the KEY/IV into KUP/IV registers.
* 4> Using Blk size, IV and Next Block Key information
* start decrypting the next block.
* 5> if the Current Image size > Total image length,
* go to next step 8. Else go back to step 5
* 6> If there are failures, return error code
* 7> If we have reached this step means the decryption is SUCCESS.
*
*
*
* @param InstancePtr is a pointer to the XSecure_Aes instance.
* @param Src is the pointer to encrypted data source location
* @param Dst is the pointer to location where decrypted data will be
* written.
* @param Length is the expected total length of decrypted image expected.
*
* @return u32 ErrorCode
*
* @note None
*
******************************************************************************/
u32 XSecure_AesDecrypt(XSecure_Aes *InstancePtr, u8 *Dst, const u8 *Src,
u32 Length)
{
/* Assert validates the input arguments */
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(Dst != NULL);
Xil_AssertNonvoid(Src != NULL);
u32 SssCfg = 0x0U;
volatile u32 Status=0x0U;
u32 ErrorCode = XSECURE_CSU_AES_DECRYPTION_DONE ;
u32 CurrentImgLen = 0x0U;
u32 NextBlkLen = 0x0U;
u32 PrevBlkLen = 0x0U;
u8 *DestAddr= 0x0U;
u8 *SrcAddr = 0x0U;
u8 *GcmTagAddr = 0x0U;
u32 BlockCnt = 0x0U;
u32 ImageLen = 0x0U;
/* Configure the SSS for AES. */
u32 SssDma = XSecure_SssInputDstDma(XSECURE_CSU_SSS_SRC_AES);
u32 SssAes = XSecure_SssInputAes(XSECURE_CSU_SSS_SRC_SRC_DMA);
SssCfg = SssDma|SssAes ;
XSecure_SssSetup(SssCfg);
/* Configure AES for Decryption */
XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_CFG_OFFSET,
XSECURE_CSU_AES_CFG_DEC);
DestAddr = Dst;
ImageLen = Length;
SrcAddr = (u8 *)Src ;
GcmTagAddr = SrcAddr + XSECURE_SECURE_HDR_SIZE;
/* Clear AES contents by reseting it. */
XSecure_AesReset(InstancePtr);
/* Clear AES_KEY_CLEAR bits to avoid clearing of key */
XSecure_WriteReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_KEY_CLR_OFFSET, (u32)0x0U);
if(InstancePtr->KeySel == XSECURE_CSU_AES_KEY_SRC_DEV)
{
XSecure_AesKeySelNLoad(InstancePtr);
}
else
{
u32 Count=0U, Value=0U;
u32 Addr=0U;
for(Count = 0U; Count < 8U; Count++)
{
/* Helion AES block expects the key in big-endian. */
Value = Xil_Htonl(InstancePtr->Key[Count]);
Addr = InstancePtr->BaseAddress +
XSECURE_CSU_AES_KUP_0_OFFSET
+ (Count * 4);
XSecure_Out32(Addr, Value);
}
XSecure_AesKeySelNLoad(InstancePtr);
}
do
{
PrevBlkLen = NextBlkLen;
/* Start decryption of Secure-Header/Block/Footer. */
Status = XSecure_AesDecryptBlk(InstancePtr, DestAddr,
(const u8 *)SrcAddr,
((const u8 *)GcmTagAddr),
NextBlkLen, BlockCnt);
/* If decryption failed then return error. */
if(0U == (u32)Status)
{
ErrorCode= XSECURE_CSU_AES_GCM_TAG_MISMATCH;
goto ENDF;
}
/*
* Find the size of next block to be decrypted.
* Size is in 32-bit words so mul it with 4
*/
NextBlkLen = Xil_Htonl(XSecure_ReadReg(InstancePtr->BaseAddress,
XSECURE_CSU_AES_IV_3_OFFSET)) * 4;
/* Update the current image size. */
CurrentImgLen += NextBlkLen;
if(0U == NextBlkLen)
{
if(CurrentImgLen != Length)
{
/*
* If this is the last block then check
* if the current image != size in the header
* then return error.
*/
ErrorCode = XSECURE_CSU_AES_IMAGE_LEN_MISMATCH;
goto ENDF;
}
else
{
goto ENDF;
}
}
else
{
/*
* If this is not the last block then check
* if the current image > size in the header
* then return error.
*/
if(CurrentImgLen > ImageLen)
{
ErrorCode = XSECURE_CSU_AES_IMAGE_LEN_MISMATCH;
goto ENDF;
}
}
if(BlockCnt > 0U)
{
/* Update DestAddr and SrcAddr for next Block decryption. */
DestAddr += PrevBlkLen;
SrcAddr = (GcmTagAddr + XSECURE_SECURE_GCM_TAG_SIZE);
/*
* This means we are done with Secure header and Block 0
* And now we can change the AES key source to KUP.
*/
InstancePtr->KeySel = XSECURE_CSU_AES_KEY_SRC_KUP;
XSecure_AesKeySelNLoad(InstancePtr);
}
else
{
/* Update SrcAddr for Block-0 */
SrcAddr = (SrcAddr + XSECURE_SECURE_HDR_SIZE +
XSECURE_SECURE_GCM_TAG_SIZE);
/* Point IV to the CSU IV register. */
InstancePtr->Iv = (u32 *)(InstancePtr->BaseAddress +
XSECURE_CSU_AES_IV_0_OFFSET);
}
/* Update the GcmTagAddr to get GCM-TAG for next block. */
GcmTagAddr = SrcAddr + NextBlkLen + XSECURE_SECURE_HDR_SIZE;
/* Update block count. */
BlockCnt++;
}while(1);
ENDF:
XSecure_AesReset(InstancePtr);
return ErrorCode;
}