/** * This function checks if PMU FW is loaded and gives handoff to PMU Microblaze * * @param FsblInstancePtr is pointer to the XFsbl Instance * * @param PartitionNum is the partition number of the image * * @return None * *****************************************************************************/ static void XFsbl_CheckPmuFw(XFsblPs * FsblInstancePtr, u32 PartitionNum) { u32 DestinationDev; u32 DestinationDevNxt = 0; u32 PmuFwLoadDone = FALSE; DestinationDev = XFsbl_GetDestinationDevice( &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]); if (DestinationDev == XIH_PH_ATTRB_DEST_DEVICE_PMU) { if ((PartitionNum + 1) < (FsblInstancePtr-> ImageHeader.ImageHeaderTable.NoOfPartitions-1U)) { DestinationDevNxt = XFsbl_GetDestinationDevice( &FsblInstancePtr-> ImageHeader.PartitionHeader[PartitionNum + 1]); if (DestinationDevNxt != XIH_PH_ATTRB_DEST_DEVICE_PMU) { /* there is a partition after this but that is not PMU FW */ PmuFwLoadDone = TRUE; } } else { /* the current partition is last PMU FW partition */ PmuFwLoadDone = TRUE; } } /* If all partitions of PMU FW loaded, handoff it to PMU MicroBlaze */ if (TRUE == PmuFwLoadDone) { /* Wakeup the processor */ XFsbl_Out32(PMU_GLOBAL_GLOBAL_CNTRL, XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) | 0x1); /* wait until done waking up */ while((XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) & PMU_GLOBAL_GLOBAL_CNTRL_FW_IS_PRESENT_MASK) != PMU_GLOBAL_GLOBAL_CNTRL_FW_IS_PRESENT_MASK ) {;} } }
/** * This function validates the partition * * @param FsblInstancePtr is pointer to the XFsbl Instance * * @param PartitionNum is the partition number in the image to be loaded * * @return returns the error codes described in xfsbl_error.h on any error * returns XFSBL_SUCCESS on success * *****************************************************************************/ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, u32 PartitionNum) { u32 Status=XFSBL_SUCCESS; u32 ChecksumType=0U; s32 IsEncryptionEnabled=FALSE; s32 IsAuthenticationEnabled=FALSE; u32 DestinationDevice=0U; u32 DestinationCpu=0U; u32 ExecState=0U; u32 CpuNo=0U; XFsblPs_PartitionHeader * PartitionHeader; #if defined(XFSBL_RSA) u32 HashLen=0U; #endif #if defined(XFSBL_AES) u32 ImageOffset = 0U; u32 FsblIv[XIH_BH_IV_LENGTH / 4U]; u32 UnencryptedLength = 0; u32 IvLocation; #endif #if defined(XFSBL_RSA) || defined(XFSBL_AES) u32 Length=0U; #endif #if defined(XFSBL_RSA) || defined(XFSBL_AES) || defined(XFSBL_BS) PTRSIZE LoadAddress=0U; #endif #if defined(XFSBL_BS) u32 BitstreamWordSize = 0; #endif /** * Update the variables */ PartitionHeader = &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]; ChecksumType = XFsbl_GetChecksumType(PartitionHeader); /** * Check the encryption status */ if (XFsbl_IsEncrypted(PartitionHeader) == XIH_PH_ATTRB_ENCRYPTION ) { IsEncryptionEnabled = TRUE; #ifdef XFSBL_AES /* Copy the Iv from Flash into local memory */ IvLocation = ImageOffset + XIH_BH_IV_OFFSET; Status = FsblInstancePtr->DeviceOps.DeviceCopy(IvLocation, (PTRSIZE) FsblIv, XIH_BH_IV_LENGTH); if (Status != XFSBL_SUCCESS) { XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_DECRYPTION_IV_COPY_FAIL \r\n"); Status = XFSBL_ERROR_DECRYPTION_IV_COPY_FAIL; goto END; } #else XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_AES_NOT_ENABLED \r\n"); Status = XFSBL_ERROR_AES_NOT_ENABLED; goto END; #endif } /** * check the authentication status */ if (XFsbl_IsRsaSignaturePresent(PartitionHeader) == XIH_PH_ATTRB_RSA_SIGNATURE ) { IsAuthenticationEnabled = TRUE; } DestinationDevice = XFsbl_GetDestinationDevice(PartitionHeader); DestinationCpu = XFsbl_GetDestinationCpu(PartitionHeader); /** * Get the execution state */ ExecState = XFsbl_GetA53ExecState(PartitionHeader); /** * if destination cpu is not present, it means it is for same cpu */ if (DestinationCpu == XIH_PH_ATTRB_DEST_CPU_NONE) { DestinationCpu = FsblInstancePtr->ProcessorID; } /** * Checksum Validation */ if (ChecksumType == XIH_PH_ATTRB_CHECKSUM_MD5) { /** * Do the checksum validation */ } #if defined(XFSBL_RSA) || defined(XFSBL_AES) if ((IsAuthenticationEnabled == TRUE) || (IsEncryptionEnabled == TRUE)) { LoadAddress = PartitionHeader->DestinationLoadAddress; Length = PartitionHeader->TotalDataWordLength * 4U; Status = XFsbl_GetLoadAddress(DestinationCpu, &LoadAddress, Length); if (XFSBL_SUCCESS != Status) { goto END; } } #endif #ifdef XFSBL_BS if ((DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) && (LoadAddress == 0U)) { LoadAddress = XFSBL_DDR_TEMP_ADDRESS; } #endif /** * Authentication Check */ if (IsAuthenticationEnabled == TRUE) { XFsbl_Printf(DEBUG_INFO,"Authentication Enabled\r\n"); #ifdef XFSBL_RSA /** * Get the Sha type to be used from * boot header attributes */ if ((FsblInstancePtr->BootHdrAttributes & XIH_BH_IMAGE_ATTRB_SHA2_MASK) == XIH_BH_IMAGE_ATTRB_SHA2_MASK) { HashLen = XFSBL_HASH_TYPE_SHA2; } else { HashLen = XFSBL_HASH_TYPE_SHA3; } /** * cache disbale can be removed */ Xil_DCacheDisable(); /** * Do the authentication validation */ Status = XFsbl_Authentication(FsblInstancePtr, LoadAddress, Length, (LoadAddress + Length) - XFSBL_AUTH_CERT_MIN_SIZE, HashLen); if (Status != XFSBL_SUCCESS) { goto END; } #else XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_RSA_NOT_ENABLED \r\n"); Status = XFSBL_ERROR_RSA_NOT_ENABLED; goto END; #endif } /** * Decrypt image through CSU DMA */ if (IsEncryptionEnabled == TRUE) { XFsbl_Printf(DEBUG_INFO, "Decryption Enabled\r\n"); #ifdef XFSBL_AES /* AES expects IV in big endian form */ FsblIv[0] = Xil_Htonl(FsblIv[0]); FsblIv[1] = Xil_Htonl(FsblIv[1]); FsblIv[2] = Xil_Htonl(FsblIv[2]); /* Initialize the Aes Instance so that it's ready to use */ XSecure_AesInitialize(&SecureAes, &CsuDma, XSECURE_CSU_AES_KEY_SRC_DEV, FsblIv, NULL); XFsbl_Printf(DEBUG_INFO, " Aes initialized \r\n"); UnencryptedLength = PartitionHeader->UnEncryptedDataWordLength * 4U; if (DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) { Status = XSecure_AesDecrypt(&SecureAes, (u8 *) LoadAddress, (u8 *) LoadAddress, UnencryptedLength); if (Status != XFSBL_SUCCESS) { Status = XFSBL_ERROR_DECRYPTION_FAIL; XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_DECRYPTION_FAIL\r\n"); goto END; } else { XFsbl_Printf(DEBUG_GENERAL, "Decryption Successful\r\n"); } } #else XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_AES_NOT_ENABLED \r\n"); Status = XFSBL_ERROR_AES_NOT_ENABLED; goto END; #endif } #ifdef XFSBL_BS /** * for PL image use CSU DMA to route to PL */ if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) { /** * Fsbl hook before bit stream download */ Status = XFsbl_HookBeforeBSDownload(); if (Status != XFSBL_SUCCESS) { Status = XFSBL_ERROR_HOOK_BEFORE_BITSTREAM_DOWNLOAD; XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_HOOK_BEFORE_BITSTREAM_DOWNLOAD\r\n"); goto END; } XFsbl_Printf(DEBUG_GENERAL, "Bitstream download to start now\r\n"); Status = XFsbl_PcapInit(); if (Status != XFSBL_SUCCESS) { goto END; } if (IsEncryptionEnabled == TRUE) { #ifdef XFSBL_AES /* * The secure bitstream would be sent through CSU DMA to AES * and the decrypted bitstream is sent directly to PCAP * by configuring SSS appropriately */ Status = XSecure_AesDecrypt(&SecureAes, (u8 *) XFSBL_DESTINATION_PCAP_ADDR, (u8 *) LoadAddress, UnencryptedLength); if (Status != XFSBL_SUCCESS) { Status = XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL; XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL\r\n"); /* Reset PL */ XFsbl_Out32(CSU_PCAP_PROG, 0x0); goto END; } else { XFsbl_Printf(DEBUG_GENERAL, "Bitstream decryption Successful\r\n"); } #endif } else { /* Use CSU DMA to load Bit stream to PL */ BitstreamWordSize = PartitionHeader->UnEncryptedDataWordLength; Status = XFsbl_WriteToPcap(BitstreamWordSize, (u8 *) LoadAddress); if (Status != XFSBL_SUCCESS) { goto END; } } Status = XFsbl_PLWaitForDone(); if (Status != XFSBL_SUCCESS) { goto END; } /** * Fsbl hook after bit stream download */ Status = XFsbl_HookAfterBSDownload(); if (Status != XFSBL_SUCCESS) { Status = XFSBL_ERROR_HOOK_AFTER_BITSTREAM_DOWNLOAD; XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_HOOK_AFTER_BITSTREAM_DOWNLOAD\r\n"); goto END; } } #endif /** * Update the handoff details */ if ((DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) && (DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PMU)) { CpuNo = FsblInstancePtr->HandoffCpuNo; if (XFsbl_CheckHandoffCpu(FsblInstancePtr, DestinationCpu) == XFSBL_SUCCESS) { FsblInstancePtr->HandoffValues[CpuNo].CpuSettings = DestinationCpu | ExecState; FsblInstancePtr->HandoffValues[CpuNo].HandoffAddress = PartitionHeader->DestinationExecutionAddress; FsblInstancePtr->HandoffCpuNo += 1U; } } END: return Status; }
/** * This function copies the partition to specified destination * * @param FsblInstancePtr is pointer to the XFsbl Instance * * @param PartitionNum is the partition number in the image to be loaded * * @return returns the error codes described in xfsbl_error.h on any error * returns XFSBL_SUCCESS on success *****************************************************************************/ static u32 XFsbl_PartitionCopy(XFsblPs * FsblInstancePtr, u32 PartitionNum) { u32 Status=XFSBL_SUCCESS; u32 DestinationCpu=0U; u32 CpuNo=0U; u32 DestinationDevice=0U; u32 ExecState=0U; XFsblPs_PartitionHeader * PartitionHeader; u32 SrcAddress=0U; PTRSIZE LoadAddress=0U; u32 Length=0U; u32 RunningCpu=0U; /** * Assign the partition header to local variable */ PartitionHeader = &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]; RunningCpu = FsblInstancePtr->ProcessorID; /** * Check for XIP image * No need to copy for XIP image */ DestinationCpu = XFsbl_GetDestinationCpu(PartitionHeader); /** * Get the execution state */ ExecState = XFsbl_GetA53ExecState(PartitionHeader); /** * if destination cpu is not present, it means it is for same cpu */ if (DestinationCpu == XIH_PH_ATTRB_DEST_CPU_NONE) { DestinationCpu = FsblInstancePtr->ProcessorID; } if (PartitionHeader->UnEncryptedDataWordLength == 0U) { /** * Update the Handoff address only for the first application * of that cpu * This is for XIP image. For other partitions it handoff * address is updated after partition validation */ CpuNo = FsblInstancePtr->HandoffCpuNo; if (XFsbl_CheckHandoffCpu(FsblInstancePtr, DestinationCpu) == XFSBL_SUCCESS) { FsblInstancePtr->HandoffValues[CpuNo].CpuSettings = DestinationCpu | ExecState; FsblInstancePtr->HandoffValues[CpuNo].HandoffAddress = PartitionHeader->DestinationExecutionAddress; FsblInstancePtr->HandoffCpuNo += 1U; } else { /** * * if two partitions has same destination cpu, error can * be triggered here */ } Status = XFSBL_SUCCESS; goto END; } /** * Copy the PL to temporary DDR Address * Copy the PS to Load Address * Copy the PMU firmware to PMU RAM */ DestinationDevice = XFsbl_GetDestinationDevice(PartitionHeader); LoadAddress = PartitionHeader->DestinationLoadAddress; if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) { #ifdef XFSBL_BS if (LoadAddress == XFSBL_DUMMY_PL_ADDR) { LoadAddress = XFSBL_DDR_TEMP_ADDRESS; } #else XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_PL_NOT_ENABLED \r\n"); Status = XFSBL_ERROR_PL_NOT_ENABLED; goto END; #endif } /** * Get the source(flash offset) address where it needs to copy */ SrcAddress = FsblInstancePtr->ImageOffsetAddress + ((PartitionHeader->DataWordOffset) * XIH_PARTITION_WORD_LENGTH); /** * Length of the partition to be copied */ Length = (PartitionHeader->TotalDataWordLength) * XIH_PARTITION_WORD_LENGTH; /** * When destination device is R5-0/R5-1/R5-L and load address is in TCM * copy to high address of TCM address map * Update the LoadAddress */ Status = XFsbl_GetLoadAddress(DestinationCpu, &LoadAddress, Length); if (XFSBL_SUCCESS != Status) { goto END; } /** * Configure the memory */ XFsbl_ConfigureMemory(RunningCpu, DestinationCpu, LoadAddress, Length); /** * * Do not copy the IVT if FSBL is running in R5-0/R5-L at 0x0 TCM * Update the SrcAddress, LoadAddress and Len based on the * above condition */ #if 1 if (((FsblInstancePtr->ProcessorID == XIH_PH_ATTRB_DEST_CPU_R5_0) || (FsblInstancePtr->ProcessorID == XIH_PH_ATTRB_DEST_CPU_R5_L)) && ((LoadAddress > XFSBL_R50_HIGH_TCM_START_ADDRESS) && (LoadAddress < XFSBL_R50_HIGH_TCM_START_ADDRESS + XFSBL_IVT_LENGTH))) { /** * Get the length of the IVT area to be * skipped from Load Address */ TcmSkipAddress = LoadAddress/XFSBL_IVT_LENGTH; TcmSkipLength = XFSBL_IVT_LENGTH - TcmSkipAddress; /** * Check if Length is less than SkipLength */ if (TcmSkipLength > Length) { TcmSkipLength = Length; } /** * Copy the Skip length to a local array */ Status = FsblInstancePtr->DeviceOps.DeviceCopy(SrcAddress, (PTRSIZE )TcmVectorArray, TcmSkipLength); if (XFSBL_SUCCESS != Status) { goto END; } SrcAddress += TcmSkipLength; LoadAddress += TcmSkipLength; Length -= TcmSkipLength; } #endif if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PMU) { /* Enable PMU_0 IPI */ XFsbl_Out32(IPI_PMU_0_IER, IPI_PMU_0_IER_PMU_0_MASK); /* Trigger PMU0 IPI in PMU IPI TRIG Reg */ XFsbl_Out32(IPI_PMU_0_TRIG, IPI_PMU_0_TRIG_PMU_0_MASK); /** * Wait until PMU Microblaze goes to sleep state, * before starting firmware download to PMU RAM */ while((XFsbl_In32(PMU_GLOBAL_GLOBAL_CNTRL) & PMU_GLOBAL_GLOBAL_CNTRL_MB_SLEEP_MASK) != PMU_GLOBAL_GLOBAL_CNTRL_MB_SLEEP_MASK ) {;} } /** * Copy the partition to PS_DDR/PL_DDR/TCM */ Status = FsblInstancePtr->DeviceOps.DeviceCopy(SrcAddress, LoadAddress, Length); if (XFSBL_SUCCESS != Status) { goto END; } END: return Status; }
/** * Configure the RSA and SHA for the SPK * Signature verification. * If SPK Signature verification fails * then return unique error code saying * XFSBL_STAGE3_SPK_SIGN_VERIF_ERROR. * * @param * * @return * ******************************************************************************/ u32 XFsbl_SpkVer(XFsblPs *FsblInstancePtr , u64 AcOffset, u32 HashLen, u32 PartitionNum) { u8 SpkHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4))); u8 * PpkModular = (u8 *)NULL; u8 * PpkModularEx = (u8 *)NULL; u32 PpkExp = 0; u8 * AcPtr = (u8*) (PTRSIZE) AcOffset; u32 Status = XFSBL_SUCCESS; void * ShaCtx = (void * )NULL; u8 XFsbl_RsaSha3Array[512]; #ifdef XFSBL_SHA2 sha2_context ShaCtxObj; ShaCtx = &ShaCtxObj; #endif #ifndef XFSBL_PS_DDR XFsblPs_PartitionHeader * PartitionHeader; u32 DestinationDevice = 0U; PartitionHeader = &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]; DestinationDevice = XFsbl_GetDestinationDevice(PartitionHeader); if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) { /* * If it is DDR less system, bitstream chunk containing * Authentication Certificate has to be read from boot device */ if(XFSBL_SUCCESS != FsblInstancePtr->DeviceOps.DeviceCopy( (INTPTR)AcPtr, (PTRSIZE)ReadBuffer, XFSBL_AUTH_CERT_MIN_SIZE)) { XFsbl_Printf(DEBUG_GENERAL, "XFsbl_SpkVer: Device to OCM copy of certificate failed \r\n"); Status = XFSBL_ERROR_SPK_RSA_DECRYPT; goto END; } /* Repoint Auth. cert. pointer to OCM buffer beginning*/ AcPtr = ReadBuffer; } #endif /* Re-initialize CSU DMA. This is a workaround and need to be removed */ Status = XFsbl_CsuDmaInit(); if (XST_SUCCESS != Status) { goto END; } (void)XFsbl_ShaStart(ShaCtx, HashLen); /* Hash the PPK + SPK choice */ XFsbl_ShaUpdate(ShaCtx, AcPtr, 8, HashLen); /* Set PPK pointer */ AcPtr += XFSBL_RSA_AC_ALIGN; PpkModular = (u8 *)AcPtr; AcPtr += XFSBL_PPK_MOD_SIZE; PpkModularEx = (u8 *)AcPtr; AcPtr += XFSBL_PPK_MOD_EXT_SIZE; PpkExp = *((u32 *)AcPtr); AcPtr += XFSBL_RSA_AC_ALIGN; XFsbl_Printf(DEBUG_DETAILED, "XFsbl_SpkVer: Ppk Mod %0x, Ppk Mod Ex %0x, Ppk Exp %0x\r\n", PpkModular, PpkModularEx, PpkExp); /* Calculate SPK + Auth header Hash */ XFsbl_ShaUpdate(ShaCtx, (u8 *)AcPtr, XFSBL_SPK_SIZE, HashLen); XFsbl_ShaFinish(ShaCtx, (u8 *)SpkHash, HashLen); /* Set SPK Signature pointer */ AcPtr += XFSBL_SPK_SIZE; XSecure_RsaInitialize(&SecureRsa, PpkModular, PpkModularEx, (u8 *)&PpkExp); /* Decrypt SPK Signature */ if(XFSBL_SUCCESS != XSecure_RsaDecrypt(&SecureRsa, AcPtr, XFsbl_RsaSha3Array)) { XFsbl_Printf(DEBUG_GENERAL, "XFsbl_SpkVer: XFSBL_ERROR_SPK_RSA_DECRYPT\r\n"); Status = XFSBL_ERROR_SPK_RSA_DECRYPT; goto END; } /* Authenticate SPK Signature */ if(XFSBL_SUCCESS != XSecure_RsaSignVerification(XFsbl_RsaSha3Array, SpkHash, HashLen)) { XFsbl_PrintArray(DEBUG_INFO, SpkHash, HashLen, "Calculated SPK Hash"); XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array, 512, "RSA decrypted Hash"); XFsbl_Printf(DEBUG_GENERAL, "XFsbl_SpkVer: XFSBL_ERROR_SPK_SIGNATURE\r\n"); Status = XFSBL_ERROR_SPK_SIGNATURE; } END: return Status; }
/** * Configure the RSA and SHA for the * Boot Header Signature verification. * If Boot Header Signature verification * fails then return unique error code saying * XFSBL_STAGE3_BOOT_HDR_SIGN_VERIF_ERROR. * * @param * * @return * ******************************************************************************/ u32 XFsbl_PartitionSignVer(XFsblPs *FsblInstancePtr, u64 PartitionOffset, u32 PartitionLen, u64 AcOffset, u32 HashLen, u32 PartitionNum) { u8 PartitionHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4))); u8 * SpkModular = (u8 *)NULL; u8 * SpkModularEx = (u8 *)NULL; u32 SpkExp = 0; u8 * AcPtr = (u8*)(PTRSIZE) AcOffset; u32 Status = XFSBL_SUCCESS; u32 HashDataLen=0U; #ifndef XFSBL_PS_DDR void * ShaCtx = (void * )NULL; #endif u8 XFsbl_RsaSha3Array[512]; #ifdef XFSBL_SHA2 sha2_context ShaCtxObj; ShaCtx = &ShaCtxObj; #endif XFsbl_Printf(DEBUG_INFO, "Doing Partition Sign verification\r\n"); /** * hash to be calculated will be total length with AC minus * signature size */ HashDataLen = PartitionLen - XFSBL_FSBL_SIG_SIZE; /* Calculate Partition Hash */ #ifndef XFSBL_PS_DDR XFsblPs_PartitionHeader * PartitionHeader; u32 DestinationDevice = 0U; PartitionHeader = &FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum]; DestinationDevice = XFsbl_GetDestinationDevice(PartitionHeader); if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) { /** * bitstream partion in DDR less system, Chunk by chunk copy * into OCM and update SHA module */ u32 NumChunks = 0U; u32 RemainingBytes = 0U; u32 Index = 0U; u32 StartAddrByte = PartitionOffset; NumChunks = HashDataLen / READ_BUFFER_SIZE; RemainingBytes = (HashDataLen % READ_BUFFER_SIZE); /* Start the SHA engine */ (void)XFsbl_ShaStart(ShaCtx, HashLen); XFsbl_Printf(DEBUG_INFO, "XFsbl_PartitionVer: NumChunks :%0d, RemainingBytes : %0d \r\n", NumChunks, RemainingBytes); for(Index = 0; Index < NumChunks; Index++) { if(XFSBL_SUCCESS !=FsblInstancePtr->DeviceOps.DeviceCopy( StartAddrByte, (PTRSIZE)ReadBuffer, READ_BUFFER_SIZE)) { XFsbl_Printf(DEBUG_GENERAL, "XFsblPartitionVer: Device " "to OCM copy of partition failed \r\n"); XFsbl_Printf(DEBUG_GENERAL, "XFsbl_PartitionVer: XFSBL_ERROR_PART_RSA_DECRYPT\r\n"); Status = XFSBL_ERROR_PART_RSA_DECRYPT; goto END; } XFsbl_ShaUpdate(ShaCtx, (u8 *)ReadBuffer, READ_BUFFER_SIZE, HashLen); StartAddrByte += READ_BUFFER_SIZE; } /* Send the residual bytes if Size is not buffer size multiple */ if(RemainingBytes != 0) { if(XFSBL_SUCCESS!=FsblInstancePtr->DeviceOps.DeviceCopy( StartAddrByte, (PTRSIZE)ReadBuffer, RemainingBytes)) { XFsbl_Printf(DEBUG_GENERAL, "XFsbl_PartitionVer: XFSBL_ERROR_PART_RSA_DECRYPT\r\n"); Status = XFSBL_ERROR_PART_RSA_DECRYPT; goto END; } XFsbl_ShaUpdate(ShaCtx, (u8 *)ReadBuffer, RemainingBytes, HashLen); } XFsbl_ShaFinish(ShaCtx, PartitionHash, HashLen); /** * Copy Auth. Certificate to OCM buffer location * Assign AcPtr to OCM buffer location */ if(XFSBL_SUCCESS != FsblInstancePtr->DeviceOps.DeviceCopy( (u32)(INTPTR)AcPtr, (PTRSIZE)ReadBuffer, XFSBL_AUTH_CERT_MIN_SIZE)) { XFsbl_Printf(DEBUG_GENERAL, "XFsbl_PartitionVer: Flash to OCM copy failed \r\n"); Status = XFSBL_ERROR_SPK_RSA_DECRYPT; goto END; } /* Repoint Auth. Certificate pointer to start of OCM buffer */ AcPtr = ReadBuffer; } else { XFsbl_Printf(DEBUG_INFO, "partver: sha calc. " "for non bs DDR less part \r\n"); /* SHA calculation for non-bitstream, DDR less partitions */ XFsbl_ShaDigest((const u8 *)(PTRSIZE)PartitionOffset, HashDataLen, PartitionHash, HashLen); } #else /* SHA calculation in DDRful systems */ XFsbl_ShaDigest((const u8 *)(PTRSIZE)PartitionOffset, HashDataLen, PartitionHash, HashLen); #endif /* Set SPK pointer */ AcPtr += (XFSBL_RSA_AC_ALIGN + XFSBL_PPK_SIZE); SpkModular = (u8 *)AcPtr; AcPtr += XFSBL_SPK_MOD_SIZE; SpkModularEx = (u8 *)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; XFsbl_Printf(DEBUG_DETAILED, "XFsbl_PartVer: Spk Mod %0x, Spk Mod Ex %0x, Spk Exp %0x\r\n", SpkModular, SpkModularEx, SpkExp); XFsbl_Printf(DEBUG_INFO, "Partition Verification done \r\n"); XSecure_RsaInitialize(&SecureRsa, SpkModular, SpkModularEx, (u8 *)&SpkExp); /* Decrypt Partition Signature. */ if(XFSBL_SUCCESS != XSecure_RsaDecrypt(&SecureRsa, AcPtr, XFsbl_RsaSha3Array)) { XFsbl_Printf(DEBUG_GENERAL, "XFsbl_SpkVer: XFSBL_ERROR_PART_RSA_DECRYPT\r\n"); Status = XFSBL_ERROR_PART_RSA_DECRYPT; goto END; } /* Authenticate Partition Signature */ if(XFSBL_SUCCESS != XSecure_RsaSignVerification(XFsbl_RsaSha3Array, PartitionHash, HashLen)) { XFsbl_PrintArray(DEBUG_INFO, PartitionHash, HashLen, "Calculated Partition Hash"); XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array, 512, "RSA decrypted Hash"); XFsbl_Printf(DEBUG_GENERAL, "XFsbl_PartVer: XFSBL_ERROR_PART_SIGNATURE\r\n"); Status = XFSBL_ERROR_PART_SIGNATURE; goto END; } END: return Status; }