NE Alpha 43

add visual validation of Intel Boot Guard coverage
This commit is contained in:
Alex Matrosov 2017-10-11 22:59:23 -07:00
parent fc579533e8
commit 68df5a64a3
28 changed files with 1591 additions and 284 deletions

View file

@ -45,6 +45,8 @@ SET(PROJECT_HEADERS
../common/Tiano/EfiTianoDecompress.h ../common/Tiano/EfiTianoDecompress.h
../common/ubytearray.h ../common/ubytearray.h
../common/ustring.h ../common/ustring.h
../common/bootguard.h
../common/sha256.h
../common/bstrlib/bstrlib.h ../common/bstrlib/bstrlib.h
../common/bstrlib/bstrwrap.h ../common/bstrlib/bstrwrap.h
) )

View file

@ -47,5 +47,7 @@ HEADERS += \
../common/LZMA/LzmaDecompress.h \ ../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \ ../common/Tiano/EfiTianoDecompress.h \
../common/ubytearray.h \ ../common/ubytearray.h \
../common/ustring.h ../common/ustring.h \
../common/bootguard.h \
../common/sha256.h

View file

@ -40,5 +40,6 @@ HEADERS += uefifind.h \
../common/LZMA/LzmaDecompress.h \ ../common/LZMA/LzmaDecompress.h \
../common/Tiano/EfiTianoDecompress.h \ ../common/Tiano/EfiTianoDecompress.h \
../common/ustring.h \ ../common/ustring.h \
../common/ubytearray.h ../common/ubytearray.h \
../common/bootguard.h \
../common/sha256.h

View file

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("NE alpha 42")) version(tr("NE alpha 44"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();
@ -80,6 +80,7 @@ version(tr("NE alpha 42"))
ui->finderMessagesListWidget->setFont(font); ui->finderMessagesListWidget->setFont(font);
ui->builderMessagesListWidget->setFont(font); ui->builderMessagesListWidget->setFont(font);
ui->fitTableWidget->setFont(font); ui->fitTableWidget->setFont(font);
ui->bootGuardEdit->setFont(font);
ui->structureTreeView->setFont(font); ui->structureTreeView->setFont(font);
searchDialog->ui->guidEdit->setFont(font); searchDialog->ui->guidEdit->setFont(font);
searchDialog->ui->hexEdit->setFont(font); searchDialog->ui->hexEdit->setFont(font);
@ -118,7 +119,9 @@ void UEFITool::init()
ui->fitTableWidget->setRowCount(0); ui->fitTableWidget->setRowCount(0);
ui->fitTableWidget->setColumnCount(0); ui->fitTableWidget->setColumnCount(0);
ui->infoEdit->clear(); ui->infoEdit->clear();
ui->bootGuardEdit->clear();
ui->messagesTabWidget->setTabEnabled(1, false); ui->messagesTabWidget->setTabEnabled(1, false);
ui->messagesTabWidget->setTabEnabled(2, false);
// Set window title // Set window title
setWindowTitle(tr("UEFITool %1").arg(version)); setWindowTitle(tr("UEFITool %1").arg(version));
@ -863,9 +866,9 @@ void UEFITool::copyMessage()
clipboard->clear(); clipboard->clear();
if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text()); clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab else if (ui->messagesTabWidget->currentIndex() == 3) // Search tab
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text()); clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
else if (ui->messagesTabWidget->currentIndex() == 3) // Builder tab else if (ui->messagesTabWidget->currentIndex() == 4) // Builder tab
clipboard->setText(ui->builderMessagesListWidget->currentItem()->text()); clipboard->setText(ui->builderMessagesListWidget->currentItem()->text());
} }
@ -878,12 +881,12 @@ void UEFITool::copyAllMessages()
text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab else if (ui->messagesTabWidget->currentIndex() == 3) { // Search tab
for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++) for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++)
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
} }
else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab else if (ui->messagesTabWidget->currentIndex() == 4) { // Builder tab
for (INT32 i = 0; i < ui->builderMessagesListWidget->count(); i++) for (INT32 i = 0; i < ui->builderMessagesListWidget->count(); i++)
text.append(ui->builderMessagesListWidget->item(i)->text()).append("\n"); text.append(ui->builderMessagesListWidget->item(i)->text()).append("\n");
clipboard->setText(text); clipboard->setText(text);
@ -896,11 +899,11 @@ void UEFITool::clearMessages()
if (ffsParser) ffsParser->clearMessages(); if (ffsParser) ffsParser->clearMessages();
ui->parserMessagesListWidget->clear(); ui->parserMessagesListWidget->clear();
} }
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab else if (ui->messagesTabWidget->currentIndex() == 3) { // Search tab
if (ffsFinder) ffsFinder->clearMessages(); if (ffsFinder) ffsFinder->clearMessages();
ui->finderMessagesListWidget->clear(); ui->finderMessagesListWidget->clear();
} }
else if (ui->messagesTabWidget->currentIndex() == 3) { // Builder tab else if (ui->messagesTabWidget->currentIndex() == 4) { // Builder tab
if (ffsBuilder) ffsBuilder->clearMessages(); if (ffsBuilder) ffsBuilder->clearMessages();
ui->builderMessagesListWidget->clear(); ui->builderMessagesListWidget->clear();
} }
@ -955,7 +958,7 @@ void UEFITool::showFinderMessages()
ui->finderMessagesListWidget->addItem(item); ui->finderMessagesListWidget->addItem(item);
} }
ui->messagesTabWidget->setCurrentIndex(2); ui->messagesTabWidget->setCurrentIndex(3);
ui->finderMessagesListWidget->scrollToBottom(); ui->finderMessagesListWidget->scrollToBottom();
} }
@ -973,7 +976,7 @@ void UEFITool::showBuilderMessages()
ui->builderMessagesListWidget->addItem(item); ui->builderMessagesListWidget->addItem(item);
} }
ui->messagesTabWidget->setCurrentIndex(3); ui->messagesTabWidget->setCurrentIndex(4);
ui->builderMessagesListWidget->scrollToBottom(); ui->builderMessagesListWidget->scrollToBottom();
} }
@ -1079,6 +1082,8 @@ void UEFITool::showFitTable()
if (fitTable.empty()) { if (fitTable.empty()) {
// Disable FIT tab // Disable FIT tab
ui->messagesTabWidget->setTabEnabled(1, false); ui->messagesTabWidget->setTabEnabled(1, false);
// Disable BootGuard tab
ui->messagesTabWidget->setTabEnabled(2, false);
return; return;
} }
@ -1107,6 +1112,18 @@ void UEFITool::showFitTable()
ui->fitTableWidget->resizeColumnsToContents(); ui->fitTableWidget->resizeColumnsToContents();
ui->fitTableWidget->resizeRowsToContents(); ui->fitTableWidget->resizeRowsToContents();
ui->messagesTabWidget->setCurrentIndex(1); ui->messagesTabWidget->setCurrentIndex(1);
// Get BootGuard info
UString bgInfo = ffsParser->getBootGuardInfo();
if (bgInfo.isEmpty()) {
// Disable BootGuard tab
ui->messagesTabWidget->setTabEnabled(2, false);
return;
}
ui->messagesTabWidget->setTabEnabled(2, true);
ui->bootGuardEdit->setPlainText(bgInfo);
ui->messagesTabWidget->setCurrentIndex(2);
} }
void UEFITool::currentTabChanged(int index) void UEFITool::currentTabChanged(int index)

View file

@ -3,6 +3,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = UEFITool TARGET = UEFITool
TEMPLATE = app TEMPLATE = app
DEFINES += "U_ENABLE_FIT_PARSING_SUPPORT"
DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT" DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT"
DEFINES += "U_ENABLE_GUID_DATABASE_SUPPORT" DEFINES += "U_ENABLE_GUID_DATABASE_SUPPORT"
@ -39,6 +40,8 @@ HEADERS += uefitool.h \
../common/Tiano/EfiTianoCompress.h \ ../common/Tiano/EfiTianoCompress.h \
../common/ustring.h \ ../common/ustring.h \
../common/ubytearray.h \ ../common/ubytearray.h \
../common/bootguard.h \
../common/sha256.h \
qhexedit2/qhexedit.h \ qhexedit2/qhexedit.h \
qhexedit2/chunks.h \ qhexedit2/chunks.h \
qhexedit2/commands.h qhexedit2/commands.h
@ -72,6 +75,7 @@ SOURCES += uefitool_main.cpp \
../common/Tiano/EfiTianoCompress.c \ ../common/Tiano/EfiTianoCompress.c \
../common/Tiano/EfiTianoCompressLegacy.c \ ../common/Tiano/EfiTianoCompressLegacy.c \
../common/ustring.cpp \ ../common/ustring.cpp \
../common/sha256.c \
qhexedit2/qhexedit.cpp \ qhexedit2/qhexedit.cpp \
qhexedit2/chunks.cpp \ qhexedit2/chunks.cpp \
qhexedit2/commands.cpp qhexedit2/commands.cpp

View file

@ -132,15 +132,15 @@
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="centerOnScroll">
<bool>false</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
<widget class="QTabWidget" name="messagesTabWidget"> <widget class="QTabWidget" name="messagesTabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
@ -203,6 +203,44 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="bootGuardTab">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title">
<string>BootGuard</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QPlainTextEdit" name="bootGuardEdit">
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="finderTab"> <widget class="QWidget" name="finderTab">
<attribute name="title"> <attribute name="title">
<string>Search</string> <string>Search</string>

View file

@ -59,6 +59,12 @@ typedef uint8_t USTATUS;
#define U_STORES_NOT_FOUND 38 #define U_STORES_NOT_FOUND 38
#define U_INVALID_IMAGE 39 #define U_INVALID_IMAGE 39
#define U_INVALID_RAW_AREA 40 #define U_INVALID_RAW_AREA 40
#define U_INVALID_FIT 41
#define U_INVALID_MICROCODE 42
#define U_INVALID_ACM 43
#define U_INVALID_BG_KEY_MANIFEST 44
#define U_INVALID_BG_BOOT_POLICY 45
#define U_ELEMENTS_NOT_FOUND 46
#define U_NOT_IMPLEMENTED 0xFF #define U_NOT_IMPLEMENTED 0xFF
// UDK porting definitions // UDK porting definitions

192
common/bootguard.h Normal file
View file

@ -0,0 +1,192 @@
/* bootguard.h
Copyright (c) 2017, LongSoft. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef BOOTGUARD_H
#define BOOTGUARD_H
#include "basetypes.h"
#include "sha256.h"
#pragma pack(push, 1)
const UByteArray BG_VENDOR_HASH_FILE_GUID_PHOENIX // 389CC6F2-1EA8-467B-AB8A-78E769AE2A15
("\xF2\xC6\x9C\x38\xA8\x1E\x7B\x46\xAB\x8A\x78\xE7\x69\xAE\x2A\x15", 16);
#define BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX (*(UINT64 *)"$HASHTBL")
const UByteArray BG_VENDOR_HASH_FILE_GUID_AMI // CBC91F44-A4BC-4A5B-8696-703451D0B053
("\x44\x1F\xC9\xCB\xBC\xA4\x5B\x4A\x86\x96\x70\x34\x51\xD0\xB0\x53", 16);
typedef struct BG_VENDOR_HASH_FILE_ENTRY
{
UINT8 Hash[SHA256_DIGEST_SIZE];
UINT32 Offset;
UINT32 Size;
} BG_VENDOR_HASH_FILE_ENTRY;
typedef struct BG_VENDOR_HASH_FILE_HEADER_PHOENIX_
{
UINT64 Signature;
UINT32 NumEntries;
//BG_VENDOR_HASH_FILE_ENTRY Entries[];
} BG_VENDOR_HASH_FILE_HEADER_PHOENIX;
typedef struct BG_VENDOR_HASH_FILE_HEADER_AMI_NEW_
{
BG_VENDOR_HASH_FILE_ENTRY Entries[2];
} BG_VENDOR_HASH_FILE_HEADER_AMI_NEW;
typedef struct BG_VENDOR_HASH_FILE_HEADER_AMI_OLD_
{
UINT8 Hash[SHA256_DIGEST_SIZE];
UINT32 Size;
// Offset is derived from flash map, will be detected as root volume with DXE core
} BG_VENDOR_HASH_FILE_HEADER_AMI_OLD;
//
// Intel ACM
//
#define INTEL_ACM_MODULE_TYPE 0x00030002
#define INTEL_ACM_MODULE_VENDOR 0x8086
typedef struct INTEL_ACM_HEADER_ {
UINT32 ModuleType;
UINT32 HeaderType;
UINT32 HeaderVersion;
UINT16 ChipsetId;
UINT16 Unknown;
UINT32 ModuleVendor;
UINT8 DateDay;
UINT8 DateMonth;
UINT16 DateYear;
UINT32 ModuleSize;
UINT16 AcmSvn;
UINT16 : 16;
UINT32 Unknown1;
UINT32 Unknown2;
UINT32 GdtMax;
UINT32 GdtBase;
UINT32 SegmentSel;
UINT32 EntryPoint;
UINT8 Unknown3[64];
UINT32 KeySize;
UINT32 Unknown4;
UINT8 RsaPubKey[256];
UINT32 RsaPubExp;
UINT8 RsaSig[256];
} INTEL_ACM_HEADER;
//
// Intel BootGuard Key Manifest
//
#define BG_BOOT_POLICY_MANIFEST_HEADER_TAG (*(UINT64 *)"__ACBP__")
typedef struct BG_BOOT_POLICY_MANIFEST_HEADER_ {
UINT64 Tag;
UINT8 Version;
UINT8 HeaderVersion;
UINT8 PMBPMVersion;
UINT8 BPSVN;
UINT8 ACMSVN;
UINT8 : 8;
UINT16 NEMDataSize;
} BG_BOOT_POLICY_MANIFEST_HEADER;
typedef struct SHA256_HASH_ {
UINT16 HashAlgorithmId;
UINT16 Size;
UINT8 HashBuffer[32];
} SHA256_HASH;
typedef struct RSA_PUBLIC_KEY_ {
UINT8 Version;
UINT16 KeySize;
UINT32 Exponent;
UINT8 Modulus[256];
} RSA_PUBLIC_KEY;
typedef struct RSA_SIGNATURE_ {
UINT8 Version;
UINT16 KeySize;
UINT16 HashId;
UINT8 Signature[256];
} RSA_SIGNATURE;
typedef struct KEY_SIGNATURE_ {
UINT8 Version;
UINT16 KeyId;
RSA_PUBLIC_KEY PubKey;
UINT16 SigScheme;
RSA_SIGNATURE Signature;
} BG_KEY_SIGNATURE;
#define BG_IBB_SEGMENT_FLAG_IBB 0x0
#define BG_IBB_SEGMENT_FLAG_NON_IBB 0x1
typedef struct BG_IBB_SEGMENT_ELEMENT_ {
UINT16: 16;
UINT16 Flags;
UINT32 Base;
UINT32 Size;
} BG_IBB_SEGMENT_ELEMENT;
#define BG_BOOT_POLICY_MANIFEST_IBB_ELEMENT_TAG (*(UINT64 *)"__IBBS__")
#define BG_IBB_FLAG_AUTHORITY_MEASURE 0x4
typedef struct BG_IBB_ELEMENT_ {
UINT64 Tag;
UINT8 Version;
UINT16 : 16;
UINT8 Unknown;
UINT32 Flags;
UINT64 IbbMchBar;
UINT64 VtdBar;
UINT32 Unknown1;
UINT32 Unknown2;
UINT64 Unknown3;
UINT64 Unknown4;
SHA256_HASH IbbHash;
UINT32 EntryPoint;
SHA256_HASH Digest;
UINT8 IbbSegCount;
// BG_IBB_SEGMENT_ELEMENT IbbSegment[];
} BG_IBB_ELEMENT;
#define BG_BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_TAG (*(UINT64 *)"__PMDA__")
typedef struct BG_PLATFORM_MANUFACTURER_ELEMENT_ {
UINT64 Tag;
UINT8 Version;
UINT16 DataSize;
} BG_PLATFORM_MANUFACTURER_ELEMENT;
#define BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_TAG (*(UINT64 *)"__PMSG__")
typedef struct BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_ {
UINT64 Tag;
UINT8 Version;
BG_KEY_SIGNATURE KeySignature;
} BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT;
#define BG_KEY_MANIFEST_TAG (*(UINT64 *)"__KEYM__")
typedef struct BG_KEY_MANIFEST_ {
UINT64 Tag;
UINT8 Version;
UINT8 KmVersion;
UINT8 KmSvn;
UINT8 KmId;
SHA256_HASH BpKeyHash;
BG_KEY_SIGNATURE KeyManifestSignature;
} BG_KEY_MANIFEST;
#pragma pack(pop)
#endif // BOOTGUARD_H

View file

@ -63,7 +63,7 @@ typedef struct FLASH_PARAMETERS_ {
UINT8 SecondChipDensity : 4; UINT8 SecondChipDensity : 4;
UINT8 : 8; UINT8 : 8;
UINT8 : 1; UINT8 : 1;
UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors and 17 Mhz (110b) in v2 ones UINT8 ReadClockFrequency : 3; // Hardcoded value of 20 Mhz (000b) in v1 descriptors
UINT8 FastReadEnabled : 1; UINT8 FastReadEnabled : 1;
UINT8 FastReadFrequency : 3; UINT8 FastReadFrequency : 3;
UINT8 FlashWriteFrequency : 3; UINT8 FlashWriteFrequency : 3;

View file

@ -149,17 +149,17 @@ const UByteArray EFI_FV_SIGNATURE("_FVH", 4);
// Firmware volume attributes // Firmware volume attributes
// Revision 1 // Revision 1
#define EFI_FVB_READ_DISABLED_CAP 0x00000001 #define EFI_FVB_READ_DISABLED_CAP 0x00000001
#define EFI_FVB_READ_ENABLED_CAP 0x00000002 #define EFI_FVB_READ_ENABLED_CAP 0x00000002
#define EFI_FVB_READ_STATUS 0x00000004 #define EFI_FVB_READ_STATUS 0x00000004
#define EFI_FVB_WRITE_DISABLED_CAP 0x00000008 #define EFI_FVB_WRITE_DISABLED_CAP 0x00000008
#define EFI_FVB_WRITE_ENABLED_CAP 0x00000010 #define EFI_FVB_WRITE_ENABLED_CAP 0x00000010
#define EFI_FVB_WRITE_STATUS 0x00000020 #define EFI_FVB_WRITE_STATUS 0x00000020
#define EFI_FVB_LOCK_CAP 0x00000040 #define EFI_FVB_LOCK_CAP 0x00000040
#define EFI_FVB_LOCK_STATUS 0x00000080 #define EFI_FVB_LOCK_STATUS 0x00000080
#define EFI_FVB_STICKY_WRITE 0x00000200 #define EFI_FVB_STICKY_WRITE 0x00000200
#define EFI_FVB_MEMORY_MAPPED 0x00000400 #define EFI_FVB_MEMORY_MAPPED 0x00000400
#define EFI_FVB_ERASE_POLARITY 0x00000800 #define EFI_FVB_ERASE_POLARITY 0x00000800
#define EFI_FVB_ALIGNMENT_CAP 0x00008000 #define EFI_FVB_ALIGNMENT_CAP 0x00008000
#define EFI_FVB_ALIGNMENT_2 0x00010000 #define EFI_FVB_ALIGNMENT_2 0x00010000
#define EFI_FVB_ALIGNMENT_4 0x00020000 #define EFI_FVB_ALIGNMENT_4 0x00020000
@ -248,7 +248,7 @@ typedef struct EFI_FIRMWARE_VOLUME_EXT_ENTRY_ {
typedef struct EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE_ { typedef struct EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE_ {
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header; EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
UINT32 TypeMask; UINT32 TypeMask;
//EFI_GUID Types[1]; //EFI_GUID Types[];
} EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE; } EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE;
#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002 #define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002
@ -339,6 +339,7 @@ extern const UINT8 ffsAlignmentTable[];
#define EFI_FILE_DELETED 0x10 #define EFI_FILE_DELETED 0x10
#define EFI_FILE_HEADER_INVALID 0x20 #define EFI_FILE_HEADER_INVALID 0x20
#define EFI_FILE_ERASE_POLARITY 0x80 // Defined as "all other bits must be set to ERASE_POLARITY" in UEFI PI Vol3 #define EFI_FILE_ERASE_POLARITY 0x80 // Defined as "all other bits must be set to ERASE_POLARITY" in UEFI PI Vol3
// PEI apriori file // PEI apriori file
const UByteArray EFI_PEI_APRIORI_FILE_GUID const UByteArray EFI_PEI_APRIORI_FILE_GUID
("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16); ("\x0A\xCC\x45\x1B\x6A\x15\x8A\x42\xAF\x62\x49\x86\x4D\xA0\xE6\xE6", 16);
@ -355,6 +356,10 @@ const UByteArray EFI_FFS_VOLUME_TOP_FILE_GUID
const UByteArray EFI_FFS_PAD_FILE_GUID const UByteArray EFI_FFS_PAD_FILE_GUID
("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16); ("\x85\x65\x53\xE4\x09\x79\x60\x4A\xB5\xC6\xEC\xDE\xA6\xEB\xFB\x54", 16);
// DXE core file
const UByteArray EFI_DXE_CORE_GUID // 5AE3F37E-4EAE-41AE-8240-35465B5E81EB
("\x7E\xF3\xE3\x5A\xAE\x4E\xAE\x41\x82\x40\x35\x46\x5B\x5E\x81\xEB", 16);
// FFS size conversion routines // FFS size conversion routines
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize); extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
extern UINT32 uint24ToUint32(const UINT8* ffsSize); extern UINT32 uint24ToUint32(const UINT8* ffsSize);
@ -479,15 +484,18 @@ typedef struct WIN_CERTIFICATE_UEFI_GUID_ {
} WIN_CERTIFICATE_UEFI_GUID; } WIN_CERTIFICATE_UEFI_GUID;
// WIN_CERTIFICATE_UEFI_GUID.CertType // WIN_CERTIFICATE_UEFI_GUID.CertType
const UByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID const UByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID // A7717414-C616-4977-9420-844712A735BF
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF"); ("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
// WIN_CERTIFICATE_UEFI_GUID.CertData // WIN_CERTIFICATE_UEFI_GUID.CertData
typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ { typedef struct EFI_CERT_BLOCK_RSA2048_SHA256_ {
UINT32 HashType; EFI_GUID HashType;
UINT8 PublicKey[256]; UINT8 PublicKey[256];
UINT8 Signature[256]; UINT8 Signature[256];
} EFI_CERT_BLOCK_RSA_2048_SHA256; } EFI_CERT_BLOCK_RSA2048_SHA256;
const UByteArray EFI_HASH_ALGORITHM_SHA256_GUID // 51aa59de-fdf2-4ea3-bc63-875fb7842ee9
("\xde\x59\xAA\x51\xF2\xFD\xA3\x4E\xBC\x63\x87\x5F\xB7\x84\x2E\xE9");
// Version section // Version section
typedef struct EFI_VERSION_SECTION_ { typedef struct EFI_VERSION_SECTION_ {

File diff suppressed because it is too large Load diff

View file

@ -21,12 +21,28 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treemodel.h" #include "treemodel.h"
#include "nvramparser.h" #include "nvramparser.h"
#include "meparser.h" #include "meparser.h"
#include "bootguard.h"
typedef struct BG_PROTECTED_RANGE_
{
UINT32 Offset;
UINT32 Size;
UINT8 Type;
UByteArray Hash;
} BG_PROTECTED_RANGE;
#define BG_PROTECTED_RANGE_INTEL_BOOT_GUARD 0x01
#define BG_PROTECTED_RANGE_VENDOR_HASH_PHOENIX 0x02
#define BG_PROTECTED_RANGE_VENDOR_HASH_AMI_OLD 0x03
#define BG_PROTECTED_RANGE_VENDOR_HASH_AMI_NEW 0x04
class FfsParser class FfsParser
{ {
public: public:
// Default constructor and destructor // Default constructor and destructor
FfsParser(TreeModel* treeModel) : model(treeModel), nvramParser(treeModel), meParser(treeModel), capsuleOffsetFixup(0), addressDiff(0x100000000ULL) {} FfsParser(TreeModel* treeModel) : model(treeModel), nvramParser(treeModel), meParser(treeModel),
capsuleOffsetFixup(0), addressDiff(0x100000000ULL),
bgAcmFound(false), bgKeyManifestFound(false), bgBootPolicyFound(false), bgFirstVolumeOffset(0x100000000ULL) {}
~FfsParser() {} ~FfsParser() {}
// Obtain parser messages // Obtain parser messages
@ -48,6 +64,9 @@ public:
// Obtain parsed FIT table // Obtain parsed FIT table
std::vector<std::pair<std::vector<UString>, UModelIndex> > getFitTable() const { return fitTable; } std::vector<std::pair<std::vector<UString>, UModelIndex> > getFitTable() const { return fitTable; }
// Obtain BootGuardInfo
UString getBootGuardInfo() const { return bootGuardInfo; }
// Obtain offset/address difference // Obtain offset/address difference
UINT64 getAddressDiff() { return addressDiff; } UINT64 getAddressDiff() { return addressDiff; }
@ -61,10 +80,22 @@ private:
NvramParser nvramParser; NvramParser nvramParser;
MeParser meParser; MeParser meParser;
UByteArray openedImage;
UModelIndex lastVtf; UModelIndex lastVtf;
UINT32 capsuleOffsetFixup; UINT32 capsuleOffsetFixup;
UINT64 addressDiff; UINT64 addressDiff;
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable; std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
UString bootGuardInfo;
bool bgAcmFound;
bool bgKeyManifestFound;
bool bgBootPolicyFound;
UByteArray bgKmHash;
UByteArray bgBpHash;
UByteArray bgBpDigest;
std::vector<BG_PROTECTED_RANGE> bgProtectedRanges;
UINT64 bgFirstVolumeOffset;
UModelIndex bgDxeCoreIndex;
// First pass // First pass
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index); USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
@ -115,8 +146,22 @@ private:
USTATUS addOffsetsRecursive(const UModelIndex & index); USTATUS addOffsetsRecursive(const UModelIndex & index);
USTATUS addMemoryAddressesRecursive(const UModelIndex & index); USTATUS addMemoryAddressesRecursive(const UModelIndex & index);
USTATUS addFixedAndCompressedRecursive(const UModelIndex & index); USTATUS addFixedAndCompressedRecursive(const UModelIndex & index);
USTATUS checkProtectedRanges(const UModelIndex & index);
USTATUS markProtectedRangeRecursive(const UModelIndex & index, const BG_PROTECTED_RANGE & range);
USTATUS parseFit(const UModelIndex & index); USTATUS parseFit(const UModelIndex & index);
USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index);
#ifdef U_ENABLE_FIT_PARSING_SUPPORT
USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset); USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
// FIT entries
USTATUS parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 localOffset, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
#endif
}; };
#endif // FFSPARSER_H #endif // FFSPARSER_H

View file

@ -42,16 +42,20 @@ const UByteArray FIT_SIGNATURE
typedef struct FIT_ENTRY_ { typedef struct FIT_ENTRY_ {
UINT64 Address; UINT64 Address;
UINT32 Size; UINT32 Size : 24;
UINT32 : 8;
UINT16 Version; UINT16 Version;
UINT8 Type; UINT8 Type : 7;
UINT8 CsFlag : 1;
UINT8 Checksum; UINT8 Checksum;
} FIT_ENTRY; } FIT_ENTRY;
typedef struct INTEL_MICROCODE_HEADER_ { typedef struct INTEL_MICROCODE_HEADER_ {
UINT32 Version; UINT32 Version;
UINT32 Revision; UINT32 Revision;
UINT32 Date; UINT16 DateYear;
UINT8 DateDay;
UINT8 DateMonth;
UINT32 CpuSignature; UINT32 CpuSignature;
UINT32 Checksum; UINT32 Checksum;
UINT32 LoaderRevision; UINT32 LoaderRevision;

View file

@ -26,7 +26,7 @@ typedef struct GBE_MAC_ADDRESS_ {
#define GBE_VERSION_OFFSET 10 #define GBE_VERSION_OFFSET 10
typedef struct GBE_VERSION_ { typedef struct GBE_VERSION_ {
UINT8 id : 4; UINT8 id : 4;
UINT8 minor : 4; UINT8 minor : 4;
UINT8 major; UINT8 major;
} GBE_VERSION; } GBE_VERSION;

View file

@ -23,7 +23,7 @@ const UByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
typedef struct ME_VERSION_ { typedef struct ME_VERSION_ {
UINT32 signature; UINT32 signature;
UINT32 reserved; // Unknown for me UINT32 reserved;
UINT16 major; UINT16 major;
UINT16 minor; UINT16 minor;
UINT16 bugfix; UINT16 bugfix;

View file

@ -106,18 +106,28 @@ typedef struct VSS_VARIABLE_STORE_HEADER_ {
typedef struct VSS_VARIABLE_HEADER_ { typedef struct VSS_VARIABLE_HEADER_ {
UINT16 StartId; // Variable start marker AA55 UINT16 StartId; // Variable start marker AA55
UINT8 State; // Variable state UINT8 State; // Variable state
UINT8 : 8; UINT8 Reserved;
UINT32 Attributes; // Variable attributes UINT32 Attributes; // Variable attributes
UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string
UINT32 DataSize; // Size of variable data without header and name UINT32 DataSize; // Size of variable data without header and name
EFI_GUID VendorGuid; // Variable vendor GUID EFI_GUID VendorGuid; // Variable vendor GUID
} VSS_VARIABLE_HEADER; } VSS_VARIABLE_HEADER;
// Intel variable header
typedef struct VSS_INTEL_VARIABLE_HEADER_ {
UINT16 StartId; // Variable start marker AA55
UINT8 State; // Variable state
UINT8 Reserved;
UINT32 Attributes; // Variable attributes
UINT32 TotalSize; // Size of variable including header
EFI_GUID VendorGuid; // Variable vendor GUID
} VSS_INTEL_VARIABLE_HEADER;
// Apple variation of normal variable header, with one new field // Apple variation of normal variable header, with one new field
typedef struct VSS_APPLE_VARIABLE_HEADER_ { typedef struct VSS_APPLE_VARIABLE_HEADER_ {
UINT16 StartId; // Variable start marker AA55 UINT16 StartId; // Variable start marker AA55
UINT8 State; // Variable state UINT8 State; // Variable state
UINT8 : 8; UINT8 Reserved;
UINT32 Attributes; // Variable attributes UINT32 Attributes; // Variable attributes
UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string UINT32 NameSize; // Size of variable name, stored as null-terminated UCS2 string
UINT32 DataSize; // Size of variable data without header and name UINT32 DataSize; // Size of variable data without header and name
@ -129,7 +139,7 @@ typedef struct VSS_APPLE_VARIABLE_HEADER_ {
typedef struct VSS_AUTH_VARIABLE_HEADER_ { typedef struct VSS_AUTH_VARIABLE_HEADER_ {
UINT16 StartId; // Variable start marker AA55 UINT16 StartId; // Variable start marker AA55
UINT8 State; // Variable state UINT8 State; // Variable state
UINT8 : 8; UINT8 Reserved;
UINT32 Attributes; // Variable attributes UINT32 Attributes; // Variable attributes
UINT64 MonotonicCounter; // Monotonic counter against replay attack UINT64 MonotonicCounter; // Monotonic counter against replay attack
EFI_TIME Timestamp; // Time stamp against replay attack EFI_TIME Timestamp; // Time stamp against replay attack
@ -144,7 +154,8 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
#define NVRAM_VSS_VARIABLE_DELETED 0xfd // Variable is obsolete #define NVRAM_VSS_VARIABLE_DELETED 0xfd // Variable is obsolete
#define NVRAM_VSS_VARIABLE_HEADER_VALID 0x7f // Variable has valid header #define NVRAM_VSS_VARIABLE_HEADER_VALID 0x7f // Variable has valid header
#define NVRAM_VSS_VARIABLE_ADDED 0x3f // Variable has been completely added #define NVRAM_VSS_VARIABLE_ADDED 0x3f // Variable has been completely added
#define NVRAM_VSS_IS_VARIABLE_STATE(_c, _Mask) (BOOLEAN) (((~_c) & (~_Mask)) != 0) #define NVRAM_VSS_INTEL_VARIABLE_VALID 0xfc // Intel special variable valid
#define NVRAM_VSS_INTEL_VARIABLE_INVALID 0xf8 // Intel special variable invalid
// VSS variable attributes // VSS variable attributes
#define NVRAM_VSS_VARIABLE_NON_VOLATILE 0x00000001 #define NVRAM_VSS_VARIABLE_NON_VOLATILE 0x00000001
@ -175,11 +186,11 @@ const UByteArray LENOVO_VSS_STORE_GUID
// Variable store header // Variable store header
typedef struct LENOVO_VSS_VARIABLE_STORE_HEADER_ { typedef struct LENOVO_VSS_VARIABLE_STORE_HEADER_ {
EFI_GUID Signature; EFI_GUID Signature;
UINT32 Size; // Size of variable store, including store header UINT32 Size; // Size of variable store, including store header
UINT8 Format; // Store format state UINT8 Format; // Store format state
UINT8 State; // Store health state UINT8 State; // Store health state
UINT16 Unknown; UINT16 Unknown;
UINT32 : 32; UINT32 : 32;
} LENOVO_VSS_VARIABLE_STORE_HEADER; } LENOVO_VSS_VARIABLE_STORE_HEADER;
// VSS entries are 4-bytes aligned in Lenovo stores // VSS entries are 4-bytes aligned in Lenovo stores
@ -212,7 +223,7 @@ const UByteArray EDKII_WORKING_BLOCK_SIGNATURE_GUID
const UByteArray LENOVO_WORKING_BLOCK_SIGNATURE_GUID const UByteArray LENOVO_WORKING_BLOCK_SIGNATURE_GUID
("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 16); ("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 16);
#define NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 0xFFF12B8D #define NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 0xFFF12B8D
#define EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1 0x9E58292B #define EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1 0x9E58292B
typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ { typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ {
@ -328,7 +339,7 @@ extern UString evsaAttributesToUString(const UINT32 attributes);
// Phoenix SCT Flash Map // Phoenix SCT Flash Map
// //
#define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1 0x414C465F #define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1 0x414C465F
#define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH 10 #define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH 10
// _FLASH_MAP // _FLASH_MAP

View file

@ -1250,11 +1250,13 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
// Add info // Add info
UString name("Intel microcode"); UString name("Intel microcode");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n" UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
"Date: %08Xh\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh", "Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
ucodeHeader->TotalSize, ucodeHeader->TotalSize, ucodeHeader->TotalSize, ucodeHeader->TotalSize,
header.size(), header.size(), header.size(), header.size(),
body.size(), body.size(), body.size(), body.size(),
ucodeHeader->Date, ucodeHeader->DateDay,
ucodeHeader->DateMonth,
ucodeHeader->DateYear,
ucodeHeader->CpuSignature, ucodeHeader->CpuSignature,
ucodeHeader->Revision, ucodeHeader->Revision,
ucodeHeader->Checksum, ucodeHeader->Checksum,
@ -1352,6 +1354,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
bool isInvalid = false; bool isInvalid = false;
bool isAuthenticated = false; bool isAuthenticated = false;
bool isAppleCrc32 = false; bool isAppleCrc32 = false;
bool isIntelSpecial = false;
UINT32 storedCrc32 = 0; UINT32 storedCrc32 = 0;
UINT32 calculatedCrc32 = 0; UINT32 calculatedCrc32 = 0;
@ -1374,9 +1377,8 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
// Check variable header to fit in still unparsed data // Check variable header to fit in still unparsed data
UINT32 variableSize = 0; UINT32 variableSize = 0;
if (unparsedSize >= sizeof(VSS_VARIABLE_HEADER) if (unparsedSize >= sizeof(VSS_VARIABLE_HEADER)
&& variableHeader->StartId == NVRAM_VSS_VARIABLE_START_ID) { && variableHeader->StartId == NVRAM_VSS_VARIABLE_START_ID) {
// Apple VSS variable with CRC32 of the data // Apple VSS variable with CRC32 of the data
if (variableHeader->Attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) { if (variableHeader->Attributes & NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM) {
isAppleCrc32 = true; isAppleCrc32 = true;
@ -1421,9 +1423,27 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
pubKeyIndex = authVariableHeader->PubKeyIndex; pubKeyIndex = authVariableHeader->PubKeyIndex;
} }
} }
// Intel special variable
else if (variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_VALID || variableHeader->State == NVRAM_VSS_INTEL_VARIABLE_INVALID) {
isIntelSpecial = true;
const VSS_INTEL_VARIABLE_HEADER* intelVariableHeader = (const VSS_INTEL_VARIABLE_HEADER*)variableHeader;
variableSize = intelVariableHeader->TotalSize;
variableGuid = (EFI_GUID*)&intelVariableHeader->VendorGuid;
variableName = (CHAR16*)(intelVariableHeader + 1);
UINT32 i = 0;
while (variableName[i] != 0) ++i;
i = sizeof(VSS_INTEL_VARIABLE_HEADER) + 2 * (i + 1);
i = i < variableSize ? i : variableSize;
header = data.mid(offset, i);
body = data.mid(offset + header.size(), variableSize - i);
}
// Normal VSS variable // Normal VSS variable
if (!isAuthenticated && !isAppleCrc32) { if (!isAuthenticated && !isAppleCrc32 && !isIntelSpecial) {
variableSize = sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize + variableHeader->DataSize; variableSize = sizeof(VSS_VARIABLE_HEADER) + variableHeader->NameSize + variableHeader->DataSize;
variableGuid = (EFI_GUID*)&variableHeader->VendorGuid; variableGuid = (EFI_GUID*)&variableHeader->VendorGuid;
variableName = (CHAR16*)(variableHeader + 1); variableName = (CHAR16*)(variableHeader + 1);
@ -1433,7 +1453,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
} }
// Check variable state // Check variable state
if (variableHeader->State != NVRAM_VSS_VARIABLE_ADDED && variableHeader->State != NVRAM_VSS_VARIABLE_HEADER_VALID) { if (variableHeader->State != NVRAM_VSS_INTEL_VARIABLE_VALID && variableHeader->State != NVRAM_VSS_VARIABLE_ADDED && variableHeader->State != NVRAM_VSS_VARIABLE_HEADER_VALID) {
isInvalid = true; isInvalid = true;
} }
@ -1481,11 +1501,12 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
} }
// Add info // Add info
info += usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nAttributes: %08Xh (", info += usprintf("Full size: %Xh (%u)\nHeader size %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (",
variableSize, variableSize, variableSize, variableSize,
header.size(), header.size(), header.size(), header.size(),
body.size(), body.size(), body.size(), body.size(),
variableHeader->State, variableHeader->State,
variableHeader->Reserved,
variableHeader->Attributes) + vssAttributesToUString(variableHeader->Attributes) + UString(")"); variableHeader->Attributes) + vssAttributesToUString(variableHeader->Attributes) + UString(")");
// Set subtype and add related info // Set subtype and add related info
@ -1501,6 +1522,9 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
info += usprintf("\nData checksum: %08Xh", storedCrc32) + info += usprintf("\nData checksum: %08Xh", storedCrc32) +
(storedCrc32 != calculatedCrc32 ? usprintf(", invalid, should be %08Xh", calculatedCrc32) : UString(", valid")); (storedCrc32 != calculatedCrc32 ? usprintf(", invalid, should be %08Xh", calculatedCrc32) : UString(", valid"));
} }
else if (isIntelSpecial) {
subtype = Subtypes::IntelVssEntry;
}
else else
subtype = Subtypes::StandardVssEntry; subtype = Subtypes::StandardVssEntry;

View file

@ -27,8 +27,9 @@ typedef struct VOLUME_PARSING_DATA_ {
UINT8 revision; UINT8 revision;
BOOLEAN hasExtendedHeader; BOOLEAN hasExtendedHeader;
BOOLEAN hasAppleCrc32; BOOLEAN hasAppleCrc32;
BOOLEAN hasAppleFSO;
BOOLEAN isWeakAligned; BOOLEAN isWeakAligned;
BOOLEAN hasValidUsedSpace;
UINT32 usedSpace;
} VOLUME_PARSING_DATA; } VOLUME_PARSING_DATA;
typedef struct FILE_PARSING_DATA_ { typedef struct FILE_PARSING_DATA_ {

215
common/sha256.c Normal file
View file

@ -0,0 +1,215 @@
/* sha256.c
Copyright (c) 2017, LongSoft. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "sha256.h"
#include <stdint.h>
#include <string.h>
struct sha256_state {
uint64_t length;
uint32_t state[8], curlen;
uint8_t buf[SHA256_DIGEST_SIZE*2];
};
void sha256_init(struct sha256_state *md);
int sha256_process(struct sha256_state *md, const unsigned char *in, unsigned long inlen);
int sha256_done(struct sha256_state *md, uint8_t *out);
#define GET_BE32(a) ((((uint32_t) (a)[0]) << 24) | (((uint32_t) (a)[1]) << 16) | \
(((uint32_t) (a)[2]) << 8) | ((uint32_t) (a)[3]))
#define PUT_BE32(a, val) \
do { \
(a)[0] = (uint8_t) ((((uint32_t) (val)) >> 24) & 0xff); \
(a)[1] = (uint8_t) ((((uint32_t) (val)) >> 16) & 0xff); \
(a)[2] = (uint8_t) ((((uint32_t) (val)) >> 8) & 0xff); \
(a)[3] = (uint8_t) (((uint32_t) (val)) & 0xff); \
} while (0)
#define PUT_BE64(a, val) \
do { \
(a)[0] = (uint8_t) (((uint64_t) (val)) >> 56); \
(a)[1] = (uint8_t) (((uint64_t) (val)) >> 48); \
(a)[2] = (uint8_t) (((uint64_t) (val)) >> 40); \
(a)[3] = (uint8_t) (((uint64_t) (val)) >> 32); \
(a)[4] = (uint8_t) (((uint64_t) (val)) >> 24); \
(a)[5] = (uint8_t) (((uint64_t) (val)) >> 16); \
(a)[6] = (uint8_t) (((uint64_t) (val)) >> 8); \
(a)[7] = (uint8_t) (((uint64_t) (val)) & 0xff); \
} while (0)
void sha256(const void *in, unsigned long inlen, void* out)
{
struct sha256_state ctx;
sha256_init(&ctx);
sha256_process(&ctx, (const unsigned char*)in, inlen);
sha256_done(&ctx, (unsigned char *)out);
}
/* This is based on SHA256 implementation in LibTomCrypt that was released into
* public domain by Tom St Denis. */
/* the K array */
static const unsigned long K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
/* Various logical functions */
#define RORc(x, y) \
( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) RORc((x), (n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
/* compress 512-bits */
static int sha256_compress(struct sha256_state *md, unsigned char *buf)
{
uint32_t S[8], W[64], t0, t1;
uint32_t t;
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->state[i];
}
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++)
W[i] = GET_BE32(buf + (4 * i));
/* fill W[16..63] */
for (i = 16; i < 64; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
W[i - 16];
}
/* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 64; ++i) {
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
}
/* feedback */
for (i = 0; i < 8; i++) {
md->state[i] = md->state[i] + S[i];
}
return 0;
}
/* Initialize the hash state */
void sha256_init(struct sha256_state *md)
{
md->curlen = 0;
md->length = 0;
md->state[0] = 0x6A09E667UL;
md->state[1] = 0xBB67AE85UL;
md->state[2] = 0x3C6EF372UL;
md->state[3] = 0xA54FF53AUL;
md->state[4] = 0x510E527FUL;
md->state[5] = 0x9B05688CUL;
md->state[6] = 0x1F83D9ABUL;
md->state[7] = 0x5BE0CD19UL;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int sha256_process(struct sha256_state *md, const unsigned char *in,
unsigned long inlen)
{
unsigned long n;
#define block_size 64
if (md->curlen > sizeof(md->buf))
return -1;
while (inlen > 0) {
if (md->curlen == 0 && inlen >= block_size) {
if (sha256_compress(md, (unsigned char *) in) < 0)
return -1;
md->length += block_size * 8;
in += block_size;
inlen -= block_size;
} else {
n = MIN(inlen, (block_size - md->curlen));
memcpy(md->buf + md->curlen, in, n);
md->curlen += n;
in += n;
inlen -= n;
if (md->curlen == block_size) {
if (sha256_compress(md, md->buf) < 0)
return -1;
md->length += 8 * block_size;
md->curlen = 0;
}
}
}
return 0;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
@return CRYPT_OK if successful
*/
int sha256_done(struct sha256_state *md, unsigned char *out)
{
int i;
if (md->curlen >= sizeof(md->buf))
return -1;
/* increase the length of the message */
md->length += md->curlen * 8;
/* append the '1' bit */
md->buf[md->curlen++] = (unsigned char) 0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->curlen > 56) {
while (md->curlen < 64) {
md->buf[md->curlen++] = (unsigned char) 0;
}
sha256_compress(md, md->buf);
md->curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->curlen < 56) {
md->buf[md->curlen++] = (unsigned char) 0;
}
/* store length */
PUT_BE64(md->buf + 56, md->length);
sha256_compress(md, md->buf);
/* copy output */
for (i = 0; i < 8; i++)
PUT_BE32(out + (4 * i), md->state[i]);
return 0;
}

27
common/sha256.h Normal file
View file

@ -0,0 +1,27 @@
/* sha256.h
Copyright (c) 2017, LongSoft. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef SHA256_H
#define SHA256_H
#ifdef __cplusplus
extern "C" {
#endif
#define SHA256_DIGEST_SIZE 32
void sha256(const void *in, unsigned long inlen, void* out);
#ifdef __cplusplus
}
#endif
#endif // SHA256_H

View file

@ -31,6 +31,7 @@ TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype,
itemTail(tail), itemTail(tail),
itemFixed(fixed), itemFixed(fixed),
itemCompressed(compressed), itemCompressed(compressed),
itemMarking(0),
parentItem(parent) parentItem(parent)
{ {
} }

View file

@ -86,12 +86,16 @@ public:
bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); } bool hasEmptyParsingData() const { return itemParsingData.isEmpty(); }
void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; } void setParsingData(const UByteArray & pdata) { itemParsingData = pdata; }
UINT8 marking() const { return itemMarking; }
void setMarking(const UINT8 marking) { itemMarking = marking; }
private: private:
std::list<TreeItem*> childItems; std::list<TreeItem*> childItems;
UINT32 itemOffset; UINT32 itemOffset;
UINT8 itemAction; UINT8 itemAction;
UINT8 itemType; UINT8 itemType;
UINT8 itemSubtype; UINT8 itemSubtype;
UINT8 itemMarking;
UString itemName; UString itemName;
UString itemText; UString itemText;
UString itemInfo; UString itemInfo;

View file

@ -21,15 +21,21 @@ QVariant TreeModel::data(const UModelIndex &index, int role) const
if (!index.isValid()) if (!index.isValid())
return QVariant(); return QVariant();
if (role != Qt::DisplayRole && role != Qt::UserRole)
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole) {
return (const char*)item->data(index.column()).toLocal8Bit(); return (const char*)item->data(index.column()).toLocal8Bit();
else }
else if (role == Qt::BackgroundRole) {
if (marking(index) > 0) {
return QBrush((Qt::GlobalColor)marking(index));
}
}
else if (role == Qt::UserRole) {
return (const char*)item->info().toLocal8Bit(); return (const char*)item->info().toLocal8Bit();
}
return QVariant();
} }
Qt::ItemFlags TreeModel::flags(const UModelIndex &index) const Qt::ItemFlags TreeModel::flags(const UModelIndex &index) const
@ -183,6 +189,14 @@ UINT8 TreeModel::subtype(const UModelIndex &index) const
return item->subtype(); return item->subtype();
} }
UINT8 TreeModel::marking(const UModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->marking();
}
UByteArray TreeModel::header(const UModelIndex &index) const UByteArray TreeModel::header(const UModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
@ -314,6 +328,17 @@ void TreeModel::setCompressed(const UModelIndex &index, const bool compressed)
emit dataChanged(index, index); emit dataChanged(index, index);
} }
void TreeModel::setMarking(const UModelIndex &index, const UINT8 marking)
{
if (!index.isValid())
return;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setMarking(marking);
emit dataChanged(index, index);
}
void TreeModel::setOffset(const UModelIndex &index, const UINT32 offset) void TreeModel::setOffset(const UModelIndex &index, const UINT32 offset)
{ {
if (!index.isValid()) if (!index.isValid())
@ -479,11 +504,11 @@ UModelIndex TreeModel::addItem(const UINT32 offset, const UINT8 type, const UINT
UModelIndex TreeModel::findParentOfType(const UModelIndex& index, UINT8 type) const UModelIndex TreeModel::findParentOfType(const UModelIndex& index, UINT8 type) const
{ {
if (!index.isValid()) if (!index.isValid() || !index.parent().isValid())
return UModelIndex(); return UModelIndex();
TreeItem *item; TreeItem *item;
UModelIndex parent = index; UModelIndex parent = index.parent();
for (item = static_cast<TreeItem*>(parent.internalPointer()); for (item = static_cast<TreeItem*>(parent.internalPointer());
item != NULL && item != rootItem && item->type() != type; item != NULL && item != rootItem && item->type() != type;
@ -495,6 +520,25 @@ UModelIndex TreeModel::findParentOfType(const UModelIndex& index, UINT8 type) co
return UModelIndex(); return UModelIndex();
} }
UModelIndex TreeModel::findLastParentOfType(const UModelIndex& index, UINT8 type) const
{
if (!index.isValid())
return UModelIndex();
UModelIndex lastParentOfType = findParentOfType(index, type);
if (!lastParentOfType.isValid())
return UModelIndex();
UModelIndex currentParentOfType = findParentOfType(lastParentOfType, type);
while (currentParentOfType.isValid()) {
lastParentOfType = currentParentOfType;
currentParentOfType = findParentOfType(lastParentOfType, type);
}
return lastParentOfType;
}
UModelIndex TreeModel::findByOffset(UINT32 offset) const UModelIndex TreeModel::findByOffset(UINT32 offset) const
{ {
UModelIndex parentIndex = index(0,0); UModelIndex parentIndex = index(0,0);

View file

@ -25,6 +25,7 @@ enum ItemFixedState {
#include <QModelIndex> #include <QModelIndex>
#include <QVariant> #include <QVariant>
#include <QObject> #include <QObject>
#include <QBrush>
#include "ustring.h" #include "ustring.h"
#include "ubytearray.h" #include "ubytearray.h"
@ -143,6 +144,7 @@ public:
void addInfo(const UModelIndex &index, const UString &info, const bool append = TRUE); void addInfo(const UModelIndex &index, const UString &info, const bool append = TRUE);
void setFixed(const UModelIndex &index, const bool fixed); void setFixed(const UModelIndex &index, const bool fixed);
void setCompressed(const UModelIndex &index, const bool compressed); void setCompressed(const UModelIndex &index, const bool compressed);
void setMarking(const UModelIndex &index, const UINT8 marking);
UINT32 offset(const UModelIndex &index) const; UINT32 offset(const UModelIndex &index) const;
UINT8 type(const UModelIndex &index) const; UINT8 type(const UModelIndex &index) const;
@ -158,6 +160,7 @@ public:
bool hasEmptyTail(const UModelIndex &index) const; bool hasEmptyTail(const UModelIndex &index) const;
bool fixed(const UModelIndex &index) const; bool fixed(const UModelIndex &index) const;
bool compressed(const UModelIndex &index) const; bool compressed(const UModelIndex &index) const;
UINT8 marking(const UModelIndex &index) const;
UINT8 action(const UModelIndex &index) const; UINT8 action(const UModelIndex &index) const;
@ -172,6 +175,7 @@ public:
const UModelIndex & parent = UModelIndex(), const UINT8 mode = CREATE_MODE_APPEND); const UModelIndex & parent = UModelIndex(), const UINT8 mode = CREATE_MODE_APPEND);
UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const; UModelIndex findParentOfType(const UModelIndex & index, UINT8 type) const;
UModelIndex findLastParentOfType(const UModelIndex & index, UINT8 type) const;
UModelIndex findByOffset(UINT32 offset) const; UModelIndex findByOffset(UINT32 offset) const;
}; };

View file

@ -115,6 +115,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
if (subtype == Subtypes::StandardVssEntry) return UString("Standard"); if (subtype == Subtypes::StandardVssEntry) return UString("Standard");
if (subtype == Subtypes::AppleVssEntry) return UString("Apple"); if (subtype == Subtypes::AppleVssEntry) return UString("Apple");
if (subtype == Subtypes::AuthVssEntry) return UString("Auth"); if (subtype == Subtypes::AuthVssEntry) return UString("Auth");
if (subtype == Subtypes::IntelVssEntry) return UString("Intel");
break; break;
case Types::FsysEntry: case Types::FsysEntry:
if (subtype == Subtypes::InvalidFsysEntry) return UString("Invalid"); if (subtype == Subtypes::InvalidFsysEntry) return UString("Invalid");

View file

@ -112,7 +112,8 @@ namespace Subtypes {
InvalidVssEntry = 140, InvalidVssEntry = 140,
StandardVssEntry, StandardVssEntry,
AppleVssEntry, AppleVssEntry,
AuthVssEntry AuthVssEntry,
IntelVssEntry
}; };
enum FsysEntrySubtypes { enum FsysEntrySubtypes {

View file

@ -24,7 +24,7 @@ UString uniqueItemName(const UModelIndex & index)
{ {
// Sanity check // Sanity check
if (!index.isValid()) if (!index.isValid())
return UString("Invalid index"); return UString("Invalid_index");
// Get model from index // Get model from index
const TreeModel* model = (const TreeModel*)index.model(); const TreeModel* model = (const TreeModel*)index.model();

View file

@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "treemodel.h" #include "treemodel.h"
#include "parsingdata.h" #include "parsingdata.h"
// Returns unique name string based for tree item // Returns unique name for tree item
UString uniqueItemName(const UModelIndex & index); UString uniqueItemName(const UModelIndex & index);
// Converts error code to UString // Converts error code to UString