Prove boringssl/mbedtls generate same certs

Use the same test vectors for mbedtls and boringssl with P256 curve.
That is, the payload of the certificate (ignoring the first tag-length
value and signature) is the same.

In addition, the profile name of mbedtls has been changes to what
boringssl uses.

Change-Id: If3b22eda7fb2972c066a1c83745c03b5b4b97cca
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/257532
Reviewed-by: Darren Krahn <dkrahn@google.com>
Commit-Queue: Darren Krahn <dkrahn@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
diff --git a/BUILD.gn b/BUILD.gn
index 568ffe6..1f7171c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -105,6 +105,7 @@
 
 pw_static_library("dice_with_boringssl_p256_ops") {
   public = [
+    "include/dice/boringssl_ecdsa_utils.h",
     "include/dice/dice.h",
     "include/dice/utils.h",
   ]
@@ -125,6 +126,7 @@
 
 pw_static_library("dice_with_boringssl_p384_ops") {
   public = [
+    "include/dice/boringssl_ecdsa_utils.h",
     "include/dice/dice.h",
     "include/dice/utils.h",
   ]
@@ -160,7 +162,10 @@
     "src/utils.c",
   ]
   deps = [ "//third_party/mbedtls:mbedcrypto" ]
-  all_dependent_configs = [ ":mbedtls_ops_config" ]
+  all_dependent_configs = [
+    ":mbedtls_ops_config",
+    ":example_profile",
+  ]
 }
 
 pw_static_library("dice_with_cbor_ed25519_cert") {
@@ -365,8 +370,23 @@
   ]
 }
 
+pw_test("boringssl_p256_ops_test") {
+  sources = [
+    "src/boringssl_p256_ops_test.cc",
+    "src/test_utils.cc",
+  ]
+  deps = [
+    ":boringssl_ecdsa_utils",
+    ":dice_with_boringssl_p256_ops",
+    "$dir_pw_string:pw_string",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c_p256",
+  ]
+}
+
 pw_executable("boringssl_p256_ops_fuzzer") {
   deps = [
+    ":boringssl_ecdsa_utils",
     ":dice_with_boringssl_p256_ops",
     ":fuzzer",
   ]
@@ -374,6 +394,7 @@
 
 pw_executable("boringssl_p384_ops_fuzzer") {
   deps = [
+    ":boringssl_ecdsa_utils",
     ":dice_with_boringssl_p384_ops",
     ":fuzzer",
   ]
@@ -532,6 +553,7 @@
   tests = [
     ":android_test",
     ":boringssl_ed25519_ops_test",
+    ":boringssl_p256_ops_test",
     ":cbor_ed25519_cert_op_test",
     ":cbor_p256_cert_op_test",
     ":cbor_p384_cert_op_test",
diff --git a/include/dice/config/mbedtls_ecdsa_p256/dice/config.h b/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
index 624682c..ae30fee 100644
--- a/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
+++ b/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
@@ -16,9 +16,8 @@
 #define DICE_CONFIG_MBEDTLS_ECDSA_P256_DICE_CONFIG_H_
 
 // ECDSA-P256
-#define DICE_PUBLIC_KEY_BUFFER_SIZE 33
+#define DICE_PUBLIC_KEY_BUFFER_SIZE 65
 #define DICE_PRIVATE_KEY_BUFFER_SIZE 32
 #define DICE_SIGNATURE_BUFFER_SIZE 64
-#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 0f45adc..a56ea56 100644
--- a/include/dice/known_test_values.h
+++ b/include/dice/known_test_values.h
@@ -151,13 +151,13 @@
 //     Data:
 //         Version: 3 (0x2)
 //         Serial Number:
-//             7c:7d:c0:a3:c1:e7:8d:4e:68:bc:c1:a2:32:9e:f9:1c:a8:12:44:91
-//         Signature Algorithm: ecdsa-with-SHA512
-//         Issuer: serialNumber=4c514d88db0f81d57beb96177e3d7ea4aa581e66
+//             2e:75:b6:e7:23:0c:20:f2:96:0b:de:4a:cf:12:88:d4:ab:66:5b:9b
+//         Signature Algorithm: ecdsa-with-SHA256
+//         Issuer: serialNumber=672d0053ae4513fbb3bac8209daeb3e8897681cd
 //         Validity
 //             Not Before: Mar 22 23:59:59 2018 GMT
 //             Not After : Dec 31 23:59:59 9999 GMT
-//         Subject: serialNumber=7c7dc0a3c1e78d4e68bcc1a2329ef91ca8124491
+//         Subject: serialNumber=2e75b6e7230c20f2960bde4acf1288d4ab665b9b
 //         Subject Public Key Info:
 //             Public Key Algorithm: id-ecPublicKey
 //                 Public-Key: (256 bit)
@@ -171,15 +171,15 @@
 //                 NIST CURVE: P-256
 //         X509v3 extensions:
 //             X509v3 Authority Key Identifier:
-//                 4C:51:4D:88:DB:0F:81:D5:7B:EB:96:17:7E:3D:7E:A4:AA:58:1E:66
+//                 67:2D:00:53:AE:45:13:FB:B3:BA:C8:20:9D:AE:B3:E8:89:76:81:CD
 //             X509v3 Subject Key Identifier:
-//                 7C:7D:C0:A3:C1:E7:8D:4E:68:BC:C1:A2:32:9E:F9:1C:A8:12:44:91
+//                 2E:75:B6:E7:23:0C:20:F2:96:0B:DE:4A:CF:12:88:D4:AB:66:5B:9B
 //             X509v3 Key Usage: critical
 //                 Certificate Sign
 //             X509v3 Basic Constraints: critical
 //                 CA:TRUE
 //             1.3.6.1.4.1.11129.2.1.24: critical
-//     0:d=0  hl=3 l= 244 cons: SEQUENCE
+//     0:d=0  hl=3 l= 229 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,32 +200,32 @@
 //       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=  33 cons:  cont [ 7 ]
-//   214:d=2  hl=2 l=  31 prim:   UTF8STRING :openssl.example.p256_compressed
+//   212:d=1  hl=2 l=  18 cons:  cont [ 7 ]
+//   214:d=2  hl=2 l=  16 prim:   UTF8STRING        :opendice.example
 //
-//     Signature Algorithm: ecdsa-with-SHA512
+//     Signature Algorithm: ecdsa-with-SHA256
 //     Signature Value:
-//         30:46:02:21:00:b8:1f:70:94:16:6a:2b:7b:8c:d8:0d:62:9b:
-//         5a:5a:ff:49:16:f7:f7:e1:f5:43:d5:14:6a:6b:f1:11:03:48:
-//         57:02:21:00:e0:24:69:f8:42:a0:03:e2:8b:51:eb:ea:9c:55:
-//         92:b7:80:a1:81:33:b3:68:42:3c:05:df:aa:13:4c:61:52:f6
-constexpr uint8_t kExpectedX509P256Cert_ZeroInput[739] = {
-    0x30, 0x82, 0x02, 0xdf, 0x30, 0x82, 0x02, 0x84, 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,
-    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x30,
+//         30:44:02:20:4a:e7:b7:40:73:3e:28:4f:02:7b:07:af:ff:6d:
+//         6c:3a:cd:01:eb:30:aa:06:67:b9:18:05:31:9f:e0:09:bb:31:
+//         02:20:59:56:4a:35:fc:46:2b:5b:99:1d:87:1b:50:5e:7b:ce:
+//         c9:91:7e:89:13:20:91:c2:85:48:46:ec:00:a4:4b:7d
+constexpr uint8_t kExpectedX509P256Cert_ZeroInput[721] = {
+    0x30, 0x82, 0x02, 0xcd, 0x30, 0x82, 0x02, 0x74, 0xa0, 0x03, 0x02, 0x01,
+    0x02, 0x02, 0x14, 0x2e, 0x75, 0xb6, 0xe7, 0x23, 0x0c, 0x20, 0xf2, 0x96,
+    0x0b, 0xde, 0x4a, 0xcf, 0x12, 0x88, 0xd4, 0xab, 0x66, 0x5b, 0x9b, 0x30,
+    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30,
     0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
-    0x34, 0x63, 0x35, 0x31, 0x34, 0x64, 0x38, 0x38, 0x64, 0x62, 0x30, 0x66,
-    0x38, 0x31, 0x64, 0x35, 0x37, 0x62, 0x65, 0x62, 0x39, 0x36, 0x31, 0x37,
-    0x37, 0x65, 0x33, 0x64, 0x37, 0x65, 0x61, 0x34, 0x61, 0x61, 0x35, 0x38,
-    0x31, 0x65, 0x36, 0x36, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
+    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, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
     0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x18, 0x0f, 0x39,
     0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35,
     0x39, 0x5a, 0x30, 0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
-    0x05, 0x13, 0x28, 0x37, 0x63, 0x37, 0x64, 0x63, 0x30, 0x61, 0x33, 0x63,
-    0x31, 0x65, 0x37, 0x38, 0x64, 0x34, 0x65, 0x36, 0x38, 0x62, 0x63, 0x63,
-    0x31, 0x61, 0x32, 0x33, 0x32, 0x39, 0x65, 0x66, 0x39, 0x31, 0x63, 0x61,
-    0x38, 0x31, 0x32, 0x34, 0x34, 0x39, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06,
+    0x05, 0x13, 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, 0x30, 0x59, 0x30, 0x13, 0x06,
     0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86,
     0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0x3b,
     0x4e, 0x82, 0xc4, 0x5a, 0xda, 0x08, 0x45, 0x89, 0xc2, 0x19, 0x7b, 0xaf,
@@ -233,45 +233,44 @@
     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, 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, 0x03, 0x55,
-    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x7d, 0xc0, 0xa3, 0xc1, 0xe7,
-    0x8d, 0x4e, 0x68, 0xbc, 0xc1, 0xa2, 0x32, 0x9e, 0xf9, 0x1c, 0xa8, 0x12,
-    0x44, 0x91, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x1b, 0x4a, 0xa3, 0x82, 0x01, 0x62, 0x30, 0x82, 0x01, 0x5e, 0x30, 0x1f,
+    0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x67,
+    0x2d, 0x00, 0x53, 0xae, 0x45, 0x13, 0xfb, 0xb3, 0xba, 0xc8, 0x20, 0x9d,
+    0xae, 0xb3, 0xe8, 0x89, 0x76, 0x81, 0xcd, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2e, 0x75, 0xb6, 0xe7, 0x23, 0x0c,
+    0x20, 0xf2, 0x96, 0x0b, 0xde, 0x4a, 0xcf, 0x12, 0x88, 0xd4, 0xab, 0x66,
+    0x5b, 0x9b, 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, 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,
+    0x81, 0xfa, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02,
+    0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xe8, 0x30, 0x81, 0xe5, 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, 0x00, 0x00, 0xa3, 0x42, 0x04, 0x40,
+    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, 0x00, 0x00, 0xa4, 0x42, 0x04, 0x40, 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, 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, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-    0x3d, 0x04, 0x03, 0x04, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00,
-    0xb8, 0x1f, 0x70, 0x94, 0x16, 0x6a, 0x2b, 0x7b, 0x8c, 0xd8, 0x0d, 0x62,
-    0x9b, 0x5a, 0x5a, 0xff, 0x49, 0x16, 0xf7, 0xf7, 0xe1, 0xf5, 0x43, 0xd5,
-    0x14, 0x6a, 0x6b, 0xf1, 0x11, 0x03, 0x48, 0x57, 0x02, 0x21, 0x00, 0xe0,
-    0x24, 0x69, 0xf8, 0x42, 0xa0, 0x03, 0xe2, 0x8b, 0x51, 0xeb, 0xea, 0x9c,
-    0x55, 0x92, 0xb7, 0x80, 0xa1, 0x81, 0x33, 0xb3, 0x68, 0x42, 0x3c, 0x05,
-    0xdf, 0xaa, 0x13, 0x4c, 0x61, 0x52, 0xf6};
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6,
+    0x03, 0x0a, 0x01, 0x00, 0xa7, 0x12, 0x0c, 0x10, 0x6f, 0x70, 0x65, 0x6e,
+    0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+    0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
+    0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x4a, 0xe7, 0xb7, 0x40, 0x73,
+    0x3e, 0x28, 0x4f, 0x02, 0x7b, 0x07, 0xaf, 0xff, 0x6d, 0x6c, 0x3a, 0xcd,
+    0x01, 0xeb, 0x30, 0xaa, 0x06, 0x67, 0xb9, 0x18, 0x05, 0x31, 0x9f, 0xe0,
+    0x09, 0xbb, 0x31, 0x02, 0x20, 0x59, 0x56, 0x4a, 0x35, 0xfc, 0x46, 0x2b,
+    0x5b, 0x99, 0x1d, 0x87, 0x1b, 0x50, 0x5e, 0x7b, 0xce, 0xc9, 0x91, 0x7e,
+    0x89, 0x13, 0x20, 0x91, 0xc2, 0x85, 0x48, 0x46, 0xec, 0x00, 0xa4, 0x4b,
+    0x7d};
 
 constexpr uint8_t kExpectedX509P384Cert_ZeroInput[0] = {};
 
@@ -351,12 +350,12 @@
     0x11, 0xc2, 0xdf, 0x97, 0x3b, 0x1b, 0x4a, 0x3a, 0x00, 0x47, 0x44, 0x58,
     0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e,
     0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-    0x58, 0x40, 0x6e, 0x90, 0x47, 0xe9, 0xe4, 0x3a, 0xe6, 0x34, 0xe2, 0xe8,
-    0x65, 0x13, 0x8a, 0xde, 0x8a, 0x0d, 0x5d, 0xa6, 0xd2, 0xad, 0xb7, 0x2c,
-    0x75, 0x23, 0x77, 0x86, 0x9e, 0x23, 0xff, 0xfc, 0xed, 0x3b, 0x28, 0x7a,
-    0xde, 0x88, 0x27, 0xa7, 0xa7, 0xa8, 0xd2, 0x66, 0xea, 0xde, 0x7b, 0x65,
-    0x5d, 0x19, 0x85, 0x7d, 0x62, 0x60, 0x8e, 0x97, 0x57, 0x75, 0x8a, 0x5c,
-    0x43, 0x99, 0xe1, 0xc3, 0x02, 0xe4};
+    0x58, 0x40, 0xf0, 0x02, 0x13, 0x25, 0x57, 0x4d, 0x4b, 0x52, 0x3d, 0xfe,
+    0x0c, 0x37, 0x02, 0x67, 0xc7, 0xeb, 0x82, 0x07, 0x37, 0x37, 0x1c, 0x6f,
+    0xd1, 0xc8, 0x04, 0x58, 0x1d, 0x64, 0x34, 0xb4, 0x7f, 0x93, 0x96, 0x1b,
+    0x65, 0xce, 0x08, 0x71, 0x00, 0x5a, 0x3e, 0xaa, 0x94, 0x8e, 0x6a, 0xcf,
+    0x4d, 0x44, 0x0d, 0xb0, 0x16, 0x99, 0xe6, 0xae, 0x17, 0x6b, 0x9b, 0x94,
+    0x91, 0xe2, 0x8c, 0xc7, 0x88, 0xf9};
 
 constexpr uint8_t kExpectedCborP384Cert_ZeroInput[564] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xc8, 0xa9, 0x01,
@@ -398,14 +397,14 @@
     0x05, 0xb5, 0x29, 0xa0, 0xf1, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
     0x3a, 0x00, 0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
     0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x58, 0x60,
-    0x65, 0x1e, 0x1b, 0x7e, 0xca, 0x79, 0xdc, 0xd1, 0x5e, 0xe2, 0xa8, 0x1d,
-    0xdf, 0x84, 0x6d, 0xd3, 0xf0, 0xe1, 0x51, 0x5f, 0xfd, 0x3e, 0x53, 0x4a,
-    0x39, 0xea, 0xcb, 0xd9, 0xc9, 0x82, 0x4b, 0xbf, 0x21, 0xce, 0x3d, 0xdf,
-    0x26, 0x83, 0x7e, 0x7c, 0xd9, 0x1c, 0xdc, 0x27, 0x19, 0x4f, 0xcf, 0xde,
-    0xc4, 0x8b, 0x7a, 0xa0, 0x72, 0x3a, 0x4a, 0x8f, 0x57, 0x00, 0x0d, 0x1b,
-    0x7a, 0x83, 0x65, 0xfe, 0xc3, 0xf2, 0x32, 0xe2, 0x27, 0xaf, 0xba, 0xd0,
-    0x64, 0x3e, 0x8f, 0x67, 0x79, 0x7b, 0xd4, 0xaa, 0x1a, 0xfe, 0xc9, 0x1f,
-    0x42, 0x4e, 0x28, 0xb6, 0xab, 0x53, 0x33, 0xc8, 0x19, 0xe4, 0xb2, 0x39};
+    0x54, 0x09, 0x4b, 0xae, 0x0c, 0x31, 0x4b, 0xcd, 0x30, 0x49, 0x02, 0x5b,
+    0x97, 0x0d, 0x12, 0x07, 0x5c, 0x0b, 0xa7, 0x0a, 0x38, 0xb3, 0x1d, 0x19,
+    0x6b, 0xeb, 0xbd, 0xc6, 0x9f, 0x40, 0x75, 0x64, 0x02, 0xfc, 0x5b, 0x68,
+    0x17, 0x6e, 0x6d, 0x5c, 0xe1, 0xdc, 0x7b, 0xd3, 0x7b, 0xc1, 0x44, 0x0a,
+    0x59, 0x6d, 0xff, 0xc4, 0xc1, 0x7f, 0xd5, 0x80, 0xce, 0x91, 0xd3, 0x52,
+    0x0a, 0x85, 0x86, 0x8b, 0x1a, 0x1f, 0x96, 0x24, 0x40, 0x31, 0x5d, 0xeb,
+    0xfa, 0x57, 0x35, 0x9a, 0x62, 0xc5, 0xb2, 0xb1, 0x15, 0xc3, 0x68, 0xd8,
+    0x3c, 0x30, 0xe1, 0x31, 0xad, 0x7c, 0x30, 0x68, 0xf3, 0xd6, 0xfc, 0xd9};
 
 constexpr uint8_t kExpectedCborEd25519Cert_AndroidZeroInput[457] = {
     0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x7e, 0xa9, 0x01, 0x78,
@@ -484,12 +483,12 @@
     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, 0x6a, 0x61, 0x6e, 0x64, 0x72,
-    0x6f, 0x69, 0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x09, 0x61, 0xd4, 0x73,
-    0x9f, 0x3f, 0xc3, 0x6c, 0x0d, 0x7c, 0x55, 0x4a, 0xa4, 0x3f, 0x38, 0x07,
-    0xcd, 0xb2, 0x3a, 0x62, 0xc2, 0xa7, 0xa1, 0xdf, 0xda, 0x06, 0xe5, 0x62,
-    0x5b, 0x2c, 0x5f, 0x8c, 0xb3, 0xc5, 0xa9, 0x33, 0xe9, 0x3b, 0x9d, 0xfc,
-    0x8d, 0xc6, 0xa7, 0x57, 0x49, 0xd4, 0x46, 0x25, 0x37, 0xc5, 0xfa, 0x28,
-    0xa7, 0x61, 0xb6, 0xf5, 0xeb, 0xfe, 0x3c, 0x91, 0x45, 0x9a, 0xa2, 0x66};
+    0x6f, 0x69, 0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0xb0, 0xdb, 0xee, 0xb7,
+    0xb6, 0x7f, 0x89, 0x77, 0x7f, 0x21, 0x48, 0xa2, 0xef, 0x91, 0x44, 0xce,
+    0xf9, 0x3e, 0x6a, 0xa1, 0x2f, 0x44, 0xb5, 0x02, 0xdf, 0x29, 0x7d, 0x61,
+    0xd3, 0x1d, 0x25, 0x25, 0x33, 0x65, 0x9d, 0x96, 0xa8, 0x4b, 0xcd, 0xf6,
+    0x4b, 0xa7, 0xef, 0xf2, 0xd4, 0xe7, 0x0e, 0xe6, 0x9f, 0x71, 0x25, 0x15,
+    0xe8, 0xa0, 0x61, 0x4f, 0x40, 0xbf, 0x9f, 0xd6, 0x7c, 0x27, 0x07, 0x33};
 
 constexpr uint8_t kExpectedCborP384Cert_AndroidZeroInput[558] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xc2, 0xa9, 0x01,
@@ -530,15 +529,15 @@
     0x67, 0xbf, 0x21, 0xd7, 0x47, 0xf3, 0x13, 0xd1, 0x47, 0x6c, 0x4b, 0xd3,
     0x05, 0xb5, 0x29, 0xa0, 0xf1, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
     0x3a, 0x00, 0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-    0x64, 0x2e, 0x31, 0x36, 0x58, 0x60, 0x19, 0x43, 0x25, 0x41, 0x71, 0xb4,
-    0xba, 0xdf, 0x86, 0x21, 0x3e, 0x34, 0xb7, 0xbf, 0x97, 0xd3, 0xb4, 0x91,
-    0xd3, 0xa7, 0x5e, 0x39, 0xbb, 0x5a, 0xae, 0x71, 0x52, 0x75, 0x81, 0x5d,
-    0x09, 0x60, 0xc1, 0x78, 0x64, 0x34, 0xbf, 0xf5, 0x36, 0xfb, 0x68, 0x9e,
-    0x30, 0xc0, 0x07, 0x0e, 0xe6, 0x9f, 0xa8, 0xa2, 0x44, 0xa7, 0xa5, 0x00,
-    0xdf, 0xfd, 0x42, 0x1a, 0x12, 0x7e, 0x68, 0xb0, 0xa9, 0x06, 0xf5, 0xe2,
-    0xa1, 0x92, 0xa6, 0xda, 0xd8, 0xe0, 0x6d, 0x52, 0x14, 0x1a, 0xa7, 0x57,
-    0xbf, 0x22, 0xe6, 0xea, 0xcf, 0x69, 0xae, 0xc3, 0x05, 0xb0, 0xfc, 0x78,
-    0xd3, 0x50, 0x0c, 0x92, 0x36, 0x69};
+    0x64, 0x2e, 0x31, 0x36, 0x58, 0x60, 0x55, 0x15, 0xd9, 0x47, 0x47, 0x6e,
+    0x61, 0xc9, 0x23, 0x91, 0x0a, 0x76, 0xbb, 0x2a, 0x97, 0x0e, 0x02, 0xb6,
+    0x98, 0x06, 0x16, 0x64, 0xb0, 0x8b, 0x27, 0x61, 0x75, 0x28, 0x86, 0x74,
+    0xf0, 0xf7, 0x80, 0xea, 0x51, 0xc9, 0x83, 0x4e, 0x08, 0xc5, 0xe5, 0xe4,
+    0x51, 0xd3, 0xa9, 0xd8, 0xc8, 0x5b, 0x76, 0xbc, 0x30, 0xbe, 0xd0, 0x3e,
+    0x49, 0xe0, 0x78, 0x34, 0xd2, 0x35, 0xba, 0xa7, 0x29, 0x61, 0xa4, 0x90,
+    0x39, 0x29, 0xd3, 0x15, 0x9a, 0xb9, 0x38, 0x5c, 0xe2, 0x6a, 0x50, 0x3d,
+    0xa4, 0x91, 0x1d, 0xe6, 0x87, 0x3b, 0xa9, 0x2f, 0x86, 0x17, 0x26, 0x24,
+    0x91, 0x8f, 0xfc, 0x70, 0xc7, 0xf4};
 
 constexpr uint8_t kExpectedCdiAttest_HashOnlyInput[32] = {
     0x08, 0x4e, 0xf4, 0x06, 0xc6, 0x9b, 0xa7, 0x4b, 0x1e, 0x24, 0xd0,
@@ -668,13 +667,13 @@
 //     Data:
 //         Version: 3 (0x2)
 //         Serial Number:
-//             68:49:58:d9:ae:a7:2e:bf:7c:06:af:20:03:b6:44:47:82:4a:62:71
-//         Signature Algorithm: ecdsa-with-SHA512
-//         Issuer: serialNumber=1be5687933db3d9cd5fca729e81d6685465a7bf1
+//             7c:20:0a:55:ef:e7:11:2e:ca:4e:02:6d:70:2c:64:e9:e2:9c:d3:e9
+//         Signature Algorithm: ecdsa-with-SHA256
+//         Issuer: serialNumber=48603c0052c1cac73cae36c3bdec7c6139885c9d
 //         Validity
 //             Not Before: Mar 22 23:59:59 2018 GMT
 //             Not After : Dec 31 23:59:59 9999 GMT
-//         Subject: serialNumber=684958d9aea72ebf7c06af2003b64447824a6271
+//         Subject: serialNumber=7c200a55efe7112eca4e026d702c64e9e29cd3e9
 //         Subject Public Key Info:
 //             Public Key Algorithm: id-ecPublicKey
 //                 Public-Key: (256 bit)
@@ -688,15 +687,15 @@
 //                 NIST CURVE: P-256
 //         X509v3 extensions:
 //             X509v3 Authority Key Identifier:
-//                 1B:E5:68:79:33:DB:3D:9C:D5:FC:A7:29:E8:1D:66:85:46:5A:7B:F1
+//                 48:60:3C:00:52:C1:CA:C7:3C:AE:36:C3:BD:EC:7C:61:39:88:5C:9D
 //             X509v3 Subject Key Identifier:
-//                 68:49:58:D9:AE:A7:2E:BF:7C:06:AF:20:03:B6:44:47:82:4A:62:71
+//                 7C:20:0A:55:EF:E7:11:2E:CA:4E:02:6D:70:2C:64:E9:E2:9C:D3:E9
 //             X509v3 Key Usage: critical
 //                 Certificate Sign
 //             X509v3 Basic Constraints: critical
 //                 CA:TRUE
 //             1.3.6.1.4.1.11129.2.1.24: critical
-//     0:d=0  hl=3 l= 244 cons: SEQUENCE
+//     0:d=0  hl=3 l= 229 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.
@@ -717,32 +716,32 @@
 //       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=  33 cons:  cont [ 7 ]
-//   214:d=2  hl=2 l=  31 prim:   UTF8STRING :openssl.example.p256_compressed
+//   212:d=1  hl=2 l=  18 cons:  cont [ 7 ]
+//   214:d=2  hl=2 l=  16 prim:   UTF8STRING        :opendice.example
 //
-//     Signature Algorithm: ecdsa-with-SHA512
+//     Signature Algorithm: ecdsa-with-SHA256
 //     Signature Value:
-//         30:46:02:21:00:c5:5e:54:a0:d7:ac:e8:b2:79:b5:87:50:31:
-//         d2:4f:67:d3:69:f0:dd:f2:c7:73:8e:25:ef:fd:f2:c4:90:e9:
-//         80:02:21:00:d0:47:f4:7d:b6:a0:84:e8:cf:96:55:43:0b:86:
-//         4c:27:e9:f8:b7:66:fd:dc:2c:22:44:4d:b1:f7:51:c7:1f:43
-constexpr uint8_t kExpectedX509P256Cert_HashOnlyInput[739] = {
-    0x30, 0x82, 0x02, 0xdf, 0x30, 0x82, 0x02, 0x84, 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,
-    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x30,
+//         30:44:02:20:7e:d9:61:b7:7b:8d:b9:94:a4:6e:3d:66:52:9d:
+//         ea:e9:6c:16:d6:61:7f:68:f6:a2:8b:79:e2:9e:de:c0:25:2e:
+//         02:20:6f:b0:08:da:2c:14:79:0e:ba:e2:12:7a:9c:5c:17:5e:
+//         01:5e:18:75:dd:6c:63:4b:58:8e:09:d4:8a:00:b2:2f
+constexpr uint8_t kExpectedX509P256Cert_HashOnlyInput[721] = {
+    0x30, 0x82, 0x02, 0xcd, 0x30, 0x82, 0x02, 0x74, 0xa0, 0x03, 0x02, 0x01,
+    0x02, 0x02, 0x14, 0x7c, 0x20, 0x0a, 0x55, 0xef, 0xe7, 0x11, 0x2e, 0xca,
+    0x4e, 0x02, 0x6d, 0x70, 0x2c, 0x64, 0xe9, 0xe2, 0x9c, 0xd3, 0xe9, 0x30,
+    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30,
     0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
-    0x31, 0x62, 0x65, 0x35, 0x36, 0x38, 0x37, 0x39, 0x33, 0x33, 0x64, 0x62,
-    0x33, 0x64, 0x39, 0x63, 0x64, 0x35, 0x66, 0x63, 0x61, 0x37, 0x32, 0x39,
-    0x65, 0x38, 0x31, 0x64, 0x36, 0x36, 0x38, 0x35, 0x34, 0x36, 0x35, 0x61,
-    0x37, 0x62, 0x66, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
+    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, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
     0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x18, 0x0f, 0x39,
     0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35,
     0x39, 0x5a, 0x30, 0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
-    0x05, 0x13, 0x28, 0x36, 0x38, 0x34, 0x39, 0x35, 0x38, 0x64, 0x39, 0x61,
-    0x65, 0x61, 0x37, 0x32, 0x65, 0x62, 0x66, 0x37, 0x63, 0x30, 0x36, 0x61,
-    0x66, 0x32, 0x30, 0x30, 0x33, 0x62, 0x36, 0x34, 0x34, 0x34, 0x37, 0x38,
-    0x32, 0x34, 0x61, 0x36, 0x32, 0x37, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06,
+    0x05, 0x13, 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, 0x30, 0x59, 0x30, 0x13, 0x06,
     0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86,
     0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xfe, 0x9d,
     0xb2, 0xf9, 0x28, 0x09, 0xc3, 0x04, 0x12, 0x85, 0xdc, 0xd3, 0x70, 0x6f,
@@ -750,45 +749,44 @@
     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, 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, 0x03, 0x55,
-    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x68, 0x49, 0x58, 0xd9, 0xae, 0xa7,
-    0x2e, 0xbf, 0x7c, 0x06, 0xaf, 0x20, 0x03, 0xb6, 0x44, 0x47, 0x82, 0x4a,
-    0x62, 0x71, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x00, 0x0b, 0xa3, 0x82, 0x01, 0x62, 0x30, 0x82, 0x01, 0x5e, 0x30, 0x1f,
+    0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48,
+    0x60, 0x3c, 0x00, 0x52, 0xc1, 0xca, 0xc7, 0x3c, 0xae, 0x36, 0xc3, 0xbd,
+    0xec, 0x7c, 0x61, 0x39, 0x88, 0x5c, 0x9d, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x20, 0x0a, 0x55, 0xef, 0xe7,
+    0x11, 0x2e, 0xca, 0x4e, 0x02, 0x6d, 0x70, 0x2c, 0x64, 0xe9, 0xe2, 0x9c,
+    0xd3, 0xe9, 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, 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, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-    0x3d, 0x04, 0x03, 0x04, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00,
-    0xc5, 0x5e, 0x54, 0xa0, 0xd7, 0xac, 0xe8, 0xb2, 0x79, 0xb5, 0x87, 0x50,
-    0x31, 0xd2, 0x4f, 0x67, 0xd3, 0x69, 0xf0, 0xdd, 0xf2, 0xc7, 0x73, 0x8e,
-    0x25, 0xef, 0xfd, 0xf2, 0xc4, 0x90, 0xe9, 0x80, 0x02, 0x21, 0x00, 0xd0,
-    0x47, 0xf4, 0x7d, 0xb6, 0xa0, 0x84, 0xe8, 0xcf, 0x96, 0x55, 0x43, 0x0b,
-    0x86, 0x4c, 0x27, 0xe9, 0xf8, 0xb7, 0x66, 0xfd, 0xdc, 0x2c, 0x22, 0x44,
-    0x4d, 0xb1, 0xf7, 0x51, 0xc7, 0x1f, 0x43};
+    0x81, 0xfa, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02,
+    0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x81, 0xe8, 0x30, 0x81, 0xe5, 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, 0x12, 0x0c, 0x10, 0x6f, 0x70, 0x65, 0x6e,
+    0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
+    0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
+    0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x7e, 0xd9, 0x61, 0xb7, 0x7b,
+    0x8d, 0xb9, 0x94, 0xa4, 0x6e, 0x3d, 0x66, 0x52, 0x9d, 0xea, 0xe9, 0x6c,
+    0x16, 0xd6, 0x61, 0x7f, 0x68, 0xf6, 0xa2, 0x8b, 0x79, 0xe2, 0x9e, 0xde,
+    0xc0, 0x25, 0x2e, 0x02, 0x20, 0x6f, 0xb0, 0x08, 0xda, 0x2c, 0x14, 0x79,
+    0x0e, 0xba, 0xe2, 0x12, 0x7a, 0x9c, 0x5c, 0x17, 0x5e, 0x01, 0x5e, 0x18,
+    0x75, 0xdd, 0x6c, 0x63, 0x4b, 0x58, 0x8e, 0x09, 0xd4, 0x8a, 0x00, 0xb2,
+    0x2f};
 
 constexpr uint8_t kExpectedX509P384Cert_HashOnlyInput[0] = {};
 
@@ -868,12 +866,12 @@
     0x15, 0xc2, 0x85, 0x77, 0x75, 0x00, 0x0b, 0x3a, 0x00, 0x47, 0x44, 0x58,
     0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e,
     0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-    0x58, 0x40, 0xea, 0xb6, 0x5d, 0xbb, 0x22, 0x2f, 0x43, 0x99, 0x82, 0xb3,
-    0x29, 0xe4, 0x7b, 0xf5, 0x65, 0xcb, 0x65, 0x6d, 0xb5, 0x66, 0xcc, 0xea,
-    0x04, 0x7a, 0xde, 0x06, 0x54, 0x62, 0xc8, 0xba, 0xa1, 0xca, 0xd3, 0xc4,
-    0x1a, 0x1c, 0x93, 0x7d, 0x46, 0x54, 0xd8, 0x59, 0x48, 0xbe, 0xf6, 0x03,
-    0x48, 0x27, 0xf5, 0x5a, 0xf7, 0xbd, 0xcd, 0xc5, 0xfe, 0x2a, 0x6b, 0xd9,
-    0x54, 0x36, 0x39, 0x2a, 0x50, 0xd6};
+    0x58, 0x40, 0x92, 0x4f, 0xb1, 0xf5, 0x5d, 0x84, 0xde, 0x89, 0x50, 0xb2,
+    0x6a, 0x2e, 0x04, 0x8e, 0xed, 0xdf, 0x7a, 0x63, 0xf5, 0x92, 0xbe, 0x3e,
+    0xda, 0xe9, 0x53, 0x6c, 0x7d, 0x8a, 0x0c, 0xbc, 0x8e, 0x82, 0x5f, 0x06,
+    0xa2, 0xef, 0x91, 0x5e, 0x64, 0x1f, 0xc6, 0xa5, 0x06, 0xb4, 0xd6, 0x72,
+    0xef, 0x4b, 0xd2, 0xaf, 0x18, 0x05, 0xc3, 0xf7, 0xbe, 0x7a, 0x6a, 0x54,
+    0x35, 0x57, 0xcb, 0xfb, 0x8b, 0x27};
 
 constexpr uint8_t kExpectedCborP384Cert_HashOnlyInput[564] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xc8, 0xa9, 0x01,
@@ -915,14 +913,14 @@
     0xc3, 0xb2, 0xe7, 0x34, 0xf5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
     0x3a, 0x00, 0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
     0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x58, 0x60,
-    0x6f, 0xa1, 0xa8, 0xcc, 0xea, 0xe0, 0x35, 0xa9, 0x19, 0x06, 0xea, 0x0d,
-    0xf1, 0x0c, 0x57, 0x3c, 0x8d, 0xa7, 0x7b, 0x63, 0x39, 0x0d, 0x30, 0x48,
-    0x93, 0x72, 0x5a, 0xd3, 0x49, 0x6c, 0x85, 0xad, 0xf6, 0x5e, 0x8e, 0x43,
-    0xa4, 0x33, 0xaa, 0x1a, 0xfc, 0x27, 0xcb, 0x44, 0xd1, 0x6b, 0xf4, 0xf4,
-    0x23, 0x14, 0x06, 0x99, 0x83, 0x03, 0x48, 0xd1, 0x83, 0xdc, 0x9d, 0xa7,
-    0x35, 0x4d, 0xe9, 0xdb, 0xba, 0xf5, 0x3d, 0x81, 0x45, 0xc8, 0x7e, 0x6d,
-    0xd5, 0x12, 0x75, 0xa3, 0x7d, 0xfd, 0x1f, 0x00, 0xe6, 0xed, 0x61, 0x66,
-    0x30, 0xd0, 0x05, 0x19, 0x47, 0x1d, 0xd9, 0xaf, 0x24, 0x82, 0x24, 0xee};
+    0x31, 0x03, 0x8f, 0x89, 0xfb, 0xa8, 0xe2, 0xf3, 0xb0, 0xb1, 0x51, 0x9d,
+    0xe9, 0x5f, 0x65, 0xa4, 0x1b, 0x2c, 0x0a, 0x7d, 0x00, 0xba, 0x61, 0x99,
+    0x42, 0x21, 0x44, 0x16, 0x77, 0x49, 0x7e, 0xdd, 0xb7, 0xe0, 0x76, 0x66,
+    0xa6, 0x10, 0x5a, 0x17, 0xb6, 0x25, 0x3e, 0x74, 0x87, 0x9c, 0x58, 0xa4,
+    0x02, 0xaf, 0x40, 0x4f, 0x5f, 0x79, 0xfc, 0x2f, 0xb2, 0x02, 0xe5, 0x95,
+    0xb9, 0x6a, 0x42, 0xd1, 0xb6, 0x1d, 0xa6, 0x05, 0x9e, 0xe3, 0xb3, 0x24,
+    0x88, 0xde, 0xed, 0x8a, 0x72, 0xf5, 0x47, 0x42, 0x4a, 0xee, 0xd8, 0xe2,
+    0x63, 0x0d, 0x06, 0xa2, 0x98, 0x8d, 0x8c, 0x2f, 0x70, 0x47, 0x53, 0x07};
 
 constexpr uint8_t kExpectedCborEd25519Cert_AndroidHashOnlyInput[457] = {
     0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x7e, 0xa9, 0x01, 0x78,
@@ -1001,12 +999,12 @@
     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, 0x6a, 0x61, 0x6e, 0x64, 0x72,
-    0x6f, 0x69, 0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x96, 0xe9, 0xb6, 0x0a,
-    0xf9, 0xa1, 0x45, 0x98, 0xfa, 0xfb, 0x91, 0x4f, 0xbf, 0xd7, 0xa7, 0x48,
-    0x8c, 0x05, 0x32, 0xb4, 0x1d, 0xf8, 0x04, 0xf8, 0x46, 0x84, 0x23, 0x1f,
-    0xc9, 0xb8, 0xb9, 0x24, 0x69, 0xc0, 0x58, 0xfc, 0x97, 0xda, 0x5e, 0x69,
-    0xd0, 0x7d, 0x76, 0x02, 0xb2, 0xda, 0x37, 0x6b, 0x7a, 0x7c, 0x2b, 0x51,
-    0x80, 0xb4, 0xa5, 0x8d, 0xb5, 0x77, 0x6b, 0x2f, 0x0b, 0x53, 0x8d, 0x60};
+    0x6f, 0x69, 0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x8b, 0x07, 0x4b, 0x1d,
+    0xb0, 0x8c, 0xb6, 0x7b, 0xbb, 0x7f, 0xec, 0x39, 0xdf, 0x1b, 0x2c, 0x92,
+    0xa2, 0x7e, 0xba, 0x6b, 0x0d, 0x0a, 0x49, 0xc1, 0xd4, 0x6f, 0xda, 0xe6,
+    0x96, 0x3d, 0x22, 0xee, 0x23, 0x5b, 0x4c, 0xb0, 0x39, 0x9e, 0xf7, 0x56,
+    0x5a, 0x28, 0x3b, 0x98, 0x93, 0xb5, 0xe3, 0xd7, 0x3b, 0x42, 0x25, 0x48,
+    0x70, 0x79, 0xf2, 0x88, 0xe1, 0x6e, 0x16, 0x3f, 0x9f, 0xfb, 0xca, 0xfc};
 
 constexpr uint8_t kExpectedCborP384Cert_AndroidHashOnlyInput[558] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x01, 0xc2, 0xa9, 0x01,
@@ -1047,15 +1045,15 @@
     0x37, 0xa7, 0x3d, 0x2e, 0xca, 0xd1, 0x2c, 0xa4, 0xd4, 0xa7, 0xaf, 0x25,
     0xc3, 0xb2, 0xe7, 0x34, 0xf5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
     0x3a, 0x00, 0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-    0x64, 0x2e, 0x31, 0x36, 0x58, 0x60, 0x6a, 0x23, 0x96, 0x6d, 0x03, 0x5d,
-    0x34, 0x65, 0x9b, 0x80, 0x53, 0x9a, 0x9c, 0xd5, 0xb7, 0x7b, 0x50, 0x79,
-    0xa7, 0x1d, 0xe8, 0xef, 0x82, 0x3b, 0x53, 0xa5, 0x8d, 0x09, 0x6f, 0xf6,
-    0x4e, 0xc0, 0xc6, 0x71, 0x7a, 0x1a, 0x58, 0xf7, 0x2b, 0x36, 0xaa, 0x2a,
-    0xaf, 0xb5, 0xcd, 0xe8, 0xf6, 0x65, 0x30, 0xc4, 0x89, 0xb8, 0xb1, 0x74,
-    0x2f, 0xa7, 0xa5, 0xfa, 0x71, 0x0b, 0x4a, 0x8f, 0xd2, 0x1c, 0x88, 0x7c,
-    0xa6, 0x3e, 0xc2, 0xcb, 0x07, 0xc1, 0x6f, 0xef, 0x08, 0x3e, 0x3f, 0xe4,
-    0x09, 0x0a, 0xb4, 0x97, 0xae, 0x4d, 0xbf, 0x02, 0x96, 0x5b, 0xe0, 0x59,
-    0x55, 0xc9, 0xae, 0x7b, 0xfc, 0xde};
+    0x64, 0x2e, 0x31, 0x36, 0x58, 0x60, 0xde, 0x4b, 0xb5, 0x6a, 0xb2, 0xfb,
+    0xc0, 0x2b, 0x88, 0x4e, 0x9a, 0x51, 0x7f, 0x30, 0x9c, 0x80, 0xea, 0x41,
+    0xd7, 0x87, 0xe8, 0x70, 0x24, 0xa7, 0x94, 0x29, 0x48, 0x44, 0xe5, 0xc9,
+    0x68, 0x73, 0x9d, 0xdf, 0xd9, 0x6e, 0x71, 0x29, 0xa9, 0xf3, 0x6f, 0xd2,
+    0xc7, 0x86, 0x84, 0x6c, 0x0e, 0x1f, 0x6f, 0x1c, 0x20, 0xea, 0x93, 0xcd,
+    0x25, 0x17, 0xc6, 0xf2, 0x32, 0x4a, 0xa6, 0xf5, 0x68, 0x1c, 0xbb, 0xb7,
+    0xe5, 0xb9, 0xb7, 0xaa, 0x18, 0x8d, 0xc5, 0x26, 0x16, 0xa4, 0xdc, 0xbb,
+    0xe9, 0x36, 0xf2, 0xeb, 0xf9, 0xf3, 0xdd, 0x83, 0xcf, 0x2d, 0x3e, 0xca,
+    0xf1, 0x34, 0x86, 0x86, 0x70, 0xea};
 
 constexpr uint8_t kExpectedCdiAttest_DescriptorInput[32] = {
     0x20, 0xd5, 0x0c, 0x68, 0x5a, 0xd9, 0xe2, 0xdf, 0x77, 0x60, 0x78,
@@ -1224,13 +1222,13 @@
 //     Data:
 //         Version: 3 (0x2)
 //         Serial Number:
-//             2c:0d:e9:55:c4:fa:08:2c:2c:3a:0b:40:66:59:af:a1:c1:c0:84:6c
-//         Signature Algorithm: ecdsa-with-SHA512
-//         Issuer: serialNumber=1be5687933db3d9cd5fca729e81d6685465a7bf1
+//             5a:04:e9:ec:f1:9a:d3:d5:26:68:b8:2a:60:81:f0:3f:db:29:f8:64
+//         Signature Algorithm: ecdsa-with-SHA256
+//         Issuer: serialNumber=48603c0052c1cac73cae36c3bdec7c6139885c9d
 //         Validity
 //             Not Before: Mar 22 23:59:59 2018 GMT
 //             Not After : Dec 31 23:59:59 9999 GMT
-//         Subject: serialNumber=2c0de955c4fa082c2c3a0b406659afa1c1c0846c
+//         Subject: serialNumber=5a04e9ecf19ad3d52668b82a6081f03fdb29f864
 //         Subject Public Key Info:
 //             Public Key Algorithm: id-ecPublicKey
 //                 Public-Key: (256 bit)
@@ -1244,15 +1242,15 @@
 //                 NIST CURVE: P-256
 //         X509v3 extensions:
 //             X509v3 Authority Key Identifier:
-//                 1B:E5:68:79:33:DB:3D:9C:D5:FC:A7:29:E8:1D:66:85:46:5A:7B:F1
+//                 48:60:3C:00:52:C1:CA:C7:3C:AE:36:C3:BD:EC:7C:61:39:88:5C:9D
 //             X509v3 Subject Key Identifier:
-//                 2C:0D:E9:55:C4:FA:08:2C:2C:3A:0B:40:66:59:AF:A1:C1:C0:84:6C
+//                 5A:04:E9:EC:F1:9A:D3:D5:26:68:B8:2A:60:81:F0:3F:DB:29:F8:64
 //             X509v3 Key Usage: critical
 //                 Certificate Sign
 //             X509v3 Basic Constraints: critical
 //                 CA:TRUE
 //             1.3.6.1.4.1.11129.2.1.24: critical
-//     0:d=0  hl=4 l= 461 cons: SEQUENCE
+//     0:d=0  hl=4 l= 446 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.
@@ -1294,32 +1292,32 @@
 //       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=  33 cons:  cont [ 7 ]
-//   432:d=2  hl=2 l=  31 prim:   UTF8STRING :openssl.example.p256_compressed
+//   430:d=1  hl=2 l=  18 cons:  cont [ 7 ]
+//   432:d=2  hl=2 l=  16 prim:   UTF8STRING        :opendice.example
 //
-//     Signature Algorithm: ecdsa-with-SHA512
+//     Signature Algorithm: ecdsa-with-SHA256
 //     Signature Value:
-//         30:44:02:20:11:ed:7d:c1:5f:53:6c:09:b9:ca:36:97:f8:5e:
-//         ed:1e:48:78:af:48:39:c7:6f:e5:ce:b6:db:75:b1:f7:5d:a7:
-//         02:20:75:17:22:36:67:59:9b:ad:4a:9e:aa:b5:9a:70:5d:f1:
-//         90:f8:82:1d:d1:84:54:f0:48:23:30:3c:98:9d:1d:1a
-constexpr uint8_t kExpectedX509P256Cert_DescriptorInput[956] = {
-    0x30, 0x82, 0x03, 0xb8, 0x30, 0x82, 0x03, 0x5f, 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,
-    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x30,
+//         30:46:02:21:00:e8:77:92:04:4d:4e:ae:1b:74:66:d6:b7:3f:
+//         cf:33:94:70:0c:9a:5a:05:f2:0b:e5:2b:67:ec:28:d9:8a:fe:
+//         71:02:21:00:fa:c2:cc:2a:be:31:06:bf:69:0d:e4:f7:c4:97:
+//         05:ef:a0:10:54:12:cf:d8:da:5c:84:1c:90:10:e7:cd:e5:fd
+constexpr uint8_t kExpectedX509P256Cert_DescriptorInput[943] = {
+    0x30, 0x82, 0x03, 0xab, 0x30, 0x82, 0x03, 0x50, 0xa0, 0x03, 0x02, 0x01,
+    0x02, 0x02, 0x14, 0x5a, 0x04, 0xe9, 0xec, 0xf1, 0x9a, 0xd3, 0xd5, 0x26,
+    0x68, 0xb8, 0x2a, 0x60, 0x81, 0xf0, 0x3f, 0xdb, 0x29, 0xf8, 0x64, 0x30,
+    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30,
     0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, 0x28,
-    0x31, 0x62, 0x65, 0x35, 0x36, 0x38, 0x37, 0x39, 0x33, 0x33, 0x64, 0x62,
-    0x33, 0x64, 0x39, 0x63, 0x64, 0x35, 0x66, 0x63, 0x61, 0x37, 0x32, 0x39,
-    0x65, 0x38, 0x31, 0x64, 0x36, 0x36, 0x38, 0x35, 0x34, 0x36, 0x35, 0x61,
-    0x37, 0x62, 0x66, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
+    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, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x33,
     0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x18, 0x0f, 0x39,
     0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35,
     0x39, 0x5a, 0x30, 0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04,
-    0x05, 0x13, 0x28, 0x32, 0x63, 0x30, 0x64, 0x65, 0x39, 0x35, 0x35, 0x63,
-    0x34, 0x66, 0x61, 0x30, 0x38, 0x32, 0x63, 0x32, 0x63, 0x33, 0x61, 0x30,
-    0x62, 0x34, 0x30, 0x36, 0x36, 0x35, 0x39, 0x61, 0x66, 0x61, 0x31, 0x63,
-    0x31, 0x63, 0x30, 0x38, 0x34, 0x36, 0x63, 0x30, 0x59, 0x30, 0x13, 0x06,
+    0x05, 0x13, 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, 0x30, 0x59, 0x30, 0x13, 0x06,
     0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86,
     0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x6d, 0x1e,
     0xdd, 0x35, 0x38, 0x70, 0xc2, 0x8a, 0x01, 0xdf, 0x80, 0xb1, 0xa5, 0xae,
@@ -1327,18 +1325,18 @@
     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, 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, 0x03, 0x55,
-    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0x0d, 0xe9, 0x55, 0xc4, 0xfa,
-    0x08, 0x2c, 0x2c, 0x3a, 0x0b, 0x40, 0x66, 0x59, 0xaf, 0xa1, 0xc1, 0xc0,
-    0x84, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
+    0x38, 0x61, 0xa3, 0x82, 0x02, 0x3e, 0x30, 0x82, 0x02, 0x3a, 0x30, 0x1f,
+    0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48,
+    0x60, 0x3c, 0x00, 0x52, 0xc1, 0xca, 0xc7, 0x3c, 0xae, 0x36, 0xc3, 0xbd,
+    0xec, 0x7c, 0x61, 0x39, 0x88, 0x5c, 0x9d, 0x30, 0x1d, 0x06, 0x03, 0x55,
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5a, 0x04, 0xe9, 0xec, 0xf1, 0x9a,
+    0xd3, 0xd5, 0x26, 0x68, 0xb8, 0x2a, 0x60, 0x81, 0xf0, 0x3f, 0xdb, 0x29,
+    0xf8, 0x64, 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, 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,
+    0x82, 0x01, 0xd5, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79,
+    0x02, 0x01, 0x18, 0x01, 0x01, 0xff, 0x04, 0x82, 0x01, 0xc2, 0x30, 0x82,
+    0x01, 0xbe, 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,
@@ -1373,17 +1371,16 @@
     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, 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, 0x0a, 0x06, 0x08, 0x2a,
-    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x03, 0x47, 0x00, 0x30, 0x44,
-    0x02, 0x20, 0x11, 0xed, 0x7d, 0xc1, 0x5f, 0x53, 0x6c, 0x09, 0xb9, 0xca,
-    0x36, 0x97, 0xf8, 0x5e, 0xed, 0x1e, 0x48, 0x78, 0xaf, 0x48, 0x39, 0xc7,
-    0x6f, 0xe5, 0xce, 0xb6, 0xdb, 0x75, 0xb1, 0xf7, 0x5d, 0xa7, 0x02, 0x20,
-    0x75, 0x17, 0x22, 0x36, 0x67, 0x59, 0x9b, 0xad, 0x4a, 0x9e, 0xaa, 0xb5,
-    0x9a, 0x70, 0x5d, 0xf1, 0x90, 0xf8, 0x82, 0x1d, 0xd1, 0x84, 0x54, 0xf0,
-    0x48, 0x23, 0x30, 0x3c, 0x98, 0x9d, 0x1d, 0x1a};
+    0x09, 0x70, 0xa2, 0xa6, 0x03, 0x0a, 0x01, 0x00, 0xa7, 0x12, 0x0c, 0x10,
+    0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x2e, 0x65, 0x78, 0x61,
+    0x6d, 0x70, 0x6c, 0x65, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+    0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00,
+    0xe8, 0x77, 0x92, 0x04, 0x4d, 0x4e, 0xae, 0x1b, 0x74, 0x66, 0xd6, 0xb7,
+    0x3f, 0xcf, 0x33, 0x94, 0x70, 0x0c, 0x9a, 0x5a, 0x05, 0xf2, 0x0b, 0xe5,
+    0x2b, 0x67, 0xec, 0x28, 0xd9, 0x8a, 0xfe, 0x71, 0x02, 0x21, 0x00, 0xfa,
+    0xc2, 0xcc, 0x2a, 0xbe, 0x31, 0x06, 0xbf, 0x69, 0x0d, 0xe4, 0xf7, 0xc4,
+    0x97, 0x05, 0xef, 0xa0, 0x10, 0x54, 0x12, 0xcf, 0xd8, 0xda, 0x5c, 0x84,
+    0x1c, 0x90, 0x10, 0xe7, 0xcd, 0xe5, 0xfd};
 
 constexpr uint8_t kExpectedX509P384Cert_DescriptorInput[0] = {};
 
@@ -1445,12 +1442,12 @@
     0x30, 0x51, 0x65, 0x38, 0x61, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
     0x3a, 0x00, 0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69,
     0x63, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x58, 0x40,
-    0xff, 0xb6, 0x72, 0x2b, 0x96, 0xb7, 0x08, 0x37, 0xdb, 0xbb, 0xf5, 0x42,
-    0x8a, 0xd2, 0xe2, 0x1f, 0x5a, 0x87, 0x3c, 0x27, 0xe6, 0xc5, 0xb1, 0x31,
-    0x26, 0x9c, 0xe4, 0x9c, 0x36, 0x57, 0xcd, 0x5d, 0xdd, 0x13, 0xcd, 0x9c,
-    0x99, 0xb3, 0xe0, 0xd1, 0x93, 0x98, 0x79, 0x74, 0xf1, 0xaa, 0xb7, 0x8d,
-    0x00, 0x59, 0x00, 0x0c, 0x33, 0x29, 0x48, 0x34, 0x1e, 0x38, 0x3d, 0xdf,
-    0x29, 0x0d, 0x30, 0xfb};
+    0x9b, 0xeb, 0x67, 0x74, 0x4c, 0xb1, 0xb4, 0x0f, 0x8f, 0x59, 0xb0, 0xc3,
+    0x31, 0x38, 0x17, 0xd2, 0x4d, 0x94, 0xf6, 0x31, 0x23, 0x10, 0xea, 0x72,
+    0x92, 0x0a, 0xa2, 0xd8, 0xf6, 0xa1, 0xee, 0x7d, 0xb0, 0x00, 0x15, 0xdf,
+    0x8b, 0x87, 0x74, 0x18, 0xe9, 0x77, 0xe1, 0x97, 0xfe, 0x5b, 0x38, 0xdf,
+    0x9e, 0x7b, 0xd8, 0xdf, 0x5b, 0x27, 0x32, 0xb5, 0x73, 0x82, 0x7c, 0xe9,
+    0x8a, 0xd1, 0xd2, 0x9b};
 
 constexpr uint8_t kExpectedCborP384Cert_DescriptorInput[790] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x02, 0xaa, 0xac, 0x01,
@@ -1510,15 +1507,15 @@
     0xf5, 0x7d, 0x26, 0xc2, 0x37, 0xe9, 0x58, 0x98, 0xeb, 0xef, 0x11, 0x7c,
     0x8d, 0x1d, 0x4b, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x3a, 0x00,
     0x47, 0x44, 0x59, 0x70, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x65,
-    0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x58, 0x60, 0xe7, 0x19,
-    0xc3, 0xe6, 0x17, 0xe3, 0x29, 0xe7, 0xb3, 0x22, 0x40, 0x94, 0x0f, 0x2b,
-    0x43, 0xdb, 0x1d, 0xa3, 0x92, 0xed, 0x80, 0x1c, 0x06, 0xf3, 0xdf, 0x60,
-    0xdf, 0x5e, 0x35, 0x06, 0x15, 0x33, 0xeb, 0x5f, 0x4d, 0x93, 0x22, 0x9d,
-    0x83, 0x10, 0x59, 0xaf, 0xe3, 0x4e, 0xab, 0x4b, 0x56, 0x6e, 0x48, 0xd6,
-    0xd8, 0x17, 0xb1, 0xad, 0xf5, 0x5b, 0x37, 0x81, 0x32, 0x1b, 0x7f, 0xd6,
-    0xc8, 0x48, 0x27, 0xbc, 0x15, 0xa8, 0xf1, 0x1c, 0x86, 0x5d, 0x7f, 0xdb,
-    0x83, 0x46, 0x75, 0x93, 0xc8, 0x0f, 0x29, 0x5b, 0xb0, 0x19, 0x6c, 0xcc,
-    0x11, 0xec, 0x31, 0xe0, 0xfa, 0xb5, 0x8a, 0x11, 0x5c, 0x84};
+    0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x58, 0x60, 0x60, 0x88,
+    0x0a, 0x15, 0x8a, 0x65, 0x4e, 0x31, 0xa7, 0x61, 0x33, 0x2f, 0x83, 0x07,
+    0x12, 0x77, 0xca, 0xfe, 0xab, 0x9d, 0xf7, 0x92, 0xb1, 0x49, 0x43, 0xdb,
+    0xfb, 0x33, 0x42, 0x68, 0xc1, 0xc2, 0xf4, 0xfa, 0x0b, 0xff, 0x0e, 0x55,
+    0x8b, 0x1b, 0x12, 0xc6, 0xe2, 0xc5, 0x44, 0xd7, 0x57, 0x73, 0x7c, 0xd2,
+    0xfe, 0xef, 0x8f, 0x3d, 0xa3, 0xf8, 0x1a, 0xaa, 0x33, 0xdf, 0xea, 0xe9,
+    0x88, 0x81, 0x4e, 0xec, 0xa4, 0xa0, 0x2a, 0x9f, 0x00, 0x0d, 0xde, 0x4e,
+    0xd6, 0x73, 0x1e, 0xfe, 0x99, 0xff, 0x1c, 0xf4, 0xed, 0x24, 0x16, 0x81,
+    0x70, 0x6e, 0xee, 0x11, 0xe8, 0x31, 0xb2, 0x1f, 0x50, 0x8e};
 
 constexpr uint8_t kExpectedCborEd25519Cert_AndroidDescriptorInput[683] = {
     0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x02, 0x60, 0xac, 0x01, 0x78,
@@ -1634,12 +1631,12 @@
     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, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-    0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x65, 0x58, 0x83, 0x1d, 0xa8, 0x36,
-    0x86, 0x29, 0xd8, 0x92, 0x35, 0x48, 0xed, 0x50, 0xb7, 0x2e, 0x3f, 0x38,
-    0xcb, 0xaa, 0x03, 0x51, 0x86, 0xbd, 0xc5, 0x85, 0x64, 0xc2, 0x1c, 0xe6,
-    0xee, 0x50, 0x53, 0x42, 0xd3, 0xb3, 0x9b, 0x53, 0x17, 0x67, 0x6e, 0xb4,
-    0x60, 0x12, 0x5b, 0x2b, 0x64, 0x43, 0x83, 0x48, 0xc5, 0xb4, 0xd7, 0xf1,
-    0x93, 0x5a, 0xbb, 0x8a, 0xf6, 0x83, 0x48, 0x4f, 0x9a, 0xab};
+    0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x84, 0xb8, 0xd7, 0x5e, 0x93, 0xdd,
+    0xc5, 0xe8, 0x9b, 0x16, 0x3b, 0x24, 0x72, 0xc3, 0x57, 0x96, 0xb0, 0x0c,
+    0xf7, 0xd5, 0x7c, 0x66, 0x1f, 0xa0, 0xd9, 0x2d, 0xbe, 0xbc, 0xe6, 0xc2,
+    0x6d, 0xb2, 0xbe, 0xa2, 0x5c, 0xc8, 0x21, 0x26, 0xd8, 0x1b, 0xed, 0x40,
+    0x23, 0x3d, 0x13, 0xfb, 0x16, 0x7c, 0xac, 0x02, 0x01, 0x7b, 0xc3, 0xbf,
+    0xb2, 0xca, 0x62, 0x4e, 0x6e, 0xaf, 0x11, 0xbc, 0x35, 0xa6};
 
 constexpr uint8_t kExpectedCborP384Cert_AndroidDescriptorInput[784] = {
     0x84, 0x44, 0xa1, 0x01, 0x38, 0x22, 0xa0, 0x59, 0x02, 0xa4, 0xac, 0x01,
@@ -1699,15 +1696,15 @@
     0xf5, 0x7d, 0x26, 0xc2, 0x37, 0xe9, 0x58, 0x98, 0xeb, 0xef, 0x11, 0x7c,
     0x8d, 0x1d, 0x4b, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x3a, 0x00,
     0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
-    0x31, 0x36, 0x58, 0x60, 0x71, 0x9e, 0xc4, 0x64, 0x88, 0x9e, 0x20, 0xe8,
-    0xb3, 0xa3, 0x89, 0x44, 0x16, 0x28, 0xd2, 0x07, 0xc0, 0x78, 0x49, 0x8b,
-    0xee, 0x49, 0x37, 0x10, 0x83, 0x7b, 0x2d, 0x2d, 0xae, 0x1a, 0x03, 0xa5,
-    0xd3, 0xe7, 0x68, 0x6c, 0xc5, 0x93, 0xf7, 0x23, 0x02, 0xe0, 0xa7, 0xaa,
-    0x57, 0xf0, 0x25, 0x69, 0x85, 0x84, 0x48, 0x12, 0xce, 0x70, 0x63, 0x7d,
-    0xb7, 0x88, 0x05, 0x29, 0x39, 0x26, 0xbf, 0x63, 0xcb, 0x28, 0x84, 0xbd,
-    0xef, 0x71, 0xf1, 0x43, 0x58, 0x44, 0x46, 0xb4, 0x78, 0xbe, 0x36, 0xad,
-    0x0c, 0xe2, 0xfa, 0xe5, 0xe0, 0xe7, 0x35, 0x8f, 0x49, 0x21, 0xec, 0x67,
-    0x9d, 0x1b, 0xa2, 0xb3};
+    0x31, 0x36, 0x58, 0x60, 0x44, 0xfc, 0x89, 0x29, 0x1b, 0x68, 0x08, 0xe2,
+    0x9b, 0x1f, 0x0c, 0x53, 0x3e, 0x96, 0x62, 0x30, 0xa8, 0x82, 0xd1, 0xf7,
+    0xb1, 0xe6, 0x2b, 0xaf, 0xd8, 0xf1, 0x37, 0x10, 0x0b, 0x18, 0xb3, 0x42,
+    0x54, 0x7a, 0x89, 0x4d, 0x1d, 0xc0, 0x07, 0x2d, 0xa3, 0x12, 0xa2, 0xf3,
+    0x07, 0x28, 0x39, 0xc6, 0x1c, 0xc7, 0x47, 0xbe, 0x01, 0x49, 0x5b, 0x58,
+    0xcc, 0x8f, 0x47, 0x8d, 0xd9, 0x27, 0x9c, 0x16, 0x0e, 0x72, 0x06, 0xa9,
+    0x34, 0xaf, 0xce, 0x68, 0xb6, 0x72, 0xba, 0xdb, 0xc8, 0xc4, 0xe5, 0xd5,
+    0x8e, 0x2f, 0xd4, 0xb3, 0x16, 0xc6, 0xd3, 0xac, 0x2c, 0xe4, 0x9a, 0xcd,
+    0x1e, 0xe2, 0xd5, 0x4e};
 
 }  // namespace test
 }  // namespace dice
diff --git a/include/dice/test_utils.h b/include/dice/test_utils.h
index c5bea9e..8c0d97a 100644
--- a/include/dice/test_utils.h
+++ b/include/dice/test_utils.h
@@ -44,6 +44,14 @@
   size_t certificate_size;
 };
 
+// Get a pointer to the payload section of a certificate.
+const uint8_t* GetX509PayloadPointer(const uint8_t* certificate);
+
+// Determines the length of the payload in a certificate. That is, exclude the
+// first tag/length at the beginning and the signature at the end.
+size_t ComputeX509PayloadSize(const uint8_t* certificate,
+                              size_t certificate_size);
+
 // Dumps |state| to a set of files in the current directory with the given
 // |suffix|.
 void DumpState(CertificateType cert_type, KeyType key_type, const char* suffix,
diff --git a/src/boringssl_cert_op.c b/src/boringssl_cert_op.c
index 79ce6d3..fda4591 100644
--- a/src/boringssl_cert_op.c
+++ b/src/boringssl_cert_op.c
@@ -13,12 +13,12 @@
 // the License.
 
 // This is a DiceGenerateCertificate implementation that uses boringssl for
-// crypto and certificate generation. The algorithms used are SHA512,
-// HKDF-SHA512, and Ed25519-SHA512.
+// crypto and certificate generation.
 
 #include <stdint.h>
 #include <string.h>
 
+#include "dice/config/cose_key_config.h"
 #include "dice/dice.h"
 #include "dice/ops.h"
 #include "dice/profile_name.h"
@@ -26,6 +26,7 @@
 #include "openssl/asn1.h"
 #include "openssl/asn1t.h"
 #include "openssl/bn.h"
+#include "openssl/crypto.h"
 #include "openssl/curve25519.h"
 #include "openssl/evp.h"
 #include "openssl/is_boringssl.h"
@@ -516,15 +517,95 @@
   return result;
 }
 
-static DiceResult GetIdFromKey(void* context, const EVP_PKEY* key,
-                               uint8_t id[DICE_ID_SIZE]) {
-  uint8_t raw_public_key[32];
-  size_t raw_public_key_size = sizeof(raw_public_key);
-  if (!EVP_PKEY_get_raw_public_key(key, raw_public_key, &raw_public_key_size)) {
-    return kDiceResultPlatformError;
+static EVP_PKEY* CreateEcPrivateKey(
+    int nid, const uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE]) {
+  int success = 0;
+  EC_KEY* ec_key = NULL;
+  BIGNUM* bn = NULL;
+  EC_POINT* point = NULL;
+  EVP_PKEY* pkey = NULL;
+
+  ec_key = EC_KEY_new_by_curve_name(nid);
+  if (!ec_key) {
+    goto out;
   }
-  return DiceDeriveCdiCertificateId(context, raw_public_key,
-                                    raw_public_key_size, id);
+
+  bn = BN_bin2bn(private_key, DICE_PRIVATE_KEY_BUFFER_SIZE, NULL);
+  if (!bn) {
+    goto out;
+  }
+
+  if (!EC_KEY_set_private_key(ec_key, bn)) {
+    goto out;
+  }
+
+  const EC_GROUP* group = EC_KEY_get0_group(ec_key);
+
+  point = EC_POINT_new(group);
+  if (!point) {
+    goto out;
+  }
+
+  if (!EC_POINT_mul(group, point, bn, NULL, NULL, NULL)) {
+    goto out;
+  }
+  if (!EC_KEY_set_public_key(ec_key, point)) {
+    goto out;
+  }
+
+  pkey = EVP_PKEY_new();
+  if (!pkey) {
+    goto out;
+  }
+
+  success = EVP_PKEY_set1_EC_KEY(pkey, ec_key);
+
+out:
+  if (ec_key) {
+    EC_KEY_free(ec_key);
+  }
+  if (bn) {
+    BN_free(bn);
+  }
+  if (point) {
+    EC_POINT_free(point);
+  }
+  if (!success && pkey) {
+    EVP_PKEY_free(pkey);
+  }
+
+  return pkey;
+}
+
+static EVP_PKEY* CreatePrivateKey(
+    const DiceKeyParam* key_param,
+    const uint8_t private_key[DICE_PRIVATE_KEY_BUFFER_SIZE]) {
+  if (key_param->cose_key_curve == kCoseCrvEd25519) {
+    return EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, private_key,
+                                        32);
+  }
+  if (key_param->cose_key_curve == kCoseCrvP256) {
+    return CreateEcPrivateKey(NID_X9_62_prime256v1, private_key);
+  }
+  if (key_param->cose_key_curve == kCoseCrvP384) {
+    return CreateEcPrivateKey(NID_secp384r1, private_key);
+  }
+  return NULL;
+}
+
+static const EVP_MD* GetDigestForX509Sign(const DiceKeyParam* key_param) {
+  if (key_param->cose_key_curve == kCoseCrvP256) {
+    return EVP_sha256();
+  }
+  if (key_param->cose_key_curve == kCoseCrvP384) {
+    return EVP_sha384();
+  }
+  // The interface for Ed25519 is different from P256 and P384.
+  // It expects NULL and will use SHA512 implicitly.
+  if (key_param->cose_key_curve == kCoseCrvEd25519) {
+    return NULL;
+  }
+  return NULL;
 }
 
 DiceResult DiceGenerateCertificate(
@@ -533,44 +614,63 @@
     const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
     const DiceInputValues* input_values, size_t certificate_buffer_size,
     uint8_t* certificate, size_t* certificate_actual_size) {
-  DiceResult result = kDiceResultOk;
-
   // Initialize variables that are cleaned up on 'goto out'.
   X509* x509 = NULL;
   EVP_PKEY* authority_key = NULL;
   EVP_PKEY* subject_key = NULL;
 
+  DiceResult result = kDiceResultOk;
+
+  DiceKeyParam key_param;
+  result = DiceGetKeyParam(context, kDicePrincipalSubject, &key_param);
+  if (result != kDiceResultOk) {
+    return result;
+  }
+
+  uint8_t authority_public_key[DICE_PUBLIC_KEY_BUFFER_SIZE];
+  uint8_t authority_private_key[DICE_PRIVATE_KEY_BUFFER_SIZE];
+  result = DiceKeypairFromSeed(context, kDicePrincipalAuthority,
+                               authority_private_key_seed, authority_public_key,
+                               authority_private_key);
+
+  authority_key = CreatePrivateKey(&key_param, authority_private_key);
+  if (!authority_key) {
+    goto out;
+  }
+
+  uint8_t subject_public_key[DICE_PUBLIC_KEY_BUFFER_SIZE];
+  uint8_t subject_private_key[DICE_PRIVATE_KEY_BUFFER_SIZE];
+  result = DiceKeypairFromSeed(context, kDicePrincipalSubject,
+                               subject_private_key_seed, subject_public_key,
+                               subject_private_key);
+
+  subject_key = CreatePrivateKey(&key_param, subject_private_key);
+  if (!subject_key) {
+    result = kDiceResultPlatformError;
+    goto out;
+  }
+
   x509 = X509_new();
   if (!x509) {
     result = kDiceResultPlatformError;
     goto out;
   }
-  authority_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
-                                               authority_private_key_seed,
-                                               DICE_PRIVATE_KEY_SEED_SIZE);
-  if (!authority_key) {
-    result = kDiceResultPlatformError;
-    goto out;
-  }
-  subject_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
-                                             subject_private_key_seed,
-                                             DICE_PRIVATE_KEY_SEED_SIZE);
-  if (!subject_key) {
-    result = kDiceResultPlatformError;
-    goto out;
-  }
+
   if (!X509_set_pubkey(x509, subject_key)) {
     result = kDiceResultPlatformError;
     goto out;
   }
 
   uint8_t authority_id[DICE_ID_SIZE];
-  result = GetIdFromKey(context, authority_key, authority_id);
+  result =
+      DiceDeriveCdiCertificateId(context, authority_public_key,
+                                 sizeof(authority_public_key), authority_id);
   if (result != kDiceResultOk) {
     goto out;
   }
   uint8_t subject_id[DICE_ID_SIZE];
-  result = GetIdFromKey(context, subject_key, subject_id);
+  result = DiceDeriveCdiCertificateId(context, subject_public_key,
+                                      sizeof(subject_public_key), subject_id);
   if (result != kDiceResultOk) {
     goto out;
   }
@@ -583,16 +683,12 @@
   if (result != kDiceResultOk) {
     goto out;
   }
-  DiceKeyParam key_param;
-  result = DiceGetKeyParam(context, kDicePrincipalSubject, &key_param);
-  if (result != kDiceResultOk) {
-    goto out;
-  }
   result = AddDiceExtension(input_values, x509);
   if (result != kDiceResultOk) {
     goto out;
   }
-  if (!X509_sign(x509, authority_key, NULL /*ED25519 always uses SHA-512*/)) {
+
+  if (!X509_sign(x509, authority_key, GetDigestForX509Sign(&key_param))) {
     result = kDiceResultPlatformError;
     goto out;
   }
diff --git a/src/boringssl_p256_ops_test.cc b/src/boringssl_p256_ops_test.cc
new file mode 100644
index 0000000..a3e09cf
--- /dev/null
+++ b/src/boringssl_p256_ops_test.cc
@@ -0,0 +1,258 @@
+// Copyright 2020 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/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_X509;
+using dice::test::ComputeX509PayloadSize;
+using dice::test::DeriveFakeInputValue;
+using dice::test::DiceStateForTest;
+using dice::test::GetX509PayloadPointer;
+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);
+  // Both CDI values and the certificate should be deterministic.
+  EXPECT_EQ(0, memcmp(next_state.cdi_attest,
+                      dice::test::kExpectedCdiAttest_ZeroInput, DICE_CDI_SIZE));
+  EXPECT_EQ(0, memcmp(next_state.cdi_seal,
+                      dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_ZeroInput,
+      sizeof(dice::test::kExpectedX509P256Cert_ZeroInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0,
+      memcmp(GetX509PayloadPointer(dice::test::kExpectedX509P256Cert_ZeroInput),
+             GetX509PayloadPointer(next_state.certificate), actual_length));
+}
+
+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);
+  // Both CDI values and the certificate should be deterministic.
+  EXPECT_EQ(
+      0, memcmp(next_state.cdi_attest,
+                dice::test::kExpectedCdiAttest_HashOnlyInput, DICE_CDI_SIZE));
+  EXPECT_EQ(
+      0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
+                DICE_CDI_SIZE));
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_HashOnlyInput,
+      sizeof(dice::test::kExpectedX509P256Cert_HashOnlyInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0, memcmp(GetX509PayloadPointer(
+                    dice::test::kExpectedX509P256Cert_HashOnlyInput),
+                GetX509PayloadPointer(next_state.certificate), actual_length));
+}
+
+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);
+  // 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));
+
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_DescriptorInput,
+      sizeof(dice::test::kExpectedX509P256Cert_DescriptorInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0, memcmp(GetX509PayloadPointer(
+                    dice::test::kExpectedX509P256Cert_DescriptorInput),
+                GetX509PayloadPointer(next_state.certificate), actual_length));
+}
+
+TEST(DiceOpsTest, NonZeroMode) {
+  constexpr size_t kModeOffsetInCert = 0x267;
+  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);
+  }
+  // Use the first derived CDI cert as the 'root' of partial chain.
+  EXPECT_TRUE(dice::test::VerifyCertificateChain(
+      CertificateType_X509, 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);
+  }
+  // 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_X509, KeyType_P256,
+      root_certificate, &root_certificate_size);
+  EXPECT_TRUE(dice::test::VerifyCertificateChain(
+      CertificateType_X509, root_certificate, root_certificate_size, &states[1],
+      kNumLayers,
+      /*is_partial_chain=*/false));
+}
+
+}  // namespace
diff --git a/src/mbedtls_ops.c b/src/mbedtls_ops.c
index 8c232dc..c7a162d 100644
--- a/src/mbedtls_ops.c
+++ b/src/mbedtls_ops.c
@@ -14,13 +14,14 @@
 
 // This is an implementation of DiceGenerateCertificate and the crypto
 // operations that uses mbedtls. The algorithms used are SHA512, HKDF-SHA512,
-// and deterministic ECDSA-P256-SHA512.
+// and deterministic ECDSA-P256-SHA256.
 
 #include <stdint.h>
 #include <string.h>
 
 #include "dice/dice.h"
 #include "dice/ops.h"
+#include "dice/profile_name.h"
 #include "dice/utils.h"
 #include "mbedtls/asn1.h"
 #include "mbedtls/asn1write.h"
@@ -73,17 +74,22 @@
 static DiceResult GetIdFromKey(void* context,
                                const mbedtls_pk_context* pk_context,
                                uint8_t id[DICE_ID_SIZE]) {
-  uint8_t raw_public_key[33];
-  size_t raw_public_key_size = 0;
+  uint8_t formatted_public_key[DICE_PUBLIC_KEY_BUFFER_SIZE];
+  size_t formatted_public_key_size = 0;
   mbedtls_ecp_keypair* key = mbedtls_pk_ec(*pk_context);
 
   if (0 != mbedtls_ecp_point_write_binary(
-               &key->grp, &key->Q, MBEDTLS_ECP_PF_COMPRESSED,
-               &raw_public_key_size, raw_public_key, sizeof(raw_public_key))) {
+               &key->grp, &key->Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
+               &formatted_public_key_size, formatted_public_key,
+               sizeof(formatted_public_key))) {
     return kDiceResultPlatformError;
   }
-  return DiceDeriveCdiCertificateId(context, raw_public_key,
-                                    raw_public_key_size, id);
+
+  // mbedtls puts a format byte at the start of a binary representation
+  // of an elliptic curve point. For consistency with other uses of the function
+  // below, this byte is not used in the derivation of the certificate ID.
+  return DiceDeriveCdiCertificateId(context, &formatted_public_key[1],
+                                    formatted_public_key_size - 1, id);
 }
 
 // 54 byte name is prefix (13), hex id (40), and a null terminator.
@@ -435,7 +441,7 @@
   }
   mbedtls_x509write_crt_set_subject_key(&cert_context, &subject_key_context);
   mbedtls_x509write_crt_set_issuer_key(&cert_context, &authority_key_context);
-  mbedtls_x509write_crt_set_md_alg(&cert_context, MBEDTLS_MD_SHA512);
+  mbedtls_x509write_crt_set_md_alg(&cert_context, MBEDTLS_MD_SHA256);
   if (0 != mbedtls_x509write_crt_set_extension(
                &cert_context, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
                MBEDTLS_OID_SIZE(MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER),
diff --git a/src/mbedtls_ops_test.cc b/src/mbedtls_ops_test.cc
index 96fc8e5..7193b26 100644
--- a/src/mbedtls_ops_test.cc
+++ b/src/mbedtls_ops_test.cc
@@ -28,10 +28,12 @@
 namespace {
 
 using dice::test::CertificateType_X509;
+using dice::test::ComputeX509PayloadSize;
 using dice::test::DeriveFakeInputValue;
 using dice::test::DiceStateForTest;
 using dice::test::DumpState;
-using dice::test::KeyType_P256_COMPRESSED;
+using dice::test::GetX509PayloadPointer;
+using dice::test::KeyType_P256;
 
 TEST(DiceOpsTest, KnownAnswerZeroInput) {
   DiceStateForTest current_state = {};
@@ -42,17 +44,22 @@
       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_COMPRESSED, "zero_input",
-            next_state);
+  DumpState(CertificateType_X509, KeyType_P256, "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));
   EXPECT_EQ(0, memcmp(next_state.cdi_seal,
                       dice::test::kExpectedCdiSeal_ZeroInput, DICE_CDI_SIZE));
-  ASSERT_EQ(sizeof(dice::test::kExpectedX509P256Cert_ZeroInput),
-            next_state.certificate_size);
-  EXPECT_EQ(0, memcmp(dice::test::kExpectedX509P256Cert_ZeroInput,
-                      next_state.certificate, next_state.certificate_size));
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_ZeroInput,
+      sizeof(dice::test::kExpectedX509P256Cert_ZeroInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0,
+      memcmp(GetX509PayloadPointer(dice::test::kExpectedX509P256Cert_ZeroInput),
+             GetX509PayloadPointer(next_state.certificate), actual_length));
 }
 
 TEST(DiceOpsTest, KnownAnswerHashOnlyInput) {
@@ -73,8 +80,7 @@
       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_COMPRESSED, "hash_only_input",
-            next_state);
+  DumpState(CertificateType_X509, KeyType_P256, "hash_only_input", next_state);
   // Both CDI values and the certificate should be deterministic.
   EXPECT_EQ(
       0, memcmp(next_state.cdi_attest,
@@ -82,10 +88,16 @@
   EXPECT_EQ(
       0, memcmp(next_state.cdi_seal, dice::test::kExpectedCdiSeal_HashOnlyInput,
                 DICE_CDI_SIZE));
-  ASSERT_EQ(sizeof(dice::test::kExpectedX509P256Cert_HashOnlyInput),
-            next_state.certificate_size);
-  EXPECT_EQ(0, memcmp(dice::test::kExpectedX509P256Cert_HashOnlyInput,
-                      next_state.certificate, next_state.certificate_size));
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_HashOnlyInput,
+      sizeof(dice::test::kExpectedX509P256Cert_HashOnlyInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0, memcmp(GetX509PayloadPointer(
+                    dice::test::kExpectedX509P256Cert_HashOnlyInput),
+                GetX509PayloadPointer(next_state.certificate), actual_length));
 }
 
 TEST(DiceOpsTest, KnownAnswerDescriptorInput) {
@@ -122,8 +134,7 @@
       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_COMPRESSED, "descriptor_input",
-            next_state);
+  DumpState(CertificateType_X509, KeyType_P256, "descriptor_input", next_state);
   // Both CDI values and the certificate should be deterministic.
   EXPECT_EQ(
       0, memcmp(next_state.cdi_attest,
@@ -131,14 +142,20 @@
   EXPECT_EQ(
       0, memcmp(next_state.cdi_seal,
                 dice::test::kExpectedCdiSeal_DescriptorInput, DICE_CDI_SIZE));
-  ASSERT_EQ(sizeof(dice::test::kExpectedX509P256Cert_DescriptorInput),
-            next_state.certificate_size);
-  EXPECT_EQ(0, memcmp(dice::test::kExpectedX509P256Cert_DescriptorInput,
-                      next_state.certificate, next_state.certificate_size));
+  size_t expected_length = ComputeX509PayloadSize(
+      dice::test::kExpectedX509P256Cert_DescriptorInput,
+      sizeof(dice::test::kExpectedX509P256Cert_DescriptorInput));
+  size_t actual_length = ComputeX509PayloadSize(next_state.certificate,
+                                                next_state.certificate_size);
+  ASSERT_EQ(expected_length, actual_length);
+  EXPECT_EQ(
+      0, memcmp(GetX509PayloadPointer(
+                    dice::test::kExpectedX509P256Cert_DescriptorInput),
+                GetX509PayloadPointer(next_state.certificate), actual_length));
 }
 
 TEST(DiceOpsTest, NonZeroMode) {
-  constexpr size_t kModeOffsetInCert = 0x268;
+  constexpr size_t kModeOffsetInCert = 0x267;
   DiceStateForTest current_state = {};
   DiceStateForTest next_state = {};
   DiceInputValues input_values = {};
@@ -199,8 +216,7 @@
                      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_COMPRESSED, suffix,
-              states[i + 1]);
+    DumpState(CertificateType_X509, KeyType_P256, suffix, states[i + 1]);
   }
   // Use the first derived CDI cert as the 'root' of partial chain.
   EXPECT_TRUE(dice::test::VerifyCertificateChain(
@@ -230,16 +246,14 @@
                      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_COMPRESSED, suffix,
-              states[i + 1]);
+    DumpState(CertificateType_X509, 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, dice::test::CertificateType_X509,
-      dice::test::KeyType_P256_COMPRESSED, root_certificate,
-      &root_certificate_size);
+      dice::test::KeyType_P256, 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 0592fc5..a8e972c 100644
--- a/src/test_utils.cc
+++ b/src/test_utils.cc
@@ -707,6 +707,32 @@
 namespace dice {
 namespace test {
 
+static constexpr uint8_t kDerTag[] = {0x30, 0x82, 0x00, 0x00};
+
+const uint8_t* GetX509PayloadPointer(const uint8_t* certificate) {
+  if (certificate == NULL) {
+    return NULL;
+  }
+  return &certificate[sizeof(kDerTag)];
+}
+
+size_t ComputeX509PayloadSize(const uint8_t* certificate,
+                              size_t certificate_size) {
+  if (certificate == NULL || certificate_size < 8) {
+    return 0;
+  }
+  // X509 header for certificate usually looks similar to
+  // 30 82 ** ** 30 82 xy zw # bytes
+  // 00 01 02 03 04 05 06 07 # offsets
+  // where xyzw is the length of the certificate payload
+  size_t payload_size =
+      sizeof(kDerTag) + (certificate[6] << 8) | certificate[7];
+  if (payload_size > certificate_size) {
+    return 0;
+  }
+  return payload_size;
+}
+
 void DumpState(CertificateType cert_type, KeyType key_type, const char* suffix,
                const DiceStateForTest& state) {
   char filename[100];
diff --git a/third_party/mbedtls/BUILD.gn b/third_party/mbedtls/BUILD.gn
index 6e5888a..0ca0cac 100644
--- a/third_party/mbedtls/BUILD.gn
+++ b/third_party/mbedtls/BUILD.gn
@@ -44,6 +44,7 @@
     "src/library/pk_wrap.c",
     "src/library/pkwrite.c",
     "src/library/platform_util.c",
+    "src/library/sha256.c",
     "src/library/sha512.c",
     "src/library/x509_create.c",
     "src/library/x509write_crt.c",
diff --git a/third_party/mbedtls/custom_config.h b/third_party/mbedtls/custom_config.h
index 765eef9..bef1ff5 100644
--- a/third_party/mbedtls/custom_config.h
+++ b/third_party/mbedtls/custom_config.h
@@ -34,6 +34,7 @@
 #define MBEDTLS_PK_C
 #define MBEDTLS_PK_PARSE_C
 #define MBEDTLS_PK_WRITE_C
+#define MBEDTLS_SHA256_C
 #define MBEDTLS_SHA512_C
 #define MBEDTLS_X509_CREATE_C
 #define MBEDTLS_X509_CRT_WRITE_C