• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <stdio.h>
18 
19 #include <memory>
20 
21 #include "dice/config.h"
22 #include "dice/dice.h"
23 #include "dice/known_test_values.h"
24 #include "dice/test_framework.h"
25 #include "dice/test_utils.h"
26 #include "dice/utils.h"
27 #include "pw_string/format.h"
28 
29 namespace {
30 
31 using dice::test::CertificateType_Cbor;
32 using dice::test::DeriveFakeInputValue;
33 using dice::test::DiceStateForTest;
34 using dice::test::KeyType_Ed25519;
35 using dice::test::KeyType_P256;
36 using dice::test::KeyType_P384;
37 
TEST(DiceOpsTest,InvalidContextReturnsError)38 TEST(DiceOpsTest, InvalidContextReturnsError) {
39   DiceStateForTest current_state = {};
40   DiceStateForTest next_state = {};
41   DiceInputValues input_values = {};
42   DiceResult result = DiceMainFlow(
43       NULL, current_state.cdi_attest, current_state.cdi_seal, &input_values,
44       sizeof(next_state.certificate), next_state.certificate,
45       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
46   EXPECT_EQ(kDiceResultInvalidInput, result);
47 }
48 
TEST(DiceOpsTest,Ed25519KnownAnswerZeroInput)49 TEST(DiceOpsTest, Ed25519KnownAnswerZeroInput) {
50   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
51                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
52   DiceStateForTest current_state = {};
53   DiceStateForTest next_state = {};
54   DiceInputValues input_values = {};
55   DiceResult result = DiceMainFlow(
56       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
57       sizeof(next_state.certificate), next_state.certificate,
58       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
59   EXPECT_EQ(kDiceResultOk, result);
60   DumpState(CertificateType_Cbor, KeyType_Ed25519, "android_zero_input",
61             next_state);
62   // The CDI values should be deterministic.
63   ASSERT_EQ(sizeof(next_state.cdi_attest),
64             sizeof(dice::test::kExpectedCdiAttest_ZeroInput));
65   EXPECT_EQ(0, memcmp(next_state.cdi_attest,
66                       dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
67   ASSERT_EQ(sizeof(next_state.cdi_seal),
68             sizeof(dice::test::kExpectedCdiSeal_ZeroInput));
69   EXPECT_EQ(0, memcmp(next_state.cdi_seal,
70                       dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
71   ASSERT_EQ(sizeof(dice::test::kExpectedCborEd25519Cert_AndroidZeroInput),
72             next_state.certificate_size);
73   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborEd25519Cert_AndroidZeroInput,
74                       next_state.certificate, next_state.certificate_size));
75 }
76 
TEST(DiceOpsTest,P256KnownAnswerZeroInput)77 TEST(DiceOpsTest, P256KnownAnswerZeroInput) {
78   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
79                       .subject_algorithm = kDiceKeyAlgorithmP256};
80   DiceStateForTest current_state = {};
81   DiceStateForTest next_state = {};
82   DiceInputValues input_values = {};
83   DiceResult result = DiceMainFlow(
84       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
85       sizeof(next_state.certificate), next_state.certificate,
86       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
87   EXPECT_EQ(kDiceResultOk, result);
88   DumpState(CertificateType_Cbor, KeyType_P256, "android_zero_input",
89             next_state);
90   // The CDI values should be deterministic.
91   ASSERT_EQ(sizeof(next_state.cdi_attest),
92             sizeof(dice::test::kExpectedCdiAttest_ZeroInput));
93   EXPECT_EQ(0, memcmp(next_state.cdi_attest,
94                       dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
95   ASSERT_EQ(sizeof(next_state.cdi_seal),
96             sizeof(dice::test::kExpectedCdiSeal_ZeroInput));
97   EXPECT_EQ(0, memcmp(next_state.cdi_seal,
98                       dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
99   ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_AndroidZeroInput),
100             next_state.certificate_size);
101   // Comparing everything except for the signature, since ECDSA signatures are
102   // not deterministic
103   constexpr size_t signature_size = 64;
104   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_AndroidZeroInput,
105                       next_state.certificate,
106                       next_state.certificate_size - signature_size));
107 }
108 
TEST(DiceOpsTest,P384KnownAnswerZeroInput)109 TEST(DiceOpsTest, P384KnownAnswerZeroInput) {
110   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
111                       .subject_algorithm = kDiceKeyAlgorithmP384};
112   DiceStateForTest current_state = {};
113   DiceStateForTest next_state = {};
114   DiceInputValues input_values = {};
115   DiceResult result = DiceMainFlow(
116       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
117       sizeof(next_state.certificate), next_state.certificate,
118       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
119   EXPECT_EQ(kDiceResultOk, result);
120   DumpState(CertificateType_Cbor, KeyType_P384, "android_zero_input",
121             next_state);
122   // The CDI values should be deterministic.
123   ASSERT_EQ(sizeof(next_state.cdi_attest),
124             sizeof(dice::test::kExpectedCdiAttest_ZeroInput));
125   EXPECT_EQ(0, memcmp(next_state.cdi_attest,
126                       dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
127   ASSERT_EQ(sizeof(next_state.cdi_seal),
128             sizeof(dice::test::kExpectedCdiSeal_ZeroInput));
129   EXPECT_EQ(0, memcmp(next_state.cdi_seal,
130                       dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
131   ASSERT_EQ(sizeof(dice::test::kExpectedCborP384Cert_AndroidZeroInput),
132             next_state.certificate_size);
133   // Comparing everything except for the signature, since ECDSA signatures are
134   // not deterministic
135   constexpr size_t signature_size = 96;
136   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP384Cert_AndroidZeroInput,
137                       next_state.certificate,
138                       next_state.certificate_size - signature_size));
139 }
140 
TEST(DiceOpsTest,Ed25519KnownAnswerHashOnlyInput)141 TEST(DiceOpsTest, Ed25519KnownAnswerHashOnlyInput) {
142   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
143                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
144   DiceStateForTest current_state = {};
145   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
146   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
147   DiceStateForTest next_state = {};
148   DiceInputValues input_values = {};
149   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
150   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
151                        input_values.authority_hash);
152   input_values.config_type = kDiceConfigTypeInline;
153   DeriveFakeInputValue("inline_config", DICE_INLINE_CONFIG_SIZE,
154                        input_values.config_value);
155 
156   DiceResult result = DiceMainFlow(
157       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
158       sizeof(next_state.certificate), next_state.certificate,
159       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
160   EXPECT_EQ(kDiceResultOk, result);
161   DumpState(CertificateType_Cbor, KeyType_Ed25519, "android_hash_only_input",
162             next_state);
163   ASSERT_EQ(sizeof(next_state.cdi_attest),
164             sizeof(dice::test::kExpectedCdiAttest_HashOnlyInput));
165   EXPECT_EQ(
166       0, memcmp(next_state.cdi_attest,
167                 dice::test::kExpectedCdiAttest_HashOnlyInput, DICE_CDI_SIZE));
168   ASSERT_EQ(sizeof(next_state.cdi_seal),
169             sizeof(dice::test::kExpectedCdiSeal_HashOnlyInput));
170   EXPECT_EQ(
171       0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
172                 DICE_CDI_SIZE));
173   ASSERT_EQ(sizeof(dice::test::kExpectedCborEd25519Cert_AndroidHashOnlyInput),
174             next_state.certificate_size);
175   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborEd25519Cert_AndroidHashOnlyInput,
176                       next_state.certificate, next_state.certificate_size));
177 }
178 
TEST(DiceOpsTest,P256KnownAnswerHashOnlyInput)179 TEST(DiceOpsTest, P256KnownAnswerHashOnlyInput) {
180   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
181                       .subject_algorithm = kDiceKeyAlgorithmP256};
182   DiceStateForTest current_state = {};
183   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
184   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
185   DiceStateForTest next_state = {};
186   DiceInputValues input_values = {};
187   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
188   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
189                        input_values.authority_hash);
190   input_values.config_type = kDiceConfigTypeInline;
191   DeriveFakeInputValue("inline_config", DICE_INLINE_CONFIG_SIZE,
192                        input_values.config_value);
193 
194   DiceResult result = DiceMainFlow(
195       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
196       sizeof(next_state.certificate), next_state.certificate,
197       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
198   EXPECT_EQ(kDiceResultOk, result);
199   DumpState(CertificateType_Cbor, KeyType_P256, "android_hash_only_input",
200             next_state);
201   ASSERT_EQ(sizeof(next_state.cdi_attest),
202             sizeof(dice::test::kExpectedCdiAttest_HashOnlyInput));
203   EXPECT_EQ(
204       0, memcmp(next_state.cdi_attest,
205                 dice::test::kExpectedCdiAttest_HashOnlyInput, DICE_CDI_SIZE));
206   ASSERT_EQ(sizeof(next_state.cdi_seal),
207             sizeof(dice::test::kExpectedCdiSeal_HashOnlyInput));
208   EXPECT_EQ(
209       0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
210                 DICE_CDI_SIZE));
211   ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_AndroidHashOnlyInput),
212             next_state.certificate_size);
213   constexpr size_t signature_size = 64;
214   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_AndroidHashOnlyInput,
215                       next_state.certificate,
216                       next_state.certificate_size - signature_size));
217 }
218 
TEST(DiceOpsTest,P384KnownAnswerHashOnlyInput)219 TEST(DiceOpsTest, P384KnownAnswerHashOnlyInput) {
220   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
221                       .subject_algorithm = kDiceKeyAlgorithmP384};
222   DiceStateForTest current_state = {};
223   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
224   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
225   DiceStateForTest next_state = {};
226   DiceInputValues input_values = {};
227   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
228   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
229                        input_values.authority_hash);
230   input_values.config_type = kDiceConfigTypeInline;
231   DeriveFakeInputValue("inline_config", DICE_INLINE_CONFIG_SIZE,
232                        input_values.config_value);
233 
234   DiceResult result = DiceMainFlow(
235       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
236       sizeof(next_state.certificate), next_state.certificate,
237       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
238   EXPECT_EQ(kDiceResultOk, result);
239   DumpState(CertificateType_Cbor, KeyType_P384, "android_hash_only_input",
240             next_state);
241   ASSERT_EQ(sizeof(next_state.cdi_attest),
242             sizeof(dice::test::kExpectedCdiAttest_HashOnlyInput));
243   EXPECT_EQ(
244       0, memcmp(next_state.cdi_attest,
245                 dice::test::kExpectedCdiAttest_HashOnlyInput, DICE_CDI_SIZE));
246   ASSERT_EQ(sizeof(next_state.cdi_seal),
247             sizeof(dice::test::kExpectedCdiSeal_HashOnlyInput));
248   EXPECT_EQ(
249       0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
250                 DICE_CDI_SIZE));
251   ASSERT_EQ(sizeof(dice::test::kExpectedCborP384Cert_AndroidHashOnlyInput),
252             next_state.certificate_size);
253   constexpr size_t signature_size = 96;
254   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP384Cert_AndroidHashOnlyInput,
255                       next_state.certificate,
256                       next_state.certificate_size - signature_size));
257 }
258 
TEST(DiceOpsTest,Ed25519KnownAnswerDescriptorInput)259 TEST(DiceOpsTest, Ed25519KnownAnswerDescriptorInput) {
260   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
261                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
262   DiceStateForTest current_state = {};
263   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
264   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
265 
266   DiceStateForTest next_state = {};
267 
268   DiceInputValues input_values = {};
269   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
270   uint8_t code_descriptor[100];
271   DeriveFakeInputValue("code_desc", sizeof(code_descriptor), code_descriptor);
272   input_values.code_descriptor = code_descriptor;
273   input_values.code_descriptor_size = sizeof(code_descriptor);
274 
275   uint8_t config_descriptor[40];
276   DeriveFakeInputValue("config_desc", sizeof(config_descriptor),
277                        config_descriptor);
278   input_values.config_descriptor = config_descriptor;
279   input_values.config_descriptor_size = sizeof(config_descriptor);
280   input_values.config_type = kDiceConfigTypeDescriptor;
281 
282   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
283                        input_values.authority_hash);
284   uint8_t authority_descriptor[65];
285   DeriveFakeInputValue("authority_desc", sizeof(authority_descriptor),
286                        authority_descriptor);
287   input_values.authority_descriptor = authority_descriptor;
288   input_values.authority_descriptor_size = sizeof(authority_descriptor);
289 
290   DiceResult result = DiceMainFlow(
291       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
292       sizeof(next_state.certificate), next_state.certificate,
293       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
294   EXPECT_EQ(kDiceResultOk, result);
295   DumpState(CertificateType_Cbor, KeyType_Ed25519, "android_descriptor_input",
296             next_state);
297   // Both CDI values and the certificate should be deterministic.
298   EXPECT_EQ(
299       0, memcmp(next_state.cdi_attest,
300                 dice::test::kExpectedCdiAttest_DescriptorInput, DICE_CDI_SIZE));
301   EXPECT_EQ(
302       0, memcmp(next_state.cdi_seal,
303                 dice::test::kExpectedCdiSeal_DescriptorInput, DICE_CDI_SIZE));
304   ASSERT_EQ(sizeof(dice::test::kExpectedCborEd25519Cert_AndroidDescriptorInput),
305             next_state.certificate_size);
306   EXPECT_EQ(0,
307             memcmp(dice::test::kExpectedCborEd25519Cert_AndroidDescriptorInput,
308                    next_state.certificate, next_state.certificate_size));
309 }
310 
TEST(DiceOpsTest,P256KnownAnswerDescriptorInput)311 TEST(DiceOpsTest, P256KnownAnswerDescriptorInput) {
312   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
313                       .subject_algorithm = kDiceKeyAlgorithmP256};
314   DiceStateForTest current_state = {};
315   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
316   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
317 
318   DiceStateForTest next_state = {};
319 
320   DiceInputValues input_values = {};
321   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
322   uint8_t code_descriptor[100];
323   DeriveFakeInputValue("code_desc", sizeof(code_descriptor), code_descriptor);
324   input_values.code_descriptor = code_descriptor;
325   input_values.code_descriptor_size = sizeof(code_descriptor);
326 
327   uint8_t config_descriptor[40];
328   DeriveFakeInputValue("config_desc", sizeof(config_descriptor),
329                        config_descriptor);
330   input_values.config_descriptor = config_descriptor;
331   input_values.config_descriptor_size = sizeof(config_descriptor);
332   input_values.config_type = kDiceConfigTypeDescriptor;
333 
334   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
335                        input_values.authority_hash);
336   uint8_t authority_descriptor[65];
337   DeriveFakeInputValue("authority_desc", sizeof(authority_descriptor),
338                        authority_descriptor);
339   input_values.authority_descriptor = authority_descriptor;
340   input_values.authority_descriptor_size = sizeof(authority_descriptor);
341 
342   DiceResult result = DiceMainFlow(
343       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
344       sizeof(next_state.certificate), next_state.certificate,
345       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
346   EXPECT_EQ(kDiceResultOk, result);
347   DumpState(CertificateType_Cbor, KeyType_P256, "android_descriptor_input",
348             next_state);
349   // Both CDI values and the certificate should be deterministic.
350   EXPECT_EQ(
351       0, memcmp(next_state.cdi_attest,
352                 dice::test::kExpectedCdiAttest_DescriptorInput, DICE_CDI_SIZE));
353   EXPECT_EQ(
354       0, memcmp(next_state.cdi_seal,
355                 dice::test::kExpectedCdiSeal_DescriptorInput, DICE_CDI_SIZE));
356   ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_AndroidDescriptorInput),
357             next_state.certificate_size);
358   constexpr size_t signature_size = 64;
359   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_AndroidDescriptorInput,
360                       next_state.certificate,
361                       next_state.certificate_size - signature_size));
362 }
363 
TEST(DiceOpsTest,P384KnownAnswerDescriptorInput)364 TEST(DiceOpsTest, P384KnownAnswerDescriptorInput) {
365   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
366                       .subject_algorithm = kDiceKeyAlgorithmP384};
367   DiceStateForTest current_state = {};
368   DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
369   DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
370 
371   DiceStateForTest next_state = {};
372 
373   DiceInputValues input_values = {};
374   DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
375   uint8_t code_descriptor[100];
376   DeriveFakeInputValue("code_desc", sizeof(code_descriptor), code_descriptor);
377   input_values.code_descriptor = code_descriptor;
378   input_values.code_descriptor_size = sizeof(code_descriptor);
379 
380   uint8_t config_descriptor[40];
381   DeriveFakeInputValue("config_desc", sizeof(config_descriptor),
382                        config_descriptor);
383   input_values.config_descriptor = config_descriptor;
384   input_values.config_descriptor_size = sizeof(config_descriptor);
385   input_values.config_type = kDiceConfigTypeDescriptor;
386 
387   DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
388                        input_values.authority_hash);
389   uint8_t authority_descriptor[65];
390   DeriveFakeInputValue("authority_desc", sizeof(authority_descriptor),
391                        authority_descriptor);
392   input_values.authority_descriptor = authority_descriptor;
393   input_values.authority_descriptor_size = sizeof(authority_descriptor);
394 
395   DiceResult result = DiceMainFlow(
396       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
397       sizeof(next_state.certificate), next_state.certificate,
398       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
399   EXPECT_EQ(kDiceResultOk, result);
400   DumpState(CertificateType_Cbor, KeyType_P384, "android_descriptor_input",
401             next_state);
402   // Both CDI values and the certificate should be deterministic.
403   EXPECT_EQ(
404       0, memcmp(next_state.cdi_attest,
405                 dice::test::kExpectedCdiAttest_DescriptorInput, DICE_CDI_SIZE));
406   EXPECT_EQ(
407       0, memcmp(next_state.cdi_seal,
408                 dice::test::kExpectedCdiSeal_DescriptorInput, DICE_CDI_SIZE));
409   ASSERT_EQ(sizeof(dice::test::kExpectedCborP384Cert_AndroidDescriptorInput),
410             next_state.certificate_size);
411   constexpr size_t signature_size = 96;
412   EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP384Cert_AndroidDescriptorInput,
413                       next_state.certificate,
414                       next_state.certificate_size - signature_size));
415 }
416 
TEST(DiceOpsTest,Ed25519NonZeroMode)417 TEST(DiceOpsTest, Ed25519NonZeroMode) {
418   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
419                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
420   constexpr size_t kModeOffsetInCert = 315;
421   DiceStateForTest current_state = {};
422   DiceStateForTest next_state = {};
423   DiceInputValues input_values = {};
424   input_values.mode = kDiceModeDebug;
425   DiceResult result = DiceMainFlow(
426       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
427       sizeof(next_state.certificate), next_state.certificate,
428       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
429   EXPECT_EQ(kDiceResultOk, result);
430   EXPECT_EQ(kDiceModeDebug, next_state.certificate[kModeOffsetInCert]);
431 }
432 
TEST(DiceOpsTest,P256NonZeroMode)433 TEST(DiceOpsTest, P256NonZeroMode) {
434   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
435                       .subject_algorithm = kDiceKeyAlgorithmP256};
436   constexpr size_t kModeOffsetInCert = 315;
437   DiceStateForTest current_state = {};
438   DiceStateForTest next_state = {};
439   DiceInputValues input_values = {};
440   input_values.mode = kDiceModeDebug;
441   DiceResult result = DiceMainFlow(
442       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
443       sizeof(next_state.certificate), next_state.certificate,
444       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
445   EXPECT_EQ(kDiceResultOk, result);
446   EXPECT_EQ(kDiceModeDebug, next_state.certificate[kModeOffsetInCert]);
447 }
448 
TEST(DiceOpsTest,P384NonZeroMode)449 TEST(DiceOpsTest, P384NonZeroMode) {
450   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
451                       .subject_algorithm = kDiceKeyAlgorithmP384};
452   constexpr size_t kModeOffsetInCert = 316;
453   DiceStateForTest current_state = {};
454   DiceStateForTest next_state = {};
455   DiceInputValues input_values = {};
456   input_values.mode = kDiceModeDebug;
457   DiceResult result = DiceMainFlow(
458       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
459       sizeof(next_state.certificate), next_state.certificate,
460       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
461   EXPECT_EQ(kDiceResultOk, result);
462   EXPECT_EQ(kDiceModeDebug, next_state.certificate[kModeOffsetInCert]);
463 }
464 
TEST(DiceOpsTest,Ed25519LargeInputs)465 TEST(DiceOpsTest, Ed25519LargeInputs) {
466   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
467                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
468   constexpr uint8_t kBigBuffer[1024 * 1024] = {};
469   DiceStateForTest current_state = {};
470   DiceStateForTest next_state = {};
471   DiceInputValues input_values = {};
472   input_values.code_descriptor = kBigBuffer;
473   input_values.code_descriptor_size = sizeof(kBigBuffer);
474   DiceResult result = DiceMainFlow(
475       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
476       sizeof(next_state.certificate), next_state.certificate,
477       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
478   EXPECT_EQ(kDiceResultBufferTooSmall, result);
479 }
480 
TEST(DiceOpsTest,P256LargeInputs)481 TEST(DiceOpsTest, P256LargeInputs) {
482   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
483                       .subject_algorithm = kDiceKeyAlgorithmP256};
484   constexpr uint8_t kBigBuffer[1024 * 1024] = {};
485   DiceStateForTest current_state = {};
486   DiceStateForTest next_state = {};
487   DiceInputValues input_values = {};
488   input_values.code_descriptor = kBigBuffer;
489   input_values.code_descriptor_size = sizeof(kBigBuffer);
490   DiceResult result = DiceMainFlow(
491       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
492       sizeof(next_state.certificate), next_state.certificate,
493       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
494   EXPECT_EQ(kDiceResultBufferTooSmall, result);
495 }
496 
TEST(DiceOpsTest,P384LargeInputs)497 TEST(DiceOpsTest, P384LargeInputs) {
498   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
499                       .subject_algorithm = kDiceKeyAlgorithmP384};
500   constexpr uint8_t kBigBuffer[1024 * 1024] = {};
501   DiceStateForTest current_state = {};
502   DiceStateForTest next_state = {};
503   DiceInputValues input_values = {};
504   input_values.code_descriptor = kBigBuffer;
505   input_values.code_descriptor_size = sizeof(kBigBuffer);
506   DiceResult result = DiceMainFlow(
507       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
508       sizeof(next_state.certificate), next_state.certificate,
509       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
510   EXPECT_EQ(kDiceResultBufferTooSmall, result);
511 }
512 
TEST(DiceOpsTest,Ed25519InvalidConfigType)513 TEST(DiceOpsTest, Ed25519InvalidConfigType) {
514   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
515                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
516   DiceStateForTest current_state = {};
517   DiceStateForTest next_state = {};
518   DiceInputValues input_values = {};
519   input_values.config_type = (DiceConfigType)55;
520   DiceResult result = DiceMainFlow(
521       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
522       sizeof(next_state.certificate), next_state.certificate,
523       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
524   EXPECT_EQ(kDiceResultInvalidInput, result);
525 }
526 
TEST(DiceOpsTest,P256InvalidConfigType)527 TEST(DiceOpsTest, P256InvalidConfigType) {
528   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
529                       .subject_algorithm = kDiceKeyAlgorithmP256};
530   DiceStateForTest current_state = {};
531   DiceStateForTest next_state = {};
532   DiceInputValues input_values = {};
533   input_values.config_type = (DiceConfigType)55;
534   DiceResult result = DiceMainFlow(
535       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
536       sizeof(next_state.certificate), next_state.certificate,
537       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
538   EXPECT_EQ(kDiceResultInvalidInput, result);
539 }
540 
TEST(DiceOpsTest,P384InvalidConfigType)541 TEST(DiceOpsTest, P384InvalidConfigType) {
542   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
543                       .subject_algorithm = kDiceKeyAlgorithmP384};
544   DiceStateForTest current_state = {};
545   DiceStateForTest next_state = {};
546   DiceInputValues input_values = {};
547   input_values.config_type = (DiceConfigType)55;
548   DiceResult result = DiceMainFlow(
549       &context, current_state.cdi_attest, current_state.cdi_seal, &input_values,
550       sizeof(next_state.certificate), next_state.certificate,
551       &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
552   EXPECT_EQ(kDiceResultInvalidInput, result);
553 }
554 
TEST(DiceOpsTest,Ed25519PartialCertChain)555 TEST(DiceOpsTest, Ed25519PartialCertChain) {
556   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
557                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
558   constexpr size_t kNumLayers = 7;
559   DiceStateForTest states[kNumLayers + 1] = {};
560   DiceInputValues inputs[kNumLayers] = {};
561   for (size_t i = 0; i < kNumLayers; ++i) {
562     char seed[40];
563     pw::string::Format(seed, "code_hash_%zu", i);
564     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
565     pw::string::Format(seed, "authority_hash_%zu", i);
566     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
567     inputs[i].config_type = kDiceConfigTypeInline;
568     pw::string::Format(seed, "inline_config_%zu", i);
569     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
570     inputs[i].mode = kDiceModeNormal;
571     EXPECT_EQ(
572         kDiceResultOk,
573         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
574                      &inputs[i], sizeof(states[i + 1].certificate),
575                      states[i + 1].certificate, &states[i + 1].certificate_size,
576                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
577     char suffix[40];
578     pw::string::Format(suffix, "part_cert_chain_%zu", i);
579     DumpState(CertificateType_Cbor, KeyType_Ed25519, suffix, states[i + 1]);
580   }
581   // Use the first derived CDI cert as the 'root' of partial chain.
582   EXPECT_TRUE(dice::test::VerifyCertificateChain(
583       CertificateType_Cbor, states[1].certificate, states[1].certificate_size,
584       &states[2], kNumLayers - 1, /*is_partial_chain=*/true));
585 }
586 
TEST(DiceOpsTest,P256PartialCertChain)587 TEST(DiceOpsTest, P256PartialCertChain) {
588   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
589                       .subject_algorithm = kDiceKeyAlgorithmP256};
590   constexpr size_t kNumLayers = 7;
591   DiceStateForTest states[kNumLayers + 1] = {};
592   DiceInputValues inputs[kNumLayers] = {};
593   for (size_t i = 0; i < kNumLayers; ++i) {
594     char seed[40];
595     pw::string::Format(seed, "code_hash_%zu", i);
596     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
597     pw::string::Format(seed, "authority_hash_%zu", i);
598     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
599     inputs[i].config_type = kDiceConfigTypeInline;
600     pw::string::Format(seed, "inline_config_%zu", i);
601     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
602     inputs[i].mode = kDiceModeNormal;
603     EXPECT_EQ(
604         kDiceResultOk,
605         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
606                      &inputs[i], sizeof(states[i + 1].certificate),
607                      states[i + 1].certificate, &states[i + 1].certificate_size,
608                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
609     char suffix[40];
610     pw::string::Format(suffix, "part_cert_chain_%zu", i);
611     DumpState(CertificateType_Cbor, KeyType_P256, suffix, states[i + 1]);
612   }
613   // Use the first derived CDI cert as the 'root' of partial chain.
614   EXPECT_TRUE(dice::test::VerifyCertificateChain(
615       CertificateType_Cbor, states[1].certificate, states[1].certificate_size,
616       &states[2], kNumLayers - 1, /*is_partial_chain=*/true));
617 }
618 
TEST(DiceOpsTest,P384PartialCertChain)619 TEST(DiceOpsTest, P384PartialCertChain) {
620   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
621                       .subject_algorithm = kDiceKeyAlgorithmP384};
622   constexpr size_t kNumLayers = 7;
623   DiceStateForTest states[kNumLayers + 1] = {};
624   DiceInputValues inputs[kNumLayers] = {};
625   for (size_t i = 0; i < kNumLayers; ++i) {
626     char seed[40];
627     pw::string::Format(seed, "code_hash_%zu", i);
628     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
629     pw::string::Format(seed, "authority_hash_%zu", i);
630     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
631     inputs[i].config_type = kDiceConfigTypeInline;
632     pw::string::Format(seed, "inline_config_%zu", i);
633     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
634     inputs[i].mode = kDiceModeNormal;
635     EXPECT_EQ(
636         kDiceResultOk,
637         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
638                      &inputs[i], sizeof(states[i + 1].certificate),
639                      states[i + 1].certificate, &states[i + 1].certificate_size,
640                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
641     char suffix[40];
642     pw::string::Format(suffix, "part_cert_chain_%zu", i);
643     DumpState(CertificateType_Cbor, KeyType_P384, suffix, states[i + 1]);
644   }
645   // Use the first derived CDI cert as the 'root' of partial chain.
646   EXPECT_TRUE(dice::test::VerifyCertificateChain(
647       CertificateType_Cbor, states[1].certificate, states[1].certificate_size,
648       &states[2], kNumLayers - 1, /*is_partial_chain=*/true));
649 }
650 
TEST(DiceOpsTest,Ed25519FullCertChain)651 TEST(DiceOpsTest, Ed25519FullCertChain) {
652   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmEd25519,
653                       .subject_algorithm = kDiceKeyAlgorithmEd25519};
654   constexpr size_t kNumLayers = 7;
655   DiceStateForTest states[kNumLayers + 1] = {};
656   DiceInputValues inputs[kNumLayers] = {};
657   for (size_t i = 0; i < kNumLayers; ++i) {
658     char seed[40];
659     pw::string::Format(seed, "code_hash_%zu", i);
660     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
661     pw::string::Format(seed, "authority_hash_%zu", i);
662     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
663     inputs[i].config_type = kDiceConfigTypeInline;
664     pw::string::Format(seed, "inline_config_%zu", i);
665     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
666     inputs[i].mode = kDiceModeNormal;
667     EXPECT_EQ(
668         kDiceResultOk,
669         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
670                      &inputs[i], sizeof(states[i + 1].certificate),
671                      states[i + 1].certificate, &states[i + 1].certificate_size,
672                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
673     char suffix[40];
674     pw::string::Format(suffix, "full_cert_chain_%zu", i);
675     DumpState(CertificateType_Cbor, KeyType_Ed25519, suffix, states[i + 1]);
676   }
677   // Use a fake self-signed UDS cert as the 'root'.
678   uint8_t root_certificate[dice::test::kTestCertSize];
679   size_t root_certificate_size = 0;
680   dice::test::CreateFakeUdsCertificate(
681       &context, states[0].cdi_attest, CertificateType_Cbor, KeyType_Ed25519,
682       root_certificate, &root_certificate_size);
683   EXPECT_TRUE(dice::test::VerifyCertificateChain(
684       CertificateType_Cbor, root_certificate, root_certificate_size, &states[1],
685       kNumLayers, /*is_partial_chain=*/false));
686 }
687 
TEST(DiceOpsTest,P256FullCertChain)688 TEST(DiceOpsTest, P256FullCertChain) {
689   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP256,
690                       .subject_algorithm = kDiceKeyAlgorithmP256};
691   constexpr size_t kNumLayers = 7;
692   DiceStateForTest states[kNumLayers + 1] = {};
693   DiceInputValues inputs[kNumLayers] = {};
694   for (size_t i = 0; i < kNumLayers; ++i) {
695     char seed[40];
696     pw::string::Format(seed, "code_hash_%zu", i);
697     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
698     pw::string::Format(seed, "authority_hash_%zu", i);
699     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
700     inputs[i].config_type = kDiceConfigTypeInline;
701     pw::string::Format(seed, "inline_config_%zu", i);
702     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
703     inputs[i].mode = kDiceModeNormal;
704     EXPECT_EQ(
705         kDiceResultOk,
706         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
707                      &inputs[i], sizeof(states[i + 1].certificate),
708                      states[i + 1].certificate, &states[i + 1].certificate_size,
709                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
710     char suffix[40];
711     pw::string::Format(suffix, "full_cert_chain_%zu", i);
712     DumpState(CertificateType_Cbor, KeyType_P256, suffix, states[i + 1]);
713   }
714   // Use a fake self-signed UDS cert as the 'root'.
715   uint8_t root_certificate[dice::test::kTestCertSize];
716   size_t root_certificate_size = 0;
717   dice::test::CreateFakeUdsCertificate(
718       &context, states[0].cdi_attest, CertificateType_Cbor, KeyType_P256,
719       root_certificate, &root_certificate_size);
720   EXPECT_TRUE(dice::test::VerifyCertificateChain(
721       CertificateType_Cbor, root_certificate, root_certificate_size, &states[1],
722       kNumLayers, /*is_partial_chain=*/false));
723 }
724 
TEST(DiceOpsTest,P384FullCertChain)725 TEST(DiceOpsTest, P384FullCertChain) {
726   DiceContext context{.authority_algorithm = kDiceKeyAlgorithmP384,
727                       .subject_algorithm = kDiceKeyAlgorithmP384};
728   constexpr size_t kNumLayers = 7;
729   DiceStateForTest states[kNumLayers + 1] = {};
730   DiceInputValues inputs[kNumLayers] = {};
731   for (size_t i = 0; i < kNumLayers; ++i) {
732     char seed[40];
733     pw::string::Format(seed, "code_hash_%zu", i);
734     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
735     pw::string::Format(seed, "authority_hash_%zu", i);
736     DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
737     inputs[i].config_type = kDiceConfigTypeInline;
738     pw::string::Format(seed, "inline_config_%zu", i);
739     DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
740     inputs[i].mode = kDiceModeNormal;
741     EXPECT_EQ(
742         kDiceResultOk,
743         DiceMainFlow(&context, states[i].cdi_attest, states[i].cdi_seal,
744                      &inputs[i], sizeof(states[i + 1].certificate),
745                      states[i + 1].certificate, &states[i + 1].certificate_size,
746                      states[i + 1].cdi_attest, states[i + 1].cdi_seal));
747     char suffix[40];
748     pw::string::Format(suffix, "full_cert_chain_%zu", i);
749     DumpState(CertificateType_Cbor, KeyType_P384, suffix, states[i + 1]);
750   }
751   // Use a fake self-signed UDS cert as the 'root'.
752   uint8_t root_certificate[dice::test::kTestCertSize];
753   size_t root_certificate_size = 0;
754   dice::test::CreateFakeUdsCertificate(
755       &context, states[0].cdi_attest, CertificateType_Cbor, KeyType_P384,
756       root_certificate, &root_certificate_size);
757   EXPECT_TRUE(dice::test::VerifyCertificateChain(
758       CertificateType_Cbor, root_certificate, root_certificate_size, &states[1],
759       kNumLayers, /*is_partial_chain=*/false));
760 }
761 
762 }  // namespace
763