📄 blcommon.c
字号:
packetData.bFlags = bFlags; // Flags
PrintPacketData( packetData );
hr = SBL_VerifyPacket( &packetData, &g_keyData );
if (FAILED(hr)) {
KITLOutputDebugString("ERROR: Signature validation failed for packet %d with error 0x%x, ABORT!\r\n", dwPacketNum, hr);
HALT (BLERR_SIGNATURE);
return (FALSE);
}
OEMShowProgress (dwPacketNum++);
if (fIsFlash)
{
OEMContinueEraseFlash ();
}
} // while( signed packets remaining )
//------------------------------------------------------------------------
// Determine the image entry point
//------------------------------------------------------------------------
// Does this .bin file contain a TOC?
if (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
{
// Contain the kernel?
if (IsKernelRegion(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
*pdwLaunchAddr = dwRecLen;
}
}
// No TOC - not made by romimage.
else if (g_DownloadManifest.dwNumRegions == 1)
{
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
*pdwLaunchAddr = dwRecLen;
}
else
{
// If we're downloading more than one .bin file, it's probably
// chain.bin which doesn't have a TOC (and which isn't
// going to be downloaded on its own) and we should ignore it.
}
KITLOutputDebugString("\r\n");
KITLOutputDebugString(" ******************************************************\r\n");
KITLOutputDebugString(" * *\r\n");
KITLOutputDebugString(" * This image was signed with a valid private key *\r\n");
KITLOutputDebugString(" * *\r\n");
KITLOutputDebugString(" ******************************************************\r\n");
KITLOutputDebugString("\r\n");
KITLOutputDebugString("Downloaded %d records\r\n", dwRecNum);
if (fIsFlash)
{
// finish the flash erase
if (!OEMFinishEraseFlash())
{
HALT (BLERR_FLASH_ERASE);
return (FALSE);
}
}
KITLOutputDebugString("ImageStart = 0x%x, ImageLength = 0x%x, LaunchAddr = 0x%x\r\n",
*pdwImageStart, *pdwImageLength, *pdwLaunchAddr);
return TRUE;
}
#endif // SECURE_BOOTLOADER
#ifdef SECURE_BOOTLOADER
static BOOL DownloadSignedNB0 (LPDWORD pdwImageStart, LPDWORD pdwImageLength, LPDWORD pdwLaunchAddr)
{
RegionInfo *pCurDownloadFile;
LPBYTE lpDest = NULL;
DWORD dwPacketNum = 1;
DWORD dwSignedDataLength, dwSigLength;
BYTE bFlags;
PACKETDATA packetData;
HRESULT hr;
g_bBINDownload = FALSE;
// Provide the download manifest to the OEM. This gives the OEM the
// opportunity to provide start addresses for the .nb0 files (which
// don't contain placement information like .bin files do).
if (!g_fOEMNotified && g_pOEMMultiBINNotify)
{
g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);
g_fOEMNotified = TRUE;
}
// Locate the current download manifest entry (current download file).
//
pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - g_downloadFilesRemaining];
// give the OEM a chance to verify memory
if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
KITLOutputDebugString ("!OEMVERIFYMEMORY: Invalid image\r\n");
HALT (BLERR_OEMVERIFY);
return (FALSE);
}
//------------------------------------------------------------------------
// Signed files are prefixed with a 16-byte random seed, which
// is included in the hash.
//------------------------------------------------------------------------
if (!OEMReadData (RANDOM_SEED_LENGTH, (LPBYTE) &packetData.bRandomSeed))
{
KITLOutputDebugString ("ERROR: Didn't find random seed at start of signed .nb0 file\r\n");
HALT (BLERR_MAGIC);
return (FALSE);
} else {
#ifdef DEBUG
int i;
KITLOutputDebugString("\r\nSigned file random seed = ");
for (i = 0; i < RANDOM_SEED_LENGTH; i++) {
KITLOutputDebugString("%x ", packetData.bRandomSeed[i]);
}
KITLOutputDebugString("\r\n\r\n");
#endif
}
//------------------------------------------------------------------------
// Download signed packets of raw data (.nb0)
//------------------------------------------------------------------------
lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart);
while ( OEMReadData (sizeof (DWORD), (LPBYTE) &dwSignedDataLength) &&
OEMReadData (sizeof (DWORD), (LPBYTE) &dwSigLength) &&
OEMReadData (sizeof (BYTE), (LPBYTE) &bFlags) )
{
#ifdef DEBUG
KITLOutputDebugString("\r\n------------------------------------------------------------------------------\r\n");
KITLOutputDebugString(" <> Packet [ %d ] dwDataLen = 0x%x, dwSigLen = 0x%x, bFlags = 0x%x\r\n",
dwPacketNum, dwSignedDataLength, dwSigLength, bFlags);
#endif
// check bFlags
if (bFlags & SBL_FLAG_END_FILE)
{
// last packet always has unused signature block, read it!
ASSERT(dwSignedDataLength == 0);
ASSERT(dwSigLength <= sizeof(g_rgpbSignature));
OEMReadData (dwSigLength, (LPBYTE) &g_rgpbSignature);
break;
}
else if (!(bFlags & SBL_FLAG_NORMAL))
{
KITLOutputDebugString("ERROR: bad bFlags 0x%x, ABORT!\r\n", bFlags);
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
// read packet data
if (!OEMReadData (dwSignedDataLength, lpDest))
{
KITLOutputDebugString ("ERROR: failed when reading raw binary file.\r\n");
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
// read packet signature
ASSERT(dwSigLength <= sizeof(g_rgpbSignature));
if (!OEMReadData (dwSigLength, (LPBYTE) &g_rgpbSignature))
{
KITLOutputDebugString ("ERROR: Failed to read signature for packet %d, ABORT!\r\n", dwPacketNum);
HALT (BLERR_SIGNATURE);
return (FALSE);
}
//------------------------------------------------------------------------
// Validate the signature for this packet
//------------------------------------------------------------------------
packetData.pbData = lpDest; // data to verify
packetData.dwDataLength = dwSignedDataLength; // length of data in bytes
packetData.pbSig = g_rgpbSignature; // signature to verify
packetData.dwSigLength = dwSigLength; // length of signature in bytes
packetData.dwRecAddress = 0; // record address
packetData.dwRecLength = 0; // record length
packetData.dwRecCheck = 0; // record checksum
packetData.dwSequenceNumber = dwPacketNum; // packet sequence number
packetData.bFlags = bFlags; // Flags
PrintPacketData( packetData );
hr = SBL_VerifyPacket( &packetData, &g_keyData );
if (FAILED(hr)) {
KITLOutputDebugString("ERROR: Signature validation failed for packet %d with error 0x%x, ABORT!\r\n", dwPacketNum, hr);
HALT (BLERR_SIGNATURE);
return (FALSE);
}
lpDest += dwSignedDataLength;
OEMShowProgress (dwPacketNum++);
} // end while(packets remaining)
KITLOutputDebugString("\r\n");
KITLOutputDebugString(" ******************************************************\r\n");
KITLOutputDebugString(" * *\r\n");
KITLOutputDebugString(" * This image was signed with a valid private key *\r\n");
KITLOutputDebugString(" * *\r\n");
KITLOutputDebugString(" ******************************************************\r\n");
KITLOutputDebugString("\r\n");
//------------------------------------------------------------------------
// PB sends the file size for .nb0 files (headers and all).
// Subtract the overhead of headers/footers; this is the true image size.
//------------------------------------------------------------------------
pCurDownloadFile->dwRegionLength -= BL_HDRSIG_SIZE;
pCurDownloadFile->dwRegionLength -= RANDOM_SEED_LENGTH;
pCurDownloadFile->dwRegionLength -= (dwPacketNum) * SBL_PACKET_HEADER_SIZE;
pCurDownloadFile->dwRegionLength -= (dwPacketNum) * dwSigLength;
KITLOutputDebugString("Image size after stripping signed headers/footers for %d packets: 0x%x\r\n",
dwPacketNum,
pCurDownloadFile->dwRegionLength);
//------------------------------------------------------------------------
// Determine the image entry point
//------------------------------------------------------------------------
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwLaunchAddr = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
KITLOutputDebugString("ImageStart = 0x%x, ImageLength = 0x%x, LaunchAddr = 0x%x\r\n",
*pdwImageStart, *pdwImageLength, *pdwLaunchAddr);
//------------------------------------------------------------------------
// If this is a flash image, erase flash.
// For signed images, we don't do this until the entire image has been
// validated.
//------------------------------------------------------------------------
if (OEMIsFlashAddr(pCurDownloadFile->dwRegionStart))
{
BOOL rval = TRUE;
rval &= OEMStartEraseFlash(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength);
OEMContinueEraseFlash();
rval &= OEMFinishEraseFlash();
if (!rval)
{
KITLOutputDebugString ("Invalid flash address/length or flash operation failed\r\n");
HALT (BLERR_FLASHADDR);
return (FALSE);
}
}
return TRUE;
}
#endif // SECURE_BOOTLOADER
static BOOL DownloadBin (LPDWORD pdwImageStart, LPDWORD pdwImageLength, LPDWORD pdwLaunchAddr)
{
RegionInfo *pCurDownloadFile;
BOOL fIsFlash = FALSE;
LPBYTE lpDest = NULL;
DWORD dwImageStart, dwImageLength, dwRecAddr, dwRecLen, dwRecChk;
DWORD dwRecNum = 0;
g_bBINDownload = TRUE;
if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)
|| !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))
{
KITLOutputDebugString ("Unable to read image start/length\r\n");
HALT (BLERR_MAGIC);
return (FALSE);
}
// If Platform Builder didn't provide a manifest (i.e., we're only
// downloading a single .bin file), manufacture a manifest so we
// can notify the OEM.
//
if (!g_DownloadManifest.dwNumRegions)
{
g_DownloadManifest.dwNumRegions = 1;
g_DownloadManifest.Region[0].dwRegionStart = dwImageStart;
g_DownloadManifest.Region[0].dwRegionLength = dwImageLength;
}
// Provide the download manifest to the OEM.
//
if (!g_fOEMNotified && g_pOEMMultiBINNotify)
{
g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);
g_fOEMNotified = TRUE;
}
// Locate the current download manifest entry (current download file).
//
pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - g_downloadFilesRemaining];
// give the OEM a chance to verify memory
if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
KITLOutputDebugString ("!OEMVERIFYMEMORY: Invalid image\r\n");
HALT (BLERR_OEMVERIFY);
return (FALSE);
}
// check for flash image. Start erasing if it is.
if ((fIsFlash = OEMIsFlashAddr (pCurDownloadFile->dwRegionStart))
&& !OEMStartEraseFlash (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
KITLOutputDebugString ("Invalid flash address/length\r\n");
HALT (BLERR_FLASHADDR);
return (FALSE);
}
#ifdef DEBUG
// Clearing memory ensures no garbage between sparse .bin records, so that
// our post-download checksum will be accurate.
memset( (LPVOID) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart),
0, pCurDownloadFile->dwRegionLength );
#endif
//------------------------------------------------------------------------
// Download .bin records
//------------------------------------------------------------------------
while ( OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen) &&
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk) )
{
#ifdef DEBUG
KITLOutputDebugString(" <> Record [ %d ] dwRecAddr = 0x%x, dwRecLen = 0x%x\r\n",
dwRecNum, dwRecAddr, dwRecLen);
#endif
// last record of .bin file uses sentinel values for address and checksum.
if (!dwRecAddr && !dwRecChk)
{
break;
}
// map the record address (FLASH data is cached, for example)
lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, dwRecAddr);
// read data block
if (!OEMReadData (dwRecLen, lpDest))
{
KITLOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******\r\n", dwRecNum);
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk))
{
KITLOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******\r\n", dwRecNum);
HALT (BLERR_CHECKSUM);
return (FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -