blob: 7212f0c2366fd651ebe46242d78914f3ef5c40ed [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/silicon_creator/rom/boot_policy.h"
#include "gtest/gtest.h"
#include "sw/device/silicon_creator/lib/base/chip.h"
#include "sw/device/silicon_creator/lib/mock_manifest.h"
#include "sw/device/silicon_creator/lib/mock_shutdown.h"
#include "sw/device/silicon_creator/rom/mock_boot_policy_ptrs.h"
#include "sw/device/silicon_creator/testing/rom_test.h"
namespace manifest_unittest {
namespace {
using ::testing::Return;
class BootPolicyTest : public rom_test::RomTest {
protected:
rom_test::MockBootPolicyPtrs boot_policy_ptrs_;
rom_test::MockManifest mock_manifest_;
};
class ManifestCheckLengthTest : public BootPolicyTest,
public testing::WithParamInterface<uint32_t> {};
TEST_P(ManifestCheckLengthTest, ManifestCheckGood) {
manifest_t manifest{};
manifest.identifier = CHIP_ROM_EXT_IDENTIFIER;
manifest.length = GetParam();
boot_data_t boot_data{};
EXPECT_CALL(mock_manifest_, Check(&manifest)).WillOnce(Return(kErrorOk));
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data), kErrorOk);
}
INSTANTIATE_TEST_SUITE_P(GoodLengths, ManifestCheckLengthTest,
testing::Values(CHIP_ROM_EXT_SIZE_MIN,
CHIP_ROM_EXT_SIZE_MAX >> 1,
CHIP_ROM_EXT_SIZE_MAX));
TEST_F(BootPolicyTest, ManifestCheckBadIdentifier) {
manifest_t manifest{};
boot_data_t boot_data{};
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data),
kErrorBootPolicyBadIdentifier);
}
TEST_F(BootPolicyTest, ManifestCheckBadLength) {
manifest_t manifest{};
manifest.identifier = CHIP_ROM_EXT_IDENTIFIER;
boot_data_t boot_data{};
manifest.length = CHIP_ROM_EXT_SIZE_MIN - 1;
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data),
kErrorBootPolicyBadLength);
manifest.length = CHIP_ROM_EXT_SIZE_MAX + 1;
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data),
kErrorBootPolicyBadLength);
}
TEST_F(BootPolicyTest, ManifestCheckBadManifest) {
manifest_t manifest{};
manifest.identifier = CHIP_ROM_EXT_IDENTIFIER;
manifest.length = CHIP_ROM_EXT_SIZE_MAX;
boot_data_t boot_data{};
EXPECT_CALL(mock_manifest_, Check(&manifest))
.WillOnce(Return(kErrorManifestBadEntryPoint));
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data),
kErrorManifestBadEntryPoint);
}
TEST_F(BootPolicyTest, ManifestCheckRollback) {
manifest_t manifest{};
manifest.identifier = CHIP_ROM_EXT_IDENTIFIER;
manifest.length = CHIP_ROM_EXT_SIZE_MAX;
boot_data_t boot_data{};
boot_data.min_security_version_rom_ext = 1;
EXPECT_CALL(mock_manifest_, Check(&manifest)).WillOnce(Return(kErrorOk));
EXPECT_EQ(boot_policy_manifest_check(&manifest, &boot_data),
kErrorBootPolicyRollback);
}
struct ManifestOrderTestCase {
uint32_t version_a;
uint32_t version_b;
bool is_a_first;
};
class ManifestOrderTest
: public BootPolicyTest,
public testing::WithParamInterface<ManifestOrderTestCase> {};
TEST_P(ManifestOrderTest, ManifestsGet) {
manifest_t manifest_a{};
manifest_t manifest_b{};
manifest_a.security_version = GetParam().version_a;
manifest_b.security_version = GetParam().version_b;
EXPECT_CALL(boot_policy_ptrs_, ManifestA).WillOnce(Return(&manifest_a));
EXPECT_CALL(boot_policy_ptrs_, ManifestB).WillOnce(Return(&manifest_b));
boot_policy_manifests_t res = boot_policy_manifests_get();
if (GetParam().is_a_first) {
EXPECT_EQ(res.ordered[0], &manifest_a);
EXPECT_EQ(res.ordered[1], &manifest_b);
} else {
EXPECT_EQ(res.ordered[0], &manifest_b);
EXPECT_EQ(res.ordered[1], &manifest_a);
}
}
INSTANTIATE_TEST_SUITE_P(
SecurityVersionCases, ManifestOrderTest,
testing::Values(
ManifestOrderTestCase{
.version_a = 0,
.version_b = 0,
.is_a_first = true,
},
ManifestOrderTestCase{
.version_a = 1,
.version_b = 0,
.is_a_first = true,
},
ManifestOrderTestCase{
.version_a = 0,
.version_b = 1,
.is_a_first = false,
},
ManifestOrderTestCase{
.version_a = std::numeric_limits<int32_t>::max(),
.version_b =
static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) + 1,
.is_a_first = false,
}));
} // namespace
} // namespace manifest_unittest