Software APIs
sigverify_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/sigverify/sigverify.h"
6 
7 #include <array>
8 #include <cstring>
9 #include <limits>
10 #include <unordered_set>
11 
12 #include "gtest/gtest.h"
15 #include "sw/device/silicon_creator/lib/drivers/mock_lifecycle.h"
16 #include "sw/device/silicon_creator/lib/drivers/mock_otp.h"
17 #include "sw/device/silicon_creator/lib/sigverify/mock_mod_exp_ibex.h"
18 #include "sw/device/silicon_creator/testing/rom_test.h"
19 
20 #include "otp_ctrl_regs.h"
21 
22 namespace sigverify_unittest {
23 namespace {
24 using ::testing::DoAll;
25 using ::testing::NotNull;
26 using ::testing::Return;
27 using ::testing::SetArgPointee;
28 
29 /**
30  * SHA2-256 digest of "test".
31  *
32  * Can be obtained using:
33  * ```
34  * echo -n "test" | openssl dgst -sha256 -binary | \
35  * xxd -p -c 4 | tac | sed 's|.*|0x&,|'
36  * ```
37  */
39  .digest =
40  {
41  0xb0f00a08,
42  0xd15d6c15,
43  0x2b0b822c,
44  0xa3bf4f1b,
45  0xc55ad015,
46  0x9a2feaa0,
47  0x884c7d65,
48  0x9f86d081,
49  },
50 };
51 
52 /**
53  * 3072-bit EMSA-PKCS1-v1_5 encoding of `kTestDigest`.
54  *
55  * Can be obtained using:
56  * ```
57  * # Create private key.
58  * openssl genrsa -out key.pem 3072
59  * # Sign.
60  * echo -n "test" | openssl dgst -sha256 -sign key.pem -out signature
61  * # Print encoded message.
62  * openssl rsautl -verify -in signature -inkey key.pem -raw | \
63  * xxd -p -c 4 | tac | sed 's|.*|0x&,|'
64  * ```
65  */
67  .data = {
68  0xb0f00a08, 0xd15d6c15, 0x2b0b822c, 0xa3bf4f1b, 0xc55ad015, 0x9a2feaa0,
69  0x884c7d65, 0x9f86d081, 0x05000420, 0x03040201, 0x86480165, 0x0d060960,
70  0x00303130, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
71  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
72  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
73  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
74  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
75  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
76  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
77  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
78  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
79  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
80  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
81  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
82  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
83  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff,
84  }};
85 
86 // The value of `kSignature` is not significant since we use mocks for
87 // `sigverify_mod_exp_ibex()`.
88 constexpr sigverify_rsa_buffer_t kSignature{};
89 
90 /**
91  * Life cycle states used in parameterized tests.
92  */
93 
94 constexpr std::array<lifecycle_state_t, 5> kLcStates{
95  kLcStateTest, kLcStateDev, kLcStateProd, kLcStateProdEnd, kLcStateRma,
96 };
97 
99  : public rom_test::RomTest,
100  public testing::WithParamInterface<lifecycle_state_t> {
101  protected:
102  rom_test::MockSigverifyModExpIbex sigverify_mod_exp_ibex_;
103  rom_test::MockOtp otp_;
104  // The content of this key is not significant since we use mocks.
105  sigverify_rsa_key_t key_{};
106 };
107 
108 TEST_P(SigverifyInLcState, GoodSignatureIbex) {
109  EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
110  .WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
111 
112  uint32_t flash_exec = 0;
113  EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
114  &flash_exec),
115  kErrorOk);
116  EXPECT_EQ(flash_exec, kSigverifyRsaSuccess);
117 }
118 
119 INSTANTIATE_TEST_SUITE_P(AllLcStates, SigverifyInLcState,
120  testing::ValuesIn(kLcStates));
121 
123  uint32_t selector_bits;
124  lifecycle_device_id_t exp_device_id;
125  uint32_t exp_manuf_state_creator;
126  uint32_t exp_manuf_state_owner;
127  uint32_t exp_life_cycle_state;
128 };
129 
131  : public rom_test::RomTest,
132  public testing::WithParamInterface<UsageConstraintsTestCase> {
133  protected:
134  rom_test::MockLifecycle lifecycle_;
135  rom_test::MockOtp otp_;
136 };
137 
138 /**
139  * Constants used in usage constraints tests.
140  */
141 
142 constexpr uint32_t kUnusedWord = MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL;
143 constexpr uint32_t kManufStateCreator = 0x30303030;
144 constexpr uint32_t kManufStateOwner = 0x31313131;
145 constexpr uint32_t kLifeCycleState = 0x32323232;
146 constexpr lifecycle_device_id_t kDeviceId{
147  .device_id =
148  {
149  0x01020304,
150  0x05060708,
151  0x09100A0B,
152  0x0C0D0E0F,
153  0x10111213,
154  0x14151617,
155  0x18192021,
156  0x22232425,
157  },
158 };
159 
160 TEST_F(SigverifyUsageConstraints, ConstantCheck) {
161  // Changing this constant breaks compatibility with the ROM, existing
162  // images and tools.
163  EXPECT_EQ(MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL, 0xA5A5A5A5);
164  EXPECT_NE(kManufStateCreator, kUnusedWord);
165  EXPECT_NE(kManufStateOwner, kUnusedWord);
166  EXPECT_NE(kLifeCycleState, kUnusedWord);
167  for (size_t i = 0; i < kLifecycleDeviceIdNumWords; ++i) {
168  EXPECT_NE(kDeviceId.device_id[i], kUnusedWord);
169  }
170 }
171 
172 constexpr std::array<UsageConstraintsTestCase, 4> kUsageConstraintsTestCases{{
173  {
174  .selector_bits = 0x7FF,
175  .exp_device_id = kDeviceId,
176  .exp_manuf_state_creator = kManufStateCreator,
177  .exp_manuf_state_owner = kManufStateOwner,
178  .exp_life_cycle_state = kLifeCycleState,
179  },
180  {
181  .selector_bits = 0x3AA,
182  .exp_device_id = {.device_id =
183  {
184  kUnusedWord,
185  kDeviceId.device_id[1],
186  kUnusedWord,
187  kDeviceId.device_id[3],
188  kUnusedWord,
189  kDeviceId.device_id[5],
190  kUnusedWord,
191  kDeviceId.device_id[7],
192  }},
193  .exp_manuf_state_creator = kUnusedWord,
194  .exp_manuf_state_owner = kUnusedWord,
195  .exp_life_cycle_state = kUnusedWord,
196  },
197  {
198  .selector_bits = 0x155,
199  .exp_device_id = {.device_id =
200  {
201  kDeviceId.device_id[0],
202  kUnusedWord,
203  kDeviceId.device_id[2],
204  kUnusedWord,
205  kDeviceId.device_id[4],
206  kUnusedWord,
207  kDeviceId.device_id[6],
208  kUnusedWord,
209  }},
210  .exp_manuf_state_creator = kUnusedWord,
211  .exp_manuf_state_owner = kUnusedWord,
212  .exp_life_cycle_state = kUnusedWord,
213  },
214  {
215  .selector_bits = 0,
216  .exp_device_id = {.device_id =
217  {
218  kUnusedWord,
219  kUnusedWord,
220  kUnusedWord,
221  kUnusedWord,
222  kUnusedWord,
223  kUnusedWord,
224  kUnusedWord,
225  kUnusedWord,
226  }},
227  .exp_manuf_state_creator = kUnusedWord,
228  .exp_manuf_state_owner = kUnusedWord,
229  .exp_life_cycle_state = kUnusedWord,
230  },
231 }};
232 
233 TEST_P(SigverifyUsageConstraints, Read) {
234  EXPECT_CALL(lifecycle_, DeviceId(NotNull()))
235  .WillOnce(SetArgPointee<0>(kDeviceId));
236 
237  EXPECT_CALL(otp_, read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_MANUF_STATE_OFFSET))
238  .WillOnce(Return(GetParam().exp_manuf_state_creator));
239 
240  EXPECT_CALL(otp_, read32(OTP_CTRL_PARAM_OWNER_SW_CFG_MANUF_STATE_OFFSET))
241  .WillOnce(Return(GetParam().exp_manuf_state_owner));
242 
243  EXPECT_CALL(lifecycle_, State())
244  .WillOnce(Return(static_cast<lifecycle_state_t>(kLifeCycleState)));
245 
246  manifest_usage_constraints_t usage_constraints;
247  sigverify_usage_constraints_get(GetParam().selector_bits, &usage_constraints);
248 
249  EXPECT_EQ(usage_constraints.selector_bits, GetParam().selector_bits);
250  EXPECT_THAT(usage_constraints.device_id.device_id,
251  testing::ElementsAreArray(GetParam().exp_device_id.device_id));
252  EXPECT_EQ(usage_constraints.manuf_state_creator,
253  GetParam().exp_manuf_state_creator);
254  EXPECT_EQ(usage_constraints.manuf_state_owner,
255  GetParam().exp_manuf_state_owner);
256  EXPECT_EQ(usage_constraints.life_cycle_state,
257  GetParam().exp_life_cycle_state);
258 }
259 
260 INSTANTIATE_TEST_SUITE_P(UsageConstraintsTestCases, SigverifyUsageConstraints,
261  testing::ValuesIn(kUsageConstraintsTestCases));
262 
263 TEST(SigverifyRsaSuccessToOk, Result) {
264  EXPECT_EQ(sigverify_rsa_success_to_ok(kSigverifyRsaSuccess), kErrorOk);
265  EXPECT_NE(sigverify_rsa_success_to_ok(kErrorOk), kErrorOk);
266  EXPECT_NE(sigverify_rsa_success_to_ok(std::numeric_limits<uint32_t>::max()),
267  kErrorOk);
268  EXPECT_NE(sigverify_rsa_success_to_ok(0), kErrorOk);
269 }
270 
271 } // namespace
272 } // namespace sigverify_unittest