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