Skip to content

Commit e167c75

Browse files
committed
[keymgr_dpe, sw] Add keymgr_dpe crypto lib test
This commit introduces the test for the `keymgr_dpe` driver inside the crypto lib. It covers the basic `keymgr_dpe` features. Add source / header file **without** linking them in the appropriate BUILD file as some dependencies do not exist yet! Signed-off-by: Raphael Roth <rroth@lowrisc.org>
1 parent 1d9da86 commit e167c75

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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/lib/crypto/drivers/keymgr_dpe.h"
6+
7+
#include "sw/device/lib/base/memory.h"
8+
#include "sw/device/lib/crypto/drivers/entropy.h"
9+
#include "sw/device/lib/crypto/impl/status.h"
10+
#include "sw/device/lib/runtime/log.h"
11+
#include "sw/device/lib/testing/keymgr_dpe_testutils.h"
12+
#include "sw/device/lib/testing/test_framework/check.h"
13+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
14+
15+
// Module ID for status codes.
16+
#define MODULE_ID MAKE_MODULE_ID('t', 's', 't')
17+
18+
// Key diversification data for testing
19+
static const keymgr_dpe_diversification_t kTestDiversification = {
20+
.salt =
21+
{
22+
0x00112233,
23+
0x44556677,
24+
0x8899aabb,
25+
0xccddeeff,
26+
0x00010203,
27+
0x04050607,
28+
0x08090a0b,
29+
0x0c0d0e0f,
30+
},
31+
.version = 0x9,
32+
// Need to match kOwnerKeyParams.slot_dst_sel in keymgr_dpe testutils
33+
.slot_src_sel = 1};
34+
35+
/**
36+
* Setup keymgr dpe / entropy complex and advance to the OwnerRootKey.
37+
*
38+
* Run this test before any others.
39+
*/
40+
status_t test_setup(void) {
41+
dif_keymgr_dpe_t keymgr_dpe;
42+
dif_kmac_t kmac;
43+
// Initialize the keymgr dpe and generate CreatorRootKey
44+
TRY(keymgr_dpe_testutils_startup(&keymgr_dpe, &kmac));
45+
// After startup the keymgr dpe state should be available
46+
TRY(keymgr_dpe_testutils_check_state(&keymgr_dpe,
47+
kDifKeymgrDpeStateAvailable));
48+
// Generate Owner Int Key (Only one key).
49+
TRY(keymgr_dpe_testutils_advance_state(&keymgr_dpe, &kOwnerIntKeyParams));
50+
// Generate Owner Key (Only one key).
51+
TRY(keymgr_dpe_testutils_advance_state(&keymgr_dpe, &kOwnerKeyParams));
52+
// Initialize entropy complex, which the key manager dpe uses to clear
53+
// sideloaded keys. The `keymgr_dpe_testutils_startup` function restarts the
54+
// device, so this should happen afterwards.
55+
return entropy_complex_init();
56+
}
57+
58+
/**
59+
* Test generating a single software-visible key.
60+
*
61+
* This test just checks that the key generation process finished without
62+
* errors, without performing any validation on the key.
63+
*/
64+
status_t sw_single_key_test(void) {
65+
keymgr_dpe_output_t key;
66+
return keymgr_dpe_generate_key_sw(kTestDiversification, &key);
67+
}
68+
69+
/**
70+
* Test generating a single sideloaded AES key.
71+
*
72+
* This test just checks that the key generation process finished without
73+
* errors, without actually attempting to use the key.
74+
*/
75+
status_t aes_basic_test(void) {
76+
return keymgr_dpe_generate_key_aes(kTestDiversification);
77+
}
78+
79+
/**
80+
* Test generating a single sideloaded KMAC key.
81+
*
82+
* This test just checks that the key generation process finished without
83+
* errors, without actually attempting to use the key.
84+
*/
85+
status_t kmac_basic_test(void) {
86+
return keymgr_dpe_generate_key_kmac(kTestDiversification);
87+
}
88+
89+
/**
90+
* Test generating a single sideloaded OTBN key.
91+
*
92+
* This test just checks that the key generation process finished without
93+
* errors, without actually attempting to use the key.
94+
*/
95+
status_t otbn_basic_test(void) {
96+
return keymgr_dpe_generate_key_otbn(kTestDiversification);
97+
}
98+
99+
/**
100+
* Check whether two key manager dpe output values are equivalent.
101+
*
102+
* Unmasks both keys and compares their unmasked values; masking should not
103+
* affect this comparison.
104+
*
105+
* @param key1 First key manager output.
106+
* @param key2 Second key manager output.
107+
* @return true if the keys are equivalent, false otherwise.
108+
*/
109+
static bool output_equiv(keymgr_dpe_output_t key1, keymgr_dpe_output_t key2) {
110+
for (size_t i = 0; i < kKeymgrDPEOutputShareNumWords; i++) {
111+
uint32_t word1 = key1.share0[i] ^ key1.share1[i];
112+
uint32_t word2 = key2.share0[i] ^ key2.share1[i];
113+
if (word1 != word2) {
114+
return false;
115+
}
116+
}
117+
return true;
118+
}
119+
120+
/**
121+
* Test generating software-visible keys with different salts.
122+
*
123+
* Different salts should produce different keys; the same salt should produce
124+
* the same key but with different masking.
125+
*/
126+
status_t sw_keys_change_salt_test(void) {
127+
// Copy the test data into a mutable structure.
128+
keymgr_dpe_diversification_t div;
129+
memcpy(div.salt, kTestDiversification.salt, sizeof(div.salt));
130+
div.version = kTestDiversification.version;
131+
div.slot_src_sel = kTestDiversification.slot_src_sel;
132+
133+
// Generate a key.
134+
keymgr_dpe_output_t key1;
135+
TRY(keymgr_dpe_generate_key_sw(div, &key1));
136+
137+
// Change the salt and generate the key again.
138+
div.salt[0]++;
139+
keymgr_dpe_output_t key2;
140+
TRY(keymgr_dpe_generate_key_sw(div, &key2));
141+
142+
// Check that the keys are distinct.
143+
TRY_CHECK(!output_equiv(key1, key2));
144+
145+
// Change the salt back to its original value and generate a third time.
146+
div.salt[0]--;
147+
keymgr_dpe_output_t key3;
148+
TRY(keymgr_dpe_generate_key_sw(div, &key3));
149+
150+
// Check that the key is the equivalent to the first key when unmasked.
151+
TRY_CHECK(output_equiv(key1, key3));
152+
153+
// Check that the masking on the equivalent keys is different.
154+
TRY_CHECK_ARRAYS_NE(key1.share0, key3.share0, sizeof(key1.share0));
155+
156+
return OK_STATUS();
157+
}
158+
159+
/**
160+
* Test generating software-visible keys with different versions.
161+
*
162+
* Different versions should produce different keys; the same version should
163+
* produce the same key but with different masking.
164+
*/
165+
status_t sw_keys_change_version_test(void) {
166+
// Copy the test data into a mutable structure.
167+
keymgr_dpe_diversification_t div;
168+
memcpy(div.salt, kTestDiversification.salt, sizeof(div.salt));
169+
div.version = kTestDiversification.version;
170+
div.slot_src_sel = kTestDiversification.slot_src_sel;
171+
172+
// Generate a key.
173+
keymgr_dpe_output_t key1;
174+
TRY(keymgr_dpe_generate_key_sw(div, &key1));
175+
176+
// Change the version and generate the key again.
177+
div.version++;
178+
keymgr_dpe_output_t key2;
179+
TRY(keymgr_dpe_generate_key_sw(div, &key2));
180+
181+
// Check that the keys are distinct.
182+
TRY_CHECK(!output_equiv(key1, key2));
183+
184+
// Change the version back to its original value and generate a third time.
185+
div.version--;
186+
keymgr_dpe_output_t key3;
187+
TRY(keymgr_dpe_generate_key_sw(div, &key3));
188+
189+
// Check that the key is the equivalent to the first key when unmasked.
190+
TRY_CHECK(output_equiv(key1, key3));
191+
192+
// Check that the masking on the equivalent keys is different.
193+
TRY_CHECK_ARRAYS_NE(key1.share0, key3.share0, sizeof(key1.share0));
194+
195+
return OK_STATUS();
196+
}
197+
198+
OTTF_DEFINE_TEST_CONFIG();
199+
200+
bool test_main(void) {
201+
static status_t result;
202+
203+
EXECUTE_TEST(result, test_setup);
204+
EXECUTE_TEST(result, sw_single_key_test);
205+
EXECUTE_TEST(result, sw_keys_change_salt_test);
206+
EXECUTE_TEST(result, sw_keys_change_version_test);
207+
EXECUTE_TEST(result, aes_basic_test);
208+
EXECUTE_TEST(result, kmac_basic_test);
209+
EXECUTE_TEST(result, otbn_basic_test);
210+
211+
return status_ok(result);
212+
}

0 commit comments

Comments
 (0)