Configure with functions instead of constants
This is a breaking change of the config API.
Replace config constants with functions that allow the values to be
determined dynamically based on the context. This enables more flexible
variants of the library that can adapt behaviour at runtime. Some
constants still remain, for example those that define the size of
statically allocated buffers for the keys and signatures.
Bug: b/357008987
Change-Id: I1ce7afaa7722e47b470bd2f7d963808d347cc40b
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/223471
Reviewed-by: Darren Krahn <dkrahn@google.com>
Commit-Queue: Darren Krahn <dkrahn@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/BUILD.gn b/BUILD.gn
index eb43c80..ccce484 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -147,7 +147,6 @@
"src/boringssl_ed25519_ops.c",
"src/boringssl_hash_kdf_ops.c",
"src/cbor_cert_op.c",
- "src/cbor_ed25519_cert_op.c",
"src/clear_memory.c",
"src/dice.c",
"src/utils.c",
@@ -178,7 +177,6 @@
"src/boringssl_hash_kdf_ops.c",
"src/boringssl_p256_ops.c",
"src/cbor_cert_op.c",
- "src/cbor_p256_cert_op.c",
"src/clear_memory.c",
"src/dice.c",
"src/utils.c",
@@ -200,7 +198,6 @@
"src/boringssl_hash_kdf_ops.c",
"src/boringssl_p384_ops.c",
"src/cbor_cert_op.c",
- "src/cbor_p384_cert_op.c",
"src/clear_memory.c",
"src/dice.c",
"src/utils.c",
diff --git a/include/dice/config/boringssl_ecdsa_p256/dice/config.h b/include/dice/config/boringssl_ecdsa_p256/dice/config.h
index 6011005..126c31d 100644
--- a/include/dice/config/boringssl_ecdsa_p256/dice/config.h
+++ b/include/dice/config/boringssl_ecdsa_p256/dice/config.h
@@ -17,10 +17,8 @@
// ECDSA P256
// From table 1 of RFC 9053
-#define DICE_COSE_KEY_ALG_VALUE (-7)
#define DICE_PUBLIC_KEY_BUFFER_SIZE 64
#define DICE_PRIVATE_KEY_SIZE 32
#define DICE_SIGNATURE_BUFFER_SIZE 64
-#define DICE_PROFILE_NAME "opendice.example.p256"
#endif // DICE_CONFIG_BORINGSSL_ECDSA_P256_DICE_DICE_CONFIG_H_
diff --git a/include/dice/config/boringssl_ecdsa_p384/dice/config.h b/include/dice/config/boringssl_ecdsa_p384/dice/config.h
index a405ce8..ea4dc5f 100644
--- a/include/dice/config/boringssl_ecdsa_p384/dice/config.h
+++ b/include/dice/config/boringssl_ecdsa_p384/dice/config.h
@@ -17,10 +17,8 @@
// ECDSA P384
// From table 1 of RFC 9053
-#define DICE_COSE_KEY_ALG_VALUE (-35)
#define DICE_PUBLIC_KEY_BUFFER_SIZE 96
#define DICE_PRIVATE_KEY_SIZE 48
#define DICE_SIGNATURE_BUFFER_SIZE 96
-#define DICE_PROFILE_NAME "opendice.example.p384"
#endif // DICE_CONFIG_BORINGSSL_ECDSA_P384_DICE_DICE_CONFIG_H_
diff --git a/include/dice/config/boringssl_ed25519/dice/config.h b/include/dice/config/boringssl_ed25519/dice/config.h
index 973bcbd..c44f4c1 100644
--- a/include/dice/config/boringssl_ed25519/dice/config.h
+++ b/include/dice/config/boringssl_ed25519/dice/config.h
@@ -17,10 +17,8 @@
// Ed25519
// COSE Key alg value from Table 2 of RFC9053
-#define DICE_COSE_KEY_ALG_VALUE (-8)
#define DICE_PUBLIC_KEY_BUFFER_SIZE 32
#define DICE_PRIVATE_KEY_SIZE 64
#define DICE_SIGNATURE_BUFFER_SIZE 64
-#define DICE_PROFILE_NAME NULL
#endif // DICE_CONFIG_BORINGSSL_ED25519_DICE_DICE_CONFIG_H_
diff --git a/include/dice/config/cose_key_config.h b/include/dice/config/cose_key_config.h
new file mode 100644
index 0000000..e6a27db
--- /dev/null
+++ b/include/dice/config/cose_key_config.h
@@ -0,0 +1,41 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#ifndef DICE_CONFIG_COSE_KEY_CONFIG_H_
+#define DICE_CONFIG_COSE_KEY_CONFIG_H_
+
+#include <stdint.h>
+
+// Constants per RFC 8152.
+static const int64_t kCoseKeyKtyLabel = 1;
+static const int64_t kCoseKeyKtyOkp = 1;
+static const int64_t kCoseKeyKtyEc2 = 2;
+static const int64_t kCoseKeyAlgLabel = 3;
+static const int64_t kCoseKeyOpsLabel = 4;
+static const int64_t kCoseKeyOpsVerify = 2;
+static const int64_t kCoseKeyCrvLabel = -1;
+static const int64_t kCoseKeyXLabel = -2;
+static const int64_t kCoseKeyYLabel = -3;
+
+// Constants for Ed25519 keys.
+static const int64_t kCoseAlgEdDsa = -8;
+static const int64_t kCoseCrvEd25519 = 6;
+
+// Constants for ECDSA P-256/P-384 keys.
+static const int64_t kCoseAlgEs256 = -7;
+static const int64_t kCoseCrvP256 = 1;
+static const int64_t kCoseAlgEs384 = -35;
+static const int64_t kCoseCrvP384 = 2;
+
+#endif // DICE_CONFIG_COSE_KEY_CONFIG_H_
diff --git a/include/dice/ops.h b/include/dice/ops.h
index f4bcd88..a6074ae 100644
--- a/include/dice/ops.h
+++ b/include/dice/ops.h
@@ -26,6 +26,10 @@
extern "C" {
#endif
+// Retrieves the DICE key parameters based on the key pair generation
+// algorithm set up at compile time or in the |context| parameter at runtime.
+DiceResult DiceGetKeyParam(void* context, DiceKeyParam* key_param);
+
// An implementation of SHA-512, or an alternative hash. Hashes |input_size|
// bytes of |input| and populates |output| on success.
DiceResult DiceHash(void* context, const uint8_t* input, size_t input_size,
diff --git a/include/dice/types.h b/include/dice/types.h
index 99050c8..38eebc6 100644
--- a/include/dice/types.h
+++ b/include/dice/types.h
@@ -15,6 +15,9 @@
#ifndef DICE_TYPES_H_
#define DICE_TYPES_H_
+#include <stddef.h>
+#include <stdint.h>
+
typedef enum {
kDiceResultOk,
kDiceResultInvalidInput,
@@ -34,4 +37,24 @@
kDiceConfigTypeDescriptor,
} DiceConfigType;
+// Parameters related to the DICE key operations.
+//
+// Fields:
+// profile_name: Name of the profile. NULL if not specified. The pointer
+// should point to a valid static string or NULL.
+// public_key_size: Actual size of the public key.
+// signature_size: Actual size of the signature.
+// cose_key_type: Key type that is represented as the 'kty' member of the
+// COSE_Key object as per RFC 8152.
+// cose_key_algorithm: COSE algorithm identifier for the key.
+// cose_key_curve: COSE curve identifier for the key.
+typedef struct DiceKeyParam_ {
+ const char* profile_name;
+ size_t public_key_size;
+ size_t signature_size;
+ int64_t cose_key_type;
+ int64_t cose_key_algorithm;
+ int64_t cose_key_curve;
+} DiceKeyParam;
+
#endif // DICE_TYPES_H_
diff --git a/src/boringssl_cert_op.c b/src/boringssl_cert_op.c
index 9ece559..18fdc4e 100644
--- a/src/boringssl_cert_op.c
+++ b/src/boringssl_cert_op.c
@@ -310,7 +310,8 @@
return result;
}
-static DiceResult GetDiceExtensionData(const DiceInputValues* input_values,
+static DiceResult GetDiceExtensionData(const char* profile_name,
+ const DiceInputValues* input_values,
size_t buffer_size, uint8_t* buffer,
size_t* actual_size) {
DiceResult result = kDiceResultOk;
@@ -430,14 +431,14 @@
}
// Encode profile name.
- if (DICE_PROFILE_NAME) {
+ if (profile_name) {
asn1->profile_name = ASN1_UTF8STRING_new();
if (!asn1->profile_name) {
result = kDiceResultPlatformError;
goto out;
}
- if (!ASN1_STRING_set(asn1->profile_name, DICE_PROFILE_NAME,
- strlen(DICE_PROFILE_NAME))) {
+ if (!ASN1_STRING_set(asn1->profile_name, profile_name,
+ strlen(profile_name))) {
result = kDiceResultPlatformError;
goto out;
}
@@ -457,7 +458,8 @@
return result;
}
-static DiceResult AddDiceExtension(const DiceInputValues* input_values,
+static DiceResult AddDiceExtension(const char* profile_name,
+ const DiceInputValues* input_values,
X509* x509) {
const char* kDiceExtensionOid = "1.3.6.1.4.1.11129.2.1.24";
@@ -469,7 +471,7 @@
uint8_t extension_buffer[DICE_MAX_EXTENSION_SIZE];
size_t extension_size = 0;
DiceResult result =
- GetDiceExtensionData(input_values, sizeof(extension_buffer),
+ GetDiceExtensionData(profile_name, input_values, sizeof(extension_buffer),
extension_buffer, &extension_size);
if (result != kDiceResultOk) {
goto out;
@@ -582,7 +584,12 @@
if (result != kDiceResultOk) {
goto out;
}
- result = AddDiceExtension(input_values, x509);
+ DiceKeyParam key_param;
+ result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
+ result = AddDiceExtension(key_param.profile_name, input_values, x509);
if (result != kDiceResultOk) {
goto out;
}
diff --git a/src/boringssl_ed25519_ops.c b/src/boringssl_ed25519_ops.c
index 480b19f..947e99d 100644
--- a/src/boringssl_ed25519_ops.c
+++ b/src/boringssl_ed25519_ops.c
@@ -16,6 +16,7 @@
#include <stdint.h>
+#include "dice/config/cose_key_config.h"
#include "dice/dice.h"
#include "dice/ops.h"
#include "openssl/curve25519.h"
@@ -33,6 +34,20 @@
#error "Ed25519 needs 64 bytes to store the signature."
#endif
+#define DICE_PROFILE_NAME NULL
+
+DiceResult DiceGetKeyParam(void* context_not_used, DiceKeyParam* key_param) {
+ (void)context_not_used;
+ key_param->profile_name = DICE_PROFILE_NAME;
+ key_param->public_key_size = DICE_PUBLIC_KEY_BUFFER_SIZE;
+ key_param->signature_size = DICE_SIGNATURE_BUFFER_SIZE;
+
+ key_param->cose_key_type = kCoseKeyKtyOkp;
+ key_param->cose_key_algorithm = kCoseAlgEdDsa;
+ key_param->cose_key_curve = kCoseCrvEd25519;
+ return kDiceResultOk;
+}
+
DiceResult DiceKeypairFromSeed(void* context_not_used,
const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],
diff --git a/src/boringssl_p256_ops.c b/src/boringssl_p256_ops.c
index 3fef13a..fcb61b2 100644
--- a/src/boringssl_p256_ops.c
+++ b/src/boringssl_p256_ops.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include "dice/boringssl_ecdsa_utils.h"
+#include "dice/config/cose_key_config.h"
#include "dice/dice.h"
#include "dice/ops.h"
@@ -34,6 +35,20 @@
#error "P-256 needs 64 bytes to store the signature."
#endif
+#define DICE_PROFILE_NAME "opendice.example.p256"
+
+DiceResult DiceGetKeyParam(void* context_not_used, DiceKeyParam* key_param) {
+ (void)context_not_used;
+ key_param->profile_name = DICE_PROFILE_NAME;
+ key_param->public_key_size = DICE_PUBLIC_KEY_BUFFER_SIZE;
+ key_param->signature_size = DICE_SIGNATURE_BUFFER_SIZE;
+
+ key_param->cose_key_type = kCoseKeyKtyEc2;
+ key_param->cose_key_algorithm = kCoseAlgEs256;
+ key_param->cose_key_curve = kCoseCrvP256;
+ return kDiceResultOk;
+}
+
DiceResult DiceKeypairFromSeed(void* context_not_used,
const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],
diff --git a/src/boringssl_p384_ops.c b/src/boringssl_p384_ops.c
index 5c94afc..7d326e1 100644
--- a/src/boringssl_p384_ops.c
+++ b/src/boringssl_p384_ops.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include "dice/boringssl_ecdsa_utils.h"
+#include "dice/config/cose_key_config.h"
#include "dice/dice.h"
#include "dice/ops.h"
@@ -34,6 +35,20 @@
#error "P-384 needs 96 bytes to store the signature."
#endif
+#define DICE_PROFILE_NAME "opendice.example.p384"
+
+DiceResult DiceGetKeyParam(void* context_not_used, DiceKeyParam* key_param) {
+ (void)context_not_used;
+ key_param->profile_name = DICE_PROFILE_NAME;
+ key_param->public_key_size = DICE_PUBLIC_KEY_BUFFER_SIZE;
+ key_param->signature_size = DICE_SIGNATURE_BUFFER_SIZE;
+
+ key_param->cose_key_type = kCoseKeyKtyEc2;
+ key_param->cose_key_algorithm = kCoseAlgEs384;
+ key_param->cose_key_curve = kCoseCrvP384;
+ return kDiceResultOk;
+}
+
DiceResult DiceKeypairFromSeed(void* context_not_used,
const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE],
uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],
diff --git a/src/cbor_cert_op.c b/src/cbor_cert_op.c
index 2e9605b..c9a414b 100644
--- a/src/cbor_cert_op.c
+++ b/src/cbor_cert_op.c
@@ -21,6 +21,7 @@
#include <string.h>
#include "dice/cbor_writer.h"
+#include "dice/config/cose_key_config.h"
#include "dice/dice.h"
#include "dice/ops.h"
#include "dice/ops/trait/cose.h"
@@ -31,7 +32,8 @@
// Max size of the COSE_Sign1 protected attributes.
#define DICE_MAX_PROTECTED_ATTRIBUTES_SIZE 16
-static DiceResult EncodeProtectedAttributes(size_t buffer_size, uint8_t* buffer,
+static DiceResult EncodeProtectedAttributes(void* context, size_t buffer_size,
+ uint8_t* buffer,
size_t* encoded_size) {
// Constants per RFC 8152.
const int64_t kCoseHeaderAlgLabel = 1;
@@ -40,8 +42,13 @@
CborOutInit(buffer, buffer_size, &out);
CborWriteMap(/*num_elements=*/1, &out);
// Add the algorithm.
+ DiceKeyParam key_param;
+ DiceResult result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ return result;
+ }
CborWriteInt(kCoseHeaderAlgLabel, &out);
- CborWriteInt(DICE_COSE_KEY_ALG_VALUE, &out);
+ CborWriteInt(key_param.cose_key_algorithm, &out);
*encoded_size = CborOutSize(&out);
if (CborOutOverflowed(&out)) {
return kDiceResultBufferTooSmall;
@@ -75,8 +82,9 @@
}
static DiceResult EncodeCoseSign1(
- const uint8_t* protected_attributes, size_t protected_attributes_size,
- const uint8_t* payload, size_t payload_size, bool move_payload,
+ void* context, const uint8_t* protected_attributes,
+ size_t protected_attributes_size, const uint8_t* payload,
+ size_t payload_size, bool move_payload,
const uint8_t signature[DICE_SIGNATURE_BUFFER_SIZE], size_t buffer_size,
uint8_t* buffer, size_t* encoded_size) {
struct CborOut out;
@@ -103,8 +111,13 @@
} else {
CborWriteBstr(payload_size, payload, &out);
}
+ DiceKeyParam key_param;
+ DiceResult result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ return result;
+ }
// Signature.
- CborWriteBstr(/*num_elements=*/DICE_SIGNATURE_BUFFER_SIZE, signature, &out);
+ CborWriteBstr(/*num_elements=*/key_param.signature_size, signature, &out);
*encoded_size = CborOutSize(&out);
if (CborOutOverflowed(&out)) {
return kDiceResultBufferTooSmall;
@@ -125,7 +138,7 @@
// COSE_Sign1 structure.
uint8_t protected_attributes[DICE_MAX_PROTECTED_ATTRIBUTES_SIZE];
size_t protected_attributes_size = 0;
- result = EncodeProtectedAttributes(sizeof(protected_attributes),
+ result = EncodeProtectedAttributes(context, sizeof(protected_attributes),
protected_attributes,
&protected_attributes_size);
if (result != kDiceResultOk) {
@@ -141,9 +154,10 @@
if (result != kDiceResultOk) {
// Check how big the buffer needs to be in total.
size_t final_encoded_size = 0;
- EncodeCoseSign1(protected_attributes, protected_attributes_size, payload,
- payload_size, /*move_payload=*/false, /*signature=*/NULL,
- /*buffer_size=*/0, /*buffer=*/NULL, &final_encoded_size);
+ EncodeCoseSign1(context, protected_attributes, protected_attributes_size,
+ payload, payload_size, /*move_payload=*/false,
+ /*signature=*/NULL, /*buffer_size=*/0, /*buffer=*/NULL,
+ &final_encoded_size);
if (*encoded_size < final_encoded_size) {
*encoded_size = final_encoded_size;
}
@@ -159,9 +173,10 @@
}
// The final certificate is an untagged COSE_Sign1 structure.
- return EncodeCoseSign1(protected_attributes, protected_attributes_size,
- payload, payload_size, /*move_payload=*/false,
- signature, buffer_size, buffer, encoded_size);
+ return EncodeCoseSign1(context, protected_attributes,
+ protected_attributes_size, payload, payload_size,
+ /*move_payload=*/false, signature, buffer_size, buffer,
+ encoded_size);
}
// Encodes a CBOR Web Token (CWT) with an issuer, subject, and additional
@@ -202,7 +217,13 @@
if (input_values->authority_descriptor_size > 0) {
map_pairs += 1;
}
- if (DICE_PROFILE_NAME) {
+
+ DiceKeyParam key_param;
+ DiceResult result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ return result;
+ }
+ if (key_param.profile_name) {
map_pairs += 1;
}
@@ -229,9 +250,9 @@
uint8_t config_descriptor_hash[DICE_HASH_SIZE];
// Skip hashing if we're not going to use the answer.
if (!CborOutOverflowed(&out)) {
- DiceResult result = DiceHash(context, input_values->config_descriptor,
- input_values->config_descriptor_size,
- config_descriptor_hash);
+ result = DiceHash(context, input_values->config_descriptor,
+ input_values->config_descriptor_size,
+ config_descriptor_hash);
if (result != kDiceResultOk) {
return result;
}
@@ -268,9 +289,9 @@
CborWriteInt(kKeyUsageLabel, &out);
CborWriteBstr(/*data_size=*/1, &key_usage, &out);
// Add the profile name
- if (DICE_PROFILE_NAME) {
+ if (key_param.profile_name) {
CborWriteInt(kProfileNameLabel, &out);
- CborWriteTstr(DICE_PROFILE_NAME, &out);
+ CborWriteTstr(key_param.profile_name, &out);
}
*encoded_size = CborOutSize(&out);
if (CborOutOverflowed(&out)) {
@@ -305,9 +326,15 @@
goto out;
}
+ DiceKeyParam key_param;
+ result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
+
uint8_t subject_id[DICE_ID_SIZE];
result = DiceDeriveCdiCertificateId(context, subject_public_key,
- DICE_PUBLIC_KEY_BUFFER_SIZE, subject_id);
+ key_param.public_key_size, subject_id);
if (result != kDiceResultOk) {
goto out;
}
@@ -324,8 +351,8 @@
}
uint8_t authority_id[DICE_ID_SIZE];
- result = DiceDeriveCdiCertificateId(
- context, authority_public_key, DICE_PUBLIC_KEY_BUFFER_SIZE, authority_id);
+ result = DiceDeriveCdiCertificateId(context, authority_public_key,
+ key_param.public_key_size, authority_id);
if (result != kDiceResultOk) {
goto out;
}
@@ -349,7 +376,7 @@
// COSE_Sign1 structure.
uint8_t protected_attributes[DICE_MAX_PROTECTED_ATTRIBUTES_SIZE];
size_t protected_attributes_size = 0;
- result = EncodeProtectedAttributes(sizeof(protected_attributes),
+ result = EncodeProtectedAttributes(context, sizeof(protected_attributes),
protected_attributes,
&protected_attributes_size);
if (result != kDiceResultOk) {
@@ -381,9 +408,10 @@
// we need is either the amount needed for the TBS, or the amount needed for
// encoded payload and signature.
size_t final_encoded_size = 0;
- EncodeCoseSign1(protected_attributes, protected_attributes_size, cwt_ptr,
- cwt_size, /*move_payload=*/false, /*signature=*/NULL,
- /*buffer_size=*/0, /*buffer=*/NULL, &final_encoded_size);
+ EncodeCoseSign1(context, protected_attributes, protected_attributes_size,
+ cwt_ptr, cwt_size, /*move_payload=*/false,
+ /*signature=*/NULL, /*buffer_size=*/0, /*buffer=*/NULL,
+ &final_encoded_size);
*certificate_actual_size =
final_encoded_size > tbs_size ? final_encoded_size : tbs_size;
result = kDiceResultBufferTooSmall;
@@ -412,10 +440,10 @@
// And now we can produce the complete CoseSign1, including the signature, and
// moving the payload into place as we do it.
- result = EncodeCoseSign1(protected_attributes, protected_attributes_size,
- cwt_ptr, cwt_size, /*move_payload=*/true, signature,
- certificate_buffer_size, certificate,
- certificate_actual_size);
+ result = EncodeCoseSign1(
+ context, protected_attributes, protected_attributes_size, cwt_ptr,
+ cwt_size, /*move_payload=*/true, signature, certificate_buffer_size,
+ certificate, certificate_actual_size);
out:
DiceClearMemory(context, sizeof(subject_private_key), subject_private_key);
@@ -424,3 +452,54 @@
return result;
}
+
+DiceResult DiceCoseEncodePublicKey(
+ void* context, const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE],
+ size_t buffer_size, uint8_t* buffer, size_t* encoded_size) {
+ DiceKeyParam key_param;
+ DiceResult result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ return result;
+ }
+ struct CborOut out;
+ CborOutInit(buffer, buffer_size, &out);
+ if (key_param.cose_key_type == kCoseKeyKtyOkp) {
+ CborWriteMap(/*num_pairs=*/5, &out);
+ } else if (key_param.cose_key_type == kCoseKeyKtyEc2) {
+ CborWriteMap(/*num_pairs=*/6, &out);
+ } else {
+ return kDiceResultInvalidInput;
+ }
+ // Add the key type.
+ CborWriteInt(kCoseKeyKtyLabel, &out);
+ CborWriteInt(key_param.cose_key_type, &out);
+ // Add the algorithm.
+ CborWriteInt(kCoseKeyAlgLabel, &out);
+ CborWriteInt(key_param.cose_key_algorithm, &out);
+ // Add the KeyOps.
+ CborWriteInt(kCoseKeyOpsLabel, &out);
+ CborWriteArray(/*num_elements=*/1, &out);
+ CborWriteInt(kCoseKeyOpsVerify, &out);
+ // Add the curve.
+ CborWriteInt(kCoseKeyCrvLabel, &out);
+ CborWriteInt(key_param.cose_key_curve, &out);
+
+ // Add the public key.
+ if (key_param.cose_key_type == kCoseKeyKtyOkp) {
+ CborWriteInt(kCoseKeyXLabel, &out);
+ CborWriteBstr(key_param.public_key_size, public_key, &out);
+ } else if (key_param.cose_key_type == kCoseKeyKtyEc2) {
+ // Add the subject public key x and y coordinates
+ int xy_param_size = key_param.public_key_size / 2;
+ CborWriteInt(kCoseKeyXLabel, &out);
+ CborWriteBstr(xy_param_size, &public_key[0], &out);
+ CborWriteInt(kCoseKeyYLabel, &out);
+ CborWriteBstr(xy_param_size, &public_key[xy_param_size], &out);
+ }
+
+ *encoded_size = CborOutSize(&out);
+ if (CborOutOverflowed(&out)) {
+ return kDiceResultBufferTooSmall;
+ }
+ return kDiceResultOk;
+}
diff --git a/src/cbor_ed25519_cert_op.c b/src/cbor_ed25519_cert_op.c
deleted file mode 100644
index 085a9c0..0000000
--- a/src/cbor_ed25519_cert_op.c
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2023 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 <string.h>
-
-#include "dice/cbor_writer.h"
-#include "dice/ops/trait/cose.h"
-
-#if DICE_PUBLIC_KEY_BUFFER_SIZE != 32
-#error "Only Ed25519 is supported; 32 bytes needed to store the public key."
-#endif
-#if DICE_SIGNATURE_BUFFER_SIZE != 64
-#error "Only Ed25519 is supported; 64 bytes needed to store the signature."
-#endif
-
-DiceResult DiceCoseEncodePublicKey(
- void* context_not_used,
- const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE], size_t buffer_size,
- uint8_t* buffer, size_t* encoded_size) {
- (void)context_not_used;
-
- // Constants per RFC 8152.
- const int64_t kCoseKeyKtyLabel = 1;
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyOpsLabel = 4;
- const int64_t kCoseOkpCrvLabel = -1;
- const int64_t kCoseOkpXLabel = -2;
- const int64_t kCoseKeyTypeOkp = 1;
- const int64_t kCoseAlgEdDSA = DICE_COSE_KEY_ALG_VALUE;
- const int64_t kCoseKeyOpsVerify = 2;
- const int64_t kCoseCrvEd25519 = 6;
-
- struct CborOut out;
- CborOutInit(buffer, buffer_size, &out);
- CborWriteMap(/*num_pairs=*/5, &out);
- // Add the key type.
- CborWriteInt(kCoseKeyKtyLabel, &out);
- CborWriteInt(kCoseKeyTypeOkp, &out);
- // Add the algorithm.
- CborWriteInt(kCoseKeyAlgLabel, &out);
- CborWriteInt(kCoseAlgEdDSA, &out);
- // Add the KeyOps.
- CborWriteInt(kCoseKeyOpsLabel, &out);
- CborWriteArray(/*num_elements=*/1, &out);
- CborWriteInt(kCoseKeyOpsVerify, &out);
- // Add the curve.
- CborWriteInt(kCoseOkpCrvLabel, &out);
- CborWriteInt(kCoseCrvEd25519, &out);
- // Add the public key.
- CborWriteInt(kCoseOkpXLabel, &out);
- CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_BUFFER_SIZE, public_key, &out);
-
- *encoded_size = CborOutSize(&out);
- if (CborOutOverflowed(&out)) {
- return kDiceResultBufferTooSmall;
- }
- return kDiceResultOk;
-}
diff --git a/src/cbor_p256_cert_op.c b/src/cbor_p256_cert_op.c
deleted file mode 100644
index 1697b0e..0000000
--- a/src/cbor_p256_cert_op.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2024 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// This is a DiceGenerateCertificate implementation that generates a CWT-style
-// CBOR certificate using the P-256 signature algorithm.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "dice/cbor_writer.h"
-#include "dice/dice.h"
-#include "dice/ops.h"
-#include "dice/ops/trait/cose.h"
-#include "dice/utils.h"
-
-#if DICE_PUBLIC_KEY_BUFFER_SIZE != 64
-#error "64 bytes needed to store the public key."
-#endif
-#if DICE_SIGNATURE_BUFFER_SIZE != 64
-#error "64 bytes needed to store the signature."
-#endif
-
-DiceResult DiceCoseEncodePublicKey(
- void* context_not_used,
- const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE], size_t buffer_size,
- uint8_t* buffer, size_t* encoded_size) {
- (void)context_not_used;
-
- // Constants per RFC 8152.
- const int64_t kCoseKeyKtyLabel = 1;
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyAlgValue = DICE_COSE_KEY_ALG_VALUE;
- const int64_t kCoseKeyOpsLabel = 4;
- const int64_t kCoseKeyOpsValue = 2; // Verify
- const int64_t kCoseKeyKtyValue = 2; // EC2
- const int64_t kCoseEc2CrvLabel = -1;
- const int64_t kCoseEc2CrvValue = 1; // P-256
- const int64_t kCoseEc2XLabel = -2;
- const int64_t kCoseEc2YLabel = -3;
-
- struct CborOut out;
- CborOutInit(buffer, buffer_size, &out);
- CborWriteMap(/*num_pairs=*/6, &out);
- // Add the key type.
- CborWriteInt(kCoseKeyKtyLabel, &out);
- CborWriteInt(kCoseKeyKtyValue, &out);
- // Add the algorithm.
- CborWriteInt(kCoseKeyAlgLabel, &out);
- CborWriteInt(kCoseKeyAlgValue, &out);
- // Add the KeyOps.
- CborWriteInt(kCoseKeyOpsLabel, &out);
- CborWriteArray(/*num_elements=*/1, &out);
- CborWriteInt(kCoseKeyOpsValue, &out);
- // Add the curve.
- CborWriteInt(kCoseEc2CrvLabel, &out);
- CborWriteInt(kCoseEc2CrvValue, &out);
- // Add the subject public key x and y coordinates
- CborWriteInt(kCoseEc2XLabel, &out);
- CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_BUFFER_SIZE / 2, &public_key[0],
- &out);
- CborWriteInt(kCoseEc2YLabel, &out);
- CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_BUFFER_SIZE / 2,
- &public_key[DICE_PUBLIC_KEY_BUFFER_SIZE / 2], &out);
-
- *encoded_size = CborOutSize(&out);
- if (CborOutOverflowed(&out)) {
- return kDiceResultBufferTooSmall;
- }
- return kDiceResultOk;
-}
diff --git a/src/cbor_p384_cert_op.c b/src/cbor_p384_cert_op.c
deleted file mode 100644
index de623ed..0000000
--- a/src/cbor_p384_cert_op.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2023 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// This is a DiceGenerateCertificate implementation that generates a CWT-style
-// CBOR certificate using the P-384 signature algorithm.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "dice/cbor_writer.h"
-#include "dice/dice.h"
-#include "dice/ops.h"
-#include "dice/ops/trait/cose.h"
-#include "dice/utils.h"
-
-#if DICE_PUBLIC_KEY_BUFFER_SIZE != 96
-#error "96 bytes needed to store the public key."
-#endif
-#if DICE_SIGNATURE_BUFFER_SIZE != 96
-#error "96 bytes needed to store the signature."
-#endif
-
-DiceResult DiceCoseEncodePublicKey(
- void* context_not_used,
- const uint8_t public_key[DICE_PUBLIC_KEY_BUFFER_SIZE], size_t buffer_size,
- uint8_t* buffer, size_t* encoded_size) {
- (void)context_not_used;
-
- // Constants per RFC 8152.
- const int64_t kCoseKeyKtyLabel = 1;
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyAlgValue = DICE_COSE_KEY_ALG_VALUE;
- const int64_t kCoseKeyOpsLabel = 4;
- const int64_t kCoseKeyOpsValue = 2; // Verify
- const int64_t kCoseKeyKtyValue = 2; // EC2
- const int64_t kCoseEc2CrvLabel = -1;
- const int64_t kCoseEc2CrvValue = 2; // P-384
- const int64_t kCoseEc2XLabel = -2;
- const int64_t kCoseEc2YLabel = -3;
-
- struct CborOut out;
- CborOutInit(buffer, buffer_size, &out);
- CborWriteMap(/*num_pairs=*/6, &out);
- // Add the key type.
- CborWriteInt(kCoseKeyKtyLabel, &out);
- CborWriteInt(kCoseKeyKtyValue, &out);
- // Add the algorithm.
- CborWriteInt(kCoseKeyAlgLabel, &out);
- CborWriteInt(kCoseKeyAlgValue, &out);
- // Add the KeyOps.
- CborWriteInt(kCoseKeyOpsLabel, &out);
- CborWriteArray(/*num_elements=*/1, &out);
- CborWriteInt(kCoseKeyOpsValue, &out);
- // Add the curve.
- CborWriteInt(kCoseEc2CrvLabel, &out);
- CborWriteInt(kCoseEc2CrvValue, &out);
- // Add the subject public key x and y coordinates
- CborWriteInt(kCoseEc2XLabel, &out);
- CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_BUFFER_SIZE / 2, &public_key[0],
- &out);
- CborWriteInt(kCoseEc2YLabel, &out);
- CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_BUFFER_SIZE / 2,
- &public_key[DICE_PUBLIC_KEY_BUFFER_SIZE / 2], &out);
-
- *encoded_size = CborOutSize(&out);
- if (CborOutOverflowed(&out)) {
- return kDiceResultBufferTooSmall;
- }
- return kDiceResultOk;
-}
diff --git a/src/template_cbor_cert_op.c b/src/template_cbor_cert_op.c
index 88f72bc..a840ec7 100644
--- a/src/template_cbor_cert_op.c
+++ b/src/template_cbor_cert_op.c
@@ -164,10 +164,16 @@
uint8_t* certificate, size_t* certificate_actual_size) {
DiceResult result = kDiceResultOk;
+ DiceKeyParam key_param;
+ result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
+
// Variable length descriptors are not supported.
if (input_values->code_descriptor_size > 0 ||
input_values->config_type != kDiceConfigTypeInline ||
- input_values->authority_descriptor_size > 0 || DICE_PROFILE_NAME) {
+ input_values->authority_descriptor_size > 0 || key_param.profile_name) {
return kDiceResultInvalidInput;
}
diff --git a/src/template_cert_op.c b/src/template_cert_op.c
index 7dcb16f..32a6ef7 100644
--- a/src/template_cert_op.c
+++ b/src/template_cert_op.c
@@ -174,10 +174,16 @@
uint8_t* certificate, size_t* certificate_actual_size) {
DiceResult result = kDiceResultOk;
+ DiceKeyParam key_param;
+ result = DiceGetKeyParam(context, &key_param);
+ if (result != kDiceResultOk) {
+ goto out;
+ }
+
// Variable length descriptors are not supported.
if (input_values->code_descriptor_size > 0 ||
input_values->config_type != kDiceConfigTypeInline ||
- input_values->authority_descriptor_size > 0 || DICE_PROFILE_NAME) {
+ input_values->authority_descriptor_size > 0 || key_param.profile_name) {
return kDiceResultInvalidInput;
}