blob: 0b71526d8669d45862e165a6b499057ad6b073cf [file] [log] [blame]
// Copyright 2024 Google LLC
//
// 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 "dbus_mock.hpp"
#include "hoth_util.hpp"
#include "hoth_util_impl.hpp"
#include <xyz/openbmc_project/Control/Hoth/error.hpp>
#include <algorithm>
#include <cstdint>
#include <numeric>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace ::testing;
using CommandFailure =
sdbusplus::xyz::openbmc_project::Control::Hoth::Error::CommandFailure;
using ResponseFailure =
sdbusplus::xyz::openbmc_project::Control::Hoth::Error::ResponseFailure;
namespace ipmi_hoth
{
using namespace internal;
class HothUtilTest : public ::testing::Test
{
protected:
HothUtilTest() : hothUtil(std::make_unique<HothUtilImpl>(HothUtilImpl())) {}
std::unique_ptr<HothUtil> hothUtil;
};
TEST_F(HothUtilTest, Checksum)
{
uint8_t header[] = {1, 3, 5, 7};
uint8_t body[] = {2, 4, 6, 8};
// (1 + 3 + 5 + 7) + (2 + 4 + 6 + 8) = 36
EXPECT_EQ(36, HothUtil::calculateChecksum(header, body));
// Now test what happens if the sum exceeds 256.
body[0] = 200;
body[1] = 202;
// (1 + 3 + 5 + 7) + (200 + 202 + 6 + 8) = 432
// 432 % 256 = 176
EXPECT_EQ(176, HothUtil::calculateChecksum(header, body));
}
TEST_F(HothUtilTest, WrapECSKMHSSRequest)
{
std::vector<uint8_t> request(15);
std::generate(request.begin(), request.end(), std::rand);
std::vector<uint8_t> reqBytes;
reqBytes = std::move(hothUtil->wrapECSKMHSSRequest(request));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
}
TEST_F(HothUtilTest, ReadSKMHSS)
{
std::vector<uint8_t> reqBytes;
reqBytes = std::move(hothUtil->readSKMHSS(0));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->readSKMHSS(1));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->readSKMHSS(2));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->readSKMHSS(3));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
}
TEST_F(HothUtilTest, WriteSKMHSS)
{
std::vector<uint8_t> payload(128);
std::vector<uint8_t> reqBytes;
std::generate(payload.begin(), payload.end(), std::rand);
EXPECT_THROW(hothUtil->writeSKMHSS(0, payload), CommandFailure);
EXPECT_TRUE(reqBytes.empty());
payload.resize(64);
reqBytes = std::move(hothUtil->writeSKMHSS(1, payload));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
payload = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 110, 205, 147, 54, 43, 0, 0, 1, 1, 175, 58, 9, 239};
EXPECT_NO_THROW(hothUtil->writeSKMHSS(0, payload));
EXPECT_NO_THROW(hothUtil->writeSKMHSS(1, payload));
EXPECT_NO_THROW(hothUtil->writeSKMHSS(2, payload));
EXPECT_NO_THROW(hothUtil->writeSKMHSS(3, payload));
}
TEST_F(HothUtilTest, DeleteSKMHSS)
{
std::vector<uint8_t> reqBytes;
reqBytes = std::move(hothUtil->deleteSKMHSS(0));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->deleteSKMHSS(1));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->deleteSKMHSS(2));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
reqBytes = std::move(hothUtil->deleteSKMHSS(3));
EXPECT_FALSE(reqBytes.empty());
EXPECT_EQ(0, HothUtil::calculateChecksum(reqBytes));
}
TEST_F(HothUtilTest, PayloadECResponse)
{
std::vector<uint8_t> validRsp = {0x03, 0xfd, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
EXPECT_NO_THROW(hothUtil->payloadECResponse(validRsp));
std::vector<uint8_t> rspShortLength = {0x03, 0xfd};
EXPECT_THROW(hothUtil->payloadECResponse(rspShortLength), ResponseFailure);
std::vector<uint8_t> rspVersionErr = {0x05, 0xfb, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
EXPECT_THROW(hothUtil->payloadECResponse(rspVersionErr), ResponseFailure);
std::vector<uint8_t> rspNonZeroRC = {0x03, 0xfc, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00};
EXPECT_THROW(hothUtil->payloadECResponse(rspNonZeroRC), ResponseFailure);
std::vector<uint8_t> rspExpectedNonZeroRC = {0x03, 0xf4, 0x09, 0x00,
0x00, 0x00, 0x00, 0x00};
EXPECT_NO_THROW(hothUtil->payloadECResponse(rspExpectedNonZeroRC));
std::vector<uint8_t> payload(64);
std::generate(payload.begin(), payload.end(), std::rand);
uint8_t payloadSum =
std::accumulate(std::begin(payload), std::end(payload), 0) % 256;
uint8_t checksum = 0x100 - (0x03 + 0x40 + payloadSum) % 256;
std::vector<uint8_t> validRspWithRandomHss = {0x03, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00};
validRspWithRandomHss[1] = checksum;
validRspWithRandomHss.insert(validRspWithRandomHss.end(), payload.begin(),
payload.end());
auto data = hothUtil->payloadECResponse(validRspWithRandomHss);
EXPECT_EQ(std::vector<uint8_t>(data.begin(), data.end()), payload);
}
} // namespace ipmi_hoth