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