Software APIs
manifest_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/manifest.h"
6 
7 #include "gtest/gtest.h"
8 #include "sw/device/silicon_creator/testing/rom_test.h"
9 
10 namespace manifest_unittest {
11 namespace {
12 
14  protected:
15  ManifestTest() {
16  manifest_.manifest_version.major = kManifestVersionMajor2;
17  manifest_.length = sizeof(manifest_t) + 0x1000;
18  manifest_.signed_region_end = sizeof(manifest_t) + 0x900;
19  manifest_.code_start = sizeof(manifest_t);
20  manifest_.code_end = sizeof(manifest_t) + 0x800;
21  manifest_.entry_point = 0x500;
22  }
23 
24  manifest_t manifest_{};
25 };
26 
27 TEST_F(ManifestTest, DigestRegionGet) {
28  manifest_digest_region_t digest_region =
29  manifest_digest_region_get(&manifest_);
30 
31  // Digest region starts immediately after `usage_constraints` and ends at
32  // `signed_region_end`.
33  size_t digest_region_offset = offsetof(manifest_t, usage_constraints) +
35  EXPECT_EQ(digest_region.start,
36  reinterpret_cast<const char *>(&manifest_) + digest_region_offset);
37  EXPECT_EQ(digest_region.length,
38  manifest_.signed_region_end - digest_region_offset);
39 }
40 
41 TEST_F(ManifestTest, CodeRegionGet) {
42  epmp_region_t code_region = manifest_code_region_get(&manifest_);
43 
44  EXPECT_EQ(code_region.start,
45  reinterpret_cast<uintptr_t>(&manifest_) + manifest_.code_start);
46  EXPECT_EQ(code_region.end,
47  reinterpret_cast<uintptr_t>(&manifest_) + manifest_.code_end);
48 }
49 
50 TEST_F(ManifestTest, EntryPointGet) {
51  uintptr_t entry_point = manifest_entry_point_get(&manifest_);
52 
53  EXPECT_EQ(entry_point,
54  reinterpret_cast<uintptr_t>(&manifest_) + manifest_.entry_point);
55 }
56 
57 TEST_F(ManifestTest, CodeRegionEmpty) {
58  manifest_.code_start = manifest_.code_end;
59  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadCodeRegion);
60 }
61 
62 TEST_F(ManifestTest, CodeRegionInsideManifest) {
63  manifest_.code_start = sizeof(manifest_) - 1;
64  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadCodeRegion);
65 }
66 
67 TEST_F(ManifestTest, CodeRegionOutsideImage) {
68  manifest_.code_end = manifest_.length + 1;
69  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadCodeRegion);
70 }
71 
72 TEST_F(ManifestTest, CodeRegionUnalignedStart) {
73  ++manifest_.code_start;
74  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadCodeRegion);
75 }
76 
77 TEST_F(ManifestTest, CodeRegionUnalignedEnd) {
78  ++manifest_.code_end;
79  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadCodeRegion);
80 }
81 
82 TEST_F(ManifestTest, ExtensionOffsetUnaligned) {
83  manifest_.extensions.entries[1].offset = 1;
84  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadExtension);
85 }
86 
87 TEST_F(ManifestTest, EntryPointBeforeCodeStart) {
88  manifest_.entry_point = manifest_.code_start - 1;
89  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadEntryPoint);
90 }
91 
92 TEST_F(ManifestTest, EntryPointAfterCodeEnd) {
93  manifest_.entry_point = manifest_.code_end;
94  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadEntryPoint);
95 }
96 
97 TEST_F(ManifestTest, EntryPointOutsideImage) {
98  manifest_.entry_point = manifest_.length;
99  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadEntryPoint);
100 }
101 
102 TEST_F(ManifestTest, EntryPointUnaligned) {
103  ++manifest_.entry_point;
104  EXPECT_EQ(manifest_check(&manifest_), kErrorManifestBadEntryPoint);
105 }
106 
107 TEST_F(ManifestTest, ExtSpxKeyGet) {
108  char flash[CHIP_ROM_EXT_RESIZABLE_SIZE_MAX];
109  memset(flash, 0, sizeof(flash));
110  size_t ext_offset = CHIP_ROM_EXT_SIZE_MAX;
111 
112  manifest_t *manifest = reinterpret_cast<manifest_t *>(&flash[0]);
113  memcpy(manifest, &manifest_, sizeof(manifest_));
114  manifest->length = ext_offset + sizeof(manifest_ext_spx_key_t);
115 
116  manifest_ext_table_entry_t *entry = &manifest->extensions.entries[0];
117  entry->identifier = kManifestExtIdSpxKey;
118  entry->offset = ext_offset;
119 
120  manifest_ext_header_t *header =
121  reinterpret_cast<manifest_ext_header_t *>(&flash[ext_offset]);
122  header->identifier = kManifestExtIdSpxKey;
123  header->name = kManifestExtNameSpxKey;
124 
125  const manifest_ext_spx_key_t *result = nullptr;
126  EXPECT_EQ(manifest_ext_get_spx_key(manifest, &result), kErrorOk);
127  EXPECT_EQ(&result->header, header);
128 }
129 
130 } // namespace
131 } // namespace manifest_unittest