/** * This function initializes the primary boot device * * @param FsblInstancePtr is pointer to the XFsbl Instance * * @return returns the error codes described in xfsbl_error.h on any error * returns XFSBL_SUCCESS on success * ******************************************************************************/ static u32 XFsbl_PrimaryBootDeviceInit(XFsblPs * FsblInstancePtr) { u32 Status = XFSBL_SUCCESS; u32 BootMode=0U; /** * Read Boot Mode register and update the value */ BootMode = XFsbl_In32(CRL_APB_BOOT_MODE_USER) & CRL_APB_BOOT_MODE_USER_BOOT_MODE_MASK; FsblInstancePtr->PrimaryBootDevice = BootMode; /** * Enable drivers only if they are device boot modes * Not required for JTAG modes */ if ( (BootMode == XFSBL_QSPI24_BOOT_MODE) || (BootMode == XFSBL_QSPI32_BOOT_MODE) || (BootMode == XFSBL_NAND_BOOT_MODE) || (BootMode == XFSBL_SD0_BOOT_MODE) || (BootMode == XFSBL_EMMC_BOOT_MODE) || (BootMode == XFSBL_SD1_BOOT_MODE) || (BootMode == XFSBL_SD1_LS_BOOT_MODE)) { /** * Initialize the WDT and CSU drivers */ #ifdef XFSBL_WDT_PRESENT Status = XFsbl_InitWdt(); if (XFSBL_SUCCESS != Status) { XFsbl_Printf(DEBUG_GENERAL,"WDT initialization failed \n\r"); goto END; } #endif /* Initialize CSUDMA driver */ Status = XFsbl_CsuDmaInit(); if (XFSBL_SUCCESS != Status) { goto END; } } switch(BootMode) { /** * For JTAG boot mode, it will be in while loop */ case XFSBL_JTAG_BOOT_MODE: { XFsbl_Printf(DEBUG_GENERAL,"In JTAG Boot Mode \n\r"); Status = XFSBL_STATUS_JTAG; } break; case XFSBL_QSPI24_BOOT_MODE: { XFsbl_Printf(DEBUG_GENERAL,"QSPI 24bit Boot Mode \n\r"); #ifdef XFSBL_QSPI /** * Update the deviceops structure with necessary values */ FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_Qspi24Init; FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_Qspi24Copy; FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_Qspi24Release; #else /** * This bootmode is not supported in this release */ XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; #endif } break; case XFSBL_QSPI32_BOOT_MODE: { XFsbl_Printf(DEBUG_GENERAL,"QSPI 32 bit Boot Mode \n\r"); #ifdef XFSBL_QSPI /** * Update the deviceops structure with necessary values * */ FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_Qspi32Init; FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_Qspi32Copy; FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_Qspi32Release; #else /** * This bootmode is not supported in this release */ XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; #endif } break; case XFSBL_NAND_BOOT_MODE: { XFsbl_Printf(DEBUG_GENERAL,"NAND Boot Mode \n\r"); #ifdef XFSBL_NAND /** * Update the deviceops structure with necessary values * */ FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_NandInit; FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_NandCopy; FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_NandRelease; #else /** * This bootmode is not supported in this release */ XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; #endif } break; case XFSBL_SD0_BOOT_MODE: case XFSBL_EMMC_BOOT_MODE: { if (BootMode == XFSBL_SD0_BOOT_MODE) { XFsbl_Printf(DEBUG_GENERAL,"SD0 Boot Mode \n\r"); } else { XFsbl_Printf(DEBUG_GENERAL,"eMMC Boot Mode \n\r"); } #ifdef XFSBL_SD_0 /** * Update the deviceops structure with necessary values */ FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_SdInit; FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_SdCopy; FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_SdRelease; #else /** * This bootmode is not supported in this release */ XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; #endif } break; case XFSBL_SD1_BOOT_MODE: case XFSBL_SD1_LS_BOOT_MODE: { if (BootMode == XFSBL_SD1_BOOT_MODE) { XFsbl_Printf(DEBUG_GENERAL, "SD1 Boot Mode \n\r"); } else { XFsbl_Printf(DEBUG_GENERAL, "SD1 with level shifter Boot Mode \n\r"); } #ifdef XFSBL_SD_1 /** * Update the deviceops structure with necessary values */ FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_SdInit; FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_SdCopy; FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_SdRelease; #else /** * This bootmode is not supported in this release */ XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; #endif } break; default: { XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r"); Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE; } break; } /** * In case of error or Jtag boot, goto end */ if (XFSBL_SUCCESS != Status) { goto END; } /** * Initialize the Device Driver */ Status = FsblInstancePtr->DeviceOps.DeviceInit(BootMode); 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; }