1 #include "fw-update/package_parser.hpp"
2
3 #include <typeinfo>
4
5 #include <gmock/gmock.h>
6 #include <gtest/gtest.h>
7
8 using namespace pldm::fw_update;
9
imageGenerate(std::vector<uint8_t> & image,size_t size)10 void imageGenerate(std::vector<uint8_t>& image, size_t size)
11 {
12 for (size_t i = 1; i <= size; ++i)
13 {
14 image.push_back(static_cast<uint8_t>(i));
15 }
16 }
17
imageInsert(std::vector<uint8_t> & fwPkgHdr,std::vector<uint8_t> & image)18 void imageInsert(std::vector<uint8_t>& fwPkgHdr, std::vector<uint8_t>& image)
19 {
20 // Insert the image at the end of the package header
21 fwPkgHdr.insert(fwPkgHdr.end(), image.begin(), image.end());
22 }
23
TEST(PackageParser,ValidPkgSingleDescriptorSingleComponent)24 TEST(PackageParser, ValidPkgSingleDescriptorSingleComponent)
25 {
26 std::vector<uint8_t> fwPkgHdr{
27 0xF0, 0x18, 0x87, 0x8C, 0xCB, 0x7D, 0x49, 0x43, 0x98, 0x00, 0xA0, 0x2F,
28 0x05, 0x9A, 0xCA, 0x02, 0x01, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x19, 0x0C, 0xE5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0E,
30 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E,
31 0x67, 0x31, 0x01, 0x2E, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E,
32 0x00, 0x00, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74,
33 0x72, 0x69, 0x6E, 0x67, 0x32, 0x02, 0x00, 0x10, 0x00, 0x16, 0x20, 0x23,
34 0xC9, 0x3E, 0xC5, 0x41, 0x15, 0x95, 0xF4, 0x48, 0x70, 0x1D, 0x49, 0xD6,
35 0x75, 0x01, 0x00, 0x0A, 0x00, 0x64, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
36 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01,
37 0x0E, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69,
38 0x6E, 0x67, 0x33, 0x4F, 0x96, 0xAE, 0x56};
39
40 constexpr uintmax_t pkgSize = 166;
41 constexpr uintmax_t pkgHeaderSize = 139;
42 constexpr uintmax_t pkgImageSize = pkgSize - pkgHeaderSize;
43 std::vector<uint8_t> compImage;
44 imageGenerate(compImage, pkgImageSize);
45 imageInsert(fwPkgHdr, compImage);
46 constexpr std::string_view pkgVersion{"VersionString1"};
47 auto parser = parsePkgHeader(fwPkgHdr);
48 auto obj = parser.get();
49 EXPECT_EQ(typeid(*obj).name(), typeid(PackageParserV1).name());
50 EXPECT_EQ(parser->pkgHeaderSize, pkgHeaderSize);
51 EXPECT_EQ(parser->pkgVersion, pkgVersion);
52
53 parser->parse(fwPkgHdr, pkgSize);
54 auto outfwDeviceIDRecords = parser->getFwDeviceIDRecords();
55 FirmwareDeviceIDRecords fwDeviceIDRecords{
56 {1,
57 {0},
58 "VersionString2",
59 {{PLDM_FWUP_UUID,
60 std::vector<uint8_t>{0x16, 0x20, 0x23, 0xC9, 0x3E, 0xC5, 0x41, 0x15,
61 0x95, 0xF4, 0x48, 0x70, 0x1D, 0x49, 0xD6,
62 0x75}}},
63 {}},
64 };
65 EXPECT_EQ(outfwDeviceIDRecords, fwDeviceIDRecords);
66
67 auto outCompImageInfos = parser->getComponentImageInfos();
68 ComponentImageInfos compImageInfos{
69 {10, 100, 0xFFFFFFFF, 0, 0, 139, 27, "VersionString3"}};
70 EXPECT_EQ(outCompImageInfos, compImageInfos);
71 }
72
TEST(PackageParser,ValidPkgMultipleDescriptorsMultipleComponents)73 TEST(PackageParser, ValidPkgMultipleDescriptorsMultipleComponents)
74 {
75 std::vector<uint8_t> fwPkgHdr{
76 0xF0, 0x18, 0x87, 0x8C, 0xCB, 0x7D, 0x49, 0x43, 0x98, 0x00, 0xA0, 0x2F,
77 0x05, 0x9A, 0xCA, 0x02, 0x01, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x19, 0x0C, 0xE5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0E,
79 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E,
80 0x67, 0x31, 0x03, 0x45, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E,
81 0x00, 0x00, 0x03, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74,
82 0x72, 0x69, 0x6E, 0x67, 0x32, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xD2,
83 0x64, 0x8D, 0x7D, 0x47, 0x18, 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D,
84 0x5B, 0x01, 0x00, 0x04, 0x00, 0x47, 0x16, 0x00, 0x00, 0xFF, 0xFF, 0x0B,
85 0x00, 0x01, 0x07, 0x4F, 0x70, 0x65, 0x6E, 0x42, 0x4D, 0x43, 0x12, 0x34,
86 0x2E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x07,
87 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E,
88 0x67, 0x33, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D,
89 0x47, 0x18, 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D, 0x5C, 0x2E, 0x00,
90 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x01, 0x56, 0x65,
91 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x34,
92 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D, 0x47, 0x18,
93 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D, 0x5D, 0x03, 0x00, 0x0A, 0x00,
94 0x64, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x46, 0x01,
95 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x56, 0x65, 0x72, 0x73,
96 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x35, 0x0A, 0x00,
97 0xC8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x61, 0x01,
98 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x56, 0x65, 0x72, 0x73,
99 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x36, 0x10, 0x00,
100 0x2C, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0C, 0x00, 0x7C, 0x01,
101 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x56, 0x65, 0x72, 0x73,
102 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x37, 0xF1, 0x90,
103 0x9C, 0x71};
104
105 constexpr uintmax_t pkgSize = 407;
106 constexpr uintmax_t pkgHeaderSize = 326;
107 constexpr uintmax_t pkgImageSize = (pkgSize - pkgHeaderSize) / 3;
108 std::vector<uint8_t> compImage1, compImage2, compImage3;
109 imageGenerate(compImage1, pkgImageSize);
110 imageGenerate(compImage2, pkgImageSize);
111 imageGenerate(compImage3, pkgImageSize);
112 imageInsert(fwPkgHdr, compImage1);
113 imageInsert(fwPkgHdr, compImage2);
114 imageInsert(fwPkgHdr, compImage3);
115 constexpr std::string_view pkgVersion{"VersionString1"};
116 auto parser = parsePkgHeader(fwPkgHdr);
117 auto obj = parser.get();
118 EXPECT_EQ(typeid(*obj).name(), typeid(PackageParserV1).name());
119 EXPECT_EQ(parser->pkgHeaderSize, pkgHeaderSize);
120 EXPECT_EQ(parser->pkgVersion, pkgVersion);
121
122 parser->parse(fwPkgHdr, pkgSize);
123 auto outfwDeviceIDRecords = parser->getFwDeviceIDRecords();
124 FirmwareDeviceIDRecords fwDeviceIDRecords{
125 {1,
126 {0, 1},
127 "VersionString2",
128 {{PLDM_FWUP_UUID,
129 std::vector<uint8_t>{0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D, 0x47, 0x18,
130 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D,
131 0x5B}},
132 {PLDM_FWUP_IANA_ENTERPRISE_ID,
133 std::vector<uint8_t>{0x47, 0x16, 0x00, 0x00}},
134 {PLDM_FWUP_VENDOR_DEFINED,
135 std::make_tuple("OpenBMC", std::vector<uint8_t>{0x12, 0x34})}},
136 {}},
137 {0,
138 {0, 1, 2},
139 "VersionString3",
140 {{PLDM_FWUP_UUID,
141 std::vector<uint8_t>{0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D, 0x47, 0x18,
142 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D,
143 0x5C}}},
144 {}},
145 {0,
146 {0},
147 "VersionString4",
148 {{PLDM_FWUP_UUID,
149 std::vector<uint8_t>{0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D, 0x47, 0x18,
150 0xA0, 0x30, 0xFC, 0x8A, 0x56, 0x58, 0x7D,
151 0x5D}}},
152 {}},
153 };
154 EXPECT_EQ(outfwDeviceIDRecords, fwDeviceIDRecords);
155
156 auto outCompImageInfos = parser->getComponentImageInfos();
157 ComponentImageInfos compImageInfos{
158 {10, 100, 0xFFFFFFFF, 0, 0, 326, 27, "VersionString5"},
159 {10, 200, 0xFFFFFFFF, 0, 1, 353, 27, "VersionString6"},
160 {16, 300, 0xFFFFFFFF, 1, 12, 380, 27, "VersionString7"}};
161 EXPECT_EQ(outCompImageInfos, compImageInfos);
162 }
163
TEST(PackageParser,InvalidPkgHeaderInfoIncomplete)164 TEST(PackageParser, InvalidPkgHeaderInfoIncomplete)
165 {
166 std::vector<uint8_t> fwPkgHdr{0xF0, 0x18, 0x87, 0x8C, 0xCB, 0x7D,
167 0x49, 0x43, 0x98, 0x00, 0xA0, 0x2F,
168 0x05, 0x9A, 0xCA, 0x02};
169
170 auto parser = parsePkgHeader(fwPkgHdr);
171 EXPECT_EQ(parser, nullptr);
172 }
173
TEST(PackageParser,InvalidPkgNotSupportedHeaderFormat)174 TEST(PackageParser, InvalidPkgNotSupportedHeaderFormat)
175 {
176 std::vector<uint8_t> fwPkgHdr{
177 0x12, 0x44, 0xD2, 0x64, 0x8D, 0x7D, 0x47, 0x18, 0xA0, 0x30,
178 0xFC, 0x8A, 0x56, 0x58, 0x7D, 0x5B, 0x02, 0x8B, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0C, 0xE5,
180 0x07, 0x00, 0x08, 0x00, 0x01, 0x0E, 0x56, 0x65, 0x72, 0x73,
181 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x31};
182
183 auto parser = parsePkgHeader(fwPkgHdr);
184 EXPECT_EQ(parser, nullptr);
185 }
186
TEST(PackageParser,InvalidPkgBadChecksum)187 TEST(PackageParser, InvalidPkgBadChecksum)
188 {
189 std::vector<uint8_t> fwPkgHdr{
190 0xF0, 0x18, 0x87, 0x8C, 0xCB, 0x7D, 0x49, 0x43, 0x98, 0x00, 0xA0, 0x2F,
191 0x05, 0x9A, 0xCA, 0x02, 0x01, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x19, 0x0C, 0xE5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0E,
193 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69, 0x6E,
194 0x67, 0x31, 0x01, 0x2E, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0E,
195 0x00, 0x00, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74,
196 0x72, 0x69, 0x6E, 0x67, 0x32, 0x02, 0x00, 0x10, 0x00, 0x16, 0x20, 0x23,
197 0xC9, 0x3E, 0xC5, 0x41, 0x15, 0x95, 0xF4, 0x48, 0x70, 0x1D, 0x49, 0xD6,
198 0x75, 0x01, 0x00, 0x0A, 0x00, 0x64, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
199 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01,
200 0x0E, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x53, 0x74, 0x72, 0x69,
201 0x6E, 0x67, 0x33, 0x4F, 0x96, 0xAE, 0x57};
202
203 constexpr uintmax_t pkgSize = 166;
204 constexpr uintmax_t pkgHeaderSize = 139;
205 constexpr uintmax_t pkgImageSize = pkgSize - pkgHeaderSize;
206 std::vector<uint8_t> compImage;
207 imageGenerate(compImage, pkgImageSize);
208 imageInsert(fwPkgHdr, compImage);
209 EXPECT_EQ(parsePkgHeader(fwPkgHdr), nullptr);
210 }
211