Expose signing operations in DiceOps
The CBOR certificate generator previously had a dependency on boringssl
that meant it couldn't be reused with a different crypto implementation.
Remove the dependency by adding the needed operations to DiceOps so the
client can provide a suitable implementation. There are boringssl
implementations provided that can be used where boringssl is available.
The other certificate generators are tied to a crypto implementation so
don't need these operations to be provided.
Change-Id: Iee27061444da48c6dd2ef4cf91676b45fb227c7c
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/40021
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 1049920..a6290c5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -49,7 +49,7 @@
public = [ "include/dice/dice.h" ]
sources = [
"src/boringssl_cert_op.c",
- "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_hash_kdf_sign_ops.c",
"src/dice.c",
]
deps = [
@@ -73,7 +73,7 @@
pw_static_library("dice_with_cbor_cert") {
public = [ "include/dice/dice.h" ]
sources = [
- "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_hash_kdf_sign_ops.c",
"src/cbor_cert_op.c",
"src/dice.c",
]
@@ -87,7 +87,7 @@
pw_static_library("dice_with_cbor_template_cert") {
public = [ "include/dice/dice.h" ]
sources = [
- "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_hash_kdf_sign_ops.c",
"src/dice.c",
"src/template_cbor_cert_op.c",
]
@@ -100,7 +100,7 @@
pw_static_library("dice_with_x509_template_cert") {
public = [ "include/dice/dice.h" ]
sources = [
- "src/boringssl_hash_kdf_ops.c",
+ "src/boringssl_hash_kdf_sign_ops.c",
"src/dice.c",
"src/template_cert_op.c",
]
diff --git a/include/dice/boringssl_ops.h b/include/dice/boringssl_ops.h
index 51d58cd..410c41d 100644
--- a/include/dice/boringssl_ops.h
+++ b/include/dice/boringssl_ops.h
@@ -33,6 +33,22 @@
const uint8_t* info, size_t info_size,
uint8_t* output);
+DiceResult DiceBsslEd25519KeypairFromSeed(
+ const DiceOps* ops_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);
+
+DiceResult DiceBsslEd25519Sign(const DiceOps* ops, 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);
+
+DiceResult DiceBsslEd25519Verify(const DiceOps* ops, 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);
+
DiceResult DiceBsslGenerateCertificateOp(
const DiceOps* ops,
const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
diff --git a/include/dice/cbor_cert_op.h b/include/dice/cbor_cert_op.h
index bc5b28c..5bf5571 100644
--- a/include/dice/cbor_cert_op.h
+++ b/include/dice/cbor_cert_op.h
@@ -24,6 +24,10 @@
// This function implements the 'DiceOps::generate_certificate' callback
// documented in dice.h. It generates a CWT-style CBOR certificate using the
// ED25519-SHA512 signature scheme.
+//
+// The |keypair_from_seed| and |sign| operations in |ops| are required by this
+// function. |verify| is optional but will be used as a safety check of the
+// signature if it is provided.
DiceResult DiceGenerateCborCertificateOp(
const DiceOps* ops,
const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
diff --git a/include/dice/dice.h b/include/dice/dice.h
index ede56d2..647604f 100644
--- a/include/dice/dice.h
+++ b/include/dice/dice.h
@@ -27,6 +27,8 @@
#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,
@@ -114,6 +116,40 @@
size_t ikm_size, const uint8_t* salt, size_t salt_size,
const uint8_t* info, size_t info_size, uint8_t* output);
+ // Deterministically generates a public and private key pair from |seed|.
+ // Since this is deterministic, |seed| is as sensitive as a private key and
+ // can be used directly as the private key. The |private_key| may use an
+ // implementation defined format so may only be passed to the |sign|
+ // operation.
+ //
+ // This operation is optional unless otherwise documented.
+ DiceResult (*keypair_from_seed)(
+ const DiceOps* ops, 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);
+
+ // 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.
+ //
+ // This operation is optional unless otherwise documented.
+ DiceResult (*sign)(const DiceOps* ops, 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);
+
+ // Verifies, using |public_key|, that |signature| covers |message_size| bytes
+ // from |message|.
+ //
+ // This operation is optional unless otherwise documented.
+ DiceResult (*verify)(const DiceOps* ops, 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);
+
// Generates an X.509 certificate, or an alternative certificate format, from
// the given |subject_private_key_seed| and |input_values|, and signed by
// |authority_private_key_seed|. The subject private key seed is supplied
diff --git a/include/dice/template_cbor_cert_op.h b/include/dice/template_cbor_cert_op.h
index c756701..284a054 100644
--- a/include/dice/template_cbor_cert_op.h
+++ b/include/dice/template_cbor_cert_op.h
@@ -26,12 +26,14 @@
// template using the ED25519-SHA512 signature scheme.
//
// If no variable length descriptors are used in a DICE certificate, the
-// certificate can be constructed from a template instead of using a CBOR / COSE
-// library. This implementation includes only hashes and inline configuration in
-// the certificate fields. For convenience this uses the lower level curve25519
-// implementation in boringssl but does not use any CBOR or COSE library. This
-// approach may be especially useful in very low level components where
-// simplicity is paramount.
+// certificate can be constructed from a template instead of using a CBOR /
+// COSE library. This implementation includes only hashes and inline
+// configuration in the certificate fields. This approach may be especially
+// useful in very low level components where simplicity is paramount.
+//
+// The |keypair_from_seed| and |sign| operations in |ops| are required by this
+// function. |verify| is optional but will be used as a safety check of the
+// signature if it is provided.
//
// This function will return kDiceResultInvalidInput if 'input_values' specifies
// any variable length descriptors. In particular:
diff --git a/src/boringssl_hash_kdf_ops.c b/src/boringssl_hash_kdf_ops.c
deleted file mode 100644
index fb4692b..0000000
--- a/src/boringssl_hash_kdf_ops.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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 <stdint.h>
-
-#include "dice/boringssl_ops.h"
-#include "dice/dice.h"
-#include "openssl/evp.h"
-#include "openssl/hkdf.h"
-#include "openssl/is_boringssl.h"
-#include "openssl/sha.h"
-
-DiceResult DiceBsslHashOp(const DiceOps* ops_not_used, const uint8_t* input,
- size_t input_size, uint8_t output[DICE_HASH_SIZE]) {
- (void)ops_not_used;
- SHA512(input, input_size, output);
- return kDiceResultOk;
-}
-
-DiceResult DiceBsslKdfOp(const DiceOps* ops_not_used, size_t length,
- const uint8_t* ikm, size_t ikm_size,
- const uint8_t* salt, size_t salt_size,
- const uint8_t* info, size_t info_size,
- uint8_t* output) {
- (void)ops_not_used;
- if (!HKDF(output, length, EVP_sha512(), ikm, ikm_size, salt, salt_size, info,
- info_size)) {
- return kDiceResultPlatformError;
- }
- return kDiceResultOk;
-}
diff --git a/src/boringssl_hash_kdf_sign_ops.c b/src/boringssl_hash_kdf_sign_ops.c
new file mode 100644
index 0000000..a1cf5a9
--- /dev/null
+++ b/src/boringssl_hash_kdf_sign_ops.c
@@ -0,0 +1,94 @@
+// 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 <stdint.h>
+
+#include "dice/boringssl_ops.h"
+#include "dice/dice.h"
+#include "openssl/curve25519.h"
+#include "openssl/evp.h"
+#include "openssl/hkdf.h"
+#include "openssl/is_boringssl.h"
+#include "openssl/sha.h"
+
+DiceResult DiceBsslHashOp(const DiceOps* ops_not_used, const uint8_t* input,
+ size_t input_size, uint8_t output[DICE_HASH_SIZE]) {
+ (void)ops_not_used;
+ SHA512(input, input_size, output);
+ return kDiceResultOk;
+}
+
+DiceResult DiceBsslKdfOp(const DiceOps* ops_not_used, size_t length,
+ const uint8_t* ikm, size_t ikm_size,
+ const uint8_t* salt, size_t salt_size,
+ const uint8_t* info, size_t info_size,
+ uint8_t* output) {
+ (void)ops_not_used;
+ if (!HKDF(output, length, EVP_sha512(), ikm, ikm_size, salt, salt_size, info,
+ info_size)) {
+ return kDiceResultPlatformError;
+ }
+ return kDiceResultOk;
+}
+
+DiceResult DiceBsslEd25519KeypairFromSeed(
+ const DiceOps* ops_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) {
+ (void)ops_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 DiceBsslEd25519Sign(const DiceOps* ops_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) {
+ (void)ops_not_used;
+ if (private_key_size != 64 || signature_size != 64) {
+ return kDiceResultPlatformError;
+ }
+ if (1 != ED25519_sign(signature, message, message_size, private_key)) {
+ return kDiceResultPlatformError;
+ }
+ return kDiceResultOk;
+}
+
+DiceResult DiceBsslEd25519Verify(const DiceOps* ops_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) {
+ (void)ops_not_used;
+ if (public_key_size != 32 || signature_size != 64) {
+ return kDiceResultPlatformError;
+ }
+ if (1 != ED25519_verify(message, message_size, signature, public_key)) {
+ return kDiceResultPlatformError;
+ }
+ return kDiceResultOk;
+}
diff --git a/src/cbor_cert_op.c b/src/cbor_cert_op.c
index ac20f68..b8ed738 100644
--- a/src/cbor_cert_op.c
+++ b/src/cbor_cert_op.c
@@ -21,9 +21,6 @@
#include "dice/cbor_writer.h"
#include "dice/dice.h"
#include "dice/utils.h"
-#include "openssl/curve25519.h"
-#include "openssl/is_boringssl.h"
-#include "openssl/sha.h"
// Max size of COSE_Sign1 including payload.
static const size_t kMaxCertificateSize = 2048;
@@ -95,7 +92,8 @@
// Encodes a CBOR Web Token (CWT) with an issuer, subject, and additional
// fields.
-static DiceResult EncodeCwt(const DiceInputValues* input_values,
+static DiceResult EncodeCwt(const DiceOps* ops,
+ const DiceInputValues* input_values,
const char* authority_id_hex,
const char* subject_id_hex,
const uint8_t* encoded_public_key,
@@ -158,8 +156,12 @@
// Add the config inputs.
if (input_values->config_type == kDiceConfigTypeDescriptor) {
uint8_t config_descriptor_hash[DICE_HASH_SIZE];
- SHA512(input_values->config_descriptor,
- input_values->config_descriptor_size, config_descriptor_hash);
+ DiceResult result =
+ ops->hash(ops, input_values->config_descriptor,
+ input_values->config_descriptor_size, config_descriptor_hash);
+ if (result != kDiceResultOk) {
+ return result;
+ }
if (
// Add the config descriptor.
!CborWriteInt(kConfigDescriptorLabel, &out) ||
@@ -277,8 +279,8 @@
}
// Declare buffers which are cleared on 'goto out'.
- uint8_t subject_bssl_private_key[64];
- uint8_t authority_bssl_private_key[64];
+ uint8_t subject_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
+ uint8_t authority_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
// These are 'variably modified' types so need to be declared upfront.
uint8_t encoded_public_key[kMaxPublicKeySize];
@@ -286,9 +288,15 @@
uint8_t protected_attributes[kMaxProtectedAttributesSize];
// Derive keys and IDs from the private key seeds.
- uint8_t subject_public_key[32];
- ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
- subject_private_key_seed);
+ uint8_t subject_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
+ size_t subject_public_key_size;
+ size_t subject_private_key_size;
+ result = ops->keypair_from_seed(
+ ops, subject_private_key_seed, subject_public_key,
+ &subject_public_key_size, subject_private_key, &subject_private_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
uint8_t subject_id[20];
result = DiceDeriveCdiCertificateId(ops, subject_public_key, 32, subject_id);
@@ -300,13 +308,20 @@
sizeof(subject_id_hex));
subject_id_hex[sizeof(subject_id_hex) - 1] = '\0';
- uint8_t authority_public_key[32];
- ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
- authority_private_key_seed);
+ uint8_t authority_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
+ size_t authority_public_key_size;
+ size_t authority_private_key_size;
+ result = ops->keypair_from_seed(
+ ops, authority_private_key_seed, authority_public_key,
+ &authority_public_key_size, authority_private_key,
+ &authority_private_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
uint8_t authority_id[20];
- result =
- DiceDeriveCdiCertificateId(ops, authority_public_key, 32, authority_id);
+ result = DiceDeriveCdiCertificateId(ops, authority_public_key,
+ authority_public_key_size, authority_id);
if (result != kDiceResultOk) {
goto out;
}
@@ -335,7 +350,7 @@
// The CWT is the payload in both the TBS and the final COSE_Sign1 structure.
size_t payload_size = 0;
- result = EncodeCwt(input_values, authority_id_hex, subject_id_hex,
+ result = EncodeCwt(ops, input_values, authority_id_hex, subject_id_hex,
encoded_public_key, encoded_public_key_size,
sizeof(payload), payload, &payload_size);
if (result != kDiceResultOk) {
@@ -353,15 +368,19 @@
// Sign the TBS with the authority key.
uint8_t signature[64];
- if (1 != ED25519_sign(signature, certificate, *certificate_actual_size,
- authority_bssl_private_key)) {
- result = kDiceResultPlatformError;
+ result = ops->sign(ops, certificate, *certificate_actual_size,
+ authority_private_key, authority_private_key_size,
+ sizeof(signature), signature);
+ if (result != kDiceResultOk) {
goto out;
}
- if (1 != ED25519_verify(certificate, *certificate_actual_size, signature,
- authority_public_key)) {
- result = kDiceResultPlatformError;
- goto out;
+ if (ops->verify) {
+ result = ops->verify(ops, certificate, *certificate_actual_size, signature,
+ sizeof(signature), authority_public_key,
+ authority_public_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
}
// The final certificate is an untagged COSE_Sign1 structure.
@@ -370,10 +389,8 @@
signature, certificate_buffer_size, certificate, certificate_actual_size);
out:
- ops->clear_memory(ops, sizeof(subject_bssl_private_key),
- subject_bssl_private_key);
- ops->clear_memory(ops, sizeof(authority_bssl_private_key),
- authority_bssl_private_key);
+ ops->clear_memory(ops, sizeof(subject_private_key), subject_private_key);
+ ops->clear_memory(ops, sizeof(authority_private_key), authority_private_key);
return result;
}
diff --git a/src/cbor_cert_op_test.cc b/src/cbor_cert_op_test.cc
index 1d40bf5..84cee6a 100644
--- a/src/cbor_cert_op_test.cc
+++ b/src/cbor_cert_op_test.cc
@@ -35,11 +35,16 @@
using dice::test::DiceStateForTest;
using dice::test::KeyType_Ed25519;
-constexpr DiceOps kOps = {.context = NULL,
- .hash = DiceBsslHashOp,
- .kdf = DiceBsslKdfOp,
- .generate_certificate = DiceGenerateCborCertificateOp,
- .clear_memory = DiceClearMemory};
+constexpr DiceOps kOps = {
+ .context = NULL,
+ .hash = DiceBsslHashOp,
+ .kdf = DiceBsslKdfOp,
+ .keypair_from_seed = DiceBsslEd25519KeypairFromSeed,
+ .sign = DiceBsslEd25519Sign,
+ .verify = DiceBsslEd25519Verify,
+ .generate_certificate = DiceGenerateCborCertificateOp,
+ .clear_memory = DiceClearMemory,
+};
TEST(DiceOpsTest, KnownAnswerZeroInput) {
DiceStateForTest current_state = {};
diff --git a/src/dice_with_cbor_cert_main.c b/src/dice_with_cbor_cert_main.c
index 7d59308..a0cd67e 100644
--- a/src/dice_with_cbor_cert_main.c
+++ b/src/dice_with_cbor_cert_main.c
@@ -24,6 +24,9 @@
(void)argv;
const DiceOps ops = {.hash = DiceBsslHashOp,
.kdf = DiceBsslKdfOp,
+ .keypair_from_seed = DiceBsslEd25519KeypairFromSeed,
+ .sign = DiceBsslEd25519Sign,
+ .verify = DiceBsslEd25519Verify,
.generate_certificate = DiceGenerateCborCertificateOp,
.clear_memory = DiceClearMemory};
uint8_t cdi_buffer[DICE_CDI_SIZE];
diff --git a/src/dice_with_cbor_template_cert_main.c b/src/dice_with_cbor_template_cert_main.c
index b54f12d..bb131d2 100644
--- a/src/dice_with_cbor_template_cert_main.c
+++ b/src/dice_with_cbor_template_cert_main.c
@@ -25,6 +25,9 @@
const DiceOps ops = {
.hash = DiceBsslHashOp,
.kdf = DiceBsslKdfOp,
+ .keypair_from_seed = DiceBsslEd25519KeypairFromSeed,
+ .sign = DiceBsslEd25519Sign,
+ .verify = DiceBsslEd25519Verify,
.generate_certificate = DiceGenerateCborCertificateFromTemplateOp,
.clear_memory = DiceClearMemory};
uint8_t cdi_buffer[DICE_CDI_SIZE];
diff --git a/src/template_cbor_cert_op.c b/src/template_cbor_cert_op.c
index 7fe9547..96c300b 100644
--- a/src/template_cbor_cert_op.c
+++ b/src/template_cbor_cert_op.c
@@ -24,8 +24,6 @@
#include "dice/dice.h"
#include "dice/utils.h"
-#include "openssl/curve25519.h"
-#include "openssl/is_boringssl.h"
// A well-formed certificate, but with zeros in all fields to be filled.
static const uint8_t kTemplate[441] = {
@@ -155,19 +153,26 @@
}
// Declare buffers which are cleared on 'goto out'.
- uint8_t subject_bssl_private_key[64];
- uint8_t authority_bssl_private_key[64];
+ uint8_t subject_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
+ uint8_t authority_private_key[DICE_PRIVATE_KEY_MAX_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[32];
- ED25519_keypair_from_seed(subject_public_key, subject_bssl_private_key,
- subject_private_key_seed);
+ uint8_t subject_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
+ size_t subject_public_key_size;
+ size_t subject_private_key_size;
+ result = ops->keypair_from_seed(
+ ops, subject_private_key_seed, subject_public_key,
+ &subject_public_key_size, subject_private_key, &subject_private_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
uint8_t subject_id[20];
- result = DiceDeriveCdiCertificateId(ops, subject_public_key, 32, subject_id);
+ result = DiceDeriveCdiCertificateId(ops, subject_public_key,
+ subject_public_key_size, subject_id);
if (result != kDiceResultOk) {
goto out;
}
@@ -175,13 +180,20 @@
DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
sizeof(subject_id_hex));
- uint8_t authority_public_key[32];
- ED25519_keypair_from_seed(authority_public_key, authority_bssl_private_key,
- authority_private_key_seed);
+ uint8_t authority_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
+ size_t authority_public_key_size;
+ size_t authority_private_key_size;
+ result = ops->keypair_from_seed(
+ ops, authority_private_key_seed, authority_public_key,
+ &authority_public_key_size, authority_private_key,
+ &authority_private_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
uint8_t authority_id[20];
- result =
- DiceDeriveCdiCertificateId(ops, authority_public_key, 32, authority_id);
+ result = DiceDeriveCdiCertificateId(ops, authority_public_key,
+ authority_public_key_size, authority_id);
if (result != kDiceResultOk) {
goto out;
}
@@ -208,20 +220,22 @@
kFieldTable[kFieldIndexPayload].length);
uint8_t signature[64];
- if (1 != ED25519_sign(signature, tbs, kTbsSize, authority_bssl_private_key)) {
- result = kDiceResultPlatformError;
+ result = ops->sign(ops, tbs, kTbsSize, authority_private_key,
+ authority_private_key_size, sizeof(signature), signature);
+ if (result != kDiceResultOk) {
goto out;
}
- if (1 != ED25519_verify(tbs, kTbsSize, signature, authority_public_key)) {
- result = kDiceResultPlatformError;
- goto out;
+ if (ops->verify) {
+ result = ops->verify(ops, tbs, kTbsSize, signature, sizeof(signature),
+ authority_public_key, authority_public_key_size);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
}
CopyField(signature, kFieldIndexSignature, certificate);
out:
- ops->clear_memory(ops, sizeof(subject_bssl_private_key),
- subject_bssl_private_key);
- ops->clear_memory(ops, sizeof(authority_bssl_private_key),
- authority_bssl_private_key);
+ ops->clear_memory(ops, sizeof(subject_private_key), subject_private_key);
+ ops->clear_memory(ops, sizeof(authority_private_key), authority_private_key);
return result;
}
diff --git a/src/template_cbor_cert_op_test.cc b/src/template_cbor_cert_op_test.cc
index 5626224..d41535c 100644
--- a/src/template_cbor_cert_op_test.cc
+++ b/src/template_cbor_cert_op_test.cc
@@ -39,6 +39,9 @@
.context = NULL,
.hash = DiceBsslHashOp,
.kdf = DiceBsslKdfOp,
+ .keypair_from_seed = DiceBsslEd25519KeypairFromSeed,
+ .sign = DiceBsslEd25519Sign,
+ .verify = DiceBsslEd25519Verify,
.generate_certificate = DiceGenerateCborCertificateFromTemplateOp,
.clear_memory = DiceClearMemory};