/** * * Sending the last data and padding when blocksize is not multiple of 104 * bytes * * @param InstancePtr is a pointer to the XSecure_Sha3 instance. * @param Hash is the pointer to location where resulting hash will be * written * * @return None * * @note None * *****************************************************************************/ void XSecure_Sha3Finish(XSecure_Sha3 *InstancePtr, u8 *Hash) { /* Asserts validate the input arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Hash != NULL); u32 *HashPtr = (u32 *)Hash; u32 PartialLen = InstancePtr->Sha3Len % XSECURE_SHA3_BLOCK_LEN; u8 XSecure_RsaSha3Array[512] = {0U}; PartialLen = (PartialLen == 0U)?(XSECURE_SHA3_BLOCK_LEN) : (XSECURE_SHA3_BLOCK_LEN - PartialLen); XSecure_Sha3Padd(InstancePtr, XSecure_RsaSha3Array, PartialLen); XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, (UINTPTR)XSecure_RsaSha3Array, PartialLen/4, 1); /* Check the SHA3 DONE bit. */ XSecure_Sha3WaitForDone(InstancePtr); /* If requested, read out the Hash in reverse order. */ if (Hash) { u32 Index = 0U; u32 Val = 0U; for (Index=0U; Index < 12U; Index++) { Val = XSecure_ReadReg(InstancePtr->BaseAddress, XSECURE_CSU_SHA3_DIGEST_0_OFFSET + (Index * 4)); HashPtr[11U - Index] = Val; } } }
/****************************************************************************** * * This function decrypts the secure header when key rolling is enabled * * @param InstancePtr is an instance AES engine. * @param SrcAddr holds the address of secure header * @param Size holds size * * @return * Error code on failure * XFSBL_SUCESS on success * * @note None * ******************************************************************************/ static u32 XFsbl_DecrypSecureHdr(XSecure_Aes *InstancePtr, u64 SrcAddr, u32 Size) { XCsuDma_Configure ConfigurValues = {0}; u32 GcmStatus; XCsuDma_GetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, &ConfigurValues); ConfigurValues.EndianType = 1U; XCsuDma_SetConfig(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, &ConfigurValues); /* * Push secure header before that configure to * push IV and key to csu engine */ XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_KUP_WR_OFFSET, XSECURE_CSU_AES_IV_WR | XSECURE_CSU_AES_KUP_WR); XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK); /* PUSH Secure hdr */ XFsbl_DmaPlCopy(InstancePtr->CsuDmaPtr, SrcAddr, XSECURE_SECURE_HDR_SIZE/4, 1); /* Restore Key write register to 0. */ XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_KUP_WR_OFFSET, 0x0); /* Push the GCM tag. */ XFsbl_DmaPlCopy(InstancePtr->CsuDmaPtr, SrcAddr + XSECURE_SECURE_HDR_SIZE, XSECURE_SECURE_GCM_TAG_SIZE/4, 1); /* 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); XSecure_PcapWaitForDone(); XSecure_AesWaitForDone(InstancePtr); /* Get the AES status to know if GCM check passed. */ GcmStatus = XSecure_ReadReg(InstancePtr->BaseAddress, XSECURE_CSU_AES_STS_OFFSET) & XSECURE_CSU_AES_STS_GCM_TAG_OK; if (GcmStatus == 0) { XFsbl_Printf(DEBUG_GENERAL, "XFSBL_DECRYPT:" "XFSBL_ERROR_BITSTREAM_GCM_TAG_MISMATCH\r\n"); return XFSBL_ERROR_BITSTREAM_GCM_TAG_MISMATCH; } return XFSBL_SUCCESS; }
/***************************************************************************** * * @param InstancePtr is a pointer to the XSecure_Sha3 instance. * * @return None * * @note None * ******************************************************************************/ void XSecure_Sha3WaitForDone(XSecure_Sha3 *InstancePtr) { /* Asserts validate the input arguments */ Xil_AssertVoid(InstancePtr != NULL); volatile u32 Status; do { Status = XSecure_ReadReg(InstancePtr->BaseAddress, XSECURE_CSU_SHA3_DONE_OFFSET); } while (XSECURE_CSU_SHA3_DONE_DONE != ((u32)Status & XSECURE_CSU_SHA3_DONE_DONE)); }
/** * * This function handles the RSA decryption from end to end * * @param InstancePtr is a pointer to the XSecure_Rsa instance. * @param Result is the pointer to decrypted data generated by RSA. * @param EncText is the pointer to the data(hash) to be decrypted * * @return XST_SUCCESS if decryption was successful. * * @note None * ******************************************************************************/ s32 XSecure_RsaDecrypt(XSecure_Rsa *InstancePtr, u8 *EncText, u8 *Result) { /* Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(Result != NULL); volatile u32 Status = 0x0U; s32 ErrorCode = XST_SUCCESS; /* Put Modulus, exponent, Mod extension in RSA RAM */ XSecure_RsaPutData(InstancePtr); /* Initialize Digest */ XSecure_RsaWriteMem(InstancePtr, (u32 *)EncText, XSECURE_CSU_RSA_RAM_DIGEST); /* Initialize MINV values from Mod. */ XSecure_RsaMod32Inverse(InstancePtr); /* Start the RSA operation. */ XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_CONTROL_OFFSET, XSECURE_CSU_RSA_CONTROL_MASK); /* Check and wait for status */ do { Status = XSecure_ReadReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_STATUS_OFFSET); if(XSECURE_CSU_RSA_STATUS_ERROR == ((u32)Status & XSECURE_CSU_RSA_STATUS_ERROR)) { ErrorCode = XST_FAILURE; goto END; } }while(XSECURE_CSU_RSA_STATUS_DONE != ((u32)Status & XSECURE_CSU_RSA_STATUS_DONE)); /* Copy the result */ XSecure_RsaGetData(InstancePtr, (u32 *)Result); END: return ErrorCode; }
/****************************************************************************** * * This function calculates the next block size and updates the required * parameters. * * @param PartitionParams is a pointer to XFsblPs_PlPartition * @param ChunkAdrs is a pointer to the data location * @param ChunkSize is the remaining chunk size * * @return * Error code on failure * XFSBL_SUCESS on success * * @note None * ******************************************************************************/ static u32 XFsbl_DecrptSetUpNextBlk(XFsblPs_PlPartition *PartitionParams, UINTPTR ChunkAdrs, u32 ChunkSize) { u32 Status = XFSBL_SUCCESS; u32 SssAes; u32 SssCfg; /* Length of next block */ PartitionParams->PlEncrypt.NextBlkLen = Xil_Htonl(XSecure_ReadReg( PartitionParams->PlEncrypt.SecureAes->BaseAddress, XSECURE_CSU_AES_IV_3_OFFSET)) * 4; PartitionParams->PlEncrypt.SecureAes->Iv = (u32 *)(PartitionParams->PlEncrypt.SecureAes->BaseAddress + (UINTPTR)XSECURE_CSU_AES_IV_0_OFFSET); /* Configure the SSS for AES. */ SssAes = XSecure_SssInputAes(XSECURE_CSU_SSS_SRC_SRC_DMA); SssCfg = SssAes | XSecure_SssInputPcap(XSECURE_CSU_SSS_SRC_AES); XSecure_SssSetup(SssCfg); /* Start the message. */ XSecure_WriteReg(PartitionParams->PlEncrypt.SecureAes->BaseAddress, XSECURE_CSU_AES_START_MSG_OFFSET, XSECURE_CSU_AES_START_MSG); /* Transfer IV of the next block */ XFsbl_DmaPlCopy(PartitionParams->PlEncrypt.SecureAes->CsuDmaPtr, (UINTPTR)PartitionParams->PlEncrypt.SecureAes->Iv, XSECURE_SECURE_GCM_TAG_SIZE/4, 0); PartitionParams->PlEncrypt.SecureAes->SizeofData = PartitionParams->PlEncrypt.NextBlkLen; XSecure_WriteReg(PartitionParams->PlEncrypt.SecureAes->BaseAddress, XSECURE_CSU_AES_KUP_WR_OFFSET, 0x0); return Status; }
/** * * Read back the resulting data from RSA RAM * * @param InstancePtr is a pointer to the XSecure_Rsa instance. * @param RdData is the pointer to location where the decrypted data will * be written * * @return None * * @note None * ******************************************************************************/ static void XSecure_RsaGetData(XSecure_Rsa *InstancePtr, u32 *RdData) { /* Assert validates the input arguments */ Xil_AssertVoid(InstancePtr != NULL); u32 Index = 0U; u32 DataOffset = 0U; s32 TmpIndex = 0; /* Each of this loop will write 192 bits of data */ for (DataOffset = 0U; DataOffset < 22U; DataOffset++) { XSecure_WriteReg(InstancePtr->BaseAddress, XSECURE_CSU_RSA_RD_ADDR_OFFSET, (XSECURE_CSU_RSA_RAM_RES_Y * 22) + DataOffset); Index = (DataOffset == 0U) ? 2: 0; for (; Index < 6; Index++) { TmpIndex = 129 - ((DataOffset*6) + Index); if(TmpIndex < 0) { break; } /* * The Signature digest is compared in Big endian. * So because RSA h/w results in Little endian, * reverse it after reading it from RSA memory, */ RdData[TmpIndex] = Xil_Htonl(XSecure_ReadReg( InstancePtr->BaseAddress, (XSECURE_CSU_RSA_RD_DATA_0_OFFSET+ (Index * 4)))); } } }