Unify COSE-C crypto dependecy implementations
Provide a single, combined implemenation of signature verification for
all of the supported key types. This removes duplication and allows for
multiple algorithms to be supported in a single build.
The set of accepted algorithms are controlled by build-time macros in
the core library. The different build targets enable a different
subset of algorithms but share the same crypto implementation.
Bug: 341630707
Change-Id: I7f6e6be26684dc5101777d5ce161839b095a08f2
Reviewed-on: https://pigweed-review.googlesource.com/c/open-dice/+/225711
Reviewed-by: Darren Krahn <dkrahn@google.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Commit-Queue: Andrew Scull <ascull@google.com>
Reviewed-by: Alice Wang <aliceywang@google.com>
diff --git a/third_party/cose-c/BUILD.gn b/third_party/cose-c/BUILD.gn
index 9fba69c..6d26a92 100644
--- a/third_party/cose-c/BUILD.gn
+++ b/third_party/cose-c/BUILD.gn
@@ -42,15 +42,17 @@
cflags = [ "-Wno-cast-qual" ]
}
+cose_c_sources = [
+ "cose_deps.cc",
+ "src/src/Cose.cpp",
+ "src/src/CoseKey.cpp",
+ "src/src/Sign1.cpp",
+ "src/src/cbor.cpp",
+]
+
pw_static_library("cose-c_ed25519") {
public = [ "src/include/cose/cose.h" ]
- sources = [
- "cose_ed25519_deps.cc",
- "src/src/Cose.cpp",
- "src/src/CoseKey.cpp",
- "src/src/Sign1.cpp",
- "src/src/cbor.cpp",
- ]
+ sources = cose_c_sources
public_configs = [ ":external_config_ed25519" ]
configs = [ ":internal_config" ]
public_deps = [
@@ -61,13 +63,7 @@
pw_static_library("cose-c_p256") {
public = [ "src/include/cose/cose.h" ]
- sources = [
- "cose_p256_deps.cc",
- "src/src/Cose.cpp",
- "src/src/CoseKey.cpp",
- "src/src/Sign1.cpp",
- "src/src/cbor.cpp",
- ]
+ sources = cose_c_sources
public_configs = [ ":external_config_p256" ]
configs = [ ":internal_config" ]
public_deps = [
@@ -78,13 +74,7 @@
pw_static_library("cose-c_p384") {
public = [ "src/include/cose/cose.h" ]
- sources = [
- "cose_p384_deps.cc",
- "src/src/Cose.cpp",
- "src/src/CoseKey.cpp",
- "src/src/Sign1.cpp",
- "src/src/cbor.cpp",
- ]
+ sources = cose_c_sources
public_configs = [ ":external_config_p384" ]
configs = [ ":internal_config" ]
public_deps = [
diff --git a/third_party/cose-c/cose_deps.cc b/third_party/cose-c/cose_deps.cc
new file mode 100644
index 0000000..33c2d57
--- /dev/null
+++ b/third_party/cose-c/cose_deps.cc
@@ -0,0 +1,235 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <stdint.h>
+#include <string.h>
+
+#include <optional>
+
+#include "cose/cose.h"
+#include "cose/cose_configure.h"
+#include "cose_int.h"
+#include "openssl/bn.h"
+#include "openssl/curve25519.h"
+#include "openssl/ec.h"
+#include "openssl/ec_key.h"
+#include "openssl/ecdsa.h"
+#include "openssl/evp.h"
+#include "openssl/is_boringssl.h"
+#include "openssl/sha.h"
+
+namespace {
+
+// Checks the type and ops have the expected values.
+bool CheckCoseKeyTypeAndOps(const cn_cbor *key, uint64_t expected_type) {
+ const int64_t kCoseKeyOpsLabel = 4;
+ const uint64_t kCoseKeyOpsVerify = 2;
+
+ cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
+ if (!type) {
+ return false;
+ }
+ if (type->type != CN_CBOR_UINT || type->v.uint != expected_type) {
+ return false;
+ }
+
+ cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
+ if (ops) {
+ if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
+ return false;
+ }
+ bool found_verify = false;
+ for (size_t i = 0; i < ops->length; ++i) {
+ cn_cbor *item = cn_cbor_index(ops, i);
+ if (!item || item->type != CN_CBOR_UINT) {
+ return false;
+ }
+ if (item->v.uint == kCoseKeyOpsVerify) {
+ found_verify = true;
+ }
+ }
+ if (!found_verify) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Checks that the optional algorithm field is the expected value.
+bool CheckCoseKeyAlg(const cn_cbor *key, int64_t expected_alg) {
+ const int64_t kCoseKeyAlgLabel = 3;
+
+ cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
+ if (alg) {
+ if (alg->type != CN_CBOR_INT || alg->v.sint != expected_alg) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Gets the public key from a well-formed EC2 COSE_Key.
+std::optional<bssl::UniquePtr<EC_KEY>> GetEcKey(cn_cbor *key, int nid,
+ size_t coord_size) {
+ cn_cbor *raw_x = cn_cbor_mapget_int(key, COSE_Key_EC2_X);
+ if (!raw_x || raw_x->type != CN_CBOR_BYTES || raw_x->length != coord_size) {
+ return std::nullopt;
+ }
+
+ cn_cbor *raw_y = cn_cbor_mapget_int(key, COSE_Key_EC2_Y);
+ if (!raw_y || raw_y->type != CN_CBOR_BYTES || raw_y->length != coord_size) {
+ return std::nullopt;
+ }
+
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
+ bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new_by_curve_name(nid));
+ if (!x || !y || !eckey) {
+ return std::nullopt;
+ }
+
+ BN_bin2bn(raw_x->v.bytes, coord_size, x.get());
+ BN_bin2bn(raw_y->v.bytes, coord_size, y.get());
+ if (0 ==
+ EC_KEY_set_public_key_affine_coordinates(eckey.get(), x.get(), y.get())) {
+ return std::nullopt;
+ }
+
+ return eckey;
+}
+
+} // namespace
+
+// A simple implementation of 'EdDSA_Verify' using boringssl. This function is
+// required by 'COSE_Sign1_validate'.
+bool EdDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
+ const byte *message, size_t message_size, cose_errback *) {
+ const int64_t kCoseAlgEdDSA = -8;
+
+ cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
+ cn_cbor *key = cose_key->m_cborKey;
+ if (!signature || !key) {
+ return false;
+ }
+ if (signature->type != CN_CBOR_BYTES || signature->length != 64) {
+ return false;
+ }
+ if (!CheckCoseKeyTypeAndOps(key, COSE_Key_Type_OKP)) {
+ return false;
+ }
+ cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
+ cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_OPK_X);
+ if (!curve || !x) {
+ return false;
+ }
+ if (curve->type != CN_CBOR_UINT || curve->v.uint != COSE_Curve_Ed25519) {
+ return false;
+ }
+ if (x->type != CN_CBOR_BYTES || x->length != 32) {
+ return false;
+ }
+ if (!CheckCoseKeyAlg(key, kCoseAlgEdDSA)) {
+ return false;
+ }
+ if (1 !=
+ ED25519_verify(message, message_size, signature->v.bytes, x->v.bytes)) {
+ return false;
+ }
+ return true;
+}
+
+// A stub for 'EdDSA_Sign'. This is unused, but helps make linkers happy.
+bool EdDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
+ COSE_KEY * /*cose_key*/, const byte * /*message*/,
+ size_t /*message_size*/, cose_errback *) {
+ return false;
+}
+
+// A simple implementation of 'ECDSA_Verify' using boringssl. This function is
+// required by 'COSE_Sign1_validate'.
+bool ECDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
+ int cbitsDigest, const byte *message, size_t message_size,
+ cose_errback *) {
+ const int64_t kCoseAlgEs256 = -7;
+ const int64_t kCoseAlgEs384 = -35;
+
+ (void)cbitsDigest;
+ cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
+ cn_cbor *key = cose_key->m_cborKey;
+ if (!signature || !key) {
+ return false;
+ }
+
+ if (!CheckCoseKeyTypeAndOps(key, COSE_Key_Type_EC2)) {
+ return false;
+ }
+
+ cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
+ if (!curve || curve->type != CN_CBOR_UINT) {
+ return false;
+ }
+
+ size_t coord_size;
+ int nid;
+ const EVP_MD *md_type;
+ if (curve->v.uint == COSE_Curve_P256) {
+ if (!CheckCoseKeyAlg(key, kCoseAlgEs256)) {
+ return false;
+ }
+ coord_size = 32;
+ nid = NID_X9_62_prime256v1;
+ md_type = EVP_sha256();
+ } else if (curve->v.uint == COSE_Curve_P384) {
+ if (!CheckCoseKeyAlg(key, kCoseAlgEs384)) {
+ return false;
+ }
+ coord_size = 48;
+ nid = NID_secp384r1;
+ md_type = EVP_sha384();
+ } else {
+ return false;
+ }
+
+ uint8_t md[EVP_MAX_MD_SIZE];
+ unsigned int md_size;
+ if (1 != EVP_Digest(message, message_size, md, &md_size, md_type, nullptr)) {
+ return false;
+ }
+
+ std::optional<bssl::UniquePtr<EC_KEY>> eckey = GetEcKey(key, nid, coord_size);
+ if (!eckey) {
+ return false;
+ }
+
+ if (signature->type != CN_CBOR_BYTES ||
+ signature->length != (coord_size * 2)) {
+ return false;
+ }
+
+ bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
+ BN_bin2bn(&signature->v.bytes[0], coord_size, sig->r);
+ BN_bin2bn(&signature->v.bytes[coord_size], coord_size, sig->s);
+ if (1 != ECDSA_do_verify(md, md_size, sig.get(), eckey->get())) {
+ return false;
+ }
+
+ return true;
+}
+
+// A stub for 'ECDSA_Sign'. This is unused, but helps make linkers happy.
+bool ECDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
+ COSE_KEY * /*cose_key*/, const byte * /*message*/,
+ size_t /*message_size*/, cose_errback *) {
+ return false;
+}
diff --git a/third_party/cose-c/cose_ed25519_deps.cc b/third_party/cose-c/cose_ed25519_deps.cc
deleted file mode 100644
index 3d78b60..0000000
--- a/third_party/cose-c/cose_ed25519_deps.cc
+++ /dev/null
@@ -1,105 +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 <string.h>
-
-#include "cose/cose.h"
-#include "cose/cose_configure.h"
-#include "cose_int.h"
-#include "openssl/curve25519.h"
-#include "openssl/is_boringssl.h"
-
-// Gets the public key from a well-formed Ed25519 COSE_Key. On success populates
-// |public_key| and returns true.
-static bool GetPublicKeyFromCbor(const cn_cbor *key,
- uint8_t public_key[PUBLIC_KEY_SIZE]) {
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyOpsLabel = 4;
- const uint64_t kCoseKeyOpsVerify = 2;
- const int64_t kCoseAlgEdDSA = -8;
-
- // Mandatory attributes.
- cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
- cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
- cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_OPK_X);
- if (!type || !curve || !x) {
- return false;
- }
- if (type->type != CN_CBOR_UINT || type->v.uint != COSE_Key_Type_OKP) {
- return false;
- }
- if (curve->type != CN_CBOR_UINT || curve->v.uint != COSE_Curve_Ed25519) {
- return false;
- }
- if (x->type != CN_CBOR_BYTES || x->length != PUBLIC_KEY_SIZE) {
- return false;
- }
- // Optional attributes.
- cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
- if (alg) {
- if (alg->type != CN_CBOR_INT || alg->v.sint != kCoseAlgEdDSA) {
- return false;
- }
- }
- cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
- if (ops) {
- if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
- return false;
- }
- bool found_verify = false;
- for (size_t i = 0; i < ops->length; ++i) {
- cn_cbor *item = cn_cbor_index(ops, i);
- if (!item || item->type != CN_CBOR_UINT) {
- return false;
- }
- if (item->v.uint == kCoseKeyOpsVerify) {
- found_verify = true;
- }
- }
- if (!found_verify) {
- return false;
- }
- }
-
- memcpy(public_key, x->v.bytes, PUBLIC_KEY_SIZE);
- return true;
-}
-
-// A simple implementation of 'EdDSA_Verify' using boringssl. This function is
-// required by 'COSE_Sign1_validate'.
-bool EdDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
- const byte *message, size_t message_size, cose_errback *) {
- cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
- cn_cbor *key = cose_key->m_cborKey;
- if (!signature || !key) {
- return false;
- }
- if (signature->type != CN_CBOR_BYTES || signature->length != 64) {
- return false;
- }
- uint8_t public_key[PUBLIC_KEY_SIZE];
- if (!GetPublicKeyFromCbor(key, public_key)) {
- return false;
- }
- return (1 == ED25519_verify(message, message_size, signature->v.bytes,
- public_key));
-}
-
-// A stub for 'EdDSA_Sign'. This is unused, but helps make linkers happy.
-bool EdDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
- COSE_KEY * /*cose_key*/, const byte * /*message*/,
- size_t /*message_size*/, cose_errback *) {
- return false;
-}
diff --git a/third_party/cose-c/cose_p256_deps.cc b/third_party/cose-c/cose_p256_deps.cc
deleted file mode 100644
index 31f0c6b..0000000
--- a/third_party/cose-c/cose_p256_deps.cc
+++ /dev/null
@@ -1,151 +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.
-
-#include <stdint.h>
-#include <string.h>
-
-#include "cose/cose.h"
-#include "cose/cose_configure.h"
-#include "cose_int.h"
-#include "openssl/bn.h"
-#include "openssl/ec.h"
-#include "openssl/ec_key.h"
-#include "openssl/ecdsa.h"
-#include "openssl/evp.h"
-#include "openssl/hkdf.h"
-#include "openssl/is_boringssl.h"
-#include "openssl/sha.h"
-
-// Gets the public key from a well-formed ECDSA P-256 COSE_Key. On
-// success populates |public_key| and returns true; public_key must hold 64
-// bytes (uncompressed format).
-static bool GetPublicKeyFromCbor(const cn_cbor *key, uint8_t *public_key) {
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyOpsLabel = 4;
- const uint64_t kCoseKeyOpsVerify = 2;
- const int64_t kCoseAlgEs256 = -7;
-
- // Mandatory attributes.
- cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
- cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
- if (!type || !curve) {
- return false;
- }
- if (type->type != CN_CBOR_UINT || curve->type != CN_CBOR_UINT) {
- return false;
- }
-
- if (type->v.uint != COSE_Key_Type_EC2 || curve->v.uint != COSE_Curve_P256) {
- return false;
- }
-
- cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_EC2_X);
- if (!x || x->type != CN_CBOR_BYTES || x->length != (PUBLIC_KEY_SIZE / 2)) {
- return false;
- }
-
- cn_cbor *y = cn_cbor_mapget_int(key, COSE_Key_EC2_Y);
- if (!y || y->type != CN_CBOR_BYTES || y->length != (PUBLIC_KEY_SIZE / 2)) {
- return false;
- }
-
- cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
- if (alg) {
- if (alg->type != CN_CBOR_INT || alg->v.sint != kCoseAlgEs256) {
- return false;
- }
- }
-
- cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
- if (ops) {
- if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
- return false;
- }
- bool found_verify = false;
- for (size_t i = 0; i < ops->length; ++i) {
- cn_cbor *item = cn_cbor_index(ops, i);
- if (!item || item->type != CN_CBOR_UINT) {
- return false;
- }
- if (item->v.uint == kCoseKeyOpsVerify) {
- found_verify = true;
- }
- }
- if (!found_verify) {
- return false;
- }
- }
-
- memcpy(&public_key[0], x->v.bytes, PUBLIC_KEY_SIZE / 2);
- memcpy(&public_key[PUBLIC_KEY_SIZE / 2], y->v.bytes, PUBLIC_KEY_SIZE / 2);
- return true;
-}
-
-// A simple implementation of 'ECDSA_Verify' using boringssl. This function is
-// required by 'COSE_Sign1_validate'.
-bool ECDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
- int cbitsDigest, const byte *message, size_t message_size,
- cose_errback *) {
- (void)cbitsDigest;
- cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
- cn_cbor *key = cose_key->m_cborKey;
- if (!signature || !key) {
- return false;
- }
- if (signature->type != CN_CBOR_BYTES ||
- signature->length != PUBLIC_KEY_SIZE) {
- return false;
- }
- uint8_t public_key[PUBLIC_KEY_SIZE];
- if (!GetPublicKeyFromCbor(key, public_key)) {
- return false;
- }
-
- // Implementation of ECDSA verification starts here
- uint8_t output[32];
- SHA256(message, message_size, output);
- EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- BIGNUM *x = BN_new();
- BN_bin2bn(&public_key[0], 32, x);
- BIGNUM *y = BN_new();
- BN_bin2bn(&public_key[32], 32, y);
- int result = EC_KEY_set_public_key_affine_coordinates(eckey, x, y);
-
- BN_clear_free(y);
- BN_clear_free(x);
-
- if (result == 0) {
- printf("Setting affine coordinates failed\n");
- return false;
- }
-
- ECDSA_SIG *sig = ECDSA_SIG_new();
- BN_bin2bn(&(signature->v.bytes[0]), 32, sig->r);
- BN_bin2bn(&(signature->v.bytes[32]), 32, sig->s);
- result = ECDSA_do_verify(output, 32, sig, eckey);
-
- EC_KEY_free(eckey);
- ECDSA_SIG_free(sig);
- if (1 != result) {
- return false;
- }
- return true;
-}
-
-// A stub for 'ECDSA_Sign'. This is unused, but helps make linkers happy.
-bool ECDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
- COSE_KEY * /*cose_key*/, const byte * /*message*/,
- size_t /*message_size*/, cose_errback *) {
- return false;
-}
diff --git a/third_party/cose-c/cose_p384_deps.cc b/third_party/cose-c/cose_p384_deps.cc
deleted file mode 100644
index bd70708..0000000
--- a/third_party/cose-c/cose_p384_deps.cc
+++ /dev/null
@@ -1,151 +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 <stdint.h>
-#include <string.h>
-
-#include "cose/cose.h"
-#include "cose/cose_configure.h"
-#include "cose_int.h"
-#include "openssl/bn.h"
-#include "openssl/ec.h"
-#include "openssl/ec_key.h"
-#include "openssl/ecdsa.h"
-#include "openssl/evp.h"
-#include "openssl/hkdf.h"
-#include "openssl/is_boringssl.h"
-#include "openssl/sha.h"
-
-// Gets the public key from a well-formed ECDSA P-384 COSE_Key. On
-// success populates |public_key| and returns true; public_key must hold 96
-// bytes (uncompressed format).
-static bool GetPublicKeyFromCbor(const cn_cbor *key, uint8_t *public_key) {
- const int64_t kCoseKeyAlgLabel = 3;
- const int64_t kCoseKeyOpsLabel = 4;
- const uint64_t kCoseKeyOpsVerify = 2;
- const int64_t kCoseAlgEs384 = -35;
-
- // Mandatory attributes.
- cn_cbor *type = cn_cbor_mapget_int(key, COSE_Key_Type);
- cn_cbor *curve = cn_cbor_mapget_int(key, COSE_Key_OPK_Curve);
- if (!type || !curve) {
- return false;
- }
- if (type->type != CN_CBOR_UINT || curve->type != CN_CBOR_UINT) {
- return false;
- }
-
- if (type->v.uint != COSE_Key_Type_EC2 || curve->v.uint != COSE_Curve_P384) {
- return false;
- }
-
- cn_cbor *x = cn_cbor_mapget_int(key, COSE_Key_EC2_X);
- if (!x || x->type != CN_CBOR_BYTES || x->length != (PUBLIC_KEY_SIZE / 2)) {
- return false;
- }
-
- cn_cbor *y = cn_cbor_mapget_int(key, COSE_Key_EC2_Y);
- if (!y || y->type != CN_CBOR_BYTES || y->length != (PUBLIC_KEY_SIZE / 2)) {
- return false;
- }
-
- cn_cbor *alg = cn_cbor_mapget_int(key, kCoseKeyAlgLabel);
- if (alg) {
- if (alg->type != CN_CBOR_INT || alg->v.sint != kCoseAlgEs384) {
- return false;
- }
- }
-
- cn_cbor *ops = cn_cbor_mapget_int(key, kCoseKeyOpsLabel);
- if (ops) {
- if (ops->type != CN_CBOR_ARRAY || ops->length == 0) {
- return false;
- }
- bool found_verify = false;
- for (size_t i = 0; i < ops->length; ++i) {
- cn_cbor *item = cn_cbor_index(ops, i);
- if (!item || item->type != CN_CBOR_UINT) {
- return false;
- }
- if (item->v.uint == kCoseKeyOpsVerify) {
- found_verify = true;
- }
- }
- if (!found_verify) {
- return false;
- }
- }
-
- memcpy(&public_key[0], x->v.bytes, PUBLIC_KEY_SIZE / 2);
- memcpy(&public_key[PUBLIC_KEY_SIZE / 2], y->v.bytes, PUBLIC_KEY_SIZE / 2);
- return true;
-}
-
-// A simple implementation of 'ECDSA_Verify' using boringssl. This function is
-// required by 'COSE_Sign1_validate'.
-bool ECDSA_Verify(COSE *cose_signer, int signature_index, COSE_KEY *cose_key,
- int cbitsDigest, const byte *message, size_t message_size,
- cose_errback *) {
- (void)cbitsDigest;
- cn_cbor *signature = _COSE_arrayget_int(cose_signer, signature_index);
- cn_cbor *key = cose_key->m_cborKey;
- if (!signature || !key) {
- return false;
- }
- if (signature->type != CN_CBOR_BYTES ||
- signature->length != PUBLIC_KEY_SIZE) {
- return false;
- }
- uint8_t public_key[PUBLIC_KEY_SIZE];
- if (!GetPublicKeyFromCbor(key, public_key)) {
- return false;
- }
-
- // Implementation of ECDSA verification starts here
- uint8_t output[48];
- SHA384(message, message_size, output);
- EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp384r1);
- BIGNUM *x = BN_new();
- BN_bin2bn(&public_key[0], 48, x);
- BIGNUM *y = BN_new();
- BN_bin2bn(&public_key[48], 48, y);
- int result = EC_KEY_set_public_key_affine_coordinates(eckey, x, y);
-
- BN_clear_free(y);
- BN_clear_free(x);
-
- if (result == 0) {
- printf("Setting affine coordinates failed\n");
- return false;
- }
-
- ECDSA_SIG *sig = ECDSA_SIG_new();
- BN_bin2bn(&(signature->v.bytes[0]), 48, sig->r);
- BN_bin2bn(&(signature->v.bytes[48]), 48, sig->s);
- result = ECDSA_do_verify(output, 48, sig, eckey);
-
- EC_KEY_free(eckey);
- ECDSA_SIG_free(sig);
- if (1 != result) {
- return false;
- }
- return true;
-}
-
-// A stub for 'ECDSA_Sign'. This is unused, but helps make linkers happy.
-bool ECDSA_Sign(COSE * /*cose_signer*/, int /*signature_index*/,
- COSE_KEY * /*cose_key*/, const byte * /*message*/,
- size_t /*message_size*/, cose_errback *) {
- return false;
-}
diff --git a/third_party/cose-c/include/ed25519/cose/cose_configure.h b/third_party/cose-c/include/ed25519/cose/cose_configure.h
index b487905..8cbccc8 100644
--- a/third_party/cose-c/include/ed25519/cose/cose_configure.h
+++ b/third_party/cose-c/include/ed25519/cose/cose_configure.h
@@ -2,7 +2,6 @@
#define THIRD_PARTY_COSE_C_ED25519_COSE_COSE_CONFIGURE_H_
#define USE_EDDSA
-#define PUBLIC_KEY_SIZE 32
#define INCLUDE_ENCRYPT 0
#define INCLUDE_ENCRYPT0 0
diff --git a/third_party/cose-c/include/p256/cose/cose_configure.h b/third_party/cose-c/include/p256/cose/cose_configure.h
index 120a42d..64b5437 100644
--- a/third_party/cose-c/include/p256/cose/cose_configure.h
+++ b/third_party/cose-c/include/p256/cose/cose_configure.h
@@ -2,7 +2,6 @@
#define THIRD_PARTY_COSE_C_P256_COSE_COSE_CONFIGURE_H_
#define USE_ECDSA_SHA_256
-#define PUBLIC_KEY_SIZE 64
#define INCLUDE_ENCRYPT 0
#define INCLUDE_ENCRYPT0 0
diff --git a/third_party/cose-c/include/p384/cose/cose_configure.h b/third_party/cose-c/include/p384/cose/cose_configure.h
index 5ddf8d7..1559fc7 100644
--- a/third_party/cose-c/include/p384/cose/cose_configure.h
+++ b/third_party/cose-c/include/p384/cose/cose_configure.h
@@ -2,7 +2,6 @@
#define THIRD_PARTY_COSE_C_P384_COSE_COSE_CONFIGURE_H_
#define USE_ECDSA_SHA_384
-#define PUBLIC_KEY_SIZE 96
#define INCLUDE_ENCRYPT 0
#define INCLUDE_ENCRYPT0 0