Esempio n. 1
0
/**
 *
 * Calculate SHA-3 Digest on the given input data
 *
 * @param	InstancePtr is a pointer to the XSecure_Sha3 instance.
 * @param   	In is the pointer to the input data for hashing
 * @param	Size of the input data
 * @param	Out is the pointer to location where resulting hash will be
 *		written.
 *
 * @return	None
 *
 * @note	None
 *
 ******************************************************************************/
void XSecure_Sha3Digest(XSecure_Sha3 *InstancePtr, const u8 *In, const u32 Size,
								u8 *Out)
{
	/* Asserts validate the input arguments */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Size != (u32)0x00U);
	Xil_AssertVoid(Out != NULL);

	XSecure_Sha3Start(InstancePtr);
	XSecure_Sha3Update(InstancePtr, In, Size);
	XSecure_Sha3Finish(InstancePtr, Out);
}
/******************************************************************************
*
* This function performs authentication and RSA signature verification for
* each block.
*
* @param	PartitionParams is a pointer to XFsblPs_PlPartition
* @param	BlockAdrs is the block start address
* @param	BlockSize is the block size
* @param	AcOffset holds authentication certificate's address
* @param	NoOfChunks for the provided block
*
* @return
* 		Error code on failure
* 		XFSBL_SUCESS on success
*
* @note		None
*
******************************************************************************/
static u32 XFsbl_PlSignVer(XFsblPs_PlPartition *PartitionParams,
		UINTPTR BlockAdrs, u32 BlockSize, u8 *AcOffset, u32 NoOfChunks)
{

	u8 PartitionHash[XFSBL_HASH_TYPE_SHA3]={0U};
	u8 * SpkModular;
	u8* SpkModularEx;
	u32 SpkExp;
	u8 * AcPtr = (u8*)AcOffset;
	u32 Status;
	u32 HashDataLen = BlockSize;
	u8 XFsbl_RsaSha3Array[512] = {0U};
	s32 SStatus;
	u8 *ChunksHash = PartitionParams->PlAuth.HashsOfChunks;
	XSecure_Sha3 SecureSha3={0U};
	XSecure_Rsa SecureRsa={0U};
	u32 Index;
	u32 Len = PartitionParams->ChunkSize;
	u64 Offset;

	/* Start the SHA engine */
	if (XSECURE_HASH_TYPE_SHA3 == PartitionParams->PlAuth.AuthType) {
		XCsuDma_Configure ConfigurValues = {0};
		/* this needs to be modified at encryption */
		XCsuDma_GetConfig(PartitionParams->CsuDmaPtr,
			XCSUDMA_SRC_CHANNEL, &ConfigurValues);

		ConfigurValues.EndianType = 0U;

		XCsuDma_SetConfig(PartitionParams->CsuDmaPtr,
			XCSUDMA_SRC_CHANNEL, &ConfigurValues);
		(void)XSecure_Sha3Initialize(&SecureSha3,
			PartitionParams->CsuDmaPtr);

		XSecure_Sha3Start(&SecureSha3);
	}

	/* SHA calculation */
	for (Index = 0; Index < NoOfChunks; Index++) {
		/*
		 * If the block is the last it may not be complete block size
		 * mentioned so will break if it is less than chunk size
		 */
		if ((Index == NoOfChunks-1) ||
			(HashDataLen < PartitionParams->ChunkSize)) {
			Len = HashDataLen;
		}
		Offset = (u64)BlockAdrs +
			(u64)(PartitionParams->ChunkSize * Index);

		Status = XFsbl_CopyData(PartitionParams,
			PartitionParams->ChunkBuffer, (u8 *)(UINTPTR)Offset, Len);
		if (Status != XFSBL_SUCCESS) {
			return Status;
		}

		XSecure_Sha3Update(&SecureSha3,
			PartitionParams->ChunkBuffer, Len);
		XSecure_Sha3_ReadHash(&SecureSha3,
				(u8 *)ChunksHash);

		if (Index+1 < NoOfChunks) {
			HashDataLen =
				HashDataLen - PartitionParams->ChunkSize;
			ChunksHash =
				ChunksHash + PartitionParams->PlAuth.AuthType;
		}

	}

	/* Calculate hash for (AC - signature size) */
	XSecure_Sha3Update(&SecureSha3, (u8 *)AcOffset,
		(XFSBL_AUTH_CERT_MIN_SIZE - XFSBL_FSBL_SIG_SIZE));
	XSecure_Sha3Finish(&SecureSha3, (u8 *)PartitionHash);

	/* Set SPK pointer */
	AcPtr += (XFSBL_RSA_AC_ALIGN + XFSBL_PPK_SIZE);
	SpkModular = AcPtr;
	AcPtr += XFSBL_SPK_MOD_SIZE;
	SpkModularEx = AcPtr;
	AcPtr += XFSBL_SPK_MOD_EXT_SIZE;
	SpkExp = *((u32 *)AcPtr);
	AcPtr += XFSBL_RSA_AC_ALIGN;

	/* Increment by  SPK Signature pointer */
	AcPtr += XFSBL_SPK_SIG_SIZE;
	/* Increment by  BHDR Signature pointer */
	AcPtr += XFSBL_BHDR_SIG_SIZE;
	if((SpkModular != NULL) && (SpkModularEx != NULL)) {
		XFsbl_Printf(DEBUG_DETAILED,
		"XFsbl_PartVer: Spk Mod %0x, Spk Mod Ex %0x, Spk Exp %0x\r\n",
		SpkModular, SpkModularEx, SpkExp);
	}

	SStatus = XSecure_RsaInitialize(&SecureRsa, SpkModular,
				SpkModularEx, (u8 *)&SpkExp);
	if (SStatus != XFSBL_SUCCESS) {
		Status = XFSBL_ERROR_RSA_INITIALIZE;
		XFsbl_Printf(DEBUG_INFO,
		"XFSBL_ERROR_RSA_INITIALIZE at PL verification\r\n");
		goto END;
	}
	/* Decrypt Partition Signature. */
	if(XFSBL_SUCCESS !=
		XSecure_RsaDecrypt(&SecureRsa, AcPtr, XFsbl_RsaSha3Array)) {
		XFsbl_Printf(DEBUG_INFO, "XFsbl_SpkVer: "
			"XFSBL_ERROR_PART_RSA_DECRYPT at PL verification\r\n");
		Status = XFSBL_ERROR_PART_RSA_DECRYPT;
		goto END;
	}


	/* Authenticate Partition Signature */
	if(XFSBL_SUCCESS != XSecure_RsaSignVerification(XFsbl_RsaSha3Array,
			PartitionHash, PartitionParams->PlAuth.AuthType))
	{
		XFsbl_PrintArray(DEBUG_INFO, PartitionHash,
			PartitionParams->PlAuth.AuthType,
			"Calculated Partition Hash at PL verification");
		XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array,
			512, "RSA decrypted Hash at PL verification");
		Status = XFSBL_FAILURE;
		goto END;
	}

	Status = XFSBL_SUCCESS;

END:
	return Status;
}
/******************************************************************************
*
* This function re-authenticates the each chunk of the block and compares
* with the stored hash and sends the data AES engine if encryption exists
* and to PCAP directly in encryption is not existing.
*
* @param	PartitionParams is a pointer to XFsblPs_PlPartition
* @param	Address start address of the authentication block.
* @param	BlockLen size of the authentication block.
* @param	NoOfChunks holds the no of chunks for the provided block
*
* @return
* 		Error code on failure
* 		XFSBL_SUCESS on success
*
* @note		None.
*
******************************************************************************/
static u32 XFsbl_ReAuthenticationBlock(XFsblPs_PlPartition *PartitionParams,
				UINTPTR Address, u32 BlockLen, u32 NoOfChunks)
{
	u32 Status;
	u32 Index;
	u32 Len = PartitionParams->ChunkSize;;
	UINTPTR Offset;
	u8 ChunksHash[48];
	XSecure_Sha3 SecureSha3;
	u32 HashDataLen = BlockLen;
	u8 *HashStored = PartitionParams->PlAuth.HashsOfChunks;
	(void)memset(ChunksHash,0U,sizeof(ChunksHash));

	Status = XSecure_Sha3Initialize(&SecureSha3,
			PartitionParams->CsuDmaPtr);
	if (Status != XFSBL_SUCCESS) {
		return Status;
	}
	XSecure_Sha3Start(&SecureSha3);

	/* calculating hashs for all chunks copies to AES/PCAP */
	for (Index = 0; Index < NoOfChunks; Index++) {
			/* Last chunk */
			if (Index == NoOfChunks -1) {
				Len = HashDataLen;
			}
			Offset = (UINTPTR)Address +
				(u64)(PartitionParams->ChunkSize * Index);

			/* Copy from DDR or flash to Buffer */
			Status = XFsbl_CopyData(PartitionParams,
						PartitionParams->ChunkBuffer,
							(u8 *)Offset, Len);
			if (Status != XFSBL_SUCCESS) {
				return Status;
			}
			/* Calculating hash for each chunk */
			XSecure_Sha3Update(&SecureSha3,
				PartitionParams->ChunkBuffer, Len);
			XSecure_Sha3_ReadHash(&SecureSha3, (u8 *)ChunksHash);

			/* Comparing with stored Hashs */
			Status = XFsbl_CompareHashs(HashStored, ChunksHash,
					PartitionParams->PlAuth.AuthType);
			if (Status != XFSBL_SUCCESS) {
				XFsbl_Printf(DEBUG_GENERAL,
					"XFsbl_PlReAuth:"
				" XFSBL_ERROR_CHUNK_HASH_COMPARISON\r\n");
				XFsbl_PrintArray(DEBUG_INFO, HashStored,
					PartitionParams->PlAuth.AuthType,
					"Stored Chunk Hash");
				XFsbl_PrintArray(DEBUG_INFO, ChunksHash,
					PartitionParams->PlAuth.AuthType,
					"Calculated chunk Hash");
				Status = XFSBL_ERROR_CHUNK_HASH_COMPARISON;
				goto END;
			}
			/* Remaining block size will be in HashDataLen */
			HashDataLen = HashDataLen - PartitionParams->ChunkSize;
			if (Index+1 <= NoOfChunks - 1) {
				HashStored = HashStored +
					PartitionParams->PlAuth.AuthType;
			}

			/* If image is not encrypted */
			if (PartitionParams->IsEncrypted == FALSE) {
				/* Configure Secure stream swith to PCAP */
				XFsbl_Out32(CSU_CSU_SSS_CFG,
					XFSBL_CSU_SSS_SRC_SRC_DMA <<
					CSU_CSU_SSS_CFG_PCAP_SSS_SHIFT);

				/* Copy bitstream to PCAP */
				XFsbl_DmaPlCopy(PartitionParams->CsuDmaPtr,
					(UINTPTR)PartitionParams->ChunkBuffer,
						Len/4, 0);

				Status = XFsbl_PcapWaitForDone();
				if (Status != XFSBL_SUCCESS) {
					goto END;
				}
			}
			/* If image is encrypted */
			else {
				Status = XFsbl_DecrptPlChunks(PartitionParams,
					(UINTPTR)PartitionParams->ChunkBuffer, Len);
				if (Status != XFSBL_SUCCESS) {
					goto END;
				}
			}
		}

END:
	return Status;

}