aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Stokes <alanstokes@google.com>2023-11-02 15:04:49 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-02 15:04:49 +0000
commit3b910a3559b2dfe796554c39b473b875e274f265 (patch)
tree0706cf0acb631d0d098cbed0083dba8c55af2919
parenteb9bc11634396c19cf1eaac6fc16bbbaee4e684d (diff)
parentc4440e8add8407fa054cdffca825025bf421277a (diff)
downloadopen-dice-3b910a3559b2dfe796554c39b473b875e274f265.tar.gz
Merge upstream changes am: c4440e8add
Original change: https://android-review.googlesource.com/c/platform/external/open-dice/+/2813137 Change-Id: I556bc55b152831826d73c7d4908b7f0c0cb482cc Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--docs/android.md32
-rw-r--r--include/dice/android.h4
-rw-r--r--include/dice/test_utils.h9
-rw-r--r--pigweed.json10
-rw-r--r--src/cbor_cert_op.c131
-rw-r--r--src/cbor_cert_op_test.cc89
-rw-r--r--src/test_utils.cc64
-rw-r--r--tools/open_dice_tools/presubmit.py2
8 files changed, 280 insertions, 61 deletions
diff --git a/docs/android.md b/docs/android.md
index f41e6b1..fd65f12 100644
--- a/docs/android.md
+++ b/docs/android.md
@@ -76,19 +76,12 @@ of the reserved range.
Unless explicitly stated as required in the [versions](#versions) section, each
field is optional. If no fields are relevant, an empty map should be encoded.
-```
-| Name | Key | Value type | Meaning |
-| ----------------- | ------ | ---------- | -----------------------------------|
-| Component name | -70002 | tstr | Name of the component |
-| Component version | -70003 | int / tstr | Version of the component |
-| Resettable | -70004 | null | If present, key changes on factory |
-: : : : reset :
-| Security version | -70005 | uint | Machine-comparable, monotonically |
-: : : : increasing version of the component:
-: : : : where a greater value indicates a :
-: : : : newer version, for example, the :
-: : : : anti-rollback counter :
-```
+Name | Key | Value type | Meaning
+--- | --- | --- | ---
+Component&nbsp;name | -70002 | tstr | Name of the component
+Component&nbsp;version | -70003 | int&nbsp;/&nbsp;tstr | Version of the component
+Resettable | -70004 | null | If present, key changes on factory reset
+Security&nbsp;version | -70005 | uint | Machine-comparable, monotonically increasing version of the component where a greater value indicates a newer version, for example, the anti-rollback counter
### Versions
@@ -99,15 +92,16 @@ updates and lower-level software (such as ROM) that might not update.
Versions of this profile are identified by their profile name which is composed
of the prefix `"android."` followed by the Android version number it aligns
-with. If no profile name is included in the certificate, `"android.14"` is
-assumed.
+with. Certificates declare which profile they are following in the `profileName`
+field defined by the [Open Profile for DICE](specification.md). If no profile
+name is included in the certificate, `"android.14"` is assumed.
Within a DICE chain, the version of the profile used in each certificate must
be the same or greater than the version used in the previous certificate. This
ensures the all certificates are aware of, and can maintain, any chain
invariants that can be added in any version of the profile.
-Android provides the [`hwtrust`](hwtrust-tool) tool which can validate that
+Android provides the [`hwtrust`][hwtrust-tool] tool which can validate that
certificate chains conform to this profile and can assist in diagnosing
problems.
@@ -132,7 +126,8 @@ The profile named `"android.14"` aligns with Android 14.
#### `"android.15"`
-The profile named `"android.15"` aligns with Android 15.
+The profile named `"android.15"` aligns with Android 15. It is backwards
+compatible with the previous versions of the Andorid Profile for DICE.
* Based on the [Open Profile for DICE v2.5][open-dice-v2.5].
* The `configurationHash` field is permitted to be missing rather than being
@@ -141,7 +136,8 @@ The profile named `"android.15"` aligns with Android 15.
#### `"android.16"`
The profile named `"android.16"` aligns with Android 16 and is still subject to
-change.
+change. It is backwards compatible with the previous versions of the Android
+Profile for DICE.
* Based on the [Open Profile for DICE v2.5][open-dice-v2.5].
* The security version field of the [configuration
diff --git a/include/dice/android.h b/include/dice/android.h
index 5ca1f8b..7a64cc6 100644
--- a/include/dice/android.h
+++ b/include/dice/android.h
@@ -29,8 +29,8 @@ extern "C" {
#define DICE_ANDROID_CONFIG_SECURITY_VERSION (1 << 3)
// Contains the input values used to construct the Android Profile for DICE
-// configuration descriptor. Optional fields are selected in the |inputs|
-// bitfield.
+// configuration descriptor. The fields to include in the configuration
+// descriptor are selected in the |configs| bitfield.
//
// Fields:
// configs: A bitfield selecting the config fields to include.
diff --git a/include/dice/test_utils.h b/include/dice/test_utils.h
index 70469c4..7e403b9 100644
--- a/include/dice/test_utils.h
+++ b/include/dice/test_utils.h
@@ -58,6 +58,15 @@ void CreateFakeUdsCertificate(void* context, const uint8_t uds[32],
uint8_t certificate[kTestCertSize],
size_t* certificate_size);
+// Verify that a single CDI certificate is properly signed with the given key
+// and contains the expected payload.
+bool VerifyCoseSign1(const uint8_t* certificate, size_t certificate_size,
+ const uint8_t* external_aad, size_t external_aad_size,
+ const uint8_t* encoded_public_key,
+ size_t encoded_public_key_size,
+ const uint8_t* expected_payload,
+ size_t expected_payload_size);
+
// Verifies a chain of CDI certificates given by |states| against
// |root_certificate|. If |is_partial_chain| is set, then root_certificate does
// not need to be self signed. For X.509 certificate chains, only the standard
diff --git a/pigweed.json b/pigweed.json
index 11071ff..72b5934 100644
--- a/pigweed.json
+++ b/pigweed.json
@@ -11,14 +11,16 @@
"pw_presubmit": {
"format": {
"python_formatter": "black",
- "exclude": [
- "third_party/.*/src",
- "third_party/boringssl/err_data.c"
- ]
+ "exclude": [
+ "third_party/.*/src",
+ "third_party/boringssl/err_data.c",
+ "^patches\\.json$"
+ ]
}
},
"pw_env_setup": {
"root_variable": "OPEN_DICE_ROOT",
+ "relative_pigweed_root": "third_party/pigweed/src",
"cipd_package_files": [
"third_party/pigweed/src/pw_env_setup/py/pw_env_setup/cipd_setup/default.json"
],
diff --git a/src/cbor_cert_op.c b/src/cbor_cert_op.c
index 4b6d171..5416958 100644
--- a/src/cbor_cert_op.c
+++ b/src/cbor_cert_op.c
@@ -26,8 +26,6 @@
#include "dice/ops/trait/cose.h"
#include "dice/utils.h"
-// Max size of COSE_Sign1 including payload.
-#define DICE_MAX_CERTIFICATE_SIZE 2048
// Max size of COSE_Key encoding.
#define DICE_MAX_PUBLIC_KEY_SIZE (DICE_PUBLIC_KEY_SIZE + 32)
// Max size of the COSE_Sign1 protected attributes.
@@ -53,9 +51,9 @@ static DiceResult EncodeProtectedAttributes(size_t buffer_size, uint8_t* buffer,
static DiceResult EncodeCoseTbs(const uint8_t* protected_attributes,
size_t protected_attributes_size,
- const uint8_t* payload, size_t payload_size,
- const uint8_t* aad, size_t aad_size,
- size_t buffer_size, uint8_t* buffer,
+ size_t payload_size, const uint8_t* aad,
+ size_t aad_size, size_t buffer_size,
+ uint8_t* buffer, uint8_t** payload,
size_t* encoded_size) {
struct CborOut out;
CborOutInit(buffer, buffer_size, &out);
@@ -67,8 +65,8 @@ static DiceResult EncodeCoseTbs(const uint8_t* protected_attributes,
CborWriteBstr(protected_attributes_size, protected_attributes, &out);
// Additional authenticated data.
CborWriteBstr(aad_size, aad, &out);
- // Payload from COSE_Sign1.
- CborWriteBstr(payload_size, payload, &out);
+ // Space for the payload, to be filled in by the caller.
+ *payload = CborAllocBstr(payload_size, &out);
*encoded_size = CborOutSize(&out);
if (CborOutOverflowed(&out)) {
return kDiceResultBufferTooSmall;
@@ -79,6 +77,7 @@ static DiceResult EncodeCoseTbs(const uint8_t* protected_attributes,
static DiceResult EncodeCoseSign1(const uint8_t* protected_attributes,
size_t protected_attributes_size,
const uint8_t* payload, size_t payload_size,
+ bool move_payload,
const uint8_t signature[DICE_SIGNATURE_SIZE],
size_t buffer_size, uint8_t* buffer,
size_t* encoded_size) {
@@ -91,7 +90,21 @@ static DiceResult EncodeCoseSign1(const uint8_t* protected_attributes,
// Empty map for unprotected attributes.
CborWriteMap(/*num_pairs=*/0, &out);
// Payload.
- CborWriteBstr(payload_size, payload, &out);
+ if (move_payload) {
+ // The payload is already present in the buffer, so we can move it into
+ // place.
+ uint8_t* payload_alloc = CborAllocBstr(payload_size, &out);
+ if (payload_alloc) {
+ // We're assuming what we've written above is small enough that it doesn't
+ // overwrite the payload. Check in case that stops being true.
+ if (payload < payload_alloc) {
+ return kDiceResultPlatformError;
+ }
+ memmove(payload_alloc, payload, payload_size);
+ }
+ } else {
+ CborWriteBstr(payload_size, payload, &out);
+ }
// Signature.
CborWriteBstr(/*num_elements=*/DICE_SIGNATURE_SIZE, signature, &out);
*encoded_size = CborOutSize(&out);
@@ -123,20 +136,22 @@ DiceResult DiceCoseSignAndEncodeSign1(
// Construct a To-Be-Signed (TBS) structure based on the relevant fields of
// the COSE_Sign1.
+ uint8_t* payload_buffer;
result = EncodeCoseTbs(protected_attributes, protected_attributes_size,
- payload, payload_size, aad, aad_size, buffer_size,
- buffer, encoded_size);
+ payload_size, aad, aad_size, buffer_size, buffer,
+ &payload_buffer, encoded_size);
if (result != kDiceResultOk) {
// Check how big the buffer needs to be in total.
size_t final_encoded_size = 0;
EncodeCoseSign1(protected_attributes, protected_attributes_size, payload,
- payload_size, /*signature=*/NULL, /*buffer_size=*/0,
- /*buffer=*/NULL, &final_encoded_size);
+ payload_size, /*move_payload=*/false, /*signature=*/NULL,
+ /*buffer_size=*/0, /*buffer=*/NULL, &final_encoded_size);
if (*encoded_size < final_encoded_size) {
*encoded_size = final_encoded_size;
}
return result;
}
+ memcpy(payload_buffer, payload, payload_size);
// Sign the TBS with the authority key.
uint8_t signature[DICE_SIGNATURE_SIZE];
@@ -147,8 +162,8 @@ DiceResult DiceCoseSignAndEncodeSign1(
// The final certificate is an untagged COSE_Sign1 structure.
return EncodeCoseSign1(protected_attributes, protected_attributes_size,
- payload, payload_size, signature, buffer_size, buffer,
- encoded_size);
+ payload, payload_size, /*move_payload=*/false,
+ signature, buffer_size, buffer, encoded_size);
}
// Encodes a CBOR Web Token (CWT) with an issuer, subject, and additional
@@ -214,11 +229,14 @@ static DiceResult EncodeCwt(void* context, const DiceInputValues* input_values,
// Add the config inputs.
if (input_values->config_type == kDiceConfigTypeDescriptor) {
uint8_t config_descriptor_hash[DICE_HASH_SIZE];
- DiceResult result =
- DiceHash(context, input_values->config_descriptor,
- input_values->config_descriptor_size, config_descriptor_hash);
- if (result != kDiceResultOk) {
- return result;
+ // Skip hashing if we're not going to use the answer.
+ if (!CborOutOverflowed(&out)) {
+ DiceResult result = DiceHash(context, input_values->config_descriptor,
+ input_values->config_descriptor_size,
+ config_descriptor_hash);
+ if (result != kDiceResultOk) {
+ return result;
+ }
}
// Add the config descriptor.
CborWriteInt(kConfigDescriptorLabel, &out);
@@ -329,20 +347,77 @@ DiceResult DiceGenerateCertificate(
goto out;
}
- // The CWT is the payload in both the TBS and the final COSE_Sign1 structure.
- uint8_t payload[DICE_MAX_CERTIFICATE_SIZE];
- size_t payload_size = 0;
+ // The encoded protected attributes are used in the TBS and the final
+ // COSE_Sign1 structure.
+ uint8_t protected_attributes[DICE_MAX_PROTECTED_ATTRIBUTES_SIZE];
+ size_t protected_attributes_size = 0;
+ result = EncodeProtectedAttributes(sizeof(protected_attributes),
+ protected_attributes,
+ &protected_attributes_size);
+ if (result != kDiceResultOk) {
+ result = kDiceResultPlatformError;
+ goto out;
+ }
+
+ // Find out how big the CWT will be.
+ size_t cwt_size;
+ EncodeCwt(context, input_values, authority_id_hex, subject_id_hex,
+ encoded_public_key, encoded_public_key_size, /*buffer_size=*/0,
+ /*buffer=*/NULL, &cwt_size);
+
+ // We need space to assemble the TBS. The size of the buffer needed depends on
+ // the size of the CWT, which is outside our control (e.g. it might have a
+ // very large config descriptor). So we use the certificate buffer as
+ // temporary storage; if we run out of space we will make sure the caller
+ // knows the size we actually need for this.
+ // Encode the TBS, leaving space for the final payload (the CWT).
+ uint8_t* cwt_ptr;
+ size_t tbs_size;
+ result =
+ EncodeCoseTbs(protected_attributes, protected_attributes_size, cwt_size,
+ /*aad=*/NULL, /*aad_size=*/0, certificate_buffer_size,
+ certificate, &cwt_ptr, &tbs_size);
+
+ if (result != kDiceResultOk) {
+ // There wasn't enough space to put together the TBS. The total buffer size
+ // we need is either the amount needed for the TBS, or the amount needed for
+ // encoded payload and signature.
+ size_t final_encoded_size = 0;
+ EncodeCoseSign1(protected_attributes, protected_attributes_size, cwt_ptr,
+ cwt_size, /*move_payload=*/false, /*signature=*/NULL,
+ /*buffer_size=*/0, /*buffer=*/NULL, &final_encoded_size);
+ *certificate_actual_size =
+ final_encoded_size > tbs_size ? final_encoded_size : tbs_size;
+ result = kDiceResultBufferTooSmall;
+ goto out;
+ }
+
+ // Now we can encode the payload directly into the allocated BSTR in the TBS.
+ size_t final_cwt_size;
result = EncodeCwt(context, input_values, authority_id_hex, subject_id_hex,
- encoded_public_key, encoded_public_key_size,
- sizeof(payload), payload, &payload_size);
+ encoded_public_key, encoded_public_key_size, cwt_size,
+ cwt_ptr, &final_cwt_size);
+ if (result == kDiceResultBufferTooSmall || final_cwt_size != cwt_size) {
+ result = kDiceResultPlatformError;
+ }
+ if (result != kDiceResultOk) {
+ goto out;
+ }
+
+ // Sign the now-complete TBS.
+ uint8_t signature[DICE_SIGNATURE_SIZE];
+ result = DiceSign(context, certificate, tbs_size, authority_private_key,
+ signature);
if (result != kDiceResultOk) {
goto out;
}
- result = DiceCoseSignAndEncodeSign1(
- context, payload, payload_size, /*aad=*/NULL, /*aad_size=*/0,
- authority_private_key, certificate_buffer_size, certificate,
- certificate_actual_size);
+ // And now we can produce the complete CoseSign1, including the signature, and
+ // moving the payload into place as we do it.
+ result = EncodeCoseSign1(protected_attributes, protected_attributes_size,
+ cwt_ptr, cwt_size, /*move_payload=*/true, signature,
+ certificate_buffer_size, certificate,
+ certificate_actual_size);
out:
DiceClearMemory(context, sizeof(subject_private_key), subject_private_key);
diff --git a/src/cbor_cert_op_test.cc b/src/cbor_cert_op_test.cc
index 94a437b..46ae094 100644
--- a/src/cbor_cert_op_test.cc
+++ b/src/cbor_cert_op_test.cc
@@ -20,6 +20,8 @@
#include "dice/dice.h"
#include "dice/known_test_values.h"
+#include "dice/ops.h"
+#include "dice/ops/trait/cose.h"
#include "dice/test_framework.h"
#include "dice/test_utils.h"
#include "dice/utils.h"
@@ -31,6 +33,7 @@ using dice::test::CertificateType_Cbor;
using dice::test::DeriveFakeInputValue;
using dice::test::DiceStateForTest;
using dice::test::KeyType_Ed25519;
+using dice::test::VerifyCoseSign1;
TEST(DiceOpsTest, KnownAnswerZeroInput) {
DiceStateForTest current_state = {};
@@ -179,6 +182,47 @@ TEST(DiceOpsTest, LargeInputs) {
EXPECT_EQ(kDiceResultBufferTooSmall, result);
}
+TEST(DiceOpsTest, LargeDescriptor) {
+ DiceStateForTest current_state = {};
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+
+ uint8_t config_descriptor[10 * 1000];
+ DeriveFakeInputValue("config_desc", sizeof(config_descriptor),
+ config_descriptor);
+ input_values.config_descriptor = config_descriptor;
+ input_values.config_descriptor_size = sizeof(config_descriptor);
+ input_values.config_type = kDiceConfigTypeDescriptor;
+
+ uint8_t next_certificate[20 * 1000];
+ size_t next_certificate_size = 0;
+ size_t buffer_size = 0;
+
+ DiceResult result = DiceMainFlow(
+ NULL, current_state.cdi_attest, current_state.cdi_seal, &input_values,
+ buffer_size, next_certificate, &next_certificate_size,
+ next_state.cdi_attest, next_state.cdi_seal);
+ EXPECT_EQ(kDiceResultBufferTooSmall, result);
+
+ // If this fails, the test is wrong, and we need to make next_certificate
+ // bigger.
+ ASSERT_LE(next_certificate_size, sizeof(next_certificate));
+
+ buffer_size = next_certificate_size - 1;
+ result = DiceMainFlow(NULL, current_state.cdi_attest, current_state.cdi_seal,
+ &input_values, buffer_size, next_certificate,
+ &next_certificate_size, next_state.cdi_attest,
+ next_state.cdi_seal);
+ EXPECT_EQ(kDiceResultBufferTooSmall, result);
+
+ buffer_size = next_certificate_size;
+ result = DiceMainFlow(NULL, current_state.cdi_attest, current_state.cdi_seal,
+ &input_values, buffer_size, next_certificate,
+ &next_certificate_size, next_state.cdi_attest,
+ next_state.cdi_seal);
+ EXPECT_EQ(kDiceResultOk, result);
+}
+
TEST(DiceOpsTest, InvalidConfigType) {
DiceStateForTest current_state = {};
DiceStateForTest next_state = {};
@@ -191,6 +235,51 @@ TEST(DiceOpsTest, InvalidConfigType) {
EXPECT_EQ(kDiceResultInvalidInput, result);
}
+TEST(DiceOpsTest, CoseSignAndEncodeSign1) {
+ DiceStateForTest current_state = {};
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+ DiceResult result = DiceMainFlow(
+ NULL, current_state.cdi_attest, current_state.cdi_seal, &input_values,
+ sizeof(next_state.certificate), next_state.certificate,
+ &next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
+ ASSERT_EQ(kDiceResultOk, result);
+
+ uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE];
+ result = DiceDeriveCdiPrivateKeySeed(NULL, next_state.cdi_attest,
+ private_key_seed);
+ ASSERT_EQ(kDiceResultOk, result);
+
+ uint8_t private_key[DICE_PRIVATE_KEY_SIZE];
+ uint8_t public_key[DICE_PUBLIC_KEY_SIZE];
+ result = DiceKeypairFromSeed(NULL, private_key_seed, public_key, private_key);
+ ASSERT_EQ(kDiceResultOk, result);
+
+ uint8_t encoded_public_key[DICE_PUBLIC_KEY_SIZE + 32];
+ size_t encoded_public_key_size = 0;
+ result =
+ DiceCoseEncodePublicKey(NULL, public_key, sizeof(encoded_public_key),
+ encoded_public_key, &encoded_public_key_size);
+ ASSERT_EQ(kDiceResultOk, result);
+
+ uint8_t payload[500];
+ DeriveFakeInputValue("payload", sizeof(payload), payload);
+
+ uint8_t aad[100];
+ DeriveFakeInputValue("aad", sizeof(aad), aad);
+
+ uint8_t sign1[1000];
+ size_t sign1_size;
+ result = DiceCoseSignAndEncodeSign1(NULL, payload, sizeof(payload), aad,
+ sizeof(aad), private_key, sizeof(sign1),
+ sign1, &sign1_size);
+ ASSERT_EQ(kDiceResultOk, result);
+
+ EXPECT_TRUE(VerifyCoseSign1(sign1, sign1_size, aad, sizeof(aad),
+ encoded_public_key, encoded_public_key_size,
+ payload, sizeof(payload)));
+}
+
TEST(DiceOpsTest, PartialCertChain) {
constexpr size_t kNumLayers = 7;
DiceStateForTest states[kNumLayers + 1] = {};
diff --git a/src/test_utils.cc b/src/test_utils.cc
index 12663cc..f8899e0 100644
--- a/src/test_utils.cc
+++ b/src/test_utils.cc
@@ -628,13 +628,11 @@ bool ValidateCborCertificateCdiFields(const cn_cbor* cwt,
return true;
}
-bool VerifySingleCborCertificate(const uint8_t* certificate,
- size_t certificate_size,
- const cn_cbor* authority_public_key,
- const char authority_id_hex[40],
- bool expect_cdi_certificate,
- ScopedCbor* subject_public_key,
- char subject_id_hex[40]) {
+bool VerifyCoseSign1Signature(const uint8_t* certificate,
+ size_t certificate_size,
+ const uint8_t* external_aad,
+ size_t external_aad_size,
+ const cn_cbor* authority_public_key) {
// Use the COSE-C library to decode and validate.
cose_errback error;
int struct_type = 0;
@@ -643,12 +641,26 @@ bool VerifySingleCborCertificate(const uint8_t* certificate,
if (!sign1) {
return false;
}
- (void)authority_public_key;
+ COSE_Sign1_SetExternal(sign1, external_aad, external_aad_size, &error);
bool result = COSE_Sign1_validate(sign1, authority_public_key, &error);
COSE_Sign1_Free(sign1);
if (!result) {
return false;
}
+ return true;
+}
+
+bool VerifySingleCborCertificate(const uint8_t* certificate,
+ size_t certificate_size,
+ const cn_cbor* authority_public_key,
+ const char authority_id_hex[40],
+ bool expect_cdi_certificate,
+ ScopedCbor* subject_public_key,
+ char subject_id_hex[40]) {
+ if (!VerifyCoseSign1Signature(certificate, certificate_size, /*aad=*/NULL,
+ /*aad_size=*/0, authority_public_key)) {
+ return false;
+ }
ScopedCbor cwt(ExtractCwtFromCborCertificate(certificate, certificate_size));
if (!cwt) {
@@ -785,6 +797,42 @@ void CreateFakeUdsCertificate(void* context, const uint8_t uds[32],
DumpToFile(filename, certificate, *certificate_size);
}
+[[maybe_unused]] bool VerifyCoseSign1(
+ const uint8_t* certificate, size_t certificate_size,
+ const uint8_t* external_aad, size_t external_aad_size,
+ const uint8_t* encoded_public_key, size_t encoded_public_key_size,
+ const uint8_t* expected_cwt, size_t expected_cwt_size) {
+ cn_cbor_errback error;
+ ScopedCbor public_key(
+ cn_cbor_decode(encoded_public_key, encoded_public_key_size, &error));
+ if (!public_key) {
+ return false;
+ }
+
+ if (!VerifyCoseSign1Signature(certificate, certificate_size, external_aad,
+ external_aad_size, public_key.get())) {
+ return false;
+ }
+
+ ScopedCbor sign1(cn_cbor_decode(certificate, certificate_size, &error));
+ if (!sign1 || sign1->type != CN_CBOR_ARRAY || sign1->length != 4) {
+ return false;
+ }
+ cn_cbor* payload = cn_cbor_index(sign1.get(), 2);
+ if (!payload || payload->type != CN_CBOR_BYTES) {
+ return false;
+ }
+
+ if (payload->length != expected_cwt_size) {
+ return false;
+ }
+
+ if (memcmp(payload->v.bytes, expected_cwt, expected_cwt_size) != 0) {
+ return false;
+ }
+ return true;
+}
+
bool VerifyCertificateChain(CertificateType cert_type,
const uint8_t* root_certificate,
size_t root_certificate_size,
diff --git a/tools/open_dice_tools/presubmit.py b/tools/open_dice_tools/presubmit.py
index 48752ae..74d8ebb 100644
--- a/tools/open_dice_tools/presubmit.py
+++ b/tools/open_dice_tools/presubmit.py
@@ -114,7 +114,7 @@ def run(install: bool, exclude: list, **presubmit_args) -> int:
[
"python",
"-m",
- "sample_project_tools.presubmit_checks",
+ "open_dice_tools.presubmit",
"--base",
"origin/main..HEAD",
"--program",