libpldm: Add decode API for VerifyComplete request

After the component image transfer finishes successfully, the FD
transitions to the VERIFY state and performs a validation check
against the component image that was received. This implementation
works with DSP0267_1.1.0, DSP0267_1.0.1 and DSP0267_1.0.0.

Tested: Unit tests passed

Signed-off-by: gokulsanker <gokul.sanker.v.g@intel.com>
Change-Id: I32630c7035c052c499eb7916ccd5433f45518df1
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index 34cb296..9923920 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -1081,4 +1081,19 @@
 	msg->payload[0] = completion_code;

 

 	return PLDM_SUCCESS;

+}

+

+int decode_verify_complete_req(const struct pldm_msg *msg,

+			       size_t payload_length, uint8_t *verify_result)

+{

+	if (msg == NULL || verify_result == NULL) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

+	if (payload_length != sizeof(*verify_result)) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

+	*verify_result = msg->payload[0];

+	return PLDM_SUCCESS;

 }
\ No newline at end of file
diff --git a/libpldm/firmware_update.h b/libpldm/firmware_update.h
index faca594..3458680 100644
--- a/libpldm/firmware_update.h
+++ b/libpldm/firmware_update.h
@@ -208,6 +208,18 @@
 	PLDM_FWUP_VENDOR_TRANSFER_RESULT_RANGE_MAX = 0x8F

 };

 

+/**@brief VerifyResult values in the response of VerifyComplete

+ */

+enum pldm_firmware_update_verify_result_values {

+	PLDM_FWUP_VERIFY_SUCCESS = 0x00,

+	PLDM_FWUP_VERIFY_ERROR_VERIFICATION_FAILURE = 0x01,

+	PLDM_FWUP_VERIFY_ERROR_VERSION_MISMATCH = 0x02,

+	PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS = 0x03,

+	PLDM_FWUP_VERIFY_ERROR_IMAGE_INCOMPLETE = 0x04,

+	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MIN = 0x90,

+	PLDM_FWUP_VENDOR_VERIFY_RESULT_RANGE_MAX = 0xAF

+};

+

 /** @struct pldm_package_header_information

  *

  *  Structure representing fixed part of package header information

@@ -779,6 +791,18 @@
  */

 int encode_transfer_complete_resp(uint8_t instance_id, uint8_t completion_code,

 				  struct pldm_msg *msg, size_t payload_length);

+

+/** @brief Decode VerifyComplete request message

+ *

+ *  @param[in] msg - Request message

+ *  @param[in] payload_length - Length of request message payload

+ *  @param[in] verify_result - Pointer to hold VerifyResult

+ *

+ *  @return pldm_completion_codes

+ */

+int decode_verify_complete_req(const struct pldm_msg *msg,

+			       size_t payload_length, uint8_t *verify_result);

+

 #ifdef __cplusplus

 }

 #endif

diff --git a/libpldm/tests/libpldm_firmware_update_test.cpp b/libpldm/tests/libpldm_firmware_update_test.cpp
index a276e24..06641bc 100644
--- a/libpldm/tests/libpldm_firmware_update_test.cpp
+++ b/libpldm/tests/libpldm_firmware_update_test.cpp
@@ -2162,3 +2162,44 @@
     rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);

     EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

 }

+

+TEST(VerifyComplete, goodPathDecodeRequest)

+{

+    constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;

+    constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>

+        verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};

+    auto requestMsg1 =

+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());

+    uint8_t outVerifyResult = 0;

+

+    auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),

+                                         &outVerifyResult);

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(outVerifyResult, verifyResult);

+

+    constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>

+        verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};

+    auto requestMsg2 =

+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());

+    rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),

+                                    &outVerifyResult);

+    EXPECT_EQ(rc, PLDM_SUCCESS);

+    EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);

+}

+

+TEST(VerifyComplete, errorPathDecodeRequest)

+{

+    constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};

+    auto requestMsg =

+        reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());

+    uint8_t outVerifyResult = 0;

+

+    auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_verify_complete_req(requestMsg, 0, nullptr);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);

+

+    rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);

+    EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);

+}