1 /* ffsparser.h
2 
3 Copyright (c) 2017, LongSoft. All rights reserved.
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 */
12 
13 #ifndef FFSPARSER_H
14 #define FFSPARSER_H
15 
16 #include <vector>
17 
18 #include "basetypes.h"
19 #include "ustring.h"
20 #include "ubytearray.h"
21 #include "treemodel.h"
22 #include "bootguard.h"
23 #include "fit.h"
24 
25 typedef struct BG_PROTECTED_RANGE_ {
26     UINT32     Offset;
27     UINT32     Size;
28     UINT8      Type;
29     UByteArray Hash;
30 } BG_PROTECTED_RANGE;
31 
32 #define BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB      0x01
33 #define BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB 0x02
34 #define BG_PROTECTED_RANGE_VENDOR_HASH_PHOENIX       0x03
35 #define BG_PROTECTED_RANGE_VENDOR_HASH_AMI_OLD       0x04
36 #define BG_PROTECTED_RANGE_VENDOR_HASH_AMI_NEW       0x05
37 #define BG_PROTECTED_RANGE_VENDOR_HASH_MICROSOFT     0x06
38 
39 class NvramParser;
40 class MeParser;
41 
42 class FfsParser
43 {
44 public:
45     // Constructor and destructor
46     FfsParser(TreeModel* treeModel);
47     ~FfsParser();
48 
49     // Obtain parser messages
50     std::vector<std::pair<UString, UModelIndex> > getMessages() const;
51     // Clear messages
clearMessages()52     void clearMessages() { messagesVector.clear(); }
53 
54     // Parse firmware image
55     USTATUS parse(const UByteArray &buffer);
56 
57     // Obtain parsed FIT table
getFitTable()58     std::vector<std::pair<std::vector<UString>, UModelIndex> > getFitTable() const { return fitTable; }
59 
60     // Obtain Security Info
getSecurityInfo()61     UString getSecurityInfo() const { return securityInfo; }
62 
63     // Obtain offset/address difference
getAddressDiff()64     UINT64 getAddressDiff() { return addressDiff; }
65 
66     // Output some info to stdout
67     void outputInfo(void);
68 
69 private:
70     TreeModel *model;
71     std::vector<std::pair<UString, UModelIndex> > messagesVector;
72     void msg(const UString & message, const UModelIndex & index = UModelIndex()) {
73         messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
74     };
75 
76     NvramParser* nvramParser;
77     MeParser* meParser;
78 
79     UByteArray openedImage;
80     UModelIndex lastVtf;
81     UINT32 imageBase;
82     UINT64 addressDiff;
83     std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
84 
85     UString securityInfo;
86     bool bgAcmFound;
87     bool bgKeyManifestFound;
88     bool bgBootPolicyFound;
89     UByteArray bgKmHash;
90     UByteArray bgBpHash;
91     UByteArray bgBpDigest;
92     std::vector<BG_PROTECTED_RANGE> bgProtectedRanges;
93     UINT64 bgProtectedRegionsBase;
94     UModelIndex bgDxeCoreIndex;
95 
96     // First pass
97     USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
98 
99     USTATUS parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
100     USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
101     USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
102 
103     USTATUS parseBpdtRegion(const UByteArray & region, const UINT32 localOffset, const UINT32 sbpdtOffsetFixup, const UModelIndex & parent, UModelIndex & index);
104     USTATUS parseCpdRegion(const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
105     USTATUS parseCpdExtensionsArea(const UModelIndex & index);
106     USTATUS parseSignedPackageInfoData(const UModelIndex & index);
107 
108     USTATUS parseRawArea(const UModelIndex & index);
109     USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
110     USTATUS parseVolumeBody(const UModelIndex & index);
111     USTATUS parseMicrocodeVolumeBody(const UModelIndex & index);
112     USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
113     USTATUS parseFileBody(const UModelIndex & index);
114     USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
115     USTATUS parseSectionBody(const UModelIndex & index);
116 
117     USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
118     USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
119     USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
120     USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
121     USTATUS parseDevExp1Region(const UByteArray & devExp1, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
122     USTATUS parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
123 
124     USTATUS parsePadFileBody(const UModelIndex & index);
125     USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index);
126 
127     USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree);
128     USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
129     USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
130     USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
131     USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
132     USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
133     USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
134 
135     USTATUS parseCompressedSectionBody(const UModelIndex & index);
136     USTATUS parseGuidedSectionBody(const UModelIndex & index);
137     USTATUS parseVersionSectionBody(const UModelIndex & index);
138     USTATUS parseDepexSectionBody(const UModelIndex & index);
139     USTATUS parseUiSectionBody(const UModelIndex & index);
140     USTATUS parseRawSectionBody(const UModelIndex & index);
141     USTATUS parsePeImageSectionBody(const UModelIndex & index);
142     USTATUS parseTeImageSectionBody(const UModelIndex & index);
143 
144     USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
145     USTATUS findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize);
146     UINT32  getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
147     UINT32  getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
148 
149     USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
150     BOOLEAN microcodeHeaderValid(const INTEL_MICROCODE_HEADER* ucodeHeader);
151 
152     // Second pass
153     USTATUS performSecondPass(const UModelIndex & index);
154     USTATUS addInfoRecursive(const UModelIndex & index);
155     USTATUS checkTeImageBase(const UModelIndex & index);
156     USTATUS checkProtectedRanges(const UModelIndex & index);
157     USTATUS markProtectedRangeRecursive(const UModelIndex & index, const BG_PROTECTED_RANGE & range);
158 
159     USTATUS parseResetVectorData();
160     USTATUS parseFit(const UModelIndex & index);
161     USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index);
162 
163 
164 #ifdef U_ENABLE_FIT_PARSING_SUPPORT
165     void findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
166 
167     // FIT entries
168     USTATUS parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
169     USTATUS parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
170     USTATUS parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
171     USTATUS parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
172     USTATUS findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
173 #endif
174 
175 #ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
176     friend class NvramParser; // Make FFS parsing routines accessible to NvramParser
177 #endif
178 
179 #ifdef U_ENABLE_ME_PARSING_SUPPORT
180     friend class MeParser; // Make FFS parsing routines accessible to MeParser
181 #endif
182 };
183 
184 #endif // FFSPARSER_H
185