libpldm: Add API to decode package header info
This patch provides API to decode the firmware update package header
information and also do basic validation.
The API works with DSP0267_1.1.0, DSP0267_1.0.1 and DSP0267_1.0.0.
Tested: Unit tests passed
Signed-off-by: Tom Joseph <rushtotom@gmail.com>
Change-Id: I208a219cd4b9c9b9869eb3e286259b2f51206487
diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index f87fd5b..8f8775c 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -8,6 +8,142 @@
constexpr auto hdrSize = sizeof(pldm_msg_hdr);
+TEST(DecodePackageHeaderInfo, goodPath)
+{
+ // Package header identifier for Version 1.0.x
+ constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43,
+ 0x98, 0x00, 0xa0, 0x2F, 0x05, 0x9a, 0xca, 0x02};
+ // Package header version for DSP0267 version 1.0.x
+ constexpr uint8_t pkgHeaderFormatRevision = 0x01;
+ // Random PackageHeaderSize
+ constexpr uint16_t pkgHeaderSize = 303;
+ // PackageReleaseDateTime - "25/12/2021 00:00:00"
+ std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> timestamp104{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
+ constexpr uint16_t componentBitmapBitLength = 8;
+ // PackageVersionString
+ constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
+ constexpr size_t packagerHeaderSize =
+ sizeof(pldm_package_header_information) + packageVersionStr.size();
+
+ constexpr std::array<uint8_t, packagerHeaderSize> packagerHeaderInfo{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2F,
+ 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
+ 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+ pldm_package_header_information pkgHeader{};
+ variable_field packageVersion{};
+
+ auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
+ packagerHeaderInfo.size(),
+ &pkgHeader, &packageVersion);
+
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(true,
+ std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
+ uuid.begin(), uuid.end()));
+ EXPECT_EQ(pkgHeader.package_header_format_version, pkgHeaderFormatRevision);
+ EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
+ EXPECT_EQ(true, std::equal(pkgHeader.timestamp104,
+ pkgHeader.timestamp104 + PLDM_TIMESTAMP104_SIZE,
+ timestamp104.begin(), timestamp104.end()));
+ EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
+ EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
+ EXPECT_EQ(pkgHeader.package_version_string_length,
+ packageVersionStr.size());
+ std::string packageVersionString(
+ reinterpret_cast<const char*>(packageVersion.ptr),
+ packageVersion.length);
+ EXPECT_EQ(packageVersionString, packageVersionStr);
+}
+
+TEST(DecodePackageHeaderInfo, errorPaths)
+{
+ int rc = 0;
+ constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
+ constexpr size_t packagerHeaderSize =
+ sizeof(pldm_package_header_information) + packageVersionStr.size();
+
+ // Invalid Package Version String Type - 0x06
+ constexpr std::array<uint8_t, packagerHeaderSize>
+ invalidPackagerHeaderInfo1{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+ 0xa0, 0x2F, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+ 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+ 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+
+ pldm_package_header_information packageHeader{};
+ variable_field packageVersion{};
+
+ rc = decode_pldm_package_header_info(nullptr,
+ invalidPackagerHeaderInfo1.size(),
+ &packageHeader, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+ invalidPackagerHeaderInfo1.size(),
+ nullptr, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+ invalidPackagerHeaderInfo1.size(),
+ &packageHeader, nullptr);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ rc = decode_pldm_package_header_info(
+ invalidPackagerHeaderInfo1.data(),
+ sizeof(pldm_package_header_information) - 1, &packageHeader,
+ &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo1.data(),
+ invalidPackagerHeaderInfo1.size(),
+ &packageHeader, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ // Invalid Package Version String Length - 0x00
+ constexpr std::array<uint8_t, packagerHeaderSize>
+ invalidPackagerHeaderInfo2{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+ 0xa0, 0x2F, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+ 0x07, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+ 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo2.data(),
+ invalidPackagerHeaderInfo2.size(),
+ &packageHeader, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ // Package version string length less than in the header information
+ constexpr std::array<uint8_t, packagerHeaderSize - 1>
+ invalidPackagerHeaderInfo3{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+ 0xa0, 0x2F, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+ 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+ 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo3.data(),
+ invalidPackagerHeaderInfo3.size(),
+ &packageHeader, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+ // ComponentBitmapBitLength not a multiple of 8
+ constexpr std::array<uint8_t, packagerHeaderSize>
+ invalidPackagerHeaderInfo4{
+ 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
+ 0xa0, 0x2F, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
+ 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
+ 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
+ rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo4.data(),
+ invalidPackagerHeaderInfo4.size(),
+ &packageHeader, &packageVersion);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+}
+
TEST(DecodeDescriptors, goodPath3Descriptors)
{
// In the descriptor data there are 3 descriptor entries