Add AMI v3 protected ranges hash file support

This commit is contained in:
Nikolaj Schlej 2023-02-05 20:30:20 -08:00
parent 7a161f577a
commit 33c25e8255
3 changed files with 266 additions and 183 deletions

View File

@ -831,8 +831,11 @@ typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2_
typedef struct PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3_
{
UINT8 Hash[SHA256_HASH_SIZE];
// UINT32 Base[SOME_HARDCODED_N]
// UINT32 Size[SOME_HARDCODED_N];
UINT32 FvMainSegmentBase[3];
UINT32 FvMainSegmentSize[3];
UINT32 NestedFvBase;
UINT32 NestedFvSize;
UINT8 Reserved[48];
} PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3;
//

View File

@ -3468,15 +3468,13 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
// QByteArray (Qt builds) supports obtaining data from invalid offsets in QByteArray,
// so mid() here doesn't throw anything for UEFITool, just returns ranges with all zeroes
// UByteArray (non-Qt builds) throws an exception that needs to be caught every time or the tools will crash.
// TODO: add sanity checks everythere so non-Qt UByteArray stuff don't need to throw
// Calculate digest for BG-protected ranges
UByteArray protectedParts;
bool bgProtectedRangeFound = false;
try {
for (UINT32 i = 0; i < (UINT32)protectedRanges.size(); i++) {
if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB
&& protectedRanges[i].Size > 0) {
if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB) {
bgProtectedRangeFound = true;
if ((UINT64)protectedRanges[i].Offset >= addressDiff) {
protectedRanges[i].Offset -= (UINT32)addressDiff;
@ -3536,39 +3534,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
// Calculate digests for vendor-protected ranges
for (UINT32 i = 0; i < (UINT32)protectedRanges.size(); i++) {
if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V1) {
if (!dxeCore.isValid()) {
msg(usprintf("%s: can't determine DXE volume offset, old AMI protected range hash can't be checked", __FUNCTION__), index);
}
else {
// Offset will be determined as the offset of root volume with first DXE core
UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(dxeCore, Types::Volume);
if (!dxeRootVolumeIndex.isValid()) {
msg(usprintf("%s: can't determine DXE volume offset, old AMI protected range hash can't be checked", __FUNCTION__), index);
}
else {
try {
protectedRanges[i].Offset = model->base(dxeRootVolumeIndex);
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
UByteArray digest(SHA256_HASH_SIZE, '\x00');
sha256(protectedParts.constData(), protectedParts.size(), digest.data());
if (digest != protectedRanges[i].Hash) {
msg(usprintf("%s: old AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__,
protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size),
model->findByBase(protectedRanges[i].Offset));
}
markProtectedRangeRecursive(index, protectedRanges[i]);
}
catch(...) {
// Do nothing, this range is likely not found in the image
}
}
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB) {
if (protectedRanges[i].Type == PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB) {
if (!dxeCore.isValid()) {
msg(usprintf("%s: can't determine DXE volume offset, post-IBB protected range hash can't be checked", __FUNCTION__), index);
}
@ -3627,6 +3593,38 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
}
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V1) {
if (!dxeCore.isValid()) {
msg(usprintf("%s: can't determine DXE volume offset, AMI v1 protected range hash can't be checked", __FUNCTION__), index);
}
else {
// Offset will be determined as the offset of root volume with first DXE core
UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(dxeCore, Types::Volume);
if (!dxeRootVolumeIndex.isValid()) {
msg(usprintf("%s: can't determine DXE volume offset, AMI v1 protected range hash can't be checked", __FUNCTION__), index);
}
else {
try {
protectedRanges[i].Offset = model->base(dxeRootVolumeIndex);
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
UByteArray digest(SHA256_HASH_SIZE, '\x00');
sha256(protectedParts.constData(), protectedParts.size(), digest.data());
if (digest != protectedRanges[i].Hash) {
msg(usprintf("%s: AMI v1 protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__,
protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size),
model->findByBase(protectedRanges[i].Offset));
}
markProtectedRangeRecursive(index, protectedRanges[i]);
}
catch (...) {
// Do nothing, this range is likely not found in the image
}
}
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V2) {
try {
protectedRanges[i].Offset -= (UINT32)addressDiff;
@ -3636,7 +3634,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
sha256(protectedParts.constData(), protectedParts.size(), digest.data());
if (digest != protectedRanges[i].Hash) {
msg(usprintf("%s: AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__,
msg(usprintf("%s: AMI v2 protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__,
protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size),
model->findByBase(protectedRanges[i].Offset));
}
@ -3647,9 +3645,51 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
// Do nothing, this range is likely not found in the image
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_PHOENIX
&& protectedRanges[i].Size != 0 && protectedRanges[i].Size != 0xFFFFFFFF
&& protectedRanges[i].Offset != 0xFFFFFFFF) {
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) {
try {
protectedRanges[i].Offset -= (UINT32)addressDiff;
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
markProtectedRangeRecursive(index, protectedRanges[i]);
// Process second range
if (i + 1 < (UINT32)protectedRanges.size() && protectedRanges[i + 1].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) {
protectedRanges[i + 1].Offset -= (UINT32)addressDiff;
protectedParts += openedImage.mid(protectedRanges[i + 1].Offset, protectedRanges[i + 1].Size);
markProtectedRangeRecursive(index, protectedRanges[i + 1]);
// Process third range
if (i + 2 < (UINT32)protectedRanges.size() && protectedRanges[i + 2].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) {
protectedRanges[i + 2].Offset -= (UINT32)addressDiff;
protectedParts += openedImage.mid(protectedRanges[i + 2].Offset, protectedRanges[i + 2].Size);
markProtectedRangeRecursive(index, protectedRanges[i + 2]);
// Process fourth range
if (i + 3 < (UINT32)protectedRanges.size() && protectedRanges[i + 3].Type == PROTECTED_RANGE_VENDOR_HASH_AMI_V3) {
protectedRanges[i + 3].Offset -= (UINT32)addressDiff;
protectedParts += openedImage.mid(protectedRanges[i + 3].Offset, protectedRanges[i + 3].Size);
markProtectedRangeRecursive(index, protectedRanges[i + 3]);
i += 3; // Skip 3 already processed ranges
}
else {
i += 2; // Skip 2 already processed ranges
}
}
else {
i += 1; // Skip 1 already processed range
}
}
UByteArray digest(SHA256_HASH_SIZE, '\x00');
sha256(protectedParts.constData(), protectedParts.size(), digest.data());
if (digest != protectedRanges[i].Hash) {
msg(usprintf("%s: AMI v3 protected ranges hash mismatch, opened image may refuse to boot", __FUNCTION__));
}
}
catch (...) {
// Do nothing, this range is likely not found in the image
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_PHOENIX) {
try {
protectedRanges[i].Offset += (UINT32)protectedRegionsBase;
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
@ -3669,9 +3709,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
// Do nothing, this range is likely not found in the image
}
}
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA
&& protectedRanges[i].Size != 0 && protectedRanges[i].Size != 0xFFFFFFFF
&& protectedRanges[i].Offset != 0 && protectedRanges[i].Offset != 0xFFFFFFFF) {
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA) {
try {
protectedRanges[i].Offset -= (UINT32)addressDiff;
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
@ -3766,138 +3804,172 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel
return U_INVALID_PARAMETER;
}
const UByteArray& body = model->body(index);
UINT32 size = (UINT32)body.size();
if (fileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_PHOENIX) {
const UByteArray &body = model->body(index);
UINT32 size = (UINT32)body.size();
// File too small to have even a signature
if (size < sizeof(UINT64)) {
msg(usprintf("%s: unknown or corrupted Phoenix hash file found", __FUNCTION__), index);
model->setText(index, UString("Phoenix hash file"));
return U_INVALID_FILE;
if (size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX)) {
msg(usprintf("%s: unknown or corrupted Phoenix protected ranges hash file", __FUNCTION__), index);
}
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX* header = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX*)body.constData();
if (header->Signature == BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX) {
if (size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX) ||
size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX) + header->NumEntries * sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY)) {
msg(usprintf("%s: unknown or corrupted Phoenix hash file found", __FUNCTION__), index);
model->setText(index, UString("Phoenix hash file"));
return U_INVALID_FILE;
}
if (header->NumEntries > 0) {
bool protectedRangesFound = false;
for (UINT32 i = 0; i < header->NumEntries; i++) {
protectedRangesFound = true;
const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i;
PROTECTED_RANGE range = {};
range.Offset = entry->Base;
range.Size = entry->Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_PHOENIX;
protectedRanges.push_back(range);
else {
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX* header = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX*)body.constData();
if (header->Signature == BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX) {
if (size < sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_PHOENIX) + header->NumEntries * sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY)) {
msg(usprintf("%s: unknown or corrupted Phoenix protected ranges hash file", __FUNCTION__), index);
}
if (protectedRangesFound) {
securityInfo += usprintf("Phoenix hash file found at base %08Xh\nProtected ranges:\n", model->base(index));
for (UINT32 i = 0; i < header->NumEntries; i++) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i;
securityInfo += usprintf("RelativeOffset: %08Xh Size: %Xh\nHash: ", entry->Base, entry->Size);
for (UINT8 j = 0; j < sizeof(entry->Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash[j]);
else {
if (header->NumEntries > 0) {
bool protectedRangesFound = false;
for (UINT32 i = 0; i < header->NumEntries; i++) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i;
if (entry->Base != 0xFFFFFFFF && entry->Size != 0 && entry->Size != 0xFFFFFFFF) {
protectedRangesFound = true;
PROTECTED_RANGE range = {};
range.Offset = entry->Base;
range.Size = entry->Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_PHOENIX;
protectedRanges.push_back(range);
}
}
if (protectedRangesFound) {
securityInfo += usprintf("Phoenix hash file found at base %08Xh\nProtected ranges:\n", model->base(index));
for (UINT32 i = 0; i < header->NumEntries; i++) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i;
securityInfo += usprintf("RelativeOffset: %08Xh Size: %Xh\nHash: ", entry->Base, entry->Size);
for (UINT8 j = 0; j < sizeof(entry->Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash[j]);
}
securityInfo += "\n";
}
}
securityInfo += "\n";
}
securityInfo += "\n";
}
msg(usprintf("%s: Phoenix hash file found", __FUNCTION__), index);
}
else {
msg(usprintf("%s: empty Phoenix hash file found", __FUNCTION__), index);
}
model->setText(index, UString("Phoenix hash file"));
}
model->setText(index, UString("Phoenix protected ranges hash file"));
}
else if (fileGuid == PROTECTED_RANGE_VENDOR_HASH_FILE_GUID_AMI) {
UModelIndex fileIndex = model->parent(index);
const UByteArray &body = model->body(index);
UINT32 size = (UINT32)body.size();
if (size != (UINT32)body.count('\xFF')) {
if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2)) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2*)(body.constData());
securityInfo += usprintf("AMI hash file v2 found at base %08Xh\nProtected ranges:", model->base(fileIndex));
securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash0.Base, entry->Hash0.Size);
for (UINT8 j = 0; j < sizeof(entry->Hash0.Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash0.Hash[j]);
}
securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash1.Base, entry->Hash1.Size);
for (UINT8 j = 0; j < sizeof(entry->Hash1.Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash1.Hash[j]);
}
securityInfo += "\n";
if (entry->Hash0.Base != 0 && entry->Hash0.Size != 0
&& entry->Hash0.Base != 0xFFFFFFFF && entry->Hash0.Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->Hash0.Base;
range.Size = entry->Hash0.Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash0.Hash, sizeof(entry->Hash0.Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2;
protectedRanges.push_back(range);
}
if (entry->Hash1.Base != 0 && entry->Hash1.Size != 0
&& entry->Hash1.Base != 0xFFFFFFFF && entry->Hash1.Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->Hash1.Base;
range.Size = entry->Hash1.Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash1.Hash, sizeof(entry->Hash1.Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2;
protectedRanges.push_back(range);
}
msg(usprintf("%s: AMI hash file v2 found", __FUNCTION__), fileIndex);
if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1)) {
securityInfo += usprintf("AMI protected ranges hash file v1 found at base %08Xh\nProtected range:\n", model->base(fileIndex));
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1*)(body.constData());
securityInfo += usprintf("Size: %Xh\nHash (SHA256): ", entry->Size);
for (UINT8 i = 0; i < sizeof(entry->Hash); i++) {
securityInfo += usprintf("%02X", entry->Hash[i]);
}
else if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1)) {
securityInfo += usprintf("AMI hash file v1 found at base %08Xh\nProtected range:\n", model->base(fileIndex));
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V1*)(body.constData());
securityInfo += usprintf("Size: %Xh\nHash (SHA256): ", entry->Size);
for (UINT8 i = 0; i < sizeof(entry->Hash); i++) {
securityInfo += usprintf("%02X", entry->Hash[i]);
}
securityInfo += "\n\n";
if (entry->Size != 0 && entry->Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = 0;
range.Size = entry->Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V1;
protectedRanges.push_back(range);
}
msg(usprintf("%s: AMI hash file v1 found", __FUNCTION__), fileIndex);
securityInfo += "\n";
if (entry->Size != 0 && entry->Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = 0;
range.Size = entry->Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V1;
protectedRanges.push_back(range);
}
else {
msg(usprintf("%s: unknown or corrupted AMI hash file found", __FUNCTION__), index);
model->setText(fileIndex, UString("AMI v1 protected ranges hash file"));
}
else if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2)) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V2*)(body.constData());
securityInfo += usprintf("AMI v2 protected ranges hash file found at base %08Xh\nProtected ranges:", model->base(fileIndex));
securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash0.Base, entry->Hash0.Size);
for (UINT8 j = 0; j < sizeof(entry->Hash0.Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash0.Hash[j]);
}
securityInfo += usprintf("\nAddress: %08Xh, Size: %Xh\nHash (SHA256): ", entry->Hash1.Base, entry->Hash1.Size);
for (UINT8 j = 0; j < sizeof(entry->Hash1.Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash1.Hash[j]);
}
securityInfo += "\n";
if (entry->Hash0.Base != 0xFFFFFFFF && entry->Hash0.Size != 0 && entry->Hash0.Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->Hash0.Base;
range.Size = entry->Hash0.Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash0.Hash, sizeof(entry->Hash0.Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2;
protectedRanges.push_back(range);
}
if (entry->Hash1.Base != 0xFFFFFFFF && entry->Hash1.Size != 0 && entry->Hash1.Size != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->Hash1.Base;
range.Size = entry->Hash1.Size;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash1.Hash, sizeof(entry->Hash1.Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V2;
protectedRanges.push_back(range);
}
model->setText(fileIndex, UString("AMI v2 protected ranges hash file"));
}
else if (size == sizeof(PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3)) {
const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3* entry = (const PROTECTED_RANGE_VENDOR_HASH_FILE_HEADER_AMI_V3*)(body.constData());
securityInfo += usprintf("AMI v3 protected ranges hash file found at base %08Xh\nProtected ranges:", model->base(fileIndex));
securityInfo += usprintf("\nFvBaseSegment 0 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[0], entry->FvMainSegmentSize[0]);
securityInfo += usprintf("\nFvBaseSegment 1 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[1], entry->FvMainSegmentSize[1]);
securityInfo += usprintf("\nFvBaseSegment 2 Address: %08Xh, Size: %Xh", entry->FvMainSegmentBase[2], entry->FvMainSegmentSize[2]);
securityInfo += usprintf("\nNestedFvBase Address: %08Xh, Size: %Xh", entry->NestedFvBase, entry->NestedFvSize);
securityInfo += usprintf("\nHash (SHA256): ");
for (UINT8 j = 0; j < sizeof(entry->Hash); j++) {
securityInfo += usprintf("%02X", entry->Hash[j]);
}
securityInfo += "\n";
if (entry->FvMainSegmentBase[0] != 0xFFFFFFFF && entry->FvMainSegmentSize[0] != 0 && entry->FvMainSegmentSize[0] != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->FvMainSegmentBase[0];
range.Size = entry->FvMainSegmentSize[0];
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3;
protectedRanges.push_back(range);
}
if (entry->FvMainSegmentBase[1] != 0xFFFFFFFF && entry->FvMainSegmentSize[1] != 0 && entry->FvMainSegmentSize[1] != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->FvMainSegmentBase[1];
range.Size = entry->FvMainSegmentSize[1];
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3;
protectedRanges.push_back(range);
}
if (entry->FvMainSegmentBase[2] != 0xFFFFFFFF && entry->FvMainSegmentSize[2] != 0 && entry->FvMainSegmentSize[2] != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->FvMainSegmentBase[2];
range.Size = entry->FvMainSegmentSize[2];
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3;
protectedRanges.push_back(range);
}
if (entry->NestedFvBase != 0xFFFFFFFF && entry->NestedFvSize != 0 && entry->NestedFvSize != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = entry->NestedFvBase;
range.Size = entry->NestedFvSize;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray((const char*)entry->Hash, sizeof(entry->Hash));
range.Type = PROTECTED_RANGE_VENDOR_HASH_AMI_V3;
protectedRanges.push_back(range);
}
model->setText(fileIndex, UString("AMI v3 protected ranges hash file"));
}
else {
msg(usprintf("%s: empty AMI hash file found", __FUNCTION__), fileIndex);
msg(usprintf("%s: unknown or corrupted AMI protected ranges hash file", __FUNCTION__), fileIndex);
}
model->setText(fileIndex, UString("AMI hash file"));
}
return U_SUCCESS;
}

View File

@ -703,7 +703,7 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
for (intel_acbp_v1_t::acbp_element_t* element : *elements) {
const intel_acbp_v1_t::common_header_t* element_header = element->header();
UINT64 structure_id = element_header->structure_id();
UINT64 structure_id = (UINT64) element_header->structure_id();
const char* structure_id_bytes = (const char*)&structure_id;
bpInfo += usprintf("StructureId: '%c%c%c%c%c%c%c%c'\n"
@ -788,7 +788,8 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
current_segment->base(),
current_segment->size());
if (current_segment->flags() == intel_acbp_v1_t::IBB_SEGMENT_TYPE_IBB) {
if (current_segment->flags() == intel_acbp_v1_t::IBB_SEGMENT_TYPE_IBB
&& current_segment->base() != 0xFFFFFFFF && current_segment->size() != 0 && current_segment->size() != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = current_segment->base();
range.Size = current_segment->size();
@ -833,13 +834,15 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
bpInfo += "\n";
// Add protected range
PROTECTED_RANGE range = {};
range.Offset = current_element->base();
range.Size = current_element->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray(current_element->hash().data(), current_element->hash().size());
ffsParser->protectedRanges.push_back(range);
if (current_element->base() != 0xFFFFFFFF && current_element->size() != 0 && current_element->size() != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = current_element->base();
range.Size = current_element->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Hash = UByteArray(current_element->hash().data(), current_element->hash().size());
ffsParser->protectedRanges.push_back(range);
}
}
}
// v2 entries
@ -860,13 +863,15 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
bpInfo += "\n";
// Add protected range
PROTECTED_RANGE range = {};
range.Offset = current_element->base();
range.Size = current_element->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = current_element->hash()->hash_algorithm_id();
range.Hash = UByteArray(current_element->hash()->hash().data(), current_element->hash()->hash().size());
ffsParser->protectedRanges.push_back(range);
if (current_element->base() != 0xFFFFFFFF && current_element->size() != 0 && current_element->size() != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = current_element->base();
range.Size = current_element->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = current_element->hash()->hash_algorithm_id();
range.Hash = UByteArray(current_element->hash()->hash().data(), current_element->hash()->hash().size());
ffsParser->protectedRanges.push_back(range);
}
}
}
}
@ -1099,7 +1104,8 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
current_segment->base(),
current_segment->size());
if (current_segment->flags() == intel_acbp_v2_t::IBB_SEGMENT_TYPE_IBB) {
if (current_segment->flags() == intel_acbp_v2_t::IBB_SEGMENT_TYPE_IBB
&& current_segment->base() != 0xFFFFFFFF && current_segment->size() != 0 && current_segment->size() != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = current_segment->base();
range.Size =current_segment->size();
@ -1151,13 +1157,15 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
bpInfo += "\n";
// Add protected range
PROTECTED_RANGE range = {};
range.Offset = current_entry->base();
range.Size = current_entry->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = current_entry->hash()->hash_algorithm_id();
range.Hash = UByteArray(current_entry->hash()->hash().data(), current_entry->hash()->hash().size());
ffsParser->protectedRanges.push_back(range);
if (current_entry->base() != 0xFFFFFFFF && current_entry->size() != 0 && current_entry->size() != 0xFFFFFFFF) {
PROTECTED_RANGE range = {};
range.Offset = current_entry->base();
range.Size = current_entry->size();
range.Type = PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA;
range.AlgorithmId = current_entry->hash()->hash_algorithm_id();
range.Hash = UByteArray(current_entry->hash()->hash().data(), current_entry->hash()->hash().size());
ffsParser->protectedRanges.push_back(range);
}
}
}
}