diff --git a/CMakeLists.txt b/CMakeLists.txt
index 12ad5bc..4aa0f03 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -97,7 +97,7 @@
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 add_library (zinteloemcmds
-             SHARED src/oemcommands.cpp src/sensorcommands.cpp
+             SHARED src/oemcommands.cpp src/sensorcommands.cpp src/biosconfigcommands.cpp
              src/storagecommands.cpp src/multinodecommands.cpp
              src/firmware-update.cpp src/appcommands.cpp src/smbioshandler.cpp
              src/smbiosmdrv2handler.cpp src/manufacturingcommands.cpp
@@ -117,6 +117,9 @@
 target_link_libraries (zinteloemcmds ${OPENSSL_CRYPTO_LIBRARY})
 target_link_libraries (zinteloemcmds gpiodcxx)
 
+find_package (tinyxml2 REQUIRED)
+target_link_libraries (zinteloemcmds tinyxml2)
+
 install (TARGETS zinteloemcmds DESTINATION lib/ipmid-providers)
 option (INTEL_PFR_ENABLED "Intel PFR Enabled" OFF)
 option (BMC_VALIDATION_UNSECURE_FEATURE
diff --git a/include/biosconfigcommands.hpp b/include/biosconfigcommands.hpp
new file mode 100644
index 0000000..253c357
--- /dev/null
+++ b/include/biosconfigcommands.hpp
@@ -0,0 +1,90 @@
+/*
+// Copyright (c) 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#pragma once
+
+#include <array>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <variant>
+#include <vector>
+
+constexpr uint8_t maxPayloadSupported = 0x6;
+constexpr uint8_t maxHashSize = 64;
+constexpr uint8_t maxSeedSize = 16;
+constexpr uint8_t maxPasswordSize = 64;
+
+#pragma pack(push, 1)
+struct PayloadStartTransfer
+{
+    uint16_t payloadVersion;
+    uint32_t payloadTotalSize;
+    uint32_t payloadTotalChecksum;
+    uint8_t payloadFlag;
+};
+#pragma pack(pop)
+
+struct PayloadInProgress
+{
+    uint32_t payloadReservationID;
+    uint32_t payloadOffset;
+    uint32_t payloadCurrentSize;
+    uint32_t payloadCurrentChecksum;
+};
+
+struct PayloadEndTransfer
+{
+    uint32_t payloadReservationID;
+};
+
+struct SetPayloadRetValue
+{
+    uint32_t reservationToken;
+    uint32_t actualPayloadWritten;
+    uint32_t actualTotalPayloadWritten;
+};
+
+struct setBIOSCapabilitiesReq
+{
+    uint8_t OOBCapability;
+    uint8_t reserved1;
+    uint8_t reserved2;
+    uint8_t reserved3;
+};
+
+struct PayloadInfo
+{
+    uint32_t payloadReservationID;
+    uint8_t payloadType;
+    uint16_t payloadVersion;
+    uint32_t payloadTotalSize;
+    uint32_t payloadTotalChecksum;
+    uint8_t payloadStatus;
+    uint8_t payloadflag;
+    uint32_t payloadTimeStamp;
+    uint32_t payloadCurrentSize;
+    uint32_t payloadCurrentChecksum;
+    uint32_t actualTotalPayloadWritten;
+    std::string payloadFilePath;
+};
+
+struct NVOOBdata
+{
+    setBIOSCapabilitiesReq mBIOSCapabilities;
+    uint8_t mIsBIOSCapInitDone;
+    PayloadInfo payloadInfo[maxPayloadSupported];
+};
diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index 8cd8cf9..19d2bca 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -74,6 +74,12 @@
 static constexpr Cmd cmdSetSecurityMode = 0xB4;
 static constexpr Cmd cmdMtmKeepAlive = 0xB5;
 static constexpr Cmd cmdOEMGetReading = 0xE2;
+static constexpr Cmd cmdSetBIOSCap = 0xD3;
+static constexpr Cmd cmdGetBIOSCap = 0xD4;
+static constexpr Cmd cmdSetPayload = 0xD5;
+static constexpr Cmd cmdGetPayload = 0xD6;
+static constexpr Cmd cmdSetBIOSPwdHashInfo = 0xD7;
+static constexpr Cmd cmdGetBIOSPwdHash = 0xD8;
 static constexpr Cmd cmdGetNmiStatus = 0xE5;
 static constexpr Cmd cmdSetEfiBootOptions = 0xEA;
 static constexpr Cmd cmdGetEfiBootOptions = 0xEB;
diff --git a/src/biosconfigcommands.cpp b/src/biosconfigcommands.cpp
new file mode 100644
index 0000000..1c6d060
--- /dev/null
+++ b/src/biosconfigcommands.cpp
@@ -0,0 +1,902 @@
+/*
+// Copyright (c) 2020 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <openssl/sha.h>
+#include <tinyxml2.h>
+
+#include <biosconfigcommands.hpp>
+#include <boost/crc.hpp>
+#include <boost/process/child.hpp>
+#include <boost/process/io.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
+#include <ipmid/message/types.hpp>
+#include <ipmid/types.hpp>
+#include <ipmid/utils.hpp>
+#include <nlohmann/json.hpp>
+#include <oemcommands.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message/types.hpp>
+
+#include <filesystem>
+
+namespace ipmi
+{
+static void registerBIOSConfigFunctions() __attribute__((constructor));
+
+// Define BIOS config related Completion Code
+using Cc = uint8_t;
+static constexpr Cc ipmiCCPayloadPayloadPacketMissed = 0x80;
+static constexpr Cc ipmiCCBIOSPasswordInitNotDone = 0x80;
+static constexpr Cc ipmiCCPayloadChecksumFailed = 0x81;
+static constexpr Cc ipmiCCNotSupportedInCurrentState = 0x82;
+static constexpr Cc ipmiCCPayloadPayloadInComplete = 0x83;
+static constexpr Cc ipmiCCBIOSCapabilityInitNotDone = 0x85;
+static constexpr Cc ipmiCCPayloadLengthIllegal = 0x85;
+
+static constexpr uint8_t userPasswordChanged = (1 << 5);
+static constexpr uint8_t adminPasswordChanged = (1 << 4);
+
+static constexpr const char* biosConfigFolder = "/var/oob";
+static constexpr const char* biosConfigNVPath = "/var/oob/nvoobdata.dat";
+static constexpr const uint8_t algoSHA384 = 2;
+static constexpr const uint8_t biosCapOffsetBit = 0x3;
+static constexpr uint16_t maxGetPayloadDataSize = 4096;
+static constexpr const char* biosXMLFilePath = "/var/oob/bios.xml";
+static constexpr const char* biosXMLFilePath1 = "/var/oob/tempbios.xml";
+
+static constexpr const char* biosConfigBaseMgrPath =
+    "/xyz/openbmc_project/bios_config/manager";
+static constexpr const char* biosConfigIntf =
+    "xyz.openbmc_project.BIOSConfig.Manager";
+static constexpr const char* resetBIOSSettingsProp = "ResetBIOSSettings";
+/*baseBIOSTable
+map{attributeName,struct{attributeType,readonlyStatus,displayname,
+              description,menuPath,current,default,
+              array{struct{optionstring,optionvalue}}}}
+*/
+std::map<std::string,
+         std::tuple<std::string, bool, std::string, std::string, std::string,
+                    std::variant<int64_t, std::string>,
+                    std::variant<int64_t, std::string>,
+                    std::map<std::string, std::variant<int64_t, std::string>>>>
+    AttributesData;
+
+NVOOBdata gNVOOBdata;
+
+enum class PTState : uint8_t
+{
+    StartTransfer = 0,
+    InProgress = 1,
+    EndTransfer = 2,
+    UserAbort = 3
+};
+enum class PStatus : uint8_t
+{
+    Unknown = 0,
+    Valid = 1,
+    Corrupted = 2
+};
+enum class PType : uint8_t
+{
+    IntelXMLType0 = 0,
+    IntelXMLType1 = 1,
+    OTAPayload = 5,
+};
+
+//
+// GetPayload Payload status enumeration
+//
+enum class GetPayloadParameter : uint8_t
+{
+    GetPayloadInfo = 0, // 0
+    GetPayloadData = 1, // 1
+    GetPayloadStatus = 2
+};
+
+/** @brief implement to set the BaseBIOSTable property
+ *  @returns status
+ */
+static int sendAllAttributes(ipmi::Context::ptr ctx)
+{
+    boost::system::error_code ec;
+    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+    std::string service =
+        getService(*dbus, biosConfigIntf, biosConfigBaseMgrPath);
+    ec.clear();
+    ctx->bus->yield_method_call<>(
+        ctx->yield, ec, service, biosConfigBaseMgrPath,
+        "org.freedesktop.DBus.Properties", "Set", biosConfigIntf,
+        "BaseBIOSTable", AttributesData);
+    if (ec)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Failed to sendAllAttributes");
+        return -1;
+    }
+    return 0;
+}
+
+/** @brief implement to flush the updated data in nv space
+ *  @returns status
+ */
+static uint8_t flushNVOOBdata()
+{
+    std::ofstream outFile(biosConfigNVPath, std::ios::binary | std::ios::app);
+    if (outFile.good())
+    {
+        outFile.seekp(std::ios_base::beg);
+        const char* writedata = reinterpret_cast<const char*>(&gNVOOBdata);
+        outFile.write(writedata, sizeof(struct NVOOBdata));
+        outFile.close();
+    }
+    return 0;
+}
+
+/** @brief implement to get the System State
+ *  @returns status
+ */
+
+static int getSystemOSState(std::string& OsStatus)
+{
+
+    try
+    {
+        std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+        Value variant =
+            getDbusProperty(*dbus, "xyz.openbmc_project.State.OperatingSystem",
+                            "/xyz/openbmc_project/state/os",
+                            "xyz.openbmc_project.State.OperatingSystem.Status",
+                            "OperatingSystemState");
+        OsStatus = std::get<std::string>(variant);
+        return ipmi::ccSuccess;
+    }
+    catch (const std::exception& e)
+    {
+        return ipmi::ccUnspecifiedError;
+    }
+}
+
+/** @brief implement to get the Rest BIOS property
+ *  @returns status
+ */
+static int getResetBIOSSettings(uint8_t& ResetFlag)
+{
+
+    try
+    {
+        std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+        std::string service =
+            getService(*dbus, biosConfigIntf, biosConfigBaseMgrPath);
+        Value variant = getDbusProperty(*dbus, service, biosConfigBaseMgrPath,
+                                        biosConfigIntf, resetBIOSSettingsProp);
+        ResetFlag = static_cast<uint8_t>(std::get<std::uint8_t>(variant));
+        return ipmi::ccSuccess;
+    }
+    catch (const std::exception& e)
+    {
+        return ipmi::ccUnspecifiedError;
+    }
+}
+
+/** @brief implement generate naive- dbus from XML file
+ *  @returns status
+ */
+static int generateAttributesData()
+{
+    // Open the bios.xml and parse it
+    // Extract the needed data and store it in AttributesData variable
+    // Close the bios.xml
+    phosphor::logging::log<phosphor::logging::level::ERR>(
+        "generateAttributesData");
+    tinyxml2::XMLDocument xmlDoc;
+
+    xmlDoc.LoadFile(biosXMLFilePath);
+    tinyxml2::XMLNode* pRoot = xmlDoc.FirstChild();
+    if (pRoot == nullptr)
+    {
+        return 0;
+    }
+    tinyxml2::XMLElement* pElement = pRoot->FirstChildElement("biosknobs");
+    if (pElement == nullptr)
+    {
+        return 0;
+    }
+    tinyxml2::XMLElement* pKnobsElement = pElement->FirstChildElement("knob");
+
+    while (pKnobsElement != nullptr)
+    {
+        bool readOnlyStatus = false;
+        std::string attrType =
+            "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String";
+        std::string name, curvalue, dname, menupath, defaultvalue, description;
+        name = pKnobsElement->Attribute("name")
+                   ? pKnobsElement->Attribute("name")
+                   : "";
+        curvalue = pKnobsElement->Attribute("CurrentVal")
+                       ? pKnobsElement->Attribute("CurrentVal")
+                       : "";
+        dname = pKnobsElement->Attribute("prompt")
+                    ? pKnobsElement->Attribute("prompt")
+                    : "";
+        menupath = pKnobsElement->Attribute("SetupPgPtr")
+                       ? pKnobsElement->Attribute("SetupPgPtr")
+                       : "";
+        defaultvalue = pKnobsElement->Attribute("default")
+                           ? pKnobsElement->Attribute("default")
+                           : "";
+        description = pKnobsElement->Attribute("description")
+                          ? pKnobsElement->Attribute("description")
+                          : "";
+        phosphor::logging::log<phosphor::logging::level::INFO>(name.c_str());
+        if (!name.empty() && !curvalue.empty() && !dname.empty() &&
+            !menupath.empty() && !defaultvalue.empty())
+        {
+            std::string rootPath = "./" + std::string(menupath);
+
+            std::map<std::string, std::variant<int64_t, std::string>> optionMap;
+            tinyxml2::XMLElement* pOptionsElement =
+                pKnobsElement->FirstChildElement("options");
+            nlohmann::json optionsArray = nlohmann::json::array();
+            if (pOptionsElement != nullptr)
+            {
+                tinyxml2::XMLElement* pOptionElement =
+                    pOptionsElement->FirstChildElement("option");
+                while (pOptionElement != nullptr)
+                {
+                    const std::string text = pOptionElement->Attribute("text");
+                    const std::string attrValue =
+                        pOptionElement->Attribute("value");
+                    if (!text.empty() && !attrValue.empty())
+                    {
+
+                        optionMap.emplace(std::make_pair(std::move(text),
+                                                         std::move(attrValue)));
+                    }
+                    pOptionElement =
+                        pOptionElement->NextSiblingElement("option");
+                }
+            }
+
+            AttributesData.emplace(std::make_pair(
+                name,
+                std::make_tuple(attrType, readOnlyStatus, dname, description,
+                                rootPath, curvalue, defaultvalue, optionMap)));
+        }
+        pKnobsElement = pKnobsElement->NextSiblingElement("knob");
+    }
+
+    return 0;
+}
+
+/** @brief implement executing the linux command to uncompress and generate the
+ * xmlfile
+ *  @param[in] linux command
+ *  @returns status
+ */
+template <typename... ArgTypes>
+static int generateBIOSXMLFile(const char* path, ArgTypes&&... tArgs)
+{
+
+    boost::process::child execProg(path, const_cast<char*>(tArgs)...,
+                                   boost::process::std_out > biosXMLFilePath);
+    execProg.wait();
+    return execProg.exit_code();
+}
+
+/** @brief implements to clean up the temp/ existing payload file
+ **/
+static void cleanUpPayloadFile(uint8_t& payloadType)
+{
+    // Clear the payload Information
+    std::string FilePath = "/var/oob/temp" + std::to_string(payloadType);
+    unlink(FilePath.c_str());
+    FilePath = "/var/oob/Payload" + std::to_string(payloadType);
+    unlink(FilePath.c_str());
+    if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
+    {
+        unlink("/var/oob/Payload1");
+        gNVOOBdata.payloadInfo[static_cast<uint8_t>(ipmi::PType::IntelXMLType1)]
+            .payloadStatus = static_cast<uint8_t>(ipmi::PStatus::Unknown);
+    }
+}
+
+/** @brief implements to create the oob folders and nv space
+ **/
+static Cc InitNVOOBdata()
+{
+    FILE* fptr;
+    uint16_t size;
+
+    if (!(std::filesystem::exists(biosConfigFolder)))
+    {
+        std::filesystem::create_directory(biosConfigFolder);
+    }
+
+    std::ifstream ifs(biosConfigNVPath,
+                      std::ios::in | std::ios::binary | std::ios::ate);
+
+    if (ifs.good())
+    {
+
+        ifs.read(reinterpret_cast<char*>(&gNVOOBdata),
+                 sizeof(struct NVOOBdata));
+        ifs.close();
+        return ipmi::ccSuccess;
+    }
+    return ipmi::ccResponseError;
+}
+
+/** @brief implements check the command interface is
+ ** system interface or not
+ **  true mean System interface and false mean LAN or IPMB
+ **/
+static bool IsSystemInterface(ipmi::Context::ptr ctx)
+{
+    ChannelInfo chInfo;
+    Cc status = false;
+
+    try
+    {
+        getChannelInfo(ctx->channel, chInfo);
+    }
+    catch (sdbusplus::exception_t& e)
+    {
+        return false;
+    }
+    if (chInfo.mediumType !=
+        static_cast<uint8_t>(EChannelMediumType::systemInterface))
+    {
+        return false;
+    }
+    return true;
+}
+
+ipmi::RspType<> ipmiOEMSetBIOSCap(ipmi::Context::ptr ctx,
+                                  uint8_t BIOSCapabilties, uint8_t reserved1,
+                                  uint8_t reserved2, uint8_t reserved3)
+{
+    std::string OSState;
+    getSystemOSState(OSState);
+
+    if (OSState != "OperatingState" && IsSystemInterface(ctx))
+    {
+        if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0)
+        {
+            return ipmi::responseInvalidFieldRequest();
+        }
+
+        gNVOOBdata.mBIOSCapabilities.OOBCapability = BIOSCapabilties;
+        gNVOOBdata.mIsBIOSCapInitDone = true;
+
+        flushNVOOBdata();
+        return ipmi::responseSuccess();
+    }
+    else
+    {
+
+        return ipmi::response(ipmiCCNotSupportedInCurrentState);
+    }
+}
+
+ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t>
+    ipmiOEMGetBIOSCap(ipmi::Context::ptr ctx)
+{
+    if (gNVOOBdata.mIsBIOSCapInitDone)
+    {
+        return ipmi::responseSuccess(gNVOOBdata.mBIOSCapabilities.OOBCapability,
+                                     0, 0, 0);
+    }
+    else
+    {
+        return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
+    }
+}
+
+ipmi::RspType<uint32_t> ipmiOEMSetPayload(ipmi::Context::ptr ctx,
+                                          uint8_t paramSel, uint8_t payloadType,
+                                          std::vector<uint8_t> payload)
+{
+    uint8_t biosCapOffsetBit = 2; // BIT:1 0-OOB BIOS config not supported
+                                  //      1-OOB BIOS config is supported
+
+    if (!(gNVOOBdata.mBIOSCapabilities.OOBCapability & (biosCapOffsetBit)))
+    {
+        return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
+    }
+    // Validate the Payload Type
+    if (payloadType > maxPayloadSupported)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    // We should support this Payload type 0 command only in KCS Interface
+    if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
+    {
+        std::string OSState;
+
+        getSystemOSState(OSState);
+        if (!IsSystemInterface(ctx) || OSState == "OperatingState")
+        {
+            return ipmi::responseCommandNotAvailable();
+        }
+    }
+
+    switch (static_cast<PTState>(paramSel))
+    {
+        case ipmi::PTState::StartTransfer:
+        {
+            PayloadStartTransfer* pPayloadStartTransfer =
+                reinterpret_cast<PayloadStartTransfer*>(payload.data());
+            if (payload.size() < sizeof(PayloadStartTransfer))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "ipmiOEMSetPayload: BIOS Config Payload size is not "
+                    "correct");
+                return ipmi::responseReqDataLenInvalid();
+            }
+            cleanUpPayloadFile(payloadType);
+
+            gNVOOBdata.payloadInfo[payloadType].payloadReservationID = rand();
+            gNVOOBdata.payloadInfo[payloadType].payloadTotalChecksum =
+                pPayloadStartTransfer->payloadTotalChecksum;
+            gNVOOBdata.payloadInfo[payloadType].payloadTotalSize =
+                pPayloadStartTransfer->payloadTotalSize;
+            gNVOOBdata.payloadInfo[payloadType].payloadVersion =
+                pPayloadStartTransfer->payloadVersion;
+            gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten = 0;
+            gNVOOBdata.payloadInfo[payloadType].payloadStatus =
+                static_cast<uint8_t>(ipmi::PStatus::Unknown);
+
+            return ipmi::responseSuccess(
+                gNVOOBdata.payloadInfo[payloadType].payloadReservationID);
+        }
+        break;
+
+        case ipmi::PTState::InProgress:
+        {
+            PayloadInProgress* pPayloadInProgress =
+                reinterpret_cast<PayloadInProgress*>(payload.data());
+            PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
+
+            if (payload.size() < sizeof(PayloadInProgress))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "BIOS Config Payload size is not correct");
+                return ipmi::responseReqDataLenInvalid();
+            }
+
+            if (pPayloadInProgress->payloadReservationID !=
+                payloadInfo.payloadReservationID)
+            {
+                return ipmi::responseInvalidReservationId();
+            }
+            payloadInfo.payloadCurrentSize =
+                pPayloadInProgress->payloadCurrentSize;
+            // Need to verify the current Payload Checksum
+            const uint8_t* data =
+                reinterpret_cast<const uint8_t*>(payload.data());
+            // we have to remove the current size, current offset, current
+            // length,checksum bytes , reservation bytes
+            boost::crc_32_type calcChecksum;
+            calcChecksum.process_bytes(data + 16, payload.size() - 16);
+            if (calcChecksum.checksum() !=
+                pPayloadInProgress->payloadCurrentChecksum)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "ipmiOEMSetPayload: Payload Checksum Failed");
+                return ipmi::response(ipmiCCPayloadChecksumFailed);
+            }
+            // store the data in temp file
+            std::string FilePath =
+                "/var/oob/temp" + std::to_string(payloadType);
+
+            std::ofstream outFile(FilePath, std::ios::binary | std::ios::app);
+            outFile.seekp(pPayloadInProgress->payloadOffset);
+            // we have to remove the current size, current offset, current
+            // length,checksum bytes , reservation bytes
+
+            const char* writedata =
+                reinterpret_cast<const char*>(payload.data());
+            outFile.write(writedata + 16, payload.size() - 16);
+            outFile.close();
+
+            gNVOOBdata.payloadInfo[payloadType].payloadStatus =
+                static_cast<uint8_t>(ipmi::PStatus::Unknown);
+            gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten +=
+                payloadInfo.payloadCurrentSize;
+            return ipmi::responseSuccess(payloadInfo.payloadCurrentSize);
+        }
+        break;
+        case ipmi::PTState::EndTransfer:
+        {
+            PayloadEndTransfer* pPayloadEndTransfer =
+                reinterpret_cast<PayloadEndTransfer*>(payload.data());
+            PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
+            if (pPayloadEndTransfer->payloadReservationID !=
+                payloadInfo.payloadReservationID)
+            {
+                return ipmi::responseInvalidReservationId();
+            }
+            gNVOOBdata.payloadInfo[payloadType].payloadStatus =
+                static_cast<uint8_t>(ipmi::PStatus::Unknown);
+
+            if (gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten !=
+                gNVOOBdata.payloadInfo[payloadType].payloadTotalSize)
+            {
+
+                return ipmi::response(ipmiCCPayloadPayloadInComplete);
+            }
+            std::string tempFilePath =
+                "/var/oob/temp" + std::to_string(payloadType);
+            std::string PayloadFilePath =
+                "/var/oob/Payload" + std::to_string(payloadType);
+            auto renamestatus =
+                std::rename(tempFilePath.c_str(), PayloadFilePath.c_str());
+            if (renamestatus)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "ipmiOEMSetPayload: Renaming Payload file - failed");
+            }
+
+            gNVOOBdata.payloadInfo[payloadType].payloadFilePath =
+                PayloadFilePath;
+            if (payloadType == static_cast<uint8_t>(ipmi::PType::IntelXMLType0))
+            {
+                // Unzip the Intel format XML file type 0
+                auto response = generateBIOSXMLFile("/usr/bin/lzcat", "-d",
+                                                    PayloadFilePath.c_str());
+                if (response)
+                {
+
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "ipmiOEMSetPayload: generateBIOSXMLFile - failed");
+                    gNVOOBdata.payloadInfo[payloadType].payloadStatus =
+                        static_cast<uint8_t>(ipmi::PStatus::Corrupted);
+                    return ipmi::response(ipmiCCPayloadPayloadPacketMissed);
+                }
+            }
+            gNVOOBdata.payloadInfo[payloadType].payloadStatus =
+                static_cast<uint8_t>(ipmi::PStatus::Valid);
+
+            struct stat filestat;
+
+            /* Get entry's information. */
+            if (!stat(PayloadFilePath.c_str(), &filestat))
+            {
+                gNVOOBdata.payloadInfo[payloadType].payloadTimeStamp =
+                    filestat.st_mtime;
+                gNVOOBdata.payloadInfo[payloadType].payloadTotalSize =
+                    filestat.st_size;
+                gNVOOBdata.payloadInfo[payloadType].payloadFilePath =
+                    PayloadFilePath;
+            }
+            else
+            {
+                return ipmi::responseResponseError();
+            }
+
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                " ipmiOEMSetPayload : Convert XML into native-dbus DONE");
+            generateAttributesData();
+
+            phosphor::logging::log<phosphor::logging::level::INFO>(
+                " ipmiOEMSetPayload : BaseBIOSTable Property  is set");
+            sendAllAttributes(ctx);
+
+            flushNVOOBdata();
+            return ipmi::responseSuccess(
+                gNVOOBdata.payloadInfo[payloadType].actualTotalPayloadWritten);
+        }
+        break;
+        case ipmi::PTState::UserAbort:
+        {
+            PayloadEndTransfer* pPayloadEndTransfer =
+                reinterpret_cast<PayloadEndTransfer*>(payload.data());
+            PayloadInfo payloadInfo = gNVOOBdata.payloadInfo[payloadType];
+            if (pPayloadEndTransfer->payloadReservationID !=
+                payloadInfo.payloadReservationID)
+            {
+                return ipmi::responseInvalidReservationId();
+            }
+            gNVOOBdata.payloadInfo[payloadType].payloadReservationID = 0;
+            gNVOOBdata.payloadInfo[payloadType].payloadType = 0;
+            gNVOOBdata.payloadInfo[payloadType].payloadTotalSize = 0;
+            // Delete the temp file
+            std::string tempFilePath =
+                "/var/oob/temp" + std::to_string(payloadType);
+            unlink(tempFilePath.c_str());
+            flushNVOOBdata();
+            return ipmi::responseSuccess();
+        }
+        break;
+        default:
+            return ipmi::responseInvalidFieldRequest();
+    }
+    return ipmi::responseResponseError();
+}
+
+ipmi::RspType<message::Payload>
+    ipmiOEMGetPayload(ipmi::Context::ptr ctx, uint8_t paramSel,
+                      uint8_t payloadType, ipmi::message::Payload& payload)
+{
+    //      1-OOB BIOS config is supported
+    message::Payload retValue;
+
+    if (!(gNVOOBdata.mBIOSCapabilities.OOBCapability & (biosCapOffsetBit)))
+    {
+        return ipmi::response(ipmiCCBIOSCapabilityInitNotDone);
+    }
+    // Validate the Payload Type
+    if (payloadType > maxPayloadSupported)
+    {
+        return ipmi::responseInvalidFieldRequest();
+    }
+
+    struct PayloadInfo res = gNVOOBdata.payloadInfo[payloadType];
+
+    switch (static_cast<GetPayloadParameter>(paramSel))
+    {
+        case ipmi::GetPayloadParameter::GetPayloadInfo:
+        {
+            retValue.pack(res.payloadVersion);
+            retValue.pack(res.payloadType);
+            retValue.pack(res.payloadTotalSize);
+            retValue.pack(res.payloadTotalChecksum);
+            retValue.pack(res.payloadflag);
+            retValue.pack(res.payloadStatus);
+            retValue.pack(res.payloadTimeStamp);
+
+            return ipmi::responseSuccess(std::move(retValue));
+        }
+
+        break;
+        case ipmi::GetPayloadParameter::GetPayloadData:
+        {
+            if (res.payloadStatus ==
+                (static_cast<uint8_t>(ipmi::PStatus::Valid)))
+            {
+                std::vector<uint32_t> reqData;
+                if (payload.unpack(reqData) || !payload.fullyUnpacked())
+                {
+                    return ipmi::responseReqDataLenInvalid();
+                }
+                uint32_t offset = reqData.at(0);
+                uint32_t length = reqData.at(1);
+
+                std::ifstream ifs(res.payloadFilePath, std::ios::in |
+                                                           std::ios::binary |
+                                                           std::ios::ate);
+                std::ifstream::pos_type fileSize = ifs.tellg();
+                // Total file data within given offset
+                if (fileSize < static_cast<uint64_t>(offset))
+                {
+                    ifs.close();
+                    return ipmi::responseInvalidFieldRequest();
+                }
+
+                ifs.seekg(offset, std::ios::beg);
+                std::array<uint8_t, maxGetPayloadDataSize> Buffer;
+                ifs.read(reinterpret_cast<char*>(Buffer.data()), length);
+                uint32_t readCount = ifs.gcount();
+                ifs.close();
+
+                boost::crc_32_type calcChecksum;
+                calcChecksum.process_bytes(
+                    reinterpret_cast<char*>(Buffer.data()), readCount);
+                uint32_t chkSum = calcChecksum.checksum();
+                retValue.pack(payloadType);
+                retValue.pack(readCount);
+                retValue.pack(chkSum);
+
+                for (int i = 0; i < readCount; i++)
+                {
+                    retValue.pack(Buffer.at(i));
+                }
+                return ipmi::responseSuccess(std::move(retValue));
+            }
+            else
+            {
+                return ipmi::responseResponseError();
+            }
+        }
+        break;
+        case ipmi::GetPayloadParameter::GetPayloadStatus:
+        {
+            retValue.pack(gNVOOBdata.payloadInfo[payloadType].payloadStatus);
+            return ipmi::responseSuccess(std::move(retValue));
+        }
+        break;
+        default:
+            return ipmi::responseInvalidFieldRequest();
+    }
+    return ipmi::responseInvalidFieldRequest();
+}
+
+ipmi::RspType<> ipmiOEMSetBIOSHashInfo(
+    ipmi::Context::ptr ctx, std::array<uint8_t, maxSeedSize>& pwdSeed,
+    uint8_t algoInfo, std::array<uint8_t, maxHashSize>& adminPwdHash,
+    std::array<uint8_t, maxHashSize>& userPwdHash)
+{
+
+    std::string OSState;
+
+    // We should support this command only in KCS Interface
+    if (!IsSystemInterface(ctx))
+    {
+        return ipmi::responseCommandNotAvailable();
+    }
+    getSystemOSState(OSState);
+    // We should not support this command after System Booted - After Exit Boot
+    // service called
+
+    if (OSState != "OperatingState")
+    {
+
+        if (algoInfo != algoSHA384)
+        {
+            // Atpresent, we are supporting only SHA384- HASH algo in BIOS side
+            return ipmi::responseInvalidFieldRequest();
+        }
+        std::string HashFilePath = "/var/lib/bios-settings-manager/seedData";
+
+        nlohmann::json json;
+        json["Seed"] = pwdSeed;
+        json["HashAlgo"] = "SHA384";
+        json["IsAdminPwdChanged"] = false;
+        json["AdminPwdHash"] = adminPwdHash;
+        json["IsUserPwdChanged"] = false;
+        json["UserPwdHash"] = userPwdHash;
+        std::ofstream ofs(HashFilePath, std::ios::out);
+        const auto& writeData = json.dump();
+        ofs << writeData;
+        ofs.close();
+        return ipmi::responseSuccess();
+    }
+    else
+    {
+
+        return ipmi::response(ipmiCCNotSupportedInCurrentState);
+    }
+}
+
+ipmi::RspType<uint8_t, std::array<uint8_t, maxHashSize>,
+              std::array<uint8_t, maxHashSize>>
+    ipmiOEMGetBIOSHash(ipmi::Context::ptr ctx)
+{
+
+    std::string OSState;
+    nlohmann::json data = nullptr;
+
+    // We should support this command only in KCS Interface
+    if (!IsSystemInterface(ctx))
+    {
+        return ipmi::responseCommandNotAvailable();
+    }
+
+    getSystemOSState(OSState);
+    // We should not support this command after System Booted - After Exit Boot
+    // service called
+
+    if (OSState != "OperatingState")
+    {
+        std::string HashFilePath =
+            "/var/lib/bios-settings-manager/passwordData";
+
+        std::ifstream devIdFile(HashFilePath);
+        if (devIdFile.is_open())
+        {
+
+            try
+            {
+                data = nlohmann::json::parse(devIdFile, nullptr, false);
+            }
+            catch (const nlohmann::json::parse_error& e)
+            {
+                return ipmi::responseResponseError();
+            }
+
+            if (data.is_discarded())
+            {
+                return ipmi::responseResponseError();
+            }
+
+            std::array<uint8_t, maxHashSize> newAdminHash;
+            std::array<uint8_t, maxHashSize> newUserHash;
+            uint8_t flag = 0;
+            uint8_t adminPwdChangedFlag = 0;
+            uint8_t userPwdChangedFlag = 0;
+            if (!data.is_discarded())
+            {
+
+                adminPwdChangedFlag = data["IsAdminPwdChanged"];
+                newAdminHash = data["AdminPwdHash"];
+                newUserHash = data["UserPwdHash"];
+                userPwdChangedFlag = data["IsUserPwdChanged"];
+            }
+
+            // 0: BIT 4 - New Admin Password Not Present
+            // 1: BIT 4 - New Admin Password Hash Present
+            // 0: BIT 5 - New User Password Not Present
+            // 1: BIT 5 - New User Password Hash Present
+            // 0: BIT 0 - Default Setting flag is not set
+            // 1: BIT 0 - Default Setting flag is set
+            auto status = getResetBIOSSettings(flag);
+            if (status)
+            {
+                return ipmi::responseResponseError();
+            }
+            if (adminPwdChangedFlag)
+            {
+                flag |= adminPasswordChanged;
+            }
+            if (userPwdChangedFlag)
+            {
+                flag |= userPasswordChanged;
+            }
+
+            std::copy(std::begin(newAdminHash), std::end(newAdminHash),
+                      std::begin(newAdminHash));
+            std::copy(std::begin(newUserHash), std::end(newUserHash),
+                      std::begin(newUserHash));
+            return ipmi::responseSuccess(flag, newAdminHash, newUserHash);
+        }
+        else
+        {
+            return ipmi::responseResponseError();
+        }
+    }
+    else
+    {
+
+        return ipmi::response(ipmiCCNotSupportedInCurrentState);
+    }
+}
+
+static void registerBIOSConfigFunctions(void)
+{
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "BIOSConfig module initialization");
+    InitNVOOBdata();
+
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdSetBIOSCap, Privilege::Admin,
+                    ipmiOEMSetBIOSCap);
+
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdGetBIOSCap, Privilege::User,
+                    ipmiOEMGetBIOSCap);
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdSetBIOSPwdHashInfo, Privilege::Admin,
+                    ipmiOEMSetBIOSHashInfo);
+
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdGetBIOSPwdHash, Privilege::User,
+                    ipmiOEMGetBIOSHash);
+
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdGetPayload, Privilege::User,
+                    ipmiOEMGetPayload);
+    registerHandler(prioOemBase, intel::netFnGeneral,
+                    intel::general::cmdSetPayload, Privilege::Admin,
+                    ipmiOEMSetPayload);
+
+    return;
+}
+
+} // namespace ipmi
