diff --git a/zynqmp/include/readimage-zynqmp.h b/zynqmp/include/readimage-zynqmp.h index 966bf7f..06015e2 100755 --- a/zynqmp/include/readimage-zynqmp.h +++ b/zynqmp/include/readimage-zynqmp.h @@ -75,6 +75,7 @@ class ZynqMpReadImage : public ReadImage void VerifyAuthentication(bool); void VerifyHeaderTableSignature(); void VerifySPKSignature(AuthCertificate4096Structure * auth_cert); + void VerifyBootHeaderSignature(FILE * binFile, AuthCertificate4096Structure * auth_cert); void VerifyPartitionSignature(void); bool VerifySignature(bool nist, uint8_t * data, size_t dataLength, ACKey4096 * acKey, uint8_t * signature); diff --git a/zynqmp/src/verifyimage-zynqmp.cpp b/zynqmp/src/verifyimage-zynqmp.cpp index 361665a..8d58692 100755 --- a/zynqmp/src/verifyimage-zynqmp.cpp +++ b/zynqmp/src/verifyimage-zynqmp.cpp @@ -189,6 +189,9 @@ void ZynqMpReadImage::VerifyHeaderTableSignature() AuthCertificate4096Structure* auth_cert = (AuthCertificate4096Structure*)(aCs.front()); + /* Verifying Header AC Boot Header Signature */ + VerifyBootHeaderSignature(binFile, auth_cert); + /* Verifying Header SPK Signature */ VerifySPKSignature(auth_cert); @@ -269,6 +272,45 @@ void ZynqMpReadImage::VerifySPKSignature(AuthCertificate4096Structure* auth_cert } +/*******************************************************************************/ +void ZynqMpReadImage::VerifyBootHeaderSignature(FILE* binFile, AuthCertificate4096Structure* auth_cert) +{ + size_t result; + uint32_t bHLength = sizeof(ZynqMpBootHeaderStructure) + sizeof(RegisterInitTable); + if (bH->fsblAttributes & 0xC0) + { + bHLength += PUF_DATA_LENGTH; + } + + auto tempBHBuffer = std::make_unique(bHLength); + if (!(fseek(binFile, 0, SEEK_SET))) + { + result = fread(tempBHBuffer.get(), 1, bHLength, binFile); + if (result != bHLength) + { + LOG_ERROR("Error reading boot header while verifying "); + } + } + else + { + LOG_ERROR("Error seeking to boot header while verifying"); + } + + bool signatureVerified = VerifySignature(false, tempBHBuffer.get(), bHLength, &auth_cert->acSpk, (unsigned char*)(&auth_cert->acBhSignature)); + if (signatureVerified) + { + LOG_MSG(" BootHeader Signature Verified"); + } + else + { + LOG_MSG(" BootHeader Signature Verification Failed"); + authenticationVerified = false; + LOG_ERROR("Authentication verification failed on bootimage %s", binFilename.c_str()); + } + // Cleanup handled by unique_ptr +} + + /*******************************************************************************/ void ZynqMpReadImage::VerifyPartitionSignature(void) { @@ -293,35 +335,10 @@ void ZynqMpReadImage::VerifyPartitionSignature(void) bool checkLoadAddrInBhAndPht = ((*partitionHdr)->destinationExecAddress == bH->fsblExecAddress); bool isItBootloader = (checkLoadAddrInBhAndPht && (bH->sourceOffset != 0)); - - if (isItBootloader) - { - uint32_t bHLength = sizeof(ZynqMpBootHeaderStructure) + sizeof(RegisterInitTable); - if (bH->fsblAttributes & 0xC0) - { - bHLength += PUF_DATA_LENGTH; - } - auto tempBHBuffer = std::make_unique(bHLength); - size_t result = fread(tempBHBuffer.get(), 1, bHLength, binFile); - if (result != bHLength) - { - LOG_ERROR("Error reading boot header while verifying "); - } - - bool signatureVerified = VerifySignature(false, tempBHBuffer.get(), bHLength, &auth_cert->acSpk, (unsigned char*)(&auth_cert->acBhSignature)); - if (signatureVerified) - { - LOG_MSG(" BootHeader Signature Verified"); - } - else - { - LOG_MSG(" BootHeader Signature Verification Failed"); - authenticationVerified = false; - LOG_ERROR("Authentication verification failed on bootimage %s", binFilename.c_str()); - } - // tempBHBuffer is now unique_ptr, automatically deleted - } + /* Verifying each boot header with that AC's own secondary key. + For a multi-block partition only the first block's AC is checked. */ + VerifyBootHeaderSignature(binFile, auth_cert); /* Verifying Partition SPK Signature */ VerifySPKSignature(auth_cert);