Add boringssl P-256 operations for CBOR certificates
The P-256 implementation follows the general example of the existing
P-384, but uses different cryptographic algorithms.
There was overlap with the existing mbedtls P-256 implementation for
X.509 certificates that showed an incompatibility in the derivation of
the certificate ID. The mbedtls X.509 implementation uses the compressed
public key format to derive the certificate ID, whereas the boringssl
CBOR implementation uses the X|Y format for the public key. To work
around this, the tests are enhanced to handle the two different cases.
Bug: 341630707
Change-Id: I391976b0426f2e91e5f0410c86073530e4f6b141
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/215611
Commit-Queue: Andrew Scull <ascull@google.com>
Reviewed-by: Darren Krahn <dkrahn@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
diff --git a/BUILD.gn b/BUILD.gn
index 655230c..eb43c80 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -59,6 +59,10 @@
include_dirs = [ "//include/dice/config/boringssl_ed25519" ]
}
+config("boringssl_ecdsa_p256_ops_config") {
+ include_dirs = [ "//include/dice/config/boringssl_ecdsa_p256" ]
+}
+
config("boringssl_ecdsa_p384_ops_config") {
include_dirs = [ "//include/dice/config/boringssl_ecdsa_p384" ]
}
@@ -80,6 +84,23 @@
all_dependent_configs = [ ":boringssl_ed25519_ops_config" ]
}
+pw_static_library("dice_with_boringssl_p256_ops") {
+ public = [
+ "include/dice/dice.h",
+ "include/dice/utils.h",
+ ]
+ sources = [
+ "src/boringssl_cert_op.c",
+ "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_p256_ops.c",
+ "src/clear_memory.c",
+ "src/dice.c",
+ "src/utils.c",
+ ]
+ deps = [ "//third_party/boringssl:crypto" ]
+ all_dependent_configs = [ ":boringssl_ecdsa_p256_ops_config" ]
+}
+
pw_static_library("dice_with_boringssl_p384_ops") {
public = [
"include/dice/dice.h",
@@ -148,6 +169,28 @@
deps = [ "//third_party/boringssl:crypto" ]
}
+pw_static_library("dice_with_cbor_p256_cert") {
+ public = [
+ "include/dice/dice.h",
+ "include/dice/utils.h",
+ ]
+ sources = [
+ "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_p256_ops.c",
+ "src/cbor_cert_op.c",
+ "src/cbor_p256_cert_op.c",
+ "src/clear_memory.c",
+ "src/dice.c",
+ "src/utils.c",
+ ]
+ deps = [
+ ":boringssl_ecdsa_utils",
+ ":cbor_writer",
+ "//third_party/boringssl:crypto",
+ ]
+ all_dependent_configs = [ ":boringssl_ecdsa_p256_ops_config" ]
+}
+
pw_static_library("dice_with_cbor_p384_cert") {
public = [
"include/dice/dice.h",
@@ -261,6 +304,13 @@
]
}
+pw_executable("boringssl_p256_ops_fuzzer") {
+ deps = [
+ ":dice_with_boringssl_p256_ops",
+ ":fuzzer",
+ ]
+}
+
pw_executable("boringssl_p384_ops_fuzzer") {
deps = [
":dice_with_boringssl_p384_ops",
@@ -303,6 +353,20 @@
]
}
+pw_test("cbor_p256_cert_op_test") {
+ sources = [
+ "src/cbor_p256_cert_op_test.cc",
+ "src/test_utils.cc",
+ ]
+ deps = [
+ ":boringssl_ecdsa_utils",
+ ":dice_with_cbor_p256_cert",
+ "$dir_pw_string:pw_string",
+ "//third_party/boringssl:crypto",
+ "//third_party/cose-c:cose-c_p256",
+ ]
+}
+
pw_test("cbor_p384_cert_op_test") {
sources = [
"src/cbor_p384_cert_op_test.cc",
@@ -394,6 +458,7 @@
":android_test",
":boringssl_ed25519_ops_test",
":cbor_ed25519_cert_op_test",
+ ":cbor_p256_cert_op_test",
":cbor_p384_cert_op_test",
":cbor_reader_test",
":cbor_writer_test",
@@ -408,6 +473,7 @@
deps = [
":android_fuzzer",
":boringssl_ed25519_ops_fuzzer",
+ ":boringssl_p256_ops_fuzzer",
":boringssl_p384_ops_fuzzer",
":cbor_ed25519_cert_op_fuzzer",
":cbor_reader_fuzzer",
@@ -533,6 +599,11 @@
base = ":dice_standalone"
},
{
+ target = ":dice_with_cbor_p256_cert"
+ label = "CBOR P256 Cert"
+ base = ":dice_standalone"
+ },
+ {
target = ":dice_with_cbor_p384_cert"
label = "CBOR P384 Cert"
base = ":dice_standalone"
@@ -556,6 +627,7 @@
":dice_standalone",
":dice_with_boringssl_ed25519_ops",
":dice_with_cbor_ed25519_cert",
+ ":dice_with_cbor_p256_cert",
":dice_with_cbor_p384_cert",
":dice_with_cbor_template_ed25519_cert",
":dice_with_mbedtls_ops",
diff --git a/include/dice/boringssl_ecdsa_utils.h b/include/dice/boringssl_ecdsa_utils.h
index 96c3fe5..bcc32aa 100644
--- a/include/dice/boringssl_ecdsa_utils.h
+++ b/include/dice/boringssl_ecdsa_utils.h
@@ -36,6 +36,20 @@
uint8_t private_key[P256_PRIVATE_KEY_SIZE],
const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE]);
+// Calculates a signature of |message_size| bytes from |message| using
+// |private_key|. |private_key| was generated by |keypair_from_seed| to allow
+// an implementation to use their own private key format. |signature| points to
+// the buffer where the calculated signature is written.
+int P256Sign(uint8_t signature[P256_SIGNATURE_SIZE], const uint8_t* message,
+ size_t message_size,
+ const uint8_t private_key[P256_PRIVATE_KEY_SIZE]);
+
+// Verifies, using |public_key|, that |signature| covers |message_size| bytes
+// from |message|.
+int P256Verify(const uint8_t* message, size_t message_size,
+ const uint8_t signature[P256_SIGNATURE_SIZE],
+ const uint8_t public_key[P256_PUBLIC_KEY_SIZE]);
+
#define P384_PRIVATE_KEY_SIZE 48
#define P384_PUBLIC_KEY_SIZE 96
#define P384_SIGNATURE_SIZE 96
diff --git a/include/dice/config/boringssl_ecdsa_p256/dice/config.h b/include/dice/config/boringssl_ecdsa_p256/dice/config.h
new file mode 100644
index 0000000..98045f7
--- /dev/null
+++ b/include/dice/config/boringssl_ecdsa_p256/dice/config.h
@@ -0,0 +1,26 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef DICE_CONFIG_BORINGSSL_ECDSA_P256_DICE_CONFIG_H_
+#define DICE_CONFIG_BORINGSSL_ECDSA_P256_DICE_CONFIG_H_
+
+// ECDSA P256
+// From table 1 of RFC 9053
+#define DICE_COSE_KEY_ALG_VALUE (-7)
+#define DICE_PUBLIC_KEY_SIZE 64
+#define DICE_PRIVATE_KEY_SIZE 32
+#define DICE_SIGNATURE_SIZE 64
+#define DICE_PROFILE_NAME "opendice.example.p256"
+
+#endif // DICE_CONFIG_BORINGSSL_ECDSA_P256_DICE_DICE_CONFIG_H_
diff --git a/include/dice/config/mbedtls_ecdsa_p256/dice/config.h b/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
index 107e4d5..c5e23e1 100644
--- a/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
+++ b/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
@@ -19,6 +19,6 @@
#define DICE_PUBLIC_KEY_SIZE 33
#define DICE_PRIVATE_KEY_SIZE 32
#define DICE_SIGNATURE_SIZE 64
-#define DICE_PROFILE_NAME "openssl.example.p256"
+#define DICE_PROFILE_NAME "openssl.example.p256_compressed"
#endif // DICE_CONFIG_MBEDTLS_ECDSA_P256_DICE_DICE_CONFIG_H_
diff --git a/include/dice/known_test_values.h b/include/dice/known_test_values.h
index a74ed1d..3bf61cb 100644
--- a/include/dice/known_test_values.h
+++ b/include/dice/known_test_values.h
@@ -179,7 +179,7 @@
// X509v3 Basic Constraints: critical
// CA:TRUE
// 1.3.6.1.4.1.11129.2.1.24: critical
-// 0:d=0 hl=3 l= 233 cons: SEQUENCE
+// 0:d=0 hl=3 l= 244 cons: SEQUENCE
// 3:d=1 hl=2 l= 66 cons: cont [ 0 ]
// 5:d=2 hl=2 l= 64 prim: OCTET STRING
// 0000 - 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
@@ -200,17 +200,17 @@
// 0030 - 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
// 207:d=1 hl=2 l= 3 cons: cont [ 6 ]
// 209:d=2 hl=2 l= 1 prim: ENUMERATED :00
-// 212:d=1 hl=2 l= 22 cons: cont [ 7 ]
-// 214:d=2 hl=2 l= 20 prim: UTF8STRING :openssl.example.p256
+// 212:d=1 hl=2 l= 33 cons: cont [ 7 ]
+// 214:d=2 hl=2 l= 31 prim: UTF8STRING :openssl.example.p256_compressed
//
// Signature Algorithm: ecdsa-with-SHA512
// Signature Value:
-// 30:46:02:21:00:a8:d1:e1:d1:7b:89:bf:a3:f1:8c:fa:43:fa:
-// 77:bf:83:ef:28:cb:54:d1:f5:29:e4:f3:05:99:e2:7a:d0:33:
-// 13:02:21:00:d7:9c:82:91:6b:a0:ca:70:48:76:03:95:1c:a4:
-// 6d:f0:44:ed:ba:02:2d:9a:e4:bf:f2:92:f6:78:ce:08:01:26
-constexpr uint8_t kExpectedX509P256Cert_ZeroInput[731] = {
- 0x30, 0x82, 0x02, 0xd7, 0x30, 0x82, 0x02, 0x7a, 0xa0, 0x03, 0x02, 0x01,
+// 30:45:02:21:00:a9:e5:96:e1:5a:8e:83:18:34:fa:11:71:fa:
+// 9c:81:a4:ff:3f:4e:54:aa:d4:f9:9e:32:08:66:84:24:8c:80:
+// fd:02:20:5c:0a:57:e8:04:0e:16:12:4c:5d:1e:ef:17:b7:53:
+// 93:c6:21:d9:4e:aa:77:ba:cb:5d:2d:5f:98:96:9a:ea:e4
+constexpr uint8_t kExpectedX509P256Cert_ZeroInput[742] = {
+ 0x30, 0x82, 0x02, 0xe2, 0x30, 0x82, 0x02, 0x86, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x7c, 0x7d, 0xc0, 0xa3, 0xc1, 0xe7, 0x8d, 0x4e, 0x68,
0xbc, 0xc1, 0xa2, 0x32, 0x9e, 0xf9, 0x1c, 0xa8, 0x12, 0x44, 0x91, 0x30,
0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05,
@@ -233,7 +233,7 @@
0x06, 0x02, 0xae, 0xc2, 0x69, 0x54, 0x1c, 0x6b, 0xe7, 0xeb, 0x40, 0x19,
0xab, 0x55, 0xc6, 0x6b, 0xc8, 0x8b, 0xb8, 0xb4, 0x69, 0xad, 0x7e, 0xe8,
0x58, 0x9e, 0x07, 0xd2, 0xf8, 0xbc, 0x88, 0x8e, 0xb3, 0x11, 0xc2, 0xdf,
- 0x97, 0x3b, 0x1b, 0x4a, 0xa3, 0x82, 0x01, 0x66, 0x30, 0x82, 0x01, 0x62,
+ 0x97, 0x3b, 0x1b, 0x4a, 0xa3, 0x82, 0x01, 0x72, 0x30, 0x82, 0x01, 0x6e,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
0x14, 0x4c, 0x51, 0x4d, 0x88, 0xdb, 0x0f, 0x81, 0xd5, 0x7b, 0xeb, 0x96,
0x17, 0x7e, 0x3d, 0x7e, 0xa4, 0xaa, 0x58, 0x1e, 0x66, 0x30, 0x1d, 0x06,
@@ -242,35 +242,36 @@
0xa8, 0x12, 0x44, 0x91, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x0f, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
- 0xff, 0x30, 0x81, 0xfe, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xec, 0x30, 0x81,
- 0xe9, 0xa0, 0x42, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x30, 0x82, 0x01, 0x09, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0xd6, 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xf7, 0x30,
+ 0x81, 0xf4, 0xa0, 0x42, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x42, 0x04,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x42,
+ 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x42, 0x04, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x42, 0x04, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x16, 0x0c, 0x14, 0x6f, 0x70,
- 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
- 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
- 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05, 0x00, 0x03, 0x49, 0x00, 0x30,
- 0x46, 0x02, 0x21, 0x00, 0xa8, 0xd1, 0xe1, 0xd1, 0x7b, 0x89, 0xbf, 0xa3,
- 0xf1, 0x8c, 0xfa, 0x43, 0xfa, 0x77, 0xbf, 0x83, 0xef, 0x28, 0xcb, 0x54,
- 0xd1, 0xf5, 0x29, 0xe4, 0xf3, 0x05, 0x99, 0xe2, 0x7a, 0xd0, 0x33, 0x13,
- 0x02, 0x21, 0x00, 0xd7, 0x9c, 0x82, 0x91, 0x6b, 0xa0, 0xca, 0x70, 0x48,
- 0x76, 0x03, 0x95, 0x1c, 0xa4, 0x6d, 0xf0, 0x44, 0xed, 0xba, 0x02, 0x2d,
- 0x9a, 0xe4, 0xbf, 0xf2, 0x92, 0xf6, 0x78, 0xce, 0x08, 0x01, 0x26};
+ 0x00, 0x00, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x21, 0x0c, 0x1f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x5f, 0x63, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05, 0x00, 0x03, 0x48, 0x00, 0x30,
+ 0x45, 0x02, 0x21, 0x00, 0xa9, 0xe5, 0x96, 0xe1, 0x5a, 0x8e, 0x83, 0x18,
+ 0x34, 0xfa, 0x11, 0x71, 0xfa, 0x9c, 0x81, 0xa4, 0xff, 0x3f, 0x4e, 0x54,
+ 0xaa, 0xd4, 0xf9, 0x9e, 0x32, 0x08, 0x66, 0x84, 0x24, 0x8c, 0x80, 0xfd,
+ 0x02, 0x20, 0x5c, 0x0a, 0x57, 0xe8, 0x04, 0x0e, 0x16, 0x12, 0x4c, 0x5d,
+ 0x1e, 0xef, 0x17, 0xb7, 0x53, 0x93, 0xc6, 0x21, 0xd9, 0x4e, 0xaa, 0x77,
+ 0xba, 0xcb, 0x5d, 0x2d, 0x5f, 0x98, 0x96, 0x9a, 0xea, 0xe4};
constexpr uint8_t kExpectedX509P384Cert_ZeroInput[0] = {};
@@ -313,7 +314,49 @@
0x21, 0xec, 0xa3, 0xd3, 0x89, 0x7a, 0x24, 0x4d, 0xcb, 0xe1, 0x1a, 0x0f,
0x9a, 0xb7, 0x9f, 0x67, 0x09, 0x3f, 0xee, 0x56, 0x0f};
-constexpr uint8_t kExpectedCborP256Cert_ZeroInput[0] = {};
+constexpr uint8_t kExpectedCborP256Cert_ZeroInput[503] = {
+ 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x59, 0x01, 0xac, 0xa9, 0x01, 0x78,
+ 0x28, 0x36, 0x37, 0x32, 0x64, 0x30, 0x30, 0x35, 0x33, 0x61, 0x65, 0x34,
+ 0x35, 0x31, 0x33, 0x66, 0x62, 0x62, 0x33, 0x62, 0x61, 0x63, 0x38, 0x32,
+ 0x30, 0x39, 0x64, 0x61, 0x65, 0x62, 0x33, 0x65, 0x38, 0x38, 0x39, 0x37,
+ 0x36, 0x38, 0x31, 0x63, 0x64, 0x02, 0x78, 0x28, 0x32, 0x65, 0x37, 0x35,
+ 0x62, 0x36, 0x65, 0x37, 0x32, 0x33, 0x30, 0x63, 0x32, 0x30, 0x66, 0x32,
+ 0x39, 0x36, 0x30, 0x62, 0x64, 0x65, 0x34, 0x61, 0x63, 0x66, 0x31, 0x32,
+ 0x38, 0x38, 0x64, 0x34, 0x61, 0x62, 0x36, 0x36, 0x35, 0x62, 0x39, 0x62,
+ 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a,
+ 0x00, 0x47, 0x44, 0x53, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00,
+ 0x47, 0x44, 0x54, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47,
+ 0x44, 0x56, 0x41, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x50, 0xa6,
+ 0x01, 0x02, 0x03, 0x26, 0x04, 0x81, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20,
+ 0x4f, 0x3b, 0x4e, 0x82, 0xc4, 0x5a, 0xda, 0x08, 0x45, 0x89, 0xc2, 0x19,
+ 0x7b, 0xaf, 0x1f, 0x37, 0x6e, 0xac, 0x40, 0xe1, 0xfd, 0x49, 0xb0, 0x24,
+ 0x06, 0x02, 0xae, 0xc2, 0x69, 0x54, 0x1c, 0x6b, 0x22, 0x58, 0x20, 0xe7,
+ 0xeb, 0x40, 0x19, 0xab, 0x55, 0xc6, 0x6b, 0xc8, 0x8b, 0xb8, 0xb4, 0x69,
+ 0xad, 0x7e, 0xe8, 0x58, 0x9e, 0x07, 0xd2, 0xf8, 0xbc, 0x88, 0x8e, 0xb3,
+ 0x11, 0xc2, 0xdf, 0x97, 0x3b, 0x1b, 0x4a, 0x3a, 0x00, 0x47, 0x44, 0x58,
+ 0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e,
+ 0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x2e, 0x70, 0x32, 0x35, 0x36, 0x58, 0x40, 0x63, 0xb5, 0x32, 0x12, 0x4a,
+ 0x18, 0xf5, 0xa8, 0xf0, 0x67, 0x3e, 0x76, 0x46, 0xa5, 0xb6, 0xb8, 0xbf,
+ 0xfe, 0xa2, 0xeb, 0x6f, 0x4d, 0x5f, 0x18, 0x69, 0x03, 0xc6, 0x31, 0xce,
+ 0xeb, 0xae, 0xcd, 0xca, 0x93, 0x31, 0x51, 0x51, 0xcf, 0x05, 0xb6, 0x7e,
+ 0x87, 0x91, 0xd0, 0x5b, 0x88, 0xf5, 0xe3, 0x93, 0xf7, 0xba, 0xd5, 0xd7,
+ 0x07, 0xe3, 0xe6, 0x3f, 0xcb, 0xf6, 0x24, 0xd2, 0xf6, 0xc1, 0x5c};
constexpr uint8_t kExpectedCborP384Cert_ZeroInput[569] = {
0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xcd, 0xa9, 0x01,
@@ -355,15 +398,15 @@
0x05, 0xb5, 0x29, 0xa0, 0xf1, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
0x3a, 0x00, 0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70,
- 0x33, 0x38, 0x34, 0x58, 0x60, 0x19, 0x40, 0xb7, 0x32, 0x81, 0xdd, 0x03,
- 0x7b, 0x0f, 0x35, 0xd2, 0x5a, 0x01, 0x85, 0x5b, 0xbc, 0xea, 0xb4, 0x0d,
- 0x83, 0xec, 0x6a, 0x33, 0x6d, 0x2d, 0xa0, 0x7d, 0xa6, 0x2e, 0xe8, 0x64,
- 0xdc, 0x51, 0x71, 0xa0, 0x76, 0x3e, 0x5b, 0x4e, 0xee, 0x4a, 0xa1, 0x1a,
- 0xd2, 0xd4, 0xaf, 0x38, 0x86, 0xa7, 0xd8, 0x62, 0xce, 0x55, 0xdc, 0x14,
- 0x8c, 0x08, 0xda, 0xcb, 0x0a, 0x82, 0x1f, 0x89, 0x6e, 0x75, 0x08, 0xa1,
- 0x14, 0xe8, 0x74, 0xdf, 0xf9, 0x01, 0x6b, 0x1b, 0x69, 0xb5, 0xba, 0x6e,
- 0xec, 0x4b, 0x27, 0x04, 0xcf, 0xff, 0x5f, 0x07, 0xbe, 0x60, 0xf2, 0x8d,
- 0x07, 0x4a, 0xe6, 0xa1, 0xa3};
+ 0x33, 0x38, 0x34, 0x58, 0x60, 0x15, 0x22, 0x2f, 0x02, 0xdd, 0x28, 0x07,
+ 0x9a, 0x90, 0xcf, 0xae, 0x29, 0x76, 0x81, 0x14, 0xc3, 0xf2, 0x06, 0x13,
+ 0x01, 0xe1, 0x5f, 0x6e, 0xb1, 0x1d, 0x1f, 0x7a, 0xcd, 0x3f, 0xf5, 0xf9,
+ 0x87, 0x4d, 0x78, 0x6e, 0xa5, 0xff, 0x86, 0xb2, 0x1e, 0x0c, 0x8b, 0xd2,
+ 0x26, 0x20, 0x02, 0xe1, 0x65, 0x8b, 0x91, 0x8f, 0x29, 0x97, 0xdb, 0x4b,
+ 0x05, 0xa7, 0xe3, 0xc7, 0x97, 0x8e, 0x42, 0xe5, 0xbe, 0x44, 0xdd, 0xff,
+ 0xed, 0xf9, 0x70, 0xa3, 0xec, 0x64, 0xe4, 0xb9, 0x1d, 0x2b, 0xe0, 0xe9,
+ 0x29, 0xa3, 0x1d, 0xf5, 0x79, 0xd0, 0x1c, 0x3a, 0x26, 0xbc, 0xb2, 0xf9,
+ 0xd9, 0xcd, 0x59, 0xd9, 0xc1};
constexpr uint8_t kExpectedCdiAttest_HashOnlyInput[32] = {
0x08, 0x4e, 0xf4, 0x06, 0xc6, 0x9b, 0xa7, 0x4b, 0x1e, 0x24, 0xd0,
@@ -521,7 +564,7 @@
// X509v3 Basic Constraints: critical
// CA:TRUE
// 1.3.6.1.4.1.11129.2.1.24: critical
-// 0:d=0 hl=3 l= 233 cons: SEQUENCE
+// 0:d=0 hl=3 l= 244 cons: SEQUENCE
// 3:d=1 hl=2 l= 66 cons: cont [ 0 ]
// 5:d=2 hl=2 l= 64 prim: OCTET STRING
// 0000 - b7 d4 0c cb 22 5b a5 78-8f 98 ff 9e 86 93 75 f6 ...."[.x......u.
@@ -542,17 +585,17 @@
// 0030 - 94 4f be 1b 21 f9 cc 23-73 41 b6 b9 b6 98 d0 bc .O..!..#sA......
// 207:d=1 hl=2 l= 3 cons: cont [ 6 ]
// 209:d=2 hl=2 l= 1 prim: ENUMERATED :00
-// 212:d=1 hl=2 l= 22 cons: cont [ 7 ]
-// 214:d=2 hl=2 l= 20 prim: UTF8STRING :openssl.example.p256
+// 212:d=1 hl=2 l= 33 cons: cont [ 7 ]
+// 214:d=2 hl=2 l= 31 prim: UTF8STRING :openssl.example.p256_compressed
//
// Signature Algorithm: ecdsa-with-SHA512
// Signature Value:
-// 30:44:02:20:2a:d1:3e:6f:ee:42:e2:d0:64:b8:1c:bd:de:fe:
-// 49:2f:2e:4f:80:3c:66:52:05:95:2a:d9:87:7a:6d:47:44:bf:
-// 02:20:6e:1c:5a:a0:62:00:17:61:f9:c3:93:17:72:1a:ce:28:
-// 3d:c7:7d:35:22:de:b3:d6:3d:b2:6e:75:c9:f0:c1:73
-constexpr uint8_t kExpectedX509P256Cert_HashOnlyInput[729] = {
- 0x30, 0x82, 0x02, 0xd5, 0x30, 0x82, 0x02, 0x7a, 0xa0, 0x03, 0x02, 0x01,
+// 30:44:02:20:4f:9c:d7:7d:76:9c:02:41:46:f4:8a:9c:38:0c:
+// 77:32:c5:08:cc:a9:53:70:99:f7:15:68:4c:3b:22:4f:df:d1:
+// 02:20:19:ad:a1:53:1f:7d:6e:4a:70:32:9f:7d:2e:3b:be:f4:
+// c8:f0:9a:31:6d:4b:3e:32:eb:db:8e:fc:cd:28:8b:1f
+constexpr uint8_t kExpectedX509P256Cert_HashOnlyInput[741] = {
+ 0x30, 0x82, 0x02, 0xe1, 0x30, 0x82, 0x02, 0x86, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x68, 0x49, 0x58, 0xd9, 0xae, 0xa7, 0x2e, 0xbf, 0x7c,
0x06, 0xaf, 0x20, 0x03, 0xb6, 0x44, 0x47, 0x82, 0x4a, 0x62, 0x71, 0x30,
0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05,
@@ -575,7 +618,7 @@
0xfb, 0x6d, 0x57, 0x18, 0xfc, 0x8f, 0x6f, 0x0b, 0x09, 0x1a, 0x19, 0xea,
0x10, 0x7e, 0xa9, 0x38, 0xf4, 0x45, 0x33, 0xc1, 0x66, 0x5b, 0xbc, 0xfc,
0x0a, 0x6e, 0x98, 0x99, 0x72, 0x88, 0xc1, 0xad, 0x0e, 0x15, 0xc2, 0x85,
- 0x77, 0x75, 0x00, 0x0b, 0xa3, 0x82, 0x01, 0x66, 0x30, 0x82, 0x01, 0x62,
+ 0x77, 0x75, 0x00, 0x0b, 0xa3, 0x82, 0x01, 0x72, 0x30, 0x82, 0x01, 0x6e,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
0x14, 0x1b, 0xe5, 0x68, 0x79, 0x33, 0xdb, 0x3d, 0x9c, 0xd5, 0xfc, 0xa7,
0x29, 0xe8, 0x1d, 0x66, 0x85, 0x46, 0x5a, 0x7b, 0xf1, 0x30, 0x1d, 0x06,
@@ -584,35 +627,36 @@
0x82, 0x4a, 0x62, 0x71, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x0f, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
- 0xff, 0x30, 0x81, 0xfe, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6,
- 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xec, 0x30, 0x81,
- 0xe9, 0xa0, 0x42, 0x04, 0x40, 0xb7, 0xd4, 0x0c, 0xcb, 0x22, 0x5b, 0xa5,
- 0x78, 0x8f, 0x98, 0xff, 0x9e, 0x86, 0x93, 0x75, 0xf6, 0x90, 0xac, 0x50,
- 0xcf, 0x9e, 0xbd, 0x0a, 0xfe, 0xb1, 0xd9, 0xc2, 0x4e, 0x52, 0x19, 0xe4,
- 0xde, 0x29, 0xe5, 0x61, 0xf3, 0xf9, 0x29, 0xe8, 0x40, 0x87, 0x7a, 0xdd,
- 0x17, 0x48, 0x05, 0x89, 0x7e, 0x2b, 0xcb, 0x54, 0x79, 0xcc, 0x66, 0xf1,
- 0xb3, 0x13, 0x29, 0x0c, 0x68, 0x96, 0xb2, 0xbb, 0x8f, 0xa3, 0x42, 0x04,
- 0x40, 0xcf, 0x99, 0x7b, 0xea, 0x2e, 0x2c, 0x86, 0xa0, 0x7b, 0x52, 0x09,
- 0xc8, 0xb5, 0x3c, 0x41, 0x12, 0x29, 0x28, 0x1a, 0x82, 0x0d, 0x49, 0x9c,
- 0x95, 0xcb, 0x0b, 0x1b, 0x31, 0x1a, 0x01, 0x9c, 0xf2, 0x66, 0x1a, 0xd9,
- 0xb5, 0xce, 0x52, 0x59, 0xcb, 0xf4, 0x81, 0x9b, 0x21, 0xaf, 0x32, 0x5d,
- 0x07, 0xa0, 0x1e, 0x91, 0x59, 0x6f, 0x06, 0x55, 0x10, 0x8e, 0x2e, 0x08,
- 0x88, 0x52, 0x28, 0x86, 0x7f, 0xa4, 0x42, 0x04, 0x40, 0x22, 0x52, 0x60,
- 0x17, 0xef, 0x2c, 0xa1, 0xf6, 0xcb, 0xed, 0x39, 0xd5, 0xe2, 0xaa, 0x65,
- 0x20, 0xfb, 0xad, 0x82, 0x93, 0xe5, 0x78, 0x23, 0x22, 0x97, 0xc1, 0x6e,
- 0x6a, 0x4e, 0x36, 0xd7, 0x6a, 0x61, 0x39, 0x08, 0x21, 0xd4, 0xfe, 0x92,
- 0x5f, 0x36, 0x2d, 0xeb, 0x5d, 0xbb, 0x32, 0x8b, 0xe3, 0x94, 0x4f, 0xbe,
- 0x1b, 0x21, 0xf9, 0xcc, 0x23, 0x73, 0x41, 0xb6, 0xb9, 0xb6, 0x98, 0xd0,
- 0xbc, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x16, 0x0c, 0x14, 0x6f, 0x70,
- 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,
- 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
+ 0xff, 0x30, 0x82, 0x01, 0x09, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0xd6, 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xf7, 0x30,
+ 0x81, 0xf4, 0xa0, 0x42, 0x04, 0x40, 0xb7, 0xd4, 0x0c, 0xcb, 0x22, 0x5b,
+ 0xa5, 0x78, 0x8f, 0x98, 0xff, 0x9e, 0x86, 0x93, 0x75, 0xf6, 0x90, 0xac,
+ 0x50, 0xcf, 0x9e, 0xbd, 0x0a, 0xfe, 0xb1, 0xd9, 0xc2, 0x4e, 0x52, 0x19,
+ 0xe4, 0xde, 0x29, 0xe5, 0x61, 0xf3, 0xf9, 0x29, 0xe8, 0x40, 0x87, 0x7a,
+ 0xdd, 0x17, 0x48, 0x05, 0x89, 0x7e, 0x2b, 0xcb, 0x54, 0x79, 0xcc, 0x66,
+ 0xf1, 0xb3, 0x13, 0x29, 0x0c, 0x68, 0x96, 0xb2, 0xbb, 0x8f, 0xa3, 0x42,
+ 0x04, 0x40, 0xcf, 0x99, 0x7b, 0xea, 0x2e, 0x2c, 0x86, 0xa0, 0x7b, 0x52,
+ 0x09, 0xc8, 0xb5, 0x3c, 0x41, 0x12, 0x29, 0x28, 0x1a, 0x82, 0x0d, 0x49,
+ 0x9c, 0x95, 0xcb, 0x0b, 0x1b, 0x31, 0x1a, 0x01, 0x9c, 0xf2, 0x66, 0x1a,
+ 0xd9, 0xb5, 0xce, 0x52, 0x59, 0xcb, 0xf4, 0x81, 0x9b, 0x21, 0xaf, 0x32,
+ 0x5d, 0x07, 0xa0, 0x1e, 0x91, 0x59, 0x6f, 0x06, 0x55, 0x10, 0x8e, 0x2e,
+ 0x08, 0x88, 0x52, 0x28, 0x86, 0x7f, 0xa4, 0x42, 0x04, 0x40, 0x22, 0x52,
+ 0x60, 0x17, 0xef, 0x2c, 0xa1, 0xf6, 0xcb, 0xed, 0x39, 0xd5, 0xe2, 0xaa,
+ 0x65, 0x20, 0xfb, 0xad, 0x82, 0x93, 0xe5, 0x78, 0x23, 0x22, 0x97, 0xc1,
+ 0x6e, 0x6a, 0x4e, 0x36, 0xd7, 0x6a, 0x61, 0x39, 0x08, 0x21, 0xd4, 0xfe,
+ 0x92, 0x5f, 0x36, 0x2d, 0xeb, 0x5d, 0xbb, 0x32, 0x8b, 0xe3, 0x94, 0x4f,
+ 0xbe, 0x1b, 0x21, 0xf9, 0xcc, 0x23, 0x73, 0x41, 0xb6, 0xb9, 0xb6, 0x98,
+ 0xd0, 0xbc, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x21, 0x0c, 0x1f, 0x6f,
+ 0x70, 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70,
+ 0x6c, 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x5f, 0x63, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05, 0x00, 0x03, 0x47, 0x00, 0x30,
- 0x44, 0x02, 0x20, 0x2a, 0xd1, 0x3e, 0x6f, 0xee, 0x42, 0xe2, 0xd0, 0x64,
- 0xb8, 0x1c, 0xbd, 0xde, 0xfe, 0x49, 0x2f, 0x2e, 0x4f, 0x80, 0x3c, 0x66,
- 0x52, 0x05, 0x95, 0x2a, 0xd9, 0x87, 0x7a, 0x6d, 0x47, 0x44, 0xbf, 0x02,
- 0x20, 0x6e, 0x1c, 0x5a, 0xa0, 0x62, 0x00, 0x17, 0x61, 0xf9, 0xc3, 0x93,
- 0x17, 0x72, 0x1a, 0xce, 0x28, 0x3d, 0xc7, 0x7d, 0x35, 0x22, 0xde, 0xb3,
- 0xd6, 0x3d, 0xb2, 0x6e, 0x75, 0xc9, 0xf0, 0xc1, 0x73};
+ 0x44, 0x02, 0x20, 0x4f, 0x9c, 0xd7, 0x7d, 0x76, 0x9c, 0x02, 0x41, 0x46,
+ 0xf4, 0x8a, 0x9c, 0x38, 0x0c, 0x77, 0x32, 0xc5, 0x08, 0xcc, 0xa9, 0x53,
+ 0x70, 0x99, 0xf7, 0x15, 0x68, 0x4c, 0x3b, 0x22, 0x4f, 0xdf, 0xd1, 0x02,
+ 0x20, 0x19, 0xad, 0xa1, 0x53, 0x1f, 0x7d, 0x6e, 0x4a, 0x70, 0x32, 0x9f,
+ 0x7d, 0x2e, 0x3b, 0xbe, 0xf4, 0xc8, 0xf0, 0x9a, 0x31, 0x6d, 0x4b, 0x3e,
+ 0x32, 0xeb, 0xdb, 0x8e, 0xfc, 0xcd, 0x28, 0x8b, 0x1f};
constexpr uint8_t kExpectedX509P384Cert_HashOnlyInput[0] = {};
@@ -655,7 +699,49 @@
0xb6, 0x71, 0xc7, 0x76, 0x64, 0x25, 0xfb, 0x03, 0xcf, 0xd6, 0x6f, 0x2f,
0x9a, 0x15, 0xc8, 0xad, 0x47, 0x9a, 0xf3, 0x16, 0x01};
-constexpr uint8_t kExpectedCborP256Cert_HashOnlyInput[0] = {};
+constexpr uint8_t kExpectedCborP256Cert_HashOnlyInput[503] = {
+ 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x59, 0x01, 0xac, 0xa9, 0x01, 0x78,
+ 0x28, 0x34, 0x38, 0x36, 0x30, 0x33, 0x63, 0x30, 0x30, 0x35, 0x32, 0x63,
+ 0x31, 0x63, 0x61, 0x63, 0x37, 0x33, 0x63, 0x61, 0x65, 0x33, 0x36, 0x63,
+ 0x33, 0x62, 0x64, 0x65, 0x63, 0x37, 0x63, 0x36, 0x31, 0x33, 0x39, 0x38,
+ 0x38, 0x35, 0x63, 0x39, 0x64, 0x02, 0x78, 0x28, 0x37, 0x63, 0x32, 0x30,
+ 0x30, 0x61, 0x35, 0x35, 0x65, 0x66, 0x65, 0x37, 0x31, 0x31, 0x32, 0x65,
+ 0x63, 0x61, 0x34, 0x65, 0x30, 0x32, 0x36, 0x64, 0x37, 0x30, 0x32, 0x63,
+ 0x36, 0x34, 0x65, 0x39, 0x65, 0x32, 0x39, 0x63, 0x64, 0x33, 0x65, 0x39,
+ 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0xb7, 0xd4, 0x0c, 0xcb, 0x22,
+ 0x5b, 0xa5, 0x78, 0x8f, 0x98, 0xff, 0x9e, 0x86, 0x93, 0x75, 0xf6, 0x90,
+ 0xac, 0x50, 0xcf, 0x9e, 0xbd, 0x0a, 0xfe, 0xb1, 0xd9, 0xc2, 0x4e, 0x52,
+ 0x19, 0xe4, 0xde, 0x29, 0xe5, 0x61, 0xf3, 0xf9, 0x29, 0xe8, 0x40, 0x87,
+ 0x7a, 0xdd, 0x17, 0x48, 0x05, 0x89, 0x7e, 0x2b, 0xcb, 0x54, 0x79, 0xcc,
+ 0x66, 0xf1, 0xb3, 0x13, 0x29, 0x0c, 0x68, 0x96, 0xb2, 0xbb, 0x8f, 0x3a,
+ 0x00, 0x47, 0x44, 0x53, 0x58, 0x40, 0xcf, 0x99, 0x7b, 0xea, 0x2e, 0x2c,
+ 0x86, 0xa0, 0x7b, 0x52, 0x09, 0xc8, 0xb5, 0x3c, 0x41, 0x12, 0x29, 0x28,
+ 0x1a, 0x82, 0x0d, 0x49, 0x9c, 0x95, 0xcb, 0x0b, 0x1b, 0x31, 0x1a, 0x01,
+ 0x9c, 0xf2, 0x66, 0x1a, 0xd9, 0xb5, 0xce, 0x52, 0x59, 0xcb, 0xf4, 0x81,
+ 0x9b, 0x21, 0xaf, 0x32, 0x5d, 0x07, 0xa0, 0x1e, 0x91, 0x59, 0x6f, 0x06,
+ 0x55, 0x10, 0x8e, 0x2e, 0x08, 0x88, 0x52, 0x28, 0x86, 0x7f, 0x3a, 0x00,
+ 0x47, 0x44, 0x54, 0x58, 0x40, 0x22, 0x52, 0x60, 0x17, 0xef, 0x2c, 0xa1,
+ 0xf6, 0xcb, 0xed, 0x39, 0xd5, 0xe2, 0xaa, 0x65, 0x20, 0xfb, 0xad, 0x82,
+ 0x93, 0xe5, 0x78, 0x23, 0x22, 0x97, 0xc1, 0x6e, 0x6a, 0x4e, 0x36, 0xd7,
+ 0x6a, 0x61, 0x39, 0x08, 0x21, 0xd4, 0xfe, 0x92, 0x5f, 0x36, 0x2d, 0xeb,
+ 0x5d, 0xbb, 0x32, 0x8b, 0xe3, 0x94, 0x4f, 0xbe, 0x1b, 0x21, 0xf9, 0xcc,
+ 0x23, 0x73, 0x41, 0xb6, 0xb9, 0xb6, 0x98, 0xd0, 0xbc, 0x3a, 0x00, 0x47,
+ 0x44, 0x56, 0x41, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x50, 0xa6,
+ 0x01, 0x02, 0x03, 0x26, 0x04, 0x81, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20,
+ 0xfe, 0x9d, 0xb2, 0xf9, 0x28, 0x09, 0xc3, 0x04, 0x12, 0x85, 0xdc, 0xd3,
+ 0x70, 0x6f, 0x22, 0x1c, 0x72, 0xb6, 0xc4, 0x4f, 0xde, 0x93, 0xee, 0xfd,
+ 0xfb, 0x6d, 0x57, 0x18, 0xfc, 0x8f, 0x6f, 0x0b, 0x22, 0x58, 0x20, 0x09,
+ 0x1a, 0x19, 0xea, 0x10, 0x7e, 0xa9, 0x38, 0xf4, 0x45, 0x33, 0xc1, 0x66,
+ 0x5b, 0xbc, 0xfc, 0x0a, 0x6e, 0x98, 0x99, 0x72, 0x88, 0xc1, 0xad, 0x0e,
+ 0x15, 0xc2, 0x85, 0x77, 0x75, 0x00, 0x0b, 0x3a, 0x00, 0x47, 0x44, 0x58,
+ 0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e,
+ 0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+ 0x2e, 0x70, 0x32, 0x35, 0x36, 0x58, 0x40, 0x9f, 0xc7, 0x0a, 0x63, 0x96,
+ 0x61, 0xc1, 0x7a, 0x55, 0x52, 0x76, 0x30, 0xc7, 0xe1, 0xb9, 0x92, 0x21,
+ 0x43, 0x7e, 0x46, 0xf1, 0x45, 0xba, 0xf3, 0xb5, 0x99, 0xe7, 0x8b, 0x64,
+ 0x58, 0x1d, 0x5c, 0x49, 0xc7, 0x9e, 0x1d, 0xb2, 0x0c, 0xb1, 0xd3, 0x81,
+ 0x43, 0x6a, 0x2d, 0x13, 0xcb, 0xf8, 0x45, 0x1d, 0xe7, 0x76, 0xed, 0xba,
+ 0x1a, 0x09, 0x28, 0xe6, 0xd0, 0x23, 0x81, 0x9e, 0xd8, 0xb9, 0x8f};
constexpr uint8_t kExpectedCborP384Cert_HashOnlyInput[569] = {
0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xcd, 0xa9, 0x01,
@@ -697,15 +783,15 @@
0xc3, 0xb2, 0xe7, 0x34, 0xf5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
0x3a, 0x00, 0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70,
- 0x33, 0x38, 0x34, 0x58, 0x60, 0x08, 0x82, 0x40, 0x67, 0xcb, 0x0b, 0x5d,
- 0x98, 0x3b, 0x7b, 0xf0, 0x9c, 0x5f, 0x32, 0x47, 0xb4, 0x5d, 0xb9, 0x7a,
- 0xce, 0x1c, 0x55, 0x35, 0xc2, 0x18, 0x2d, 0xcb, 0x4b, 0xc1, 0xa7, 0xd2,
- 0xfa, 0x1e, 0x17, 0xa9, 0x61, 0xd5, 0x2a, 0x9f, 0x8c, 0x8e, 0x72, 0xc7,
- 0x60, 0x2e, 0x11, 0x59, 0x3a, 0xe9, 0x7d, 0x90, 0x00, 0x03, 0x67, 0xb7,
- 0x17, 0xc1, 0x95, 0x07, 0x04, 0xec, 0x81, 0x11, 0x21, 0x19, 0x4b, 0x22,
- 0x35, 0xbe, 0x93, 0xc8, 0xb8, 0x78, 0xb5, 0x16, 0xb9, 0x6e, 0x7b, 0xf6,
- 0x50, 0xe8, 0xf4, 0x81, 0xc2, 0xf4, 0x1c, 0x4b, 0xe2, 0x8d, 0x9d, 0x80,
- 0xcb, 0x34, 0x15, 0xc5, 0x63};
+ 0x33, 0x38, 0x34, 0x58, 0x60, 0x88, 0xa1, 0x0e, 0xbc, 0x51, 0xfb, 0x22,
+ 0x0c, 0x05, 0x67, 0x56, 0x39, 0x8c, 0xdb, 0x8e, 0x3f, 0x1b, 0x2c, 0x8c,
+ 0x67, 0x49, 0x85, 0xc3, 0x9b, 0x33, 0x0f, 0x2b, 0x5e, 0x99, 0x65, 0x0d,
+ 0x7b, 0xa4, 0x8e, 0xcd, 0x4a, 0xd0, 0x3c, 0x81, 0x9d, 0x34, 0xc5, 0x0a,
+ 0x4f, 0xab, 0xeb, 0xc8, 0xe6, 0xb9, 0x2e, 0x09, 0x64, 0xdc, 0xa1, 0xc5,
+ 0x19, 0x1a, 0xf2, 0x1c, 0xc2, 0xc7, 0x02, 0xb3, 0x93, 0xac, 0x8c, 0x61,
+ 0x7d, 0x4d, 0xcf, 0xc3, 0x1b, 0x06, 0x0e, 0x7f, 0x03, 0x71, 0x79, 0x21,
+ 0x4c, 0x46, 0xd5, 0x77, 0xe9, 0xd2, 0x5e, 0xa8, 0xe4, 0x71, 0xfc, 0x6d,
+ 0xa1, 0xf6, 0x12, 0xab, 0x40};
constexpr uint8_t kExpectedCdiAttest_DescriptorInput[32] = {
0x20, 0xd5, 0x0c, 0x68, 0x5a, 0xd9, 0xe2, 0xdf, 0x77, 0x60, 0x78,
@@ -902,7 +988,7 @@
// X509v3 Basic Constraints: critical
// CA:TRUE
// 1.3.6.1.4.1.11129.2.1.24: critical
-// 0:d=0 hl=4 l= 450 cons: SEQUENCE
+// 0:d=0 hl=4 l= 461 cons: SEQUENCE
// 4:d=1 hl=2 l= 66 cons: cont [ 0 ]
// 6:d=2 hl=2 l= 64 prim: OCTET STRING
// 0000 - b7 d4 0c cb 22 5b a5 78-8f 98 ff 9e 86 93 75 f6 ...."[.x......u.
@@ -944,17 +1030,17 @@
// 0040 - a2 .
// 425:d=1 hl=2 l= 3 cons: cont [ 6 ]
// 427:d=2 hl=2 l= 1 prim: ENUMERATED :00
-// 430:d=1 hl=2 l= 22 cons: cont [ 7 ]
-// 432:d=2 hl=2 l= 20 prim: UTF8STRING :openssl.example.p256
+// 430:d=1 hl=2 l= 33 cons: cont [ 7 ]
+// 432:d=2 hl=2 l= 31 prim: UTF8STRING :openssl.example.p256_compressed
//
// Signature Algorithm: ecdsa-with-SHA512
// Signature Value:
-// 30:45:02:20:4f:55:9a:0c:2a:48:d5:51:fe:a1:b9:40:e7:95:
-// 97:d0:48:0a:de:71:bf:aa:19:5f:51:3d:d9:4c:df:a8:69:a8:
-// 02:21:00:d4:8c:28:58:8e:3c:4e:b6:98:76:24:2b:92:c5:8c:
-// 42:8c:88:a7:58:35:3d:b5:0e:18:a5:6f:2d:d3:0c:4c:33
-constexpr uint8_t kExpectedX509P256Cert_DescriptorInput[950] = {
- 0x30, 0x82, 0x03, 0xb2, 0x30, 0x82, 0x03, 0x56, 0xa0, 0x03, 0x02, 0x01,
+// 30:44:02:20:1e:7d:b6:7e:85:4a:20:fc:61:a8:b8:73:40:a0:
+// c2:5f:a5:3f:06:07:0a:1c:26:82:a0:5c:d5:b9:58:f5:e5:b0:
+// 02:20:46:61:2d:29:ee:a7:b6:ad:c4:0d:c6:b2:76:f2:5a:88:
+// c1:bd:8e:dd:5e:bd:c7:1d:b3:c3:2d:84:4b:f6:ce:7f
+constexpr uint8_t kExpectedX509P256Cert_DescriptorInput[960] = {
+ 0x30, 0x82, 0x03, 0xbc, 0x30, 0x82, 0x03, 0x61, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x14, 0x2c, 0x0d, 0xe9, 0x55, 0xc4, 0xfa, 0x08, 0x2c, 0x2c,
0x3a, 0x0b, 0x40, 0x66, 0x59, 0xaf, 0xa1, 0xc1, 0xc0, 0x84, 0x6c, 0x30,
0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05,
@@ -977,7 +1063,7 @@
0x9b, 0x27, 0xf3, 0x87, 0x97, 0xb3, 0xe7, 0x36, 0xe6, 0x42, 0x87, 0x8c,
0x72, 0xde, 0xf7, 0xaf, 0x2d, 0xc6, 0x23, 0x00, 0xb1, 0x2b, 0x4e, 0x1c,
0xf3, 0xaf, 0x67, 0xf0, 0x9b, 0x88, 0x40, 0x79, 0x3b, 0x09, 0x78, 0x30,
- 0x51, 0x65, 0x38, 0x61, 0xa3, 0x82, 0x02, 0x42, 0x30, 0x82, 0x02, 0x3e,
+ 0x51, 0x65, 0x38, 0x61, 0xa3, 0x82, 0x02, 0x4d, 0x30, 0x82, 0x02, 0x49,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
0x14, 0x1b, 0xe5, 0x68, 0x79, 0x33, 0xdb, 0x3d, 0x9c, 0xd5, 0xfc, 0xa7,
0x29, 0xe8, 0x1d, 0x66, 0x85, 0x46, 0x5a, 0x7b, 0xf1, 0x30, 0x1d, 0x06,
@@ -986,9 +1072,9 @@
0xc1, 0xc0, 0x84, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x0f, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
- 0xff, 0x30, 0x82, 0x01, 0xd9, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
- 0xd6, 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x82, 0x01, 0xc6,
- 0x30, 0x82, 0x01, 0xc2, 0xa0, 0x42, 0x04, 0x40, 0xb7, 0xd4, 0x0c, 0xcb,
+ 0xff, 0x30, 0x82, 0x01, 0xe4, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+ 0xd6, 0x79, 0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x82, 0x01, 0xd1,
+ 0x30, 0x82, 0x01, 0xcd, 0xa0, 0x42, 0x04, 0x40, 0xb7, 0xd4, 0x0c, 0xcb,
0x22, 0x5b, 0xa5, 0x78, 0x8f, 0x98, 0xff, 0x9e, 0x86, 0x93, 0x75, 0xf6,
0x90, 0xac, 0x50, 0xcf, 0x9e, 0xbd, 0x0a, 0xfe, 0xb1, 0xd9, 0xc2, 0x4e,
0x52, 0x19, 0xe4, 0xde, 0x29, 0xe5, 0x61, 0xf3, 0xf9, 0x29, 0xe8, 0x40,
@@ -1023,17 +1109,17 @@
0x11, 0x2d, 0x08, 0x4d, 0x7c, 0x39, 0x76, 0xdc, 0x73, 0xe7, 0x1c, 0x16,
0x62, 0xd5, 0x59, 0xd7, 0x49, 0x2b, 0x6a, 0xa2, 0x36, 0x67, 0x57, 0xd1,
0xf2, 0xf9, 0xaf, 0x13, 0xd7, 0xa3, 0xe4, 0xd3, 0x39, 0x5b, 0x02, 0x78,
- 0xb1, 0xe0, 0x09, 0x70, 0xa2, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x16,
- 0x0c, 0x14, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78,
- 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x30, 0x0c,
- 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05, 0x00,
- 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x4f, 0x55, 0x9a, 0x0c, 0x2a,
- 0x48, 0xd5, 0x51, 0xfe, 0xa1, 0xb9, 0x40, 0xe7, 0x95, 0x97, 0xd0, 0x48,
- 0x0a, 0xde, 0x71, 0xbf, 0xaa, 0x19, 0x5f, 0x51, 0x3d, 0xd9, 0x4c, 0xdf,
- 0xa8, 0x69, 0xa8, 0x02, 0x21, 0x00, 0xd4, 0x8c, 0x28, 0x58, 0x8e, 0x3c,
- 0x4e, 0xb6, 0x98, 0x76, 0x24, 0x2b, 0x92, 0xc5, 0x8c, 0x42, 0x8c, 0x88,
- 0xa7, 0x58, 0x35, 0x3d, 0xb5, 0x0e, 0x18, 0xa5, 0x6f, 0x2d, 0xd3, 0x0c,
- 0x4c, 0x33};
+ 0xb1, 0xe0, 0x09, 0x70, 0xa2, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x21,
+ 0x0c, 0x1f, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x6c, 0x2e, 0x65, 0x78,
+ 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x32, 0x35, 0x36, 0x5f, 0x63,
+ 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x30, 0x0c, 0x06,
+ 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x05, 0x00, 0x03,
+ 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x1e, 0x7d, 0xb6, 0x7e, 0x85, 0x4a,
+ 0x20, 0xfc, 0x61, 0xa8, 0xb8, 0x73, 0x40, 0xa0, 0xc2, 0x5f, 0xa5, 0x3f,
+ 0x06, 0x07, 0x0a, 0x1c, 0x26, 0x82, 0xa0, 0x5c, 0xd5, 0xb9, 0x58, 0xf5,
+ 0xe5, 0xb0, 0x02, 0x20, 0x46, 0x61, 0x2d, 0x29, 0xee, 0xa7, 0xb6, 0xad,
+ 0xc4, 0x0d, 0xc6, 0xb2, 0x76, 0xf2, 0x5a, 0x88, 0xc1, 0xbd, 0x8e, 0xdd,
+ 0x5e, 0xbd, 0xc7, 0x1d, 0xb3, 0xc3, 0x2d, 0x84, 0x4b, 0xf6, 0xce, 0x7f};
constexpr uint8_t kExpectedX509P384Cert_DescriptorInput[0] = {};
@@ -1095,7 +1181,68 @@
0x5a, 0xfa, 0xca, 0xcd, 0x5d, 0x44, 0x58, 0x45, 0xdf, 0xbb, 0x3d, 0x08,
0x88, 0x9b, 0x0c, 0x3b, 0x06, 0x7c, 0x0e};
-constexpr uint8_t kExpectedCborP256Cert_DescriptorInput[0] = {};
+constexpr uint8_t kExpectedCborP256Cert_DescriptorInput[729] = {
+ 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x59, 0x02, 0x8e, 0xac, 0x01, 0x78,
+ 0x28, 0x34, 0x38, 0x36, 0x30, 0x33, 0x63, 0x30, 0x30, 0x35, 0x32, 0x63,
+ 0x31, 0x63, 0x61, 0x63, 0x37, 0x33, 0x63, 0x61, 0x65, 0x33, 0x36, 0x63,
+ 0x33, 0x62, 0x64, 0x65, 0x63, 0x37, 0x63, 0x36, 0x31, 0x33, 0x39, 0x38,
+ 0x38, 0x35, 0x63, 0x39, 0x64, 0x02, 0x78, 0x28, 0x35, 0x61, 0x30, 0x34,
+ 0x65, 0x39, 0x65, 0x63, 0x66, 0x31, 0x39, 0x61, 0x64, 0x33, 0x64, 0x35,
+ 0x32, 0x36, 0x36, 0x38, 0x62, 0x38, 0x32, 0x61, 0x36, 0x30, 0x38, 0x31,
+ 0x66, 0x30, 0x33, 0x66, 0x64, 0x62, 0x32, 0x39, 0x66, 0x38, 0x36, 0x34,
+ 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0xb7, 0xd4, 0x0c, 0xcb, 0x22,
+ 0x5b, 0xa5, 0x78, 0x8f, 0x98, 0xff, 0x9e, 0x86, 0x93, 0x75, 0xf6, 0x90,
+ 0xac, 0x50, 0xcf, 0x9e, 0xbd, 0x0a, 0xfe, 0xb1, 0xd9, 0xc2, 0x4e, 0x52,
+ 0x19, 0xe4, 0xde, 0x29, 0xe5, 0x61, 0xf3, 0xf9, 0x29, 0xe8, 0x40, 0x87,
+ 0x7a, 0xdd, 0x17, 0x48, 0x05, 0x89, 0x7e, 0x2b, 0xcb, 0x54, 0x79, 0xcc,
+ 0x66, 0xf1, 0xb3, 0x13, 0x29, 0x0c, 0x68, 0x96, 0xb2, 0xbb, 0x8f, 0x3a,
+ 0x00, 0x47, 0x44, 0x51, 0x58, 0x64, 0x6c, 0x46, 0x01, 0x33, 0x26, 0x73,
+ 0x4b, 0x22, 0x65, 0xfd, 0xfa, 0x58, 0xd7, 0x57, 0x3e, 0x95, 0x59, 0xe0,
+ 0x3a, 0xc3, 0xb9, 0xf7, 0xc8, 0x0e, 0x98, 0x80, 0x8c, 0xf5, 0xc4, 0xb8,
+ 0xaf, 0xe3, 0x16, 0x84, 0x25, 0xa5, 0x35, 0x5d, 0x17, 0x72, 0x56, 0x8f,
+ 0x8e, 0xec, 0x2f, 0x5a, 0x74, 0x60, 0x77, 0x2a, 0x6e, 0x90, 0xc0, 0x4e,
+ 0x9f, 0x87, 0x6b, 0xf4, 0x8d, 0x9c, 0x66, 0xe3, 0x0b, 0xd2, 0x10, 0x35,
+ 0x21, 0xa8, 0x1d, 0xa2, 0x31, 0x17, 0xe7, 0x0c, 0xdf, 0x18, 0xf7, 0x94,
+ 0xe4, 0xd1, 0xca, 0x32, 0x7d, 0xf2, 0x63, 0x23, 0x1d, 0xbc, 0x84, 0x74,
+ 0x61, 0xdb, 0x87, 0xf2, 0xab, 0x72, 0xad, 0xaf, 0x08, 0xf8, 0x3a, 0x00,
+ 0x47, 0x44, 0x53, 0x58, 0x28, 0x1b, 0x40, 0xc1, 0xa9, 0x77, 0x60, 0xeb,
+ 0xc3, 0x67, 0xf0, 0x5f, 0x6a, 0xe1, 0x5e, 0x20, 0xc2, 0x51, 0x68, 0x4d,
+ 0x82, 0x48, 0x8b, 0x03, 0x32, 0x16, 0x79, 0x88, 0x14, 0x37, 0x78, 0x7f,
+ 0x16, 0x9a, 0x06, 0xfd, 0xc0, 0x8a, 0x15, 0x80, 0x62, 0x3a, 0x00, 0x47,
+ 0x44, 0x52, 0x58, 0x40, 0x45, 0x00, 0xe9, 0x5c, 0xbd, 0x00, 0x57, 0x04,
+ 0x55, 0x87, 0x6c, 0xbd, 0x2f, 0xea, 0x41, 0x9c, 0x66, 0x42, 0x51, 0x41,
+ 0xbb, 0x44, 0xed, 0x0e, 0xe9, 0x66, 0xcf, 0xd5, 0x10, 0x73, 0x0d, 0x4b,
+ 0x48, 0xe4, 0x7a, 0x53, 0x35, 0x01, 0x0e, 0x6d, 0x15, 0x55, 0xc5, 0xb7,
+ 0xd2, 0xd5, 0x36, 0xb6, 0xbc, 0x7e, 0xb0, 0xf3, 0x3d, 0xe6, 0x19, 0x78,
+ 0x62, 0xeb, 0x02, 0x57, 0x39, 0x56, 0x73, 0x4f, 0x3a, 0x00, 0x47, 0x44,
+ 0x54, 0x58, 0x40, 0x22, 0x52, 0x60, 0x17, 0xef, 0x2c, 0xa1, 0xf6, 0xcb,
+ 0xed, 0x39, 0xd5, 0xe2, 0xaa, 0x65, 0x20, 0xfb, 0xad, 0x82, 0x93, 0xe5,
+ 0x78, 0x23, 0x22, 0x97, 0xc1, 0x6e, 0x6a, 0x4e, 0x36, 0xd7, 0x6a, 0x61,
+ 0x39, 0x08, 0x21, 0xd4, 0xfe, 0x92, 0x5f, 0x36, 0x2d, 0xeb, 0x5d, 0xbb,
+ 0x32, 0x8b, 0xe3, 0x94, 0x4f, 0xbe, 0x1b, 0x21, 0xf9, 0xcc, 0x23, 0x73,
+ 0x41, 0xb6, 0xb9, 0xb6, 0x98, 0xd0, 0xbc, 0x3a, 0x00, 0x47, 0x44, 0x55,
+ 0x58, 0x41, 0x92, 0xd6, 0x97, 0xb3, 0x83, 0xdf, 0xe7, 0x8c, 0xc7, 0xbc,
+ 0x4a, 0xfc, 0xea, 0x76, 0xc0, 0x53, 0x66, 0xbd, 0x2c, 0x1e, 0x10, 0x31,
+ 0x90, 0x80, 0x11, 0x2d, 0x08, 0x4d, 0x7c, 0x39, 0x76, 0xdc, 0x73, 0xe7,
+ 0x1c, 0x16, 0x62, 0xd5, 0x59, 0xd7, 0x49, 0x2b, 0x6a, 0xa2, 0x36, 0x67,
+ 0x57, 0xd1, 0xf2, 0xf9, 0xaf, 0x13, 0xd7, 0xa3, 0xe4, 0xd3, 0x39, 0x5b,
+ 0x02, 0x78, 0xb1, 0xe0, 0x09, 0x70, 0xa2, 0x3a, 0x00, 0x47, 0x44, 0x56,
+ 0x41, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x50, 0xa6, 0x01, 0x02,
+ 0x03, 0x26, 0x04, 0x81, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20, 0x6d, 0x1e,
+ 0xdd, 0x35, 0x38, 0x70, 0xc2, 0x8a, 0x01, 0xdf, 0x80, 0xb1, 0xa5, 0xae,
+ 0x85, 0x4b, 0x7a, 0x12, 0xdd, 0x11, 0xf6, 0x97, 0x27, 0x44, 0x9b, 0x27,
+ 0xf3, 0x87, 0x97, 0xb3, 0xe7, 0x36, 0x22, 0x58, 0x20, 0xe6, 0x42, 0x87,
+ 0x8c, 0x72, 0xde, 0xf7, 0xaf, 0x2d, 0xc6, 0x23, 0x00, 0xb1, 0x2b, 0x4e,
+ 0x1c, 0xf3, 0xaf, 0x67, 0xf0, 0x9b, 0x88, 0x40, 0x79, 0x3b, 0x09, 0x78,
+ 0x30, 0x51, 0x65, 0x38, 0x61, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
+ 0x3a, 0x00, 0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
+ 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70,
+ 0x32, 0x35, 0x36, 0x58, 0x40, 0x5e, 0x90, 0x5d, 0x5b, 0x1e, 0xfc, 0xda,
+ 0xab, 0x8d, 0x52, 0xb0, 0xb4, 0xa3, 0xb9, 0xb1, 0x7e, 0x36, 0x20, 0x7f,
+ 0x2e, 0x4b, 0x2c, 0x86, 0x77, 0x1f, 0xf2, 0x7d, 0x5a, 0x18, 0xfb, 0x15,
+ 0x7b, 0x3a, 0x0a, 0xdc, 0x0a, 0x1e, 0xcb, 0xfa, 0x72, 0xac, 0x30, 0xb1,
+ 0x1c, 0x4b, 0xd8, 0x28, 0x70, 0x43, 0x73, 0x91, 0xe5, 0x6b, 0xab, 0xd1,
+ 0x55, 0xc7, 0x0c, 0xed, 0x32, 0x9b, 0xa0, 0x5e, 0x26};
constexpr uint8_t kExpectedCborP384Cert_DescriptorInput[795] = {
0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x02, 0xaf, 0xac, 0x01,
@@ -1156,15 +1303,15 @@
0x8d, 0x1d, 0x4b, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x3a, 0x00,
0x47, 0x44, 0x59, 0x75, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x65,
0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x33, 0x38,
- 0x34, 0x58, 0x60, 0xe4, 0x8c, 0x6b, 0x6b, 0x24, 0xb2, 0xc6, 0x17, 0xcf,
- 0xfb, 0xb0, 0x8b, 0x28, 0x81, 0x8c, 0xb7, 0xc0, 0xed, 0x46, 0x9d, 0xb7,
- 0xb6, 0x7f, 0xfd, 0xc6, 0xdd, 0xb8, 0x61, 0xb9, 0x03, 0xbc, 0x66, 0x01,
- 0xb2, 0x7e, 0x9d, 0x4e, 0x62, 0x7b, 0xb0, 0x41, 0x39, 0x81, 0x7f, 0x30,
- 0x64, 0x4e, 0x5b, 0x33, 0x22, 0x1c, 0xa4, 0xac, 0x88, 0x33, 0x87, 0xe1,
- 0x7b, 0x0f, 0xa1, 0x55, 0xaa, 0x8a, 0x4e, 0xbd, 0x50, 0xec, 0xc0, 0x35,
- 0x28, 0xb4, 0xaa, 0xaa, 0x2a, 0x78, 0x42, 0x5f, 0xcb, 0x76, 0xa7, 0x84,
- 0xa1, 0xca, 0xf2, 0xda, 0xdb, 0x14, 0x6a, 0x87, 0x05, 0x11, 0xa8, 0xfa,
- 0x09, 0x30, 0x9c};
+ 0x34, 0x58, 0x60, 0x5b, 0xe4, 0xf7, 0x39, 0x88, 0x09, 0x93, 0x73, 0x57,
+ 0x5d, 0xb9, 0xb1, 0xb9, 0x39, 0xa8, 0x45, 0x8c, 0xba, 0x07, 0x11, 0x9d,
+ 0xda, 0x23, 0x3c, 0x56, 0x82, 0x04, 0x81, 0xcb, 0x61, 0xb0, 0x1c, 0xe5,
+ 0xbe, 0x3b, 0xa1, 0x77, 0x44, 0xa3, 0xe0, 0x18, 0x11, 0x78, 0x9e, 0xc4,
+ 0x2c, 0x3f, 0xb6, 0x60, 0xa6, 0x3b, 0xe3, 0x74, 0x4d, 0xcc, 0x3a, 0x99,
+ 0x22, 0x66, 0x1b, 0x09, 0xb8, 0x1c, 0x81, 0x32, 0x57, 0x66, 0xde, 0xa2,
+ 0x76, 0x50, 0xa1, 0xee, 0xb3, 0x95, 0x60, 0x82, 0x40, 0x29, 0x30, 0x8b,
+ 0x19, 0x33, 0x90, 0x54, 0x47, 0xd1, 0x38, 0x25, 0xb8, 0x28, 0xe9, 0xc5,
+ 0x9d, 0x9a, 0x3e};
} // namespace test
} // namespace dice
diff --git a/include/dice/test_utils.h b/include/dice/test_utils.h
index 7e403b9..c5bea9e 100644
--- a/include/dice/test_utils.h
+++ b/include/dice/test_utils.h
@@ -33,6 +33,7 @@
enum KeyType {
KeyType_Ed25519,
KeyType_P256,
+ KeyType_P256_COMPRESSED,
KeyType_P384,
};
diff --git a/src/boringssl_ecdsa_utils.c b/src/boringssl_ecdsa_utils.c
index 91817a8..e42f679 100644
--- a/src/boringssl_ecdsa_utils.c
+++ b/src/boringssl_ecdsa_utils.c
@@ -12,8 +12,7 @@
// License for the specific language governing permissions and limitations under
// the License.
-// This is an implementation of the crypto operations that uses boringssl. The
-// algorithms used are SHA512, HKDF-SHA512, and ECDSA P384-SHA384.
+// This is an implementation of the ECDSA crypto operations that uses boringssl.
#include "dice/boringssl_ecdsa_utils.h"
@@ -210,36 +209,40 @@
private_key, P384_PRIVATE_KEY_SIZE, seed);
}
-int P384Sign(uint8_t signature[P384_SIGNATURE_SIZE], const uint8_t *message,
- size_t message_size,
- const uint8_t private_key[P384_PRIVATE_KEY_SIZE]) {
+static int Sign(int nid, uint8_t *signature, size_t signature_size,
+ const EVP_MD *md_type, const uint8_t *message,
+ size_t message_size, const uint8_t *private_key,
+ size_t private_key_size) {
int ret = 0;
BIGNUM *pD = NULL;
EC_KEY *key = NULL;
- uint8_t output[48];
+ uint8_t output[EVP_MAX_MD_SIZE];
+ unsigned int md_size;
ECDSA_SIG *sig = NULL;
- pD = BN_bin2bn(private_key, P384_PRIVATE_KEY_SIZE, NULL);
+ pD = BN_bin2bn(private_key, private_key_size, NULL);
if (!pD) {
goto out;
}
- key = EC_KEY_new_by_curve_name(NID_secp384r1);
+ key = EC_KEY_new_by_curve_name(nid);
if (!key) {
goto out;
}
if (1 != EC_KEY_set_private_key(key, pD)) {
goto out;
}
- SHA384(message, message_size, output);
- sig = ECDSA_do_sign(output, 48, key);
+ if (1 != EVP_Digest(message, message_size, output, &md_size, md_type, NULL)) {
+ goto out;
+ }
+ sig = ECDSA_do_sign(output, md_size, key);
if (!sig) {
goto out;
}
- if (1 != BN_bn2bin_padded(&signature[0], P384_SIGNATURE_SIZE / 2, sig->r)) {
+ size_t coord_size = signature_size / 2;
+ if (1 != BN_bn2bin_padded(&signature[0], coord_size, sig->r)) {
goto out;
}
- if (1 != BN_bn2bin_padded(&signature[P384_SIGNATURE_SIZE / 2],
- P384_SIGNATURE_SIZE / 2, sig->s)) {
+ if (1 != BN_bn2bin_padded(&signature[coord_size], coord_size, sig->s)) {
goto out;
}
ret = 1;
@@ -251,19 +254,38 @@
return ret;
}
-int P384Verify(const uint8_t *message, size_t message_size,
- const uint8_t signature[P384_SIGNATURE_SIZE],
- const uint8_t public_key[P384_PUBLIC_KEY_SIZE]) {
+int P256Sign(uint8_t signature[P256_SIGNATURE_SIZE], const uint8_t *message,
+ size_t message_size,
+ const uint8_t private_key[P256_PRIVATE_KEY_SIZE]) {
+ return Sign(NID_X9_62_prime256v1, signature, P256_SIGNATURE_SIZE,
+ EVP_sha256(), message, message_size, private_key,
+ P256_PRIVATE_KEY_SIZE);
+}
+
+int P384Sign(uint8_t signature[P384_SIGNATURE_SIZE], const uint8_t *message,
+ size_t message_size,
+ const uint8_t private_key[P384_PRIVATE_KEY_SIZE]) {
+ return Sign(NID_secp384r1, signature, P384_SIGNATURE_SIZE, EVP_sha384(),
+ message, message_size, private_key, P384_PRIVATE_KEY_SIZE);
+}
+
+static int Verify(int nid, const EVP_MD *md_type, const uint8_t *message,
+ size_t message_size, const uint8_t *signature,
+ size_t signature_size, const uint8_t *public_key,
+ size_t public_key_size) {
int ret = 0;
- uint8_t output[48];
+ uint8_t output[EVP_MAX_MD_SIZE];
+ unsigned int md_size;
EC_KEY *key = NULL;
BIGNUM *bn_ret = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
ECDSA_SIG *sig = NULL;
- SHA384(message, message_size, output);
- key = EC_KEY_new_by_curve_name(NID_secp384r1);
+ if (1 != EVP_Digest(message, message_size, output, &md_size, md_type, NULL)) {
+ goto out;
+ }
+ key = EC_KEY_new_by_curve_name(nid);
if (!key) {
goto out;
}
@@ -271,7 +293,8 @@
if (!x) {
goto out;
}
- bn_ret = BN_bin2bn(&public_key[0], P384_PUBLIC_KEY_SIZE / 2, x);
+ size_t coord_size = public_key_size / 2;
+ bn_ret = BN_bin2bn(&public_key[0], coord_size, x);
if (!bn_ret) {
goto out;
}
@@ -279,8 +302,7 @@
if (!y) {
goto out;
}
- bn_ret = BN_bin2bn(&public_key[P384_PUBLIC_KEY_SIZE / 2],
- P384_PUBLIC_KEY_SIZE / 2, y);
+ bn_ret = BN_bin2bn(&public_key[coord_size], coord_size, y);
if (!bn_ret) {
goto out;
}
@@ -292,16 +314,16 @@
if (!sig) {
goto out;
}
- bn_ret = BN_bin2bn(&signature[0], P384_SIGNATURE_SIZE / 2, sig->r);
+ coord_size = signature_size / 2;
+ bn_ret = BN_bin2bn(&signature[0], coord_size, sig->r);
if (!bn_ret) {
goto out;
}
- bn_ret = BN_bin2bn(&signature[P384_SIGNATURE_SIZE / 2],
- P384_SIGNATURE_SIZE / 2, sig->s);
+ bn_ret = BN_bin2bn(&signature[coord_size], coord_size, sig->s);
if (!bn_ret) {
goto out;
}
- ret = ECDSA_do_verify(output, 48, sig, key);
+ ret = ECDSA_do_verify(output, md_size, sig, key);
out:
BN_clear_free(y);
@@ -310,3 +332,18 @@
ECDSA_SIG_free(sig);
return ret;
}
+
+int P256Verify(const uint8_t *message, size_t message_size,
+ const uint8_t signature[P256_SIGNATURE_SIZE],
+ const uint8_t public_key[P256_PUBLIC_KEY_SIZE]) {
+ return Verify(NID_X9_62_prime256v1, EVP_sha256(), message, message_size,
+ signature, P256_SIGNATURE_SIZE, public_key,
+ P256_PUBLIC_KEY_SIZE);
+}
+
+int P384Verify(const uint8_t *message, size_t message_size,
+ const uint8_t signature[P384_SIGNATURE_SIZE],
+ const uint8_t public_key[P384_PUBLIC_KEY_SIZE]) {
+ return Verify(NID_secp384r1, EVP_sha384(), message, message_size, signature,
+ P384_SIGNATURE_SIZE, public_key, P384_PUBLIC_KEY_SIZE);
+}
diff --git a/src/boringssl_p256_ops.c b/src/boringssl_p256_ops.c
new file mode 100644
index 0000000..e6e030a
--- /dev/null
+++ b/src/boringssl_p256_ops.c
@@ -0,0 +1,68 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// This is an implementation of P-256 signature operations using boringssl.
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "dice/boringssl_ecdsa_utils.h"
+#include "dice/dice.h"
+#include "dice/ops.h"
+
+#if DICE_PRIVATE_KEY_SEED_SIZE != 32
+#error "Private key seed is expected to be 32 bytes."
+#endif
+#if DICE_PUBLIC_KEY_SIZE != 64
+#error "This P-256 implementation needs 64 bytes to store the public key."
+#endif
+#if DICE_PRIVATE_KEY_SIZE != 32
+#error "P-256 needs 32 bytes for the private key."
+#endif
+#if DICE_SIGNATURE_SIZE != 64
+#error "P-256 needs 64 bytes to store the signature."
+#endif
+
+DiceResult DiceKeypairFromSeed(void* context_not_used,
+ const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
+ uint8_t public_key[DICE_PUBLIC_KEY_SIZE],
+ uint8_t private_key[DICE_PRIVATE_KEY_SIZE]) {
+ (void)context_not_used;
+ if (1 == P256KeypairFromSeed(public_key, private_key, seed)) {
+ return kDiceResultOk;
+ }
+ return kDiceResultPlatformError;
+}
+
+DiceResult DiceSign(void* context_not_used, const uint8_t* message,
+ size_t message_size,
+ const uint8_t private_key[DICE_PRIVATE_KEY_SIZE],
+ uint8_t signature[DICE_SIGNATURE_SIZE]) {
+ (void)context_not_used;
+ if (1 == P256Sign(signature, message, message_size, private_key)) {
+ return kDiceResultOk;
+ }
+ return kDiceResultPlatformError;
+}
+
+DiceResult DiceVerify(void* context_not_used, const uint8_t* message,
+ size_t message_size,
+ const uint8_t signature[DICE_SIGNATURE_SIZE],
+ const uint8_t public_key[DICE_PUBLIC_KEY_SIZE]) {
+ (void)context_not_used;
+ if (1 == P256Verify(message, message_size, signature, public_key)) {
+ return kDiceResultOk;
+ }
+ return kDiceResultPlatformError;
+}
diff --git a/src/cbor_p256_cert_op.c b/src/cbor_p256_cert_op.c
new file mode 100644
index 0000000..fdc7e11
--- /dev/null
+++ b/src/cbor_p256_cert_op.c
@@ -0,0 +1,80 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// This is a DiceGenerateCertificate implementation that generates a CWT-style
+// CBOR certificate using the P-256 signature algorithm.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "dice/cbor_writer.h"
+#include "dice/dice.h"
+#include "dice/ops.h"
+#include "dice/ops/trait/cose.h"
+#include "dice/utils.h"
+
+#if DICE_PUBLIC_KEY_SIZE != 64
+#error "64 bytes needed to store the public key."
+#endif
+#if DICE_SIGNATURE_SIZE != 64
+#error "64 bytes needed to store the signature."
+#endif
+
+DiceResult DiceCoseEncodePublicKey(
+ void* context_not_used, const uint8_t public_key[DICE_PUBLIC_KEY_SIZE],
+ size_t buffer_size, uint8_t* buffer, size_t* encoded_size) {
+ (void)context_not_used;
+
+ // Constants per RFC 8152.
+ const int64_t kCoseKeyKtyLabel = 1;
+ const int64_t kCoseKeyAlgLabel = 3;
+ const int64_t kCoseKeyAlgValue = DICE_COSE_KEY_ALG_VALUE;
+ const int64_t kCoseKeyOpsLabel = 4;
+ const int64_t kCoseKeyOpsValue = 2; // Verify
+ const int64_t kCoseKeyKtyValue = 2; // EC2
+ const int64_t kCoseEc2CrvLabel = -1;
+ const int64_t kCoseEc2CrvValue = 1; // P-256
+ const int64_t kCoseEc2XLabel = -2;
+ const int64_t kCoseEc2YLabel = -3;
+
+ struct CborOut out;
+ CborOutInit(buffer, buffer_size, &out);
+ CborWriteMap(/*num_pairs=*/6, &out);
+ // Add the key type.
+ CborWriteInt(kCoseKeyKtyLabel, &out);
+ CborWriteInt(kCoseKeyKtyValue, &out);
+ // Add the algorithm.
+ CborWriteInt(kCoseKeyAlgLabel, &out);
+ CborWriteInt(kCoseKeyAlgValue, &out);
+ // Add the KeyOps.
+ CborWriteInt(kCoseKeyOpsLabel, &out);
+ CborWriteArray(/*num_elements=*/1, &out);
+ CborWriteInt(kCoseKeyOpsValue, &out);
+ // Add the curve.
+ CborWriteInt(kCoseEc2CrvLabel, &out);
+ CborWriteInt(kCoseEc2CrvValue, &out);
+ // Add the subject public key x and y coordinates
+ CborWriteInt(kCoseEc2XLabel, &out);
+ CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2, &public_key[0], &out);
+ CborWriteInt(kCoseEc2YLabel, &out);
+ CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2,
+ &public_key[DICE_PUBLIC_KEY_SIZE / 2], &out);
+
+ *encoded_size = CborOutSize(&out);
+ if (CborOutOverflowed(&out)) {
+ return kDiceResultBufferTooSmall;
+ }
+ return kDiceResultOk;
+}
diff --git a/src/cbor_p256_cert_op_test.cc b/src/cbor_p256_cert_op_test.cc
new file mode 100644
index 0000000..32fc2e2
--- /dev/null
+++ b/src/cbor_p256_cert_op_test.cc
@@ -0,0 +1,254 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <memory>
+
+#include "dice/config.h"
+#include "dice/dice.h"
+#include "dice/known_test_values.h"
+#include "dice/test_framework.h"
+#include "dice/test_utils.h"
+#include "dice/utils.h"
+#include "pw_string/format.h"
+
+namespace {
+
+using dice::test::CertificateType_Cbor;
+using dice::test::DeriveFakeInputValue;
+using dice::test::DiceStateForTest;
+using dice::test::KeyType_P256;
+
+TEST(DiceOpsTest, KnownAnswerZeroInput) {
+ 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);
+ EXPECT_EQ(kDiceResultOk, result);
+ DumpState(CertificateType_Cbor, KeyType_P256, "zero_input", next_state);
+ // The CDI values should be deterministic.
+ ASSERT_EQ(sizeof(next_state.cdi_attest),
+ sizeof(dice::test::kExpectedCdiAttest_ZeroInput));
+ EXPECT_EQ(0, memcmp(next_state.cdi_attest,
+ dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
+ ASSERT_EQ(sizeof(next_state.cdi_seal),
+ sizeof(dice::test::kExpectedCdiSeal_ZeroInput));
+ EXPECT_EQ(0, memcmp(next_state.cdi_seal,
+ dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
+ ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_ZeroInput),
+ next_state.certificate_size);
+ // Comparing everything except for the signature, since ECDSA signatures are
+ // not deterministic
+ EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_ZeroInput,
+ next_state.certificate,
+ next_state.certificate_size - DICE_SIGNATURE_SIZE));
+}
+
+TEST(DiceOpsTest, KnownAnswerHashOnlyInput) {
+ DiceStateForTest current_state = {};
+ DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
+ DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+ DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
+ DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
+ input_values.authority_hash);
+ input_values.config_type = kDiceConfigTypeInline;
+ DeriveFakeInputValue("inline_config", DICE_INLINE_CONFIG_SIZE,
+ input_values.config_value);
+
+ 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);
+ EXPECT_EQ(kDiceResultOk, result);
+ DumpState(CertificateType_Cbor, KeyType_P256, "hash_only_input", next_state);
+ ASSERT_EQ(sizeof(next_state.cdi_attest),
+ sizeof(dice::test::kExpectedCdiAttest_HashOnlyInput));
+ EXPECT_EQ(
+ 0, memcmp(next_state.cdi_attest,
+ dice::test::kExpectedCdiAttest_HashOnlyInput, DICE_CDI_SIZE));
+ ASSERT_EQ(sizeof(next_state.cdi_seal),
+ sizeof(dice::test::kExpectedCdiSeal_HashOnlyInput));
+ EXPECT_EQ(
+ 0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
+ DICE_CDI_SIZE));
+ ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_HashOnlyInput),
+ next_state.certificate_size);
+ EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_HashOnlyInput,
+ next_state.certificate,
+ next_state.certificate_size - DICE_SIGNATURE_SIZE));
+}
+
+TEST(DiceOpsTest, KnownAnswerDescriptorInput) {
+ DiceStateForTest current_state = {};
+ DeriveFakeInputValue("cdi_attest", DICE_CDI_SIZE, current_state.cdi_attest);
+ DeriveFakeInputValue("cdi_seal", DICE_CDI_SIZE, current_state.cdi_seal);
+
+ DiceStateForTest next_state = {};
+
+ DiceInputValues input_values = {};
+ DeriveFakeInputValue("code_hash", DICE_HASH_SIZE, input_values.code_hash);
+ uint8_t code_descriptor[100];
+ DeriveFakeInputValue("code_desc", sizeof(code_descriptor), code_descriptor);
+ input_values.code_descriptor = code_descriptor;
+ input_values.code_descriptor_size = sizeof(code_descriptor);
+
+ uint8_t config_descriptor[40];
+ 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;
+
+ DeriveFakeInputValue("authority_hash", DICE_HASH_SIZE,
+ input_values.authority_hash);
+ uint8_t authority_descriptor[65];
+ DeriveFakeInputValue("authority_desc", sizeof(authority_descriptor),
+ authority_descriptor);
+ input_values.authority_descriptor = authority_descriptor;
+ input_values.authority_descriptor_size = sizeof(authority_descriptor);
+
+ 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);
+ EXPECT_EQ(kDiceResultOk, result);
+ DumpState(CertificateType_Cbor, KeyType_P256, "descriptor_input", next_state);
+ // Both CDI values and the certificate should be deterministic.
+ EXPECT_EQ(
+ 0, memcmp(next_state.cdi_attest,
+ dice::test::kExpectedCdiAttest_DescriptorInput, DICE_CDI_SIZE));
+ EXPECT_EQ(
+ 0, memcmp(next_state.cdi_seal,
+ dice::test::kExpectedCdiSeal_DescriptorInput, DICE_CDI_SIZE));
+ ASSERT_EQ(sizeof(dice::test::kExpectedCborP256Cert_DescriptorInput),
+ next_state.certificate_size);
+ EXPECT_EQ(0, memcmp(dice::test::kExpectedCborP256Cert_DescriptorInput,
+ next_state.certificate,
+ next_state.certificate_size - DICE_SIGNATURE_SIZE));
+}
+
+TEST(DiceOpsTest, NonZeroMode) {
+ constexpr size_t kModeOffsetInCert = 315;
+ DiceStateForTest current_state = {};
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+ input_values.mode = kDiceModeDebug;
+ 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);
+ EXPECT_EQ(kDiceResultOk, result);
+ EXPECT_EQ(kDiceModeDebug, next_state.certificate[kModeOffsetInCert]);
+}
+
+TEST(DiceOpsTest, LargeInputs) {
+ constexpr uint8_t kBigBuffer[1024 * 1024] = {};
+ DiceStateForTest current_state = {};
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+ input_values.code_descriptor = kBigBuffer;
+ input_values.code_descriptor_size = sizeof(kBigBuffer);
+ 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);
+ EXPECT_EQ(kDiceResultBufferTooSmall, result);
+}
+
+TEST(DiceOpsTest, InvalidConfigType) {
+ DiceStateForTest current_state = {};
+ DiceStateForTest next_state = {};
+ DiceInputValues input_values = {};
+ input_values.config_type = (DiceConfigType)55;
+ 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);
+ EXPECT_EQ(kDiceResultInvalidInput, result);
+}
+
+TEST(DiceOpsTest, PartialCertChain) {
+ constexpr size_t kNumLayers = 7;
+ DiceStateForTest states[kNumLayers + 1] = {};
+ DiceInputValues inputs[kNumLayers] = {};
+ for (size_t i = 0; i < kNumLayers; ++i) {
+ char seed[40];
+ pw::string::Format(seed, "code_hash_%zu", i);
+ DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
+ pw::string::Format(seed, "authority_hash_%zu", i);
+ DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
+ inputs[i].config_type = kDiceConfigTypeInline;
+ pw::string::Format(seed, "inline_config_%zu", i);
+ DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
+ inputs[i].mode = kDiceModeNormal;
+ EXPECT_EQ(
+ kDiceResultOk,
+ DiceMainFlow(/*context=*/NULL, states[i].cdi_attest, states[i].cdi_seal,
+ &inputs[i], sizeof(states[i + 1].certificate),
+ states[i + 1].certificate, &states[i + 1].certificate_size,
+ states[i + 1].cdi_attest, states[i + 1].cdi_seal));
+ char suffix[40];
+ pw::string::Format(suffix, "part_cert_chain_%zu", i);
+ DumpState(CertificateType_Cbor, KeyType_P256, suffix, states[i + 1]);
+ }
+ // Use the first derived CDI cert as the 'root' of partial chain.
+ EXPECT_TRUE(dice::test::VerifyCertificateChain(
+ CertificateType_Cbor, states[1].certificate, states[1].certificate_size,
+ &states[2], kNumLayers - 1, /*is_partial_chain=*/true));
+}
+
+TEST(DiceOpsTest, FullCertChain) {
+ constexpr size_t kNumLayers = 7;
+ DiceStateForTest states[kNumLayers + 1] = {};
+ DiceInputValues inputs[kNumLayers] = {};
+ for (size_t i = 0; i < kNumLayers; ++i) {
+ char seed[40];
+ pw::string::Format(seed, "code_hash_%zu", i);
+ DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].code_hash);
+ pw::string::Format(seed, "authority_hash_%zu", i);
+ DeriveFakeInputValue(seed, DICE_HASH_SIZE, inputs[i].authority_hash);
+ inputs[i].config_type = kDiceConfigTypeInline;
+ pw::string::Format(seed, "inline_config_%zu", i);
+ DeriveFakeInputValue(seed, DICE_INLINE_CONFIG_SIZE, inputs[i].config_value);
+ inputs[i].mode = kDiceModeNormal;
+ EXPECT_EQ(
+ kDiceResultOk,
+ DiceMainFlow(/*context=*/NULL, states[i].cdi_attest, states[i].cdi_seal,
+ &inputs[i], sizeof(states[i + 1].certificate),
+ states[i + 1].certificate, &states[i + 1].certificate_size,
+ states[i + 1].cdi_attest, states[i + 1].cdi_seal));
+ char suffix[40];
+ pw::string::Format(suffix, "full_cert_chain_%zu", i);
+ DumpState(CertificateType_Cbor, KeyType_P256, suffix, states[i + 1]);
+ }
+ // Use a fake self-signed UDS cert as the 'root'.
+ uint8_t root_certificate[dice::test::kTestCertSize];
+ size_t root_certificate_size = 0;
+ dice::test::CreateFakeUdsCertificate(
+ NULL, states[0].cdi_attest, CertificateType_Cbor, KeyType_P256,
+ root_certificate, &root_certificate_size);
+ EXPECT_TRUE(dice::test::VerifyCertificateChain(
+ CertificateType_Cbor, root_certificate, root_certificate_size, &states[1],
+ kNumLayers, /*is_partial_chain=*/false));
+}
+
+} // namespace
diff --git a/src/mbedtls_ops_test.cc b/src/mbedtls_ops_test.cc
index 7f97366..66db7c4 100644
--- a/src/mbedtls_ops_test.cc
+++ b/src/mbedtls_ops_test.cc
@@ -31,7 +31,7 @@
using dice::test::DeriveFakeInputValue;
using dice::test::DiceStateForTest;
using dice::test::DumpState;
-using dice::test::KeyType_P256;
+using dice::test::KeyType_P256_COMPRESSED;
TEST(DiceOpsTest, KnownAnswerZeroInput) {
DiceStateForTest current_state = {};
@@ -42,7 +42,8 @@
sizeof(next_state.certificate), next_state.certificate,
&next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
EXPECT_EQ(kDiceResultOk, result);
- DumpState(CertificateType_X509, KeyType_P256, "zero_input", next_state);
+ DumpState(CertificateType_X509, KeyType_P256_COMPRESSED, "zero_input",
+ next_state);
// Both CDI values and the certificate should be deterministic.
EXPECT_EQ(0, memcmp(next_state.cdi_attest,
dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
@@ -72,7 +73,8 @@
sizeof(next_state.certificate), next_state.certificate,
&next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
EXPECT_EQ(kDiceResultOk, result);
- DumpState(CertificateType_X509, KeyType_P256, "hash_only_input", next_state);
+ DumpState(CertificateType_X509, KeyType_P256_COMPRESSED, "hash_only_input",
+ next_state);
// Both CDI values and the certificate should be deterministic.
EXPECT_EQ(
0, memcmp(next_state.cdi_attest,
@@ -120,7 +122,8 @@
sizeof(next_state.certificate), next_state.certificate,
&next_state.certificate_size, next_state.cdi_attest, next_state.cdi_seal);
EXPECT_EQ(kDiceResultOk, result);
- DumpState(CertificateType_X509, KeyType_P256, "descriptor_input", next_state);
+ DumpState(CertificateType_X509, KeyType_P256_COMPRESSED, "descriptor_input",
+ next_state);
// Both CDI values and the certificate should be deterministic.
EXPECT_EQ(
0, memcmp(next_state.cdi_attest,
@@ -135,7 +138,7 @@
}
TEST(DiceOpsTest, NonZeroMode) {
- constexpr size_t kModeOffsetInCert = 0x269;
+ constexpr size_t kModeOffsetInCert = 0x26a;
DiceStateForTest current_state = {};
DiceStateForTest next_state = {};
DiceInputValues input_values = {};
@@ -196,7 +199,8 @@
states[i + 1].cdi_attest, states[i + 1].cdi_seal));
char suffix[40];
pw::string::Format(suffix, "part_cert_chain_%zu", i);
- DumpState(CertificateType_X509, KeyType_P256, suffix, states[i + 1]);
+ DumpState(CertificateType_X509, KeyType_P256_COMPRESSED, suffix,
+ states[i + 1]);
}
// Use the first derived CDI cert as the 'root' of partial chain.
EXPECT_TRUE(dice::test::VerifyCertificateChain(
@@ -226,14 +230,16 @@
states[i + 1].cdi_attest, states[i + 1].cdi_seal));
char suffix[40];
pw::string::Format(suffix, "full_cert_chain_%zu", i);
- DumpState(CertificateType_X509, KeyType_P256, suffix, states[i + 1]);
+ DumpState(CertificateType_X509, KeyType_P256_COMPRESSED, suffix,
+ states[i + 1]);
}
// Use a fake self-signed UDS cert as the 'root'.
uint8_t root_certificate[dice::test::kTestCertSize];
size_t root_certificate_size = 0;
dice::test::CreateFakeUdsCertificate(
NULL, states[0].cdi_attest, dice::test::CertificateType_X509,
- dice::test::KeyType_P256, root_certificate, &root_certificate_size);
+ dice::test::KeyType_P256_COMPRESSED, root_certificate,
+ &root_certificate_size);
EXPECT_TRUE(dice::test::VerifyCertificateChain(
CertificateType_X509, root_certificate, root_certificate_size, &states[1],
kNumLayers,
diff --git a/src/test_utils.cc b/src/test_utils.cc
index cc40e49..0592fc5 100644
--- a/src/test_utils.cc
+++ b/src/test_utils.cc
@@ -18,7 +18,10 @@
#include <stdint.h>
#include <string.h>
+#include <functional>
#include <memory>
+#include <span>
+#include <vector>
#include "cose/cose.h"
#include "dice/boringssl_ecdsa_utils.h"
@@ -62,6 +65,7 @@
case dice::test::KeyType_Ed25519:
return "Ed25519";
case dice::test::KeyType_P256:
+ case dice::test::KeyType_P256_COMPRESSED:
return "P256";
case dice::test::KeyType_P384:
return "P384";
@@ -113,19 +117,24 @@
*raw_public_key_size = 32;
EVP_PKEY_get_raw_public_key(key.get(), raw_public_key, raw_public_key_size);
return key;
- } else if (key_type == dice::test::KeyType_P256) {
+ } else if (key_type == dice::test::KeyType_P256 ||
+ key_type == dice::test::KeyType_P256_COMPRESSED) {
const size_t kPublicKeySize = 64;
const size_t kPrivateKeySize = 32;
uint8_t pk[kPrivateKeySize];
P256KeypairFromSeed(raw_public_key, pk, raw_key);
bssl::UniquePtr<EVP_PKEY> pkey =
EcKeyFromCoords(NID_X9_62_prime256v1, raw_public_key, kPublicKeySize);
- const EC_KEY* key = EVP_PKEY_get0_EC_KEY(pkey.get());
- const EC_GROUP* group = EC_KEY_get0_group(key);
- const EC_POINT* pub = EC_KEY_get0_public_key(key);
- *raw_public_key_size =
- EC_POINT_point2oct(group, pub, POINT_CONVERSION_COMPRESSED,
- raw_public_key, 33, /*ctx=*/nullptr);
+ if (key_type == dice::test::KeyType_P256_COMPRESSED) {
+ const EC_KEY* key = EVP_PKEY_get0_EC_KEY(pkey.get());
+ const EC_GROUP* group = EC_KEY_get0_group(key);
+ const EC_POINT* pub = EC_KEY_get0_public_key(key);
+ *raw_public_key_size = EC_POINT_point2oct(
+ group, pub, POINT_CONVERSION_COMPRESSED, raw_public_key,
+ MAX_PUBLIC_KEY_SIZE, /*ctx=*/nullptr);
+ } else {
+ *raw_public_key_size = kPublicKeySize;
+ }
return pkey;
} else if (key_type == dice::test::KeyType_P384) {
const size_t kPublicKeySize = 96;
@@ -321,42 +330,37 @@
certificate, 0, dice::test::kTestCertSize, sign1.get());
}
-void CreateP384CborUdsCertificate(
- const uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
- const uint8_t id[DICE_ID_SIZE],
+void CreateEcdsaCborUdsCertificate(
+ std::span<uint8_t> public_key,
+ std::function<std::vector<uint8_t>(std::span<uint8_t>)> sign,
+ const uint8_t id[DICE_ID_SIZE], int8_t alg, uint8_t crv,
uint8_t certificate[dice::test::kTestCertSize], size_t* certificate_size) {
const int64_t kCwtIssuerLabel = 1;
const int64_t kCwtSubjectLabel = 2;
const int64_t kUdsPublicKeyLabel = -4670552;
const int64_t kUdsKeyUsageLabel = -4670553;
const uint8_t kKeyUsageCertSign = 32; // Bit 5.
- const uint8_t kProtectedAttributesCbor[4] = {
- 0xa1 /* map(1) */, 0x01 /* alg(1) */, 0x38, 0x22 /* ES384(-34) */};
- const size_t kPublicKeySize = 96;
- const size_t kPrivateKeySize = 48;
- const size_t kSignatureSize = 96;
+ const uint8_t kProtectedAttributesCbor[4] = {0xa1 /* map(1) */,
+ 0x01 /* alg(1) */, 0x38,
+ static_cast<uint8_t>(-alg - 1)};
- // Public key encoded as a COSE_Key.
- uint8_t public_key[kPublicKeySize];
- uint8_t private_key[kPrivateKeySize];
- P384KeypairFromSeed(public_key, private_key, private_key_seed);
cn_cbor_errback error;
ScopedCbor public_key_cbor(cn_cbor_map_create(&error));
// kty = ec2
cn_cbor_mapput_int(public_key_cbor.get(), 1, cn_cbor_int_create(2, &error),
&error);
- // crv = P-384
- cn_cbor_mapput_int(public_key_cbor.get(), -1, cn_cbor_int_create(2, &error),
+ // crv
+ cn_cbor_mapput_int(public_key_cbor.get(), -1, cn_cbor_int_create(crv, &error),
&error);
// x = public_key X
- cn_cbor_mapput_int(
- public_key_cbor.get(), -2,
- cn_cbor_data_create(&public_key[0], kPublicKeySize / 2, &error), &error);
- // y = public_key Y
- cn_cbor_mapput_int(public_key_cbor.get(), -3,
- cn_cbor_data_create(&public_key[kPublicKeySize / 2],
- kPublicKeySize / 2, &error),
+ size_t coord_size = public_key.size() / 2;
+ cn_cbor_mapput_int(public_key_cbor.get(), -2,
+ cn_cbor_data_create(&public_key[0], coord_size, &error),
&error);
+ // y = public_key Y
+ cn_cbor_mapput_int(
+ public_key_cbor.get(), -3,
+ cn_cbor_data_create(&public_key[coord_size], coord_size, &error), &error);
uint8_t encoded_public_key[200];
size_t encoded_public_key_size =
cn_cbor_encoder_write(encoded_public_key, 0, 200, public_key_cbor.get());
@@ -397,8 +401,7 @@
uint8_t tbs[dice::test::kTestCertSize];
size_t tbs_size =
cn_cbor_encoder_write(tbs, 0, dice::test::kTestCertSize, tbs_cbor.get());
- uint8_t signature[kSignatureSize];
- P384Sign(signature, tbs, tbs_size, private_key);
+ std::vector signature = sign({tbs, tbs_size});
// COSE Sign1.
ScopedCbor sign1(cn_cbor_array_create(&error));
@@ -408,13 +411,63 @@
cn_cbor_array_append(sign1.get(), cn_cbor_map_create(&error), &error);
cn_cbor_array_append(
sign1.get(), cn_cbor_data_create(payload, payload_size, &error), &error);
- cn_cbor_array_append(sign1.get(),
- cn_cbor_data_create(signature, kSignatureSize, &error),
- &error);
+ cn_cbor_array_append(
+ sign1.get(),
+ cn_cbor_data_create(signature.data(), signature.size(), &error), &error);
*certificate_size = cn_cbor_encoder_write(
certificate, 0, dice::test::kTestCertSize, sign1.get());
}
+void CreateP256CborUdsCertificate(
+ const uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
+ const uint8_t id[DICE_ID_SIZE],
+ uint8_t certificate[dice::test::kTestCertSize], size_t* certificate_size) {
+ const int8_t kAlgEs256 = -7;
+ const uint8_t kCrvP256 = 1;
+ const size_t kPublicKeySize = 64;
+ const size_t kPrivateKeySize = 32;
+ const size_t kSignatureSize = 64;
+
+ // Public key encoded as a COSE_Key.
+ uint8_t public_key[kPublicKeySize];
+ uint8_t private_key[kPrivateKeySize];
+ P256KeypairFromSeed(public_key, private_key, private_key_seed);
+
+ auto sign = [&](std::span<uint8_t> tbs) {
+ std::vector<uint8_t> signature(kSignatureSize);
+ P256Sign(signature.data(), tbs.data(), tbs.size(), private_key);
+ return signature;
+ };
+
+ CreateEcdsaCborUdsCertificate(public_key, sign, id, kAlgEs256, kCrvP256,
+ certificate, certificate_size);
+}
+
+void CreateP384CborUdsCertificate(
+ const uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
+ const uint8_t id[DICE_ID_SIZE],
+ uint8_t certificate[dice::test::kTestCertSize], size_t* certificate_size) {
+ const int8_t kAlgEs384 = -35;
+ const uint8_t kCrvP384 = 2;
+ const size_t kPublicKeySize = 96;
+ const size_t kPrivateKeySize = 48;
+ const size_t kSignatureSize = 96;
+
+ // Public key encoded as a COSE_Key.
+ uint8_t public_key[kPublicKeySize];
+ uint8_t private_key[kPrivateKeySize];
+ P384KeypairFromSeed(public_key, private_key, private_key_seed);
+
+ auto sign = [&](std::span<uint8_t> tbs) {
+ std::vector<uint8_t> signature(kSignatureSize);
+ P384Sign(signature.data(), tbs.data(), tbs.size(), private_key);
+ return signature;
+ };
+
+ CreateEcdsaCborUdsCertificate(public_key, sign, id, kAlgEs384, kCrvP384,
+ certificate, certificate_size);
+}
+
void CreateCborUdsCertificate(
const uint8_t private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
dice::test::KeyType key_type, const uint8_t id[DICE_ID_SIZE],
@@ -425,10 +478,12 @@
certificate_size);
break;
case dice::test::KeyType_P256:
- printf(
- "Error: encountered unsupported KeyType P256 when creating CBOR UDS "
- "certificate\n");
+ CreateP256CborUdsCertificate(private_key_seed, id, certificate,
+ certificate_size);
break;
+ case dice::test::KeyType_P256_COMPRESSED:
+ fprintf(stderr, "ERROR: Unsupported key type.\n");
+ abort();
case dice::test::KeyType_P384:
CreateP384CborUdsCertificate(private_key_seed, id, certificate,
certificate_size);
diff --git a/third_party/cose-c/BUILD.gn b/third_party/cose-c/BUILD.gn
index e5a46aa..9fba69c 100644
--- a/third_party/cose-c/BUILD.gn
+++ b/third_party/cose-c/BUILD.gn
@@ -22,6 +22,13 @@
]
}
+config("external_config_p256") {
+ include_dirs = [
+ "src/include",
+ "include/p256",
+ ]
+}
+
config("external_config_p384") {
include_dirs = [
"src/include",
@@ -52,6 +59,23 @@
]
}
+pw_static_library("cose-c_p256") {
+ public = [ "src/include/cose/cose.h" ]
+ sources = [
+ "cose_p256_deps.cc",
+ "src/src/Cose.cpp",
+ "src/src/CoseKey.cpp",
+ "src/src/Sign1.cpp",
+ "src/src/cbor.cpp",
+ ]
+ public_configs = [ ":external_config_p256" ]
+ configs = [ ":internal_config" ]
+ public_deps = [
+ "//third_party/boringssl:crypto",
+ "//third_party/cn-cbor:cn-cbor",
+ ]
+}
+
pw_static_library("cose-c_p384") {
public = [ "src/include/cose/cose.h" ]
sources = [
diff --git a/third_party/cose-c/cose_p256_deps.cc b/third_party/cose-c/cose_p256_deps.cc
new file mode 100644
index 0000000..31f0c6b
--- /dev/null
+++ b/third_party/cose-c/cose_p256_deps.cc
@@ -0,0 +1,151 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <stdint.h>
+#include <string.h>
+
+#include "cose/cose.h"
+#include "cose/cose_configure.h"
+#include "cose_int.h"
+#include "openssl/bn.h"
+#include "openssl/ec.h"
+#include "openssl/ec_key.h"
+#include "openssl/ecdsa.h"
+#include "openssl/evp.h"
+#include "openssl/hkdf.h"
+#include "openssl/is_boringssl.h"
+#include "openssl/sha.h"
+
+// Gets the public key from a well-formed ECDSA P-256 COSE_Key. On
+// success populates |public_key| and returns true; public_key must hold 64
+// bytes (uncompressed format).
+static bool GetPublicKeyFromCbor(const cn_cbor *key, uint8_t *public_key) {
+ const int64_t kCoseKeyAlgLabel = 3;
+ const int64_t kCoseKeyOpsLabel = 4;
+ const uint64_t kCoseKeyOpsVerify = 2;
+ const int64_t kCoseAlgEs256 = -7;
+
+ // Mandatory attributes.
+ cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
+ cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
+ if (!type || !curve) {
+ return false;
+ }
+ if (type->type != CN_CBOR_UINT || curve->type != CN_CBOR_UINT) {
+ return false;
+ }
+
+ if (type->v.uint != COSE_Key_Type_EC2 || curve->v.uint != COSE_Curve_P256) {
+ return false;
+ }
+
+ cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_EC2_X);
+ if (!x || x->type != CN_CBOR_BYTES || x->length != (PUBLIC_KEY_SIZE / 2)) {
+ return false;
+ }
+
+ cn_cbor *y = cn_cbor_mapget_int(key, COSE_Key_EC2_Y);
+ if (!y || y->type != CN_CBOR_BYTES || y->length != (PUBLIC_KEY_SIZE / 2)) {
+ return false;
+ }
+
+ cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
+ if (alg) {
+ if (alg->type != CN_CBOR_INT || alg->v.sint != kCoseAlgEs256) {
+ return false;
+ }
+ }
+
+ cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
+ if (ops) {
+ if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
+ return false;
+ }
+ bool found_verify = false;
+ for (size_t i = 0; i < ops->length; ++i) {
+ cn_cbor *item = cn_cbor_index(ops, i);
+ if (!item || item->type != CN_CBOR_UINT) {
+ return false;
+ }
+ if (item->v.uint == kCoseKeyOpsVerify) {
+ found_verify = true;
+ }
+ }
+ if (!found_verify) {
+ return false;
+ }
+ }
+
+ memcpy(&public_key[0], x->v.bytes, PUBLIC_KEY_SIZE / 2);
+ memcpy(&public_key[PUBLIC_KEY_SIZE / 2], y->v.bytes, PUBLIC_KEY_SIZE / 2);
+ return true;
+}
+
+// A simple implementation of 'ECDSA_Verify' using boringssl. This function is
+// required by 'COSE_Sign1_validate'.
+bool ECDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
+ int cbitsDigest, const byte *message, size_t message_size,
+ cose_errback *) {
+ (void)cbitsDigest;
+ cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
+ cn_cbor *key = cose_key->m_cborKey;
+ if (!signature || !key) {
+ return false;
+ }
+ if (signature->type != CN_CBOR_BYTES ||
+ signature->length != PUBLIC_KEY_SIZE) {
+ return false;
+ }
+ uint8_t public_key[PUBLIC_KEY_SIZE];
+ if (!GetPublicKeyFromCbor(key, public_key)) {
+ return false;
+ }
+
+ // Implementation of ECDSA verification starts here
+ uint8_t output[32];
+ SHA256(message, message_size, output);
+ EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ BIGNUM *x = BN_new();
+ BN_bin2bn(&public_key[0], 32, x);
+ BIGNUM *y = BN_new();
+ BN_bin2bn(&public_key[32], 32, y);
+ int result = EC_KEY_set_public_key_affine_coordinates(eckey, x, y);
+
+ BN_clear_free(y);
+ BN_clear_free(x);
+
+ if (result == 0) {
+ printf("Setting affine coordinates failed\n");
+ return false;
+ }
+
+ ECDSA_SIG *sig = ECDSA_SIG_new();
+ BN_bin2bn(&(signature->v.bytes[0]), 32, sig->r);
+ BN_bin2bn(&(signature->v.bytes[32]), 32, sig->s);
+ result = ECDSA_do_verify(output, 32, sig, eckey);
+
+ EC_KEY_free(eckey);
+ ECDSA_SIG_free(sig);
+ if (1 != result) {
+ return false;
+ }
+ return true;
+}
+
+// A stub for 'ECDSA_Sign'. This is unused, but helps make linkers happy.
+bool ECDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
+ COSE_KEY * /*cose_key*/, const byte * /*message*/,
+ size_t /*message_size*/, cose_errback *) {
+ return false;
+}
diff --git a/third_party/cose-c/cose_p384_deps.cc b/third_party/cose-c/cose_p384_deps.cc
index 3b9a9d9..bd70708 100644
--- a/third_party/cose-c/cose_p384_deps.cc
+++ b/third_party/cose-c/cose_p384_deps.cc
@@ -92,6 +92,8 @@
return true;
}
+// A simple implementation of 'ECDSA_Verify' using boringssl. This function is
+// required by 'COSE_Sign1_validate'.
bool ECDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
int cbitsDigest, const byte *message, size_t message_size,
cose_errback *) {
diff --git a/third_party/cose-c/include/p256/cose/cose_configure.h b/third_party/cose-c/include/p256/cose/cose_configure.h
new file mode 100644
index 0000000..120a42d
--- /dev/null
+++ b/third_party/cose-c/include/p256/cose/cose_configure.h
@@ -0,0 +1,16 @@
+#ifndef THIRD_PARTY_COSE_C_P256_COSE_COSE_CONFIGURE_H_
+#define THIRD_PARTY_COSE_C_P256_COSE_COSE_CONFIGURE_H_
+
+#define USE_ECDSA_SHA_256
+#define PUBLIC_KEY_SIZE 64
+
+#define INCLUDE_ENCRYPT 0
+#define INCLUDE_ENCRYPT0 0
+#define INCLUDE_MAC 0
+#define INCLUDE_MAC0 0
+#define INCLUDE_SIGN 0
+#define INCLUDE_SIGN1 1
+#define INCLUDE_COUNTERSIGNATURE 0
+#define INCLUDE_COUNTERSIGNATURE1 0
+
+#endif // THIRD_PARTY_COSE_C_P256_COSE_COSE_CONFIGURE_H_