-
Notifications
You must be signed in to change notification settings - Fork 802
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[sw/silicon_creator] Add initial files for ROM_EXT boot policy
This change adds skeleton code for ROM_EXT boot policy by mostly copying the corresponding files from `sw/device/silicon_creato/mask_rom` to unblock booting the first owner boot stage. Signed-off-by: Alphan Ulusoy <alphan@google.com>
- Loading branch information
Showing
7 changed files
with
341 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
sw/device/silicon_creator/rom_exts/mock_rom_ext_boot_policy_ptrs.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_MOCK_ROM_EXT_BOOT_POLICY_PTRS_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_MOCK_ROM_EXT_BOOT_POLICY_PTRS_H_ | ||
|
||
#include "sw/device/silicon_creator/rom_exts/rom_ext_boot_policy_ptrs.h" | ||
#include "sw/device/silicon_creator/testing/mask_rom_test.h" | ||
|
||
namespace mask_rom_test { | ||
namespace internal { | ||
|
||
/** | ||
* Mock class for rom_ext_boot_policy_ptrs.h | ||
*/ | ||
class MockRomExtBootPolicyPtrs : public GlobalMock<MockRomExtBootPolicyPtrs> { | ||
public: | ||
MOCK_METHOD(const manifest_t *, ManifestA, ()); | ||
MOCK_METHOD(const manifest_t *, ManifestB, ()); | ||
}; | ||
|
||
} // namespace internal | ||
|
||
using MockRomExtBootPolicyPtrs = | ||
testing::StrictMock<internal::MockRomExtBootPolicyPtrs>; | ||
|
||
extern "C" { | ||
|
||
const manifest_t *rom_ext_boot_policy_manifest_a_get() { | ||
return MockRomExtBootPolicyPtrs::Instance().ManifestA(); | ||
} | ||
|
||
const manifest_t *rom_ext_boot_policy_manifest_b_get() { | ||
return MockRomExtBootPolicyPtrs::Instance().ManifestB(); | ||
} | ||
|
||
} // extern "C" | ||
} // namespace mask_rom_test | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_MOCK_ROM_EXT_BOOT_POLICY_PTRS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// 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_exts/rom_ext_boot_policy.h" | ||
|
||
#include "sw/device/silicon_creator/lib/error.h" | ||
#include "sw/device/silicon_creator/rom_exts/rom_ext_boot_policy_ptrs.h" | ||
|
||
rom_ext_boot_policy_manifests_t rom_ext_boot_policy_manifests_get(void) { | ||
const manifest_t *slot_a = rom_ext_boot_policy_manifest_a_get(); | ||
const manifest_t *slot_b = rom_ext_boot_policy_manifest_b_get(); | ||
if (slot_a->security_version >= slot_b->security_version) { | ||
return (rom_ext_boot_policy_manifests_t){ | ||
.ordered = {slot_a, slot_b}, | ||
}; | ||
} | ||
return (rom_ext_boot_policy_manifests_t){ | ||
.ordered = {slot_b, slot_a}, | ||
}; | ||
} | ||
|
||
rom_error_t rom_ext_boot_policy_manifest_check(const manifest_t *manifest) { | ||
RETURN_IF_ERROR(manifest_check(manifest)); | ||
if (manifest->identifier != kRomExtBootPolicyOwnerStageIdentifier) { | ||
return kErrorBootPolicyBadIdentifier; | ||
} | ||
// TODO(#7879): Implement anti-rollback. | ||
uint32_t min_security_version = 0; | ||
if (manifest->security_version < min_security_version) { | ||
return kErrorBootPolicyRollback; | ||
} | ||
return kErrorOk; | ||
} | ||
|
||
extern const manifest_t *rom_ext_boot_policy_manifest_a_get(void); | ||
extern const manifest_t *rom_ext_boot_policy_manifest_b_get(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_H_ | ||
|
||
#include "sw/device/silicon_creator/lib/error.h" | ||
#include "sw/device/silicon_creator/lib/manifest.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif // __cplusplus | ||
|
||
enum { | ||
/** | ||
* First owner boot stage manifest identifier (ASCII "OTSO"). | ||
*/ | ||
kRomExtBootPolicyOwnerStageIdentifier = 0x4f53544f, | ||
}; | ||
|
||
/** | ||
* Type alias for the first owner boot stage entry point. | ||
* | ||
* The entry point address obtained from the first owner boot stage manifest | ||
* must be cast to a pointer to this type before being called. | ||
*/ | ||
typedef void owner_stage_entry_point(void); | ||
|
||
/** | ||
* Manifests of first boot owner boot stages in descending order according to | ||
* their security versions. | ||
* | ||
* These boot stages must be verified prior to handing over execution. | ||
*/ | ||
typedef struct rom_ext_boot_policy_manifests { | ||
/** | ||
* First owner boot stage manifests in descending order according to | ||
* their security versions. | ||
*/ | ||
const manifest_t *ordered[2]; | ||
} rom_ext_boot_policy_manifests_t; | ||
|
||
/** | ||
* Returns the manifests of first owner boot stages that should be attempted to | ||
* boot in descending order according to their security versions. | ||
* | ||
* These boot stages must be verified prior to handing over execution. | ||
* | ||
* @return Manifests of first owner boot stages in descending order according to | ||
* their security versions. | ||
*/ | ||
rom_ext_boot_policy_manifests_t rom_ext_boot_policy_manifests_get(void); | ||
|
||
/** | ||
* Checks the fields of a first owner boot stage manifest. | ||
* | ||
* This function performs bounds checks on the fields of the manifest, checks | ||
* that its `identifier` is correct, and its `security_version` is greater than | ||
* or equal to the minimum required security version. | ||
* | ||
* @param manifest A first boot owner boot stage manifest. | ||
* @return Result of the operation. | ||
*/ | ||
rom_error_t rom_ext_boot_policy_manifest_check(const manifest_t *manifest); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif // __cplusplus | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_H_ |
57 changes: 57 additions & 0 deletions
57
sw/device/silicon_creator/rom_exts/rom_ext_boot_policy_ptrs.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright lowRISC contributors. | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_PTRS_H_ | ||
#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_PTRS_H_ | ||
|
||
#include "sw/device/silicon_creator/lib/manifest.h" | ||
|
||
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif // __cplusplus | ||
|
||
static_assert((TOP_EARLGREY_EFLASH_SIZE_BYTES % 2) == 0, | ||
"Flash size is not divisible by 2"); | ||
|
||
#ifndef OT_OFF_TARGET_TEST | ||
/** | ||
* Returns a pointer to the manifest of the first owner boot stage image stored | ||
* in flash slot A. | ||
* | ||
* @return Pointer to the manifest of the first owner boot stage image in slot | ||
* A. | ||
*/ | ||
// TODO(#7893): Should these be volatile? | ||
inline const manifest_t *rom_ext_boot_policy_manifest_a_get(void) { | ||
return (const manifest_t *)(TOP_EARLGREY_EFLASH_BASE_ADDR + | ||
MANIFEST_LENGTH_FIELD_MAX); | ||
} | ||
|
||
/** | ||
* Returns a pointer to the manifest of the first owner boot stage image stored | ||
* in flash slot B. | ||
* | ||
* @return Pointer to the manifest of the first owner boot stage image in slot | ||
* B. | ||
*/ | ||
inline const manifest_t *rom_ext_boot_policy_manifest_b_get(void) { | ||
return (const manifest_t *)(TOP_EARLGREY_EFLASH_BASE_ADDR + | ||
(TOP_EARLGREY_EFLASH_SIZE_BYTES / 2) + | ||
MANIFEST_LENGTH_FIELD_MAX); | ||
} | ||
#else | ||
/** | ||
* Declarations for the functions above that should be defined in tests. | ||
*/ | ||
const manifest_t *rom_ext_boot_policy_manifest_a_get(void); | ||
const manifest_t *rom_ext_boot_policy_manifest_b_get(void); | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif // __cplusplus | ||
|
||
#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_ROM_EXTS_ROM_EXT_BOOT_POLICY_PTRS_H_ |
107 changes: 107 additions & 0 deletions
107
sw/device/silicon_creator/rom_exts/rom_ext_boot_policy_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// 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_exts/rom_ext_boot_policy.h" | ||
|
||
#include "gtest/gtest.h" | ||
#include "sw/device/silicon_creator/lib/mock_manifest.h" | ||
#include "sw/device/silicon_creator/rom_exts/mock_rom_ext_boot_policy_ptrs.h" | ||
#include "sw/device/silicon_creator/testing/mask_rom_test.h" | ||
|
||
namespace manifest_unittest { | ||
namespace { | ||
using ::testing::Return; | ||
|
||
class RomExtBootPolicyTest : public mask_rom_test::MaskRomTest { | ||
protected: | ||
mask_rom_test::MockRomExtBootPolicyPtrs rom_ext_boot_policy_ptrs_; | ||
mask_rom_test::MockManifest mock_manifest_; | ||
}; | ||
|
||
TEST_F(RomExtBootPolicyTest, ManifestCheck) { | ||
manifest_t manifest{}; | ||
manifest.identifier = kRomExtBootPolicyOwnerStageIdentifier; | ||
|
||
EXPECT_CALL(mock_manifest_, Check(&manifest)).WillOnce(Return(kErrorOk)); | ||
|
||
EXPECT_EQ(rom_ext_boot_policy_manifest_check(&manifest), kErrorOk); | ||
} | ||
|
||
TEST_F(RomExtBootPolicyTest, ManifestCheckOutOfBounds) { | ||
manifest_t manifest{}; | ||
|
||
EXPECT_CALL(mock_manifest_, Check(&manifest)) | ||
.WillOnce(Return(kErrorManifestBadLength)); | ||
|
||
EXPECT_EQ(rom_ext_boot_policy_manifest_check(&manifest), | ||
kErrorManifestBadLength); | ||
} | ||
|
||
TEST_F(RomExtBootPolicyTest, ManifestCheckBadIdentifier) { | ||
manifest_t manifest{}; | ||
|
||
EXPECT_CALL(mock_manifest_, Check(&manifest)).WillOnce(Return(kErrorOk)); | ||
|
||
EXPECT_EQ(rom_ext_boot_policy_manifest_check(&manifest), | ||
kErrorBootPolicyBadIdentifier); | ||
} | ||
|
||
struct ManifestOrderTestCase { | ||
uint32_t version_a; | ||
uint32_t version_b; | ||
bool is_a_first; | ||
}; | ||
|
||
class ManifestOrderTest | ||
: public RomExtBootPolicyTest, | ||
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(rom_ext_boot_policy_ptrs_, ManifestA) | ||
.WillOnce(Return(&manifest_a)); | ||
EXPECT_CALL(rom_ext_boot_policy_ptrs_, ManifestB) | ||
.WillOnce(Return(&manifest_b)); | ||
|
||
rom_ext_boot_policy_manifests_t res = rom_ext_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 |