Introduce config header

Initially, the header is used to configure the size of public and
private keys. The build rules need to use correct include paths at
compile time which means shared build rules don't always work any more.

Change-Id: Ie2a0daccf0232e84043d6c08f76c9302eb69476d
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/55660
Commit-Queue: Andrew Scull <ascull@google.com>
Pigweed-Auto-Submit: Andrew Scull <ascull@google.com>
Reviewed-by: Darren Krahn <dkrahn@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 42d5e46..917b4e8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -25,17 +25,6 @@
   ]
 }
 
-pw_source_set("utils") {
-  public = [
-    "include/dice/dice.h",
-    "include/dice/utils.h",
-  ]
-  sources = [
-    "src/clear_memory.c",
-    "src/utils.c",
-  ]
-}
-
 pw_source_set("cbor_writer") {
   public = [
     "include/dice/cbor_writer.h",
@@ -43,88 +32,118 @@
   sources = [ "src/cbor_writer.c" ]
 }
 
+config("standalone_ops_config") {
+  include_dirs = [ "//include/dice/config/standalone" ]
+}
+
 pw_static_library("dice_standalone") {
-  public = [ "include/dice/dice.h" ]
-  sources = [ "src/dice.c" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
+  sources = [
+    "src/clear_memory.c",
+    "src/dice.c"
+  ]
+  all_dependent_configs = [ ":standalone_ops_config" ]
+}
+
+config("boringssl_ed25519_ops_config") {
+  include_dirs = [ "//include/dice/config/boringssl_ed25519" ]
 }
 
 pw_static_library("dice_with_boringssl_ops") {
-  public = [ "include/dice/dice.h" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
   sources = [
     "src/boringssl_cert_op.c",
     "src/boringssl_hash_kdf_sign_ops.c",
+    "src/clear_memory.c",
     "src/dice.c",
+    "src/utils.c",
   ]
   deps = [
-    ":utils",
     "//third_party/boringssl:crypto",
   ]
+  all_dependent_configs = [ ":boringssl_ed25519_ops_config" ]
+}
+
+config("mbedtls_ops_config") {
+  include_dirs = [ "//include//dice/config/mbedtls_ecdsa_p256" ]
 }
 
 pw_static_library("dice_with_mbedtls_ops") {
-  public = [ "include/dice/dice.h" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
   sources = [
+    "src/clear_memory.c",
     "src/dice.c",
     "src/mbedtls_ops.c",
+    "src/utils.c",
   ]
   deps = [
-    ":utils",
     "//third_party/mbedtls:mbedcrypto",
   ]
+  all_dependent_configs = [ ":mbedtls_ops_config" ]
 }
 
 pw_static_library("dice_with_cbor_cert") {
-  public = [ "include/dice/dice.h" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
   sources = [
     "src/boringssl_hash_kdf_sign_ops.c",
     "src/cbor_cert_op.c",
+    "src/clear_memory.c",
     "src/dice.c",
+    "src/utils.c",
   ]
   deps = [
     ":cbor_writer",
-    ":utils",
     "//third_party/boringssl:crypto",
   ]
+  all_dependent_configs = [ ":boringssl_ed25519_ops_config" ]
 }
 
 pw_static_library("dice_with_cbor_template_cert") {
-  public = [ "include/dice/dice.h" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
   sources = [
     "src/boringssl_hash_kdf_sign_ops.c",
+    "src/clear_memory.c",
     "src/dice.c",
     "src/template_cbor_cert_op.c",
+    "src/utils.c",
   ]
   deps = [
-    ":utils",
     "//third_party/boringssl:crypto",
   ]
+  all_dependent_configs = [ ":boringssl_ed25519_ops_config" ]
 }
 
 pw_static_library("dice_with_x509_template_cert") {
-  public = [ "include/dice/dice.h" ]
+  public = [
+    "include/dice/dice.h",
+    "include/dice/utils.h",
+  ]
   sources = [
     "src/boringssl_hash_kdf_sign_ops.c",
+    "src/clear_memory.c",
     "src/dice.c",
     "src/template_cert_op.c",
+    "src/utils.c",
   ]
   deps = [
-    ":utils",
     "//third_party/boringssl:crypto",
   ]
-}
-
-pw_source_set("test_utils") {
-  public = [ "include/dice/test_utils.h" ]
-  sources = [ "src/test_utils.cc" ]
-  deps = [
-    ":utils",
-    "$dir_pw_string:pw_string",
-  ]
-  public_deps = [
-    "//third_party/boringssl:crypto",
-    "//third_party/cose-c:cose-c",
-  ]
-  cflags = [ "-Wno-ignored-qualifiers" ]
+  all_dependent_configs = [ ":boringssl_ed25519_ops_config" ]
 }
 
 pw_source_set("fuzzer") {
@@ -149,17 +168,20 @@
   sources = [ "src/dice_test.cc" ]
   deps = [
     ":dice_standalone",
-    ":utils",
     "//third_party/boringssl:crypto",
   ]
 }
 
 pw_test("boringssl_ops_test") {
-  sources = [ "src/boringssl_ops_test.cc" ]
+  sources = [
+    "src/boringssl_ops_test.cc",
+    "src/test_utils.cc",
+  ]
   deps = [
     ":dice_with_boringssl_ops",
-    ":test_utils",
-    ":utils",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c",
+    "$dir_pw_string:pw_string",
   ]
 }
 
@@ -171,11 +193,15 @@
 }
 
 pw_test("template_cert_op_test") {
-  sources = [ "src/template_cert_op_test.cc" ]
+  sources = [
+    "src/template_cert_op_test.cc",
+    "src/test_utils.cc",
+  ]
   deps = [
     ":dice_with_x509_template_cert",
-    ":test_utils",
-    ":utils",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c",
+    "$dir_pw_string:pw_string",
   ]
 }
 
@@ -187,11 +213,15 @@
 }
 
 pw_test("cbor_cert_op_test") {
-  sources = [ "src/cbor_cert_op_test.cc" ]
+  sources = [
+    "src/cbor_cert_op_test.cc",
+    "src/test_utils.cc",
+  ]
   deps = [
     ":dice_with_cbor_cert",
-    ":test_utils",
-    ":utils",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c",
+    "$dir_pw_string:pw_string",
   ]
 }
 
@@ -203,11 +233,15 @@
 }
 
 pw_test("template_cbor_cert_op_test") {
-  sources = [ "src/template_cbor_cert_op_test.cc" ]
+  sources = [
+    "src/template_cbor_cert_op_test.cc",
+    "src/test_utils.cc",
+  ]
   deps = [
     ":dice_with_cbor_template_cert",
-    ":test_utils",
-    ":utils",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c",
+    "$dir_pw_string:pw_string",
   ]
 }
 
@@ -219,11 +253,15 @@
 }
 
 pw_test("mbedtls_ops_test") {
-  sources = [ "src/mbedtls_ops_test.cc" ]
+  sources = [
+    "src/mbedtls_ops_test.cc",
+    "src/test_utils.cc",
+  ]
   deps = [
     ":dice_with_mbedtls_ops",
-    ":test_utils",
-    ":utils",
+    "//third_party/boringssl:crypto",
+    "//third_party/cose-c:cose-c",
+    "$dir_pw_string:pw_string",
   ]
 }
 
@@ -266,10 +304,7 @@
 
 pw_executable("dice_standalone_main") {
   sources = [ "src/dice_standalone_main.c" ]
-  deps = [
-    ":dice_standalone",
-    ":utils",
-  ]
+  deps = [ ":dice_standalone" ]
 }
 
 pw_source_set("dice_main") {
diff --git a/include/dice/config/boringssl_ed25519/dice/config.h b/include/dice/config/boringssl_ed25519/dice/config.h
new file mode 100644
index 0000000..583ac68
--- /dev/null
+++ b/include/dice/config/boringssl_ed25519/dice/config.h
@@ -0,0 +1,23 @@
+// Copyright 2021 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_H_
+#define DICE_CONFIG_H_
+
+// Ed25519
+#define DICE_PUBLIC_KEY_SIZE 32
+#define DICE_PRIVATE_KEY_SIZE 64
+#define DICE_SIGNATURE_SIZE 64
+
+#endif  // 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
new file mode 100644
index 0000000..11f4875
--- /dev/null
+++ b/include/dice/config/mbedtls_ecdsa_p256/dice/config.h
@@ -0,0 +1,23 @@
+// Copyright 2021 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_H_
+#define DICE_CONFIG_H_
+
+// ECDSA-P256
+#define DICE_PUBLIC_KEY_SIZE 33
+#define DICE_PRIVATE_KEY_SIZE 32
+#define DICE_SIGNATURE_SIZE 64
+
+#endif  // DICE_DICE_CONFIG_H_
diff --git a/include/dice/config/standalone/dice/config.h b/include/dice/config/standalone/dice/config.h
new file mode 100644
index 0000000..5f6188f
--- /dev/null
+++ b/include/dice/config/standalone/dice/config.h
@@ -0,0 +1,26 @@
+// Copyright 2021 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_H_
+#define DICE_CONFIG_H_
+
+// The standalone config is only used for testing. In particular, it is used
+// for tests that focus on the core aspects of the library and not the ops.
+// These value aren't yet used meaningfully in such tests so are given
+// placeholder values.
+#define DICE_PUBLIC_KEY_SIZE 1
+#define DICE_PRIVATE_KEY_SIZE 1
+#define DICE_SIGNATURE_SIZE 1
+
+#endif  // DICE_DICE_CONFIG_H_
diff --git a/include/dice/dice.h b/include/dice/dice.h
index 2f4caa7..9731247 100644
--- a/include/dice/dice.h
+++ b/include/dice/dice.h
@@ -27,8 +27,6 @@
 #define DICE_HIDDEN_SIZE 64
 #define DICE_INLINE_CONFIG_SIZE 64
 #define DICE_PRIVATE_KEY_SEED_SIZE 32
-#define DICE_PUBLIC_KEY_MAX_SIZE 48
-#define DICE_PRIVATE_KEY_MAX_SIZE 64
 
 typedef enum {
   kDiceResultOk,
diff --git a/include/dice/ops.h b/include/dice/ops.h
index cb3ee45..53f8d8e 100644
--- a/include/dice/ops.h
+++ b/include/dice/ops.h
@@ -15,6 +15,7 @@
 #ifndef DICE_OPS_H_
 #define DICE_OPS_H_
 
+#include <dice/config.h>
 #include <dice/dice.h>
 
 // These are the set of functions that implement various operations that the
@@ -43,27 +44,23 @@
 // implementation defined format so may only be passed to the |sign| operation.
 DiceResult DiceKeypairFromSeed(void* context,
                                const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
-                               uint8_t public_key[DICE_PUBLIC_KEY_MAX_SIZE],
-                               size_t* public_key_size,
-                               uint8_t private_key[DICE_PRIVATE_KEY_MAX_SIZE],
-                               size_t* private_key_size);
+                               uint8_t public_key[DICE_PUBLIC_KEY_SIZE],
+                               uint8_t private_key[DICE_PRIVATE_KEY_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
-// |signature_size| bytes into which the calculated signature is written.  If
-// |signature_size| differs from the implementation's signature size,
-// kDiceResultPlatformError is returned.
+// the buffer where the calculated signature is written.
 DiceResult DiceSign(void* context, const uint8_t* message, size_t message_size,
-                    const uint8_t* private_key, size_t private_key_size,
-                    size_t signature_size, uint8_t* signature);
+                    const uint8_t private_key[DICE_PRIVATE_KEY_SIZE],
+                    uint8_t signature[DICE_SIGNATURE_SIZE]);
 
 // Verifies, using |public_key|, that |signature| covers |message_size| bytes
 // from |message|.
 DiceResult DiceVerify(void* context, 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);
+                      size_t message_size,
+                      const uint8_t signature[DICE_SIGNATURE_SIZE],
+                      const uint8_t public_key[DICE_PUBLIC_KEY_SIZE]);
 
 // Generates an X.509 certificate, or an alternative certificate format, from
 // the given |subject_private_key_seed| and |input_values|, and signed by
diff --git a/src/boringssl_hash_kdf_sign_ops.c b/src/boringssl_hash_kdf_sign_ops.c
index c135dae..9198b4a 100644
--- a/src/boringssl_hash_kdf_sign_ops.c
+++ b/src/boringssl_hash_kdf_sign_ops.c
@@ -25,6 +25,19 @@
 #include "openssl/is_boringssl.h"
 #include "openssl/sha.h"
 
+#if DICE_PRIVATE_KEY_SEED_SIZE != 32
+#error "Private key seed is expected to be 32 bytes."
+#endif
+#if DICE_PUBLIC_KEY_SIZE != 32
+#error "Ed25519 needs 32 bytes to store the public key."
+#endif
+#if DICE_PRIVATE_KEY_SIZE != 64
+#error "This Ed25519 implementation needs 64 bytes for the private key."
+#endif
+#if DICE_SIGNATURE_SIZE != 64
+#error "Ed25519 needs 64 bytes to store the signature."
+#endif
+
 DiceResult DiceHash(void* context_not_used, const uint8_t* input,
                     size_t input_size, uint8_t output[DICE_HASH_SIZE]) {
   (void)context_not_used;
@@ -45,34 +58,18 @@
 
 DiceResult DiceKeypairFromSeed(void* context_not_used,
                                const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
-                               uint8_t public_key[DICE_PUBLIC_KEY_MAX_SIZE],
-                               size_t* public_key_size,
-                               uint8_t private_key[DICE_PRIVATE_KEY_MAX_SIZE],
-                               size_t* private_key_size) {
+                               uint8_t public_key[DICE_PUBLIC_KEY_SIZE],
+                               uint8_t private_key[DICE_PRIVATE_KEY_SIZE]) {
   (void)context_not_used;
-#if DICE_PRIVATE_KEY_SEED_SIZE != 32
-#error "Private key seed is expected to be 32 bytes."
-#endif
-#if DICE_PUBLIC_KEY_MAX_SIZE < 32
-#error "Ed25519 needs 32 bytes to store the public key."
-#endif
-#if DICE_PRIVATE_KEY_MAX_SIZE < 64
-#error "This Ed25519 implementation needs  64 bytes for the private key."
-#endif
   ED25519_keypair_from_seed(public_key, private_key, seed);
-  *public_key_size = 32;
-  *private_key_size = 64;
   return kDiceResultOk;
 }
 
 DiceResult DiceSign(void* context_not_used, const uint8_t* message,
-                    size_t message_size, const uint8_t* private_key,
-                    size_t private_key_size, size_t signature_size,
-                    uint8_t* signature) {
+                    size_t message_size,
+                    const uint8_t private_key[DICE_PRIVATE_KEY_SIZE],
+                    uint8_t signature[DICE_SIGNATURE_SIZE]) {
   (void)context_not_used;
-  if (private_key_size != 64 || signature_size != 64) {
-    return kDiceResultPlatformError;
-  }
   if (1 != ED25519_sign(signature, message, message_size, private_key)) {
     return kDiceResultPlatformError;
   }
@@ -80,13 +77,10 @@
 }
 
 DiceResult DiceVerify(void* context_not_used, 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) {
+                      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 (public_key_size != 32 || signature_size != 64) {
-    return kDiceResultPlatformError;
-  }
   if (1 != ED25519_verify(message, message_size, signature, public_key)) {
     return kDiceResultPlatformError;
   }
diff --git a/src/cbor_cert_op.c b/src/cbor_cert_op.c
index a49947f..1746083 100644
--- a/src/cbor_cert_op.c
+++ b/src/cbor_cert_op.c
@@ -24,6 +24,13 @@
 #include "dice/ops.h"
 #include "dice/utils.h"
 
+#if DICE_PUBLIC_KEY_SIZE != 32
+#error "Only Ed25519 is supported; 32 bytes needed to store the public key."
+#endif
+#if DICE_SIGNATURE_SIZE != 64
+#error "Only Ed25519 is supported; 64 bytes needed to store the signature."
+#endif
+
 // Max size of COSE_Sign1 including payload.
 static const size_t kMaxCertificateSize = 2048;
 // Max size of COSE_Key encoding.
@@ -50,7 +57,7 @@
   return kDiceResultOk;
 }
 
-static DiceResult EncodePublicKey(uint8_t subject_public_key[32],
+static DiceResult EncodePublicKey(uint8_t subject_public_key[DICE_PUBLIC_KEY_SIZE],
                                   size_t buffer_size, uint8_t* buffer,
                                   size_t* encoded_size) {
   // Constants per RFC 8152.
@@ -82,7 +89,7 @@
   CborWriteInt(kCoseCrvEd25519, &out);
   // Add the subject public key.
   CborWriteInt(kCoseOkpXLabel, &out);
-  CborWriteBstr(/*data_size=*/32, subject_public_key, &out);
+  CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE, subject_public_key, &out);
   if (CborOutOverflowed(&out)) {
     return kDiceResultBufferTooSmall;
   }
@@ -220,7 +227,7 @@
 static DiceResult EncodeCoseSign1(const uint8_t* protected_attributes,
                                   size_t protected_attributes_size,
                                   const uint8_t* payload, size_t payload_size,
-                                  const uint8_t signature[64],
+                                  const uint8_t signature[DICE_SIGNATURE_SIZE],
                                   size_t buffer_size, uint8_t* buffer,
                                   size_t* encoded_size) {
   struct CborOut out;
@@ -234,7 +241,7 @@
   // Payload.
   CborWriteBstr(payload_size, payload, &out);
   // Signature.
-  CborWriteBstr(/*num_elements=*/64, signature, &out);
+  CborWriteBstr(/*num_elements=*/DICE_SIGNATURE_SIZE, signature, &out);
   if (CborOutOverflowed(&out)) {
     return kDiceResultBufferTooSmall;
   }
@@ -257,8 +264,8 @@
   }
 
   // Declare buffers which are cleared on 'goto out'.
-  uint8_t subject_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
-  uint8_t authority_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
+  uint8_t subject_private_key[DICE_PRIVATE_KEY_SIZE];
+  uint8_t authority_private_key[DICE_PRIVATE_KEY_SIZE];
 
   // These are 'variably modified' types so need to be declared upfront.
   uint8_t encoded_public_key[kMaxPublicKeySize];
@@ -266,19 +273,16 @@
   uint8_t protected_attributes[kMaxProtectedAttributesSize];
 
   // Derive keys and IDs from the private key seeds.
-  uint8_t subject_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
-  size_t subject_public_key_size;
-  size_t subject_private_key_size;
+  uint8_t subject_public_key[DICE_PUBLIC_KEY_SIZE];
   result = DiceKeypairFromSeed(context, subject_private_key_seed,
-                               subject_public_key, &subject_public_key_size,
-                               subject_private_key, &subject_private_key_size);
+                               subject_public_key, subject_private_key);
   if (result != kDiceResultOk) {
     goto out;
   }
 
   uint8_t subject_id[20];
   result =
-      DiceDeriveCdiCertificateId(context, subject_public_key, 32, subject_id);
+      DiceDeriveCdiCertificateId(context, subject_public_key, DICE_PUBLIC_KEY_SIZE, subject_id);
   if (result != kDiceResultOk) {
     goto out;
   }
@@ -287,20 +291,16 @@
                 sizeof(subject_id_hex));
   subject_id_hex[sizeof(subject_id_hex) - 1] = '\0';
 
-  uint8_t authority_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
-  size_t authority_public_key_size;
-  size_t authority_private_key_size;
-  result =
-      DiceKeypairFromSeed(context, authority_private_key_seed,
-                          authority_public_key, &authority_public_key_size,
-                          authority_private_key, &authority_private_key_size);
+  uint8_t authority_public_key[DICE_PUBLIC_KEY_SIZE];
+  result = DiceKeypairFromSeed(context, authority_private_key_seed,
+                               authority_public_key, authority_private_key);
   if (result != kDiceResultOk) {
     goto out;
   }
 
   uint8_t authority_id[20];
   result = DiceDeriveCdiCertificateId(context, authority_public_key,
-                                      authority_public_key_size, authority_id);
+                                      DICE_PUBLIC_KEY_SIZE, authority_id);
   if (result != kDiceResultOk) {
     goto out;
   }
@@ -346,16 +346,14 @@
   }
 
   // Sign the TBS with the authority key.
-  uint8_t signature[64];
+  uint8_t signature[DICE_SIGNATURE_SIZE];
   result = DiceSign(context, certificate, *certificate_actual_size,
-                    authority_private_key, authority_private_key_size,
-                    sizeof(signature), signature);
+                    authority_private_key, signature);
   if (result != kDiceResultOk) {
     goto out;
   }
   result = DiceVerify(context, certificate, *certificate_actual_size, signature,
-                      sizeof(signature), authority_public_key,
-                      authority_public_key_size);
+                      authority_public_key);
   if (result != kDiceResultOk) {
     goto out;
   }
diff --git a/src/template_cbor_cert_op.c b/src/template_cbor_cert_op.c
index 21aa186..52eb131 100644
--- a/src/template_cbor_cert_op.c
+++ b/src/template_cbor_cert_op.c
@@ -42,6 +42,13 @@
 #include "dice/ops.h"
 #include "dice/utils.h"
 
+#if DICE_PUBLIC_KEY_SIZE != 32
+#error "Only Ed25519 is supported; 32 bytes needed to store the public key."
+#endif
+#if DICE_SIGNATURE_SIZE != 64
+#error "Only Ed25519 is supported; 64 bytes needed to store the signature."
+#endif
+
 // A well-formed certificate, but with zeros in all fields to be filled.
 static const uint8_t kTemplate[441] = {
     // Constant encoding.
@@ -170,26 +177,23 @@
   }
 
   // Declare buffers which are cleared on 'goto out'.
-  uint8_t subject_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
-  uint8_t authority_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
+  uint8_t subject_private_key[DICE_PRIVATE_KEY_SIZE];
+  uint8_t authority_private_key[DICE_PRIVATE_KEY_SIZE];
 
   // These are 'variably modified' types so need to be declared upfront.
   uint8_t tbs[kTbsSize];
 
   // Derive keys and IDs from the private key seeds.
-  uint8_t subject_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
-  size_t subject_public_key_size;
-  size_t subject_private_key_size;
+  uint8_t subject_public_key[DICE_PUBLIC_KEY_SIZE];
   result = DiceKeypairFromSeed(context, subject_private_key_seed,
-                               subject_public_key, &subject_public_key_size,
-                               subject_private_key, &subject_private_key_size);
+                               subject_public_key, subject_private_key);
   if (result != kDiceResultOk) {
     goto out;
   }
 
   uint8_t subject_id[20];
   result = DiceDeriveCdiCertificateId(context, subject_public_key,
-                                      subject_public_key_size, subject_id);
+                                      DICE_PUBLIC_KEY_SIZE, subject_id);
   if (result != kDiceResultOk) {
     goto out;
   }
@@ -197,20 +201,16 @@
   DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
                 sizeof(subject_id_hex));
 
-  uint8_t authority_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
-  size_t authority_public_key_size;
-  size_t authority_private_key_size;
-  result =
-      DiceKeypairFromSeed(context, authority_private_key_seed,
-                          authority_public_key, &authority_public_key_size,
-                          authority_private_key, &authority_private_key_size);
+  uint8_t authority_public_key[DICE_PUBLIC_KEY_SIZE];
+  result = DiceKeypairFromSeed(context, authority_private_key_seed,
+                               authority_public_key, authority_private_key);
   if (result != kDiceResultOk) {
     goto out;
   }
 
   uint8_t authority_id[20];
   result = DiceDeriveCdiCertificateId(context, authority_public_key,
-                                      authority_public_key_size, authority_id);
+                                      DICE_PUBLIC_KEY_SIZE, authority_id);
   if (result != kDiceResultOk) {
     goto out;
   }
@@ -236,14 +236,12 @@
          &certificate[kFieldTable[kFieldIndexPayload].offset],
          kFieldTable[kFieldIndexPayload].length);
 
-  uint8_t signature[64];
-  result = DiceSign(context, tbs, kTbsSize, authority_private_key,
-                    authority_private_key_size, sizeof(signature), signature);
+  uint8_t signature[DICE_SIGNATURE_SIZE];
+  result = DiceSign(context, tbs, kTbsSize, authority_private_key, signature);
   if (result != kDiceResultOk) {
     goto out;
   }
-  result = DiceVerify(context, tbs, kTbsSize, signature, sizeof(signature),
-                      authority_public_key, authority_public_key_size);
+  result = DiceVerify(context, tbs, kTbsSize, signature, authority_public_key);
   if (result != kDiceResultOk) {
     goto out;
   }