/**
*
* This function Validate Partition Data by using checksum preset in image
*
* @param	Partition header pointer
* @param	Partition check sum offset
* @return
*		- XST_SUCCESS if partition data is ok
*		- XST_FAILURE if partition data is corrupted
*
* @note		None
*
*******************************************************************************/
u32 ValidateParition(u32 StartAddr, u32 Length, u32 ChecksumOffset)
{
    u8  Checksum[MD5_CHECKSUM_SIZE];
    u8  CalcChecksum[MD5_CHECKSUM_SIZE];
    u32 Status;
    u32 Index;

#ifdef	XPAR_XWDTPS_0_BASEADDR
	/*
	 * Prevent WDT reset
	 */
	XWdtPs_RestartWdt(&Watchdog);
#endif

    /*
     * Get checksum from flash
     */
    Status = GetPartitionChecksum(ChecksumOffset, &Checksum[0]);
    if(Status != XST_SUCCESS) {
            return XST_FAILURE;
    }

    fsbl_printf(DEBUG_INFO, "Actual checksum\r\n");

    for (Index = 0; Index < MD5_CHECKSUM_SIZE; Index++) {
    	fsbl_printf(DEBUG_INFO, "0x%0x ",Checksum[Index]);
    }

    fsbl_printf(DEBUG_INFO, "\r\n");

    /*
     * Calculate checksum for the partition
     */
    Status = CalcPartitionChecksum(StartAddr, Length, &CalcChecksum[0]);
	if(Status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    fsbl_printf(DEBUG_INFO, "Calculated checksum\r\n");

    for (Index = 0; Index < MD5_CHECKSUM_SIZE; Index++) {
        	fsbl_printf(DEBUG_INFO, "0x%0x ",CalcChecksum[Index]);
    }

    fsbl_printf(DEBUG_INFO, "\r\n");

    /*
     * Compare actual checksum with the calculated checksum
     */
	for (Index = 0; Index < MD5_CHECKSUM_SIZE; Index++) {
        if(Checksum[Index] != CalcChecksum[Index]) {
            fsbl_printf(DEBUG_GENERAL, "Error: "
            		"Partition DataChecksum 0x%0x!= 0x%0x\r\n",
			Checksum[Index], CalcChecksum[Index]);
		    return XST_FAILURE;
        }
    }

    return XST_SUCCESS;
}
Beispiel #2
0
/**
*
* This function loads PL partition using PCAP
*
* @param 	SourceDataPtr is a pointer to where the data is read from
* @param 	DestinationDataPtr is a pointer to where the data is written to
* @param 	SourceLength is the length of the data to be moved in words
* @param 	DestinationLength is the length of the data to be moved in words
* @param 	SecureTransfer indicated the encryption key location, 0 for
* 			non-encrypted
*
* @return
*		- XST_SUCCESS if the transfer is successful
*		- XST_FAILURE if the transfer fails
*
* @note		 None
*
****************************************************************************/
u32 PcapLoadPartition(u32 *SourceDataPtr, u32 *DestinationDataPtr,
		u32 SourceLength, u32 DestinationLength, u32 SecureTransfer)
{
	u32 Status;
	u32 IntrStsReg;
	u32 PcapTransferType = XDCFG_NON_SECURE_PCAP_WRITE;

	/*
	 * Check for secure transfer
	 */
	if (SecureTransfer) {
		PcapTransferType = XDCFG_SECURE_PCAP_WRITE;
	}

#ifdef FSBL_PERF
	XTime tXferCur = 0;
	FsblGetGlobalTime(&tXferCur);
#endif

	/*
	 * Clear the PCAP status registers
	 */
	Status = ClearPcapStatus();
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO,"PCAP_CLEAR_STATUS_FAIL \r\n");
		return XST_FAILURE;
	}

	/*
	 * For Bitstream case destination address will be 0xFFFFFFFF
	 */
	DestinationDataPtr = (u32*)XDCFG_DMA_INVALID_ADDRESS;

	/*
	 * New Bitstream download initialization sequence
	 */
	FabricInit();


#ifdef	XPAR_XWDTPS_0_BASEADDR
	/*
	 * Prevent WDT reset
	 */
	XWdtPs_RestartWdt(&Watchdog);
#endif

	/*
	 * PCAP single DMA transfer setup
	 */
	SourceDataPtr = (u32*)((u32)SourceDataPtr | PCAP_LAST_TRANSFER);
	DestinationDataPtr = (u32*)((u32)DestinationDataPtr | PCAP_LAST_TRANSFER);

	/*
	 * Transfer using Device Configuration
	 */
	Status = XDcfg_Transfer(DcfgInstPtr, (u8 *)SourceDataPtr,
					SourceLength,
					(u8 *)DestinationDataPtr,
					DestinationLength, PcapTransferType);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO,"Status of XDcfg_Transfer = %d \r \n",Status);
		return XST_FAILURE;
	}


	/*
	 * Dump the PCAP registers
	 */
	PcapDumpRegisters();


	/*
	 * Poll for the DMA done
	 */
	Status = XDcfgPollDone(XDCFG_IXR_DMA_DONE_MASK, MAX_COUNT);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO,"PCAP_DMA_DONE_FAIL \r\n");
		return XST_FAILURE;
	}

	fsbl_printf(DEBUG_INFO,"DMA Done ! \n\r");

	/*
	 * Poll for FPGA Done
	 */
	Status = XDcfgPollDone(XDCFG_IXR_PCFG_DONE_MASK, MAX_COUNT);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO,"PCAP_FPGA_DONE_FAIL\r\n");
		return XST_FAILURE;
	}

	fsbl_printf(DEBUG_INFO,"FPGA Done ! \n\r");
	
	/*
	 * Check for errors
	 */
	IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
	if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
		fsbl_printf(DEBUG_INFO,"Errors in PCAP \r\n");
		return XST_FAILURE;
	}

	/*
	 * For Performance measurement
	 */
#ifdef FSBL_PERF
	XTime tXferEnd = 0;
	fsbl_printf(DEBUG_GENERAL,"Time taken is ");
	FsblMeasurePerfTime(tXferCur,tXferEnd);
#endif

	return XST_SUCCESS;
}
Beispiel #3
0
/**
*
* This function Authenticate Partition Signature
*
* @param	Partition header pointer
*
* @return
*		- XST_SUCCESS if Authentication passed
*		- XST_FAILURE if Authentication failed
*
* @note		None
*
******************************************************************************/
u32 AuthenticatePartition(u8 *Buffer, u32 Size)
{
	u8 DecryptSignature[256];
	u8 HashSignature[32];
	u8 *SpkModular;
	u8 *SpkModularEx;
	u32 SpkExp;
	u8 *SignaturePtr;
	u32 Status;

#ifdef	XPAR_XWDTPS_0_BASEADDR
	/*
	 * Prevent WDT reset
	 */
	XWdtPs_RestartWdt(&Watchdog);
#endif

	/*
	 * Point to Authentication Certificate
	 */
	SignaturePtr = (u8 *)(Buffer + Size - RSA_SIGNATURE_SIZE);

	/*
	 * Increment the pointer by authentication Header size
	 */
	SignaturePtr += RSA_HEADER_SIZE;

	/*
	 * Increment the pointer by Magic word size
	 */
	SignaturePtr += RSA_MAGIC_WORD_SIZE;

	/*
	 * Increment the pointer beyond the PPK
	 */
	SignaturePtr += RSA_PPK_MODULAR_SIZE;
	SignaturePtr += RSA_PPK_MODULAR_EXT_SIZE;
	SignaturePtr += RSA_PPK_EXPO_SIZE;

	/*
	 * Calculate Hash Signature
	 */
	sha_256((u8 *)SignaturePtr, (RSA_SPK_MODULAR_EXT_SIZE +
				RSA_SPK_EXPO_SIZE + RSA_SPK_MODULAR_SIZE),
				HashSignature);
	FsblPrintArray(HashSignature, 32, "SPK Hash Calculated");

   	/*
   	 * Extract SPK signature
   	 */
	SpkModular = (u8 *)SignaturePtr;
	SignaturePtr += RSA_SPK_MODULAR_SIZE;
	SpkModularEx = (u8 *)SignaturePtr;
	SignaturePtr += RSA_SPK_MODULAR_EXT_SIZE;
	SpkExp = *((u32 *)SignaturePtr);
	SignaturePtr += RSA_SPK_EXPO_SIZE;

	/*
	 * Decrypt SPK Signature
	 */
	rsa2048_pubexp((RSA_NUMBER)DecryptSignature,
			(RSA_NUMBER)SignaturePtr,
			(u32)PpkExp,
			(RSA_NUMBER)PpkModular,
			(RSA_NUMBER)PpkModularEx);
	FsblPrintArray(DecryptSignature, RSA_SPK_SIGNATURE_SIZE,
					"SPK Decrypted Hash");


	Status = RecreatePaddingAndCheck(DecryptSignature, HashSignature);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO, "Partition SPK Signature "
				"Authentication failed\r\n");
		return XST_FAILURE;
	}
	SignaturePtr += RSA_SPK_SIGNATURE_SIZE;

	/*
	 * Decrypt Partition Signature
	 */
	rsa2048_pubexp((RSA_NUMBER)DecryptSignature,
			(RSA_NUMBER)SignaturePtr,
			(u32)SpkExp,
			(RSA_NUMBER)SpkModular,
			(RSA_NUMBER)SpkModularEx);
	FsblPrintArray(DecryptSignature, RSA_PARTITION_SIGNATURE_SIZE,
					"Partition Decrypted Hash");

	/*
	 * Partition Authentication
	 * Calculate Hash Signature
	 */
	sha_256((u8 *)Buffer,
			(Size - RSA_PARTITION_SIGNATURE_SIZE),
			HashSignature);
	FsblPrintArray(HashSignature, 32,
						"Partition Hash Calculated");

	Status = RecreatePaddingAndCheck(DecryptSignature, HashSignature);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_INFO, "Partition Signature "
				"Authentication failed\r\n");
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
/******************************************************************************
*
* This function is used to restart Watchdog
*
* @param	None
*
* @return   None
*
* @note		None
*
*******************************************************************************/
void XFsbl_RestartWdt(void)
{
	XWdtPs_RestartWdt(&Watchdog);
}
/**
 * This function is used to initialize the system
 *
 * @param	None
 *
 * @return	None
 *
 *****************************************************************************/
u32 XFsbl_InitWdt(void)
{
	s32 Status;
	u32 UStatus;
	XWdtPs_Config *ConfigPtr; 	/* Config structure of the WatchDog Timer */
	u32 CounterValue;
	u32 RegValue;


	/**
	 * Initialize the WDT timer
	 */
	ConfigPtr = XWdtPs_LookupConfig(XFSBL_WDT_DEVICE_ID);

	if(ConfigPtr==NULL) {
		UStatus = XFSBL_WDT_INIT_FAILED;
		goto END;
	}

	Status = XWdtPs_CfgInitialize(&Watchdog,
			ConfigPtr,
			ConfigPtr->BaseAddress);
	if (Status != XFSBL_SUCCESS) {
		XFsbl_Printf(DEBUG_INFO, "XFSBL_WDT_INIT_FAILED\n\r");
		UStatus = XFSBL_WDT_INIT_FAILED;
		goto END;
	}

	/**
	 * Setting the divider value
	 */
	XWdtPs_SetControlValue(&Watchdog,
			XWDTPS_CLK_PRESCALE,
			XWDTPS_CCR_PSCALE_4096);
	/**
	 * Convert time to  Watchdog counter reset value
	 */
	CounterValue = XFsbl_ConvertTime_WdtCounter(XFSBL_WDT_EXPIRE_TIME);

	/**
	 * Set the Watchdog counter reset value
	 */
	XWdtPs_SetControlValue(&Watchdog,
			XWDTPS_COUNTER_RESET,
			CounterValue);
	/**
	 * enable reset output, as we are only using this as a basic counter
	 */
	XWdtPs_EnableOutput(&Watchdog, XWDTPS_RESET_SIGNAL);

	/* Enable generation of system reset by PMU due to LPD SWDT */
	RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_SRST_EN_1);
	RegValue |= PMU_GLOBAL_ERROR_SRST_EN_1_LPD_SWDT_MASK;
	XFsbl_Out32(PMU_GLOBAL_ERROR_SRST_EN_1, RegValue);

	/* Enable LPD System Watchdog Timer Error */
	RegValue = XFsbl_In32(PMU_GLOBAL_ERROR_EN_1);
	RegValue |= PMU_GLOBAL_ERROR_EN_1_LPD_SWDT_MASK;
	XFsbl_Out32(PMU_GLOBAL_ERROR_EN_1, RegValue);

	/**
	 * Start the Watchdog timer
	 */
	XWdtPs_Start(&Watchdog);

	XWdtPs_RestartWdt(&Watchdog);

	UStatus = XFSBL_SUCCESS;
END:
	return UStatus;
}