Software APIs
sigverify_keys_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/rom_ext/sigverify_keys.h"
6 
7 #include <array>
8 #include <cstring>
9 #include <limits>
10 #include <numeric>
11 #include <unordered_set>
12 
13 #include "gtest/gtest.h"
15 #include "sw/device/silicon_creator/lib/drivers/mock_rnd.h"
16 #include "sw/device/silicon_creator/lib/error.h"
17 #include "sw/device/silicon_creator/testing/rom_test.h"
18 
19 // Define the symbols that the sigverify library expects for the mock keys
20 // defined below.
21 extern "C" {
22 /**
23  * Mock keys used in tests.
24  *
25  * We only initialize the first word of `n`, which is the key ID, and `key_type`
26  * since these are the only fields that are used for determining the validity of
27  * a key. The remaining fields are initialized only because non-trivial
28  * designated initializers are not supported.
29  */
30 constexpr sigverify_rom_ext_key_t kSigverifyRsaKeys[]{
31  {
32  .key = {.n = {{0xa0}}, .n0_inv = {0}},
33  .key_type = kSigverifyKeyTypeFirmwareTest,
34  },
35  {
36  .key = {.n = {{0xb0}}, .n0_inv = {0}},
37  .key_type = kSigverifyKeyTypeFirmwareProd,
38  },
39  {
40  .key = {.n = {{0xc0}}, .n0_inv = {0}},
41  .key_type = kSigverifyKeyTypeFirmwareDev,
42  },
43  {
44  .key = {.n = {{0xa1}}, .n0_inv = {0}},
45  .key_type = kSigverifyKeyTypeFirmwareTest,
46  },
47  {
48  .key = {.n = {{0xb1}}, .n0_inv = {0}},
49  .key_type = kSigverifyKeyTypeFirmwareProd,
50  },
51  {
52  .key = {.n = {{0xc1}}, .n0_inv = {0}},
53  .key_type = kSigverifyKeyTypeFirmwareDev,
54  },
55  {
56  .key = {.n = {{0xff}}, .n0_inv = {0}},
57  .key_type = static_cast<sigverify_key_type_t>(
58  std::numeric_limits<uint32_t>::max()),
59  },
60 };
61 
62 constexpr size_t kSigverifyRsaKeysCnt =
63  std::extent<decltype(kSigverifyRsaKeys)>::value;
64 // Using 1 as the step size since it is coprime with every integer.
65 constexpr size_t kSigverifyRsaKeysStep = 1;
66 }
67 
68 namespace sigverify_keys_unittest {
69 namespace {
70 using ::testing::Return;
71 
72 /**
73  * Returns the indices of mock keys of the given type.
74  *
75  * @param key_type A key type.
76  * @return Indices of mock keys of the given type.
77  */
78 std::vector<size_t> MockKeyIndicesOfType(sigverify_key_type_t key_type) {
79  std::vector<size_t> indices;
80  for (size_t i = 0; i < kSigverifyRsaKeysCnt; ++i) {
81  if (kSigverifyRsaKeys[i].key_type == key_type) {
82  indices.push_back(i);
83  }
84  }
85  return indices;
86 }
87 
89  protected:
90  /**
91  * Sets expectations for getting the keys stored in the ROM.
92  */
93  void ExpectKeysGet() {
94  EXPECT_CALL(rnd_, Uint32())
95  .WillOnce(Return(std::numeric_limits<uint32_t>::max()));
96  }
97 
98  rom_test::MockRnd rnd_;
99 };
100 
101 class BadKeyIdTypeTest : public SigverifyKeys {};
102 
103 TEST_F(BadKeyIdTypeTest, BadKeyId) {
104  ExpectKeysGet();
105 
106  const sigverify_rsa_key_t *key;
107  EXPECT_EQ(sigverify_rsa_key_get(0, &key), kErrorSigverifyBadKey);
108 }
109 
111 
112 TEST_F(BadKeyIdTypeDeathTest, BadKeyType) {
113  const sigverify_rsa_key_t *key;
114 
115  EXPECT_DEATH(
116  {
117  ExpectKeysGet();
118  sigverify_rsa_key_get(0xff, &key);
119  },
120  "");
121 }
122 
123 /**
124  * Base class for paramaterized tests below.
125  */
127  public testing::WithParamInterface<size_t> {};
128 
129 TEST_P(KeyValidityTest, Get) {
130  size_t key_index = GetParam();
131 
132  ExpectKeysGet();
133 
134  const sigverify_rsa_key_t *key;
135  EXPECT_EQ(
136  sigverify_rsa_key_get(
137  sigverify_rsa_key_id_get(&kSigverifyRsaKeys[key_index].key.n), &key),
138  kErrorOk);
139  EXPECT_EQ(key, &kSigverifyRsaKeys[key_index].key);
140 }
141 
142 INSTANTIATE_TEST_SUITE_P(
143  FirmwareProdKeys, KeyValidityTest,
144  testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeFirmwareProd)));
145 
146 INSTANTIATE_TEST_SUITE_P(
147  FirmwareTestKeys, KeyValidityTest,
148  testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeFirmwareTest)));
149 
150 INSTANTIATE_TEST_SUITE_P(
151  FirmwareDevKeys, KeyValidityTest,
152  testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeFirmwareDev)));
153 
154 } // namespace
155 } // namespace sigverify_keys_unittest