Add signature verification to BCC validator

Each entry in BCC is signed by its parent. BCC validator should be able to
validate the signature along the chain.

In OPK reference, EdDSA is used. Also adding functions to support ECDSA
in oemcrypto_ecc_key module.

Test: opk_ta_p40
Bug: 300310163
Bug: 307968622
Change-Id: Ibed895933eeb71b18c467604588cca449cac1af9
This commit is contained in:
Cong Lin
2023-10-19 16:41:52 -07:00
committed by Robert Shih
parent 64124a7832
commit 91e573f574
4 changed files with 337 additions and 65 deletions

View File

@@ -16,6 +16,28 @@
namespace wvoec {
namespace util {
// Enums and struct to hold EC public key info
enum BccSignatureAlgorithm {
kBccDefaultSignature = 0,
kBccEdDsa = 1,
kBccEcdsaSha256 = 2,
kBccEcdsaSha384 = 3
};
enum BccCurve {
kBccDefaultCurve = 0,
kBccEd25519 = 1,
kBccP256 = 2,
kBccP384 = 3
};
struct BccPublicKeyInfo {
BccSignatureAlgorithm signature_algorithm;
BccCurve curve;
// Raw EC key bytes extracted from BCC
std::vector<uint8_t> key_bytes;
};
// BccValidator processes a Provisioning 4.0 device root of trust. It extracts
// and validates relevant pieces of information of BCC.
// Relevant documents:
@@ -37,15 +59,20 @@ class BccValidator : public CborValidator {
private:
// Processes CoseKey PubKeyEd25519 / PubKeyECDSA256, prints into |fmt_msgs|,
// and extracts the PubKey string to *|public_key_bytes|.
// and extracts the PubKey to *|public_key_info|.
CborMessageStatus ProcessSubjectPublicKeyInfo(
const cppbor::Map& public_key_info_map,
std::vector<std::string>& fmt_msgs, std::string* public_key_bytes);
std::vector<std::string>& fmt_msgs, BccPublicKeyInfo* public_key_info);
// Processes DiceChainEntryPayload, which contains subject public key, prints
// into |fmt_msgs|, and extracts the PubKey string to *|public_key_bytes|.
// into |fmt_msgs|, and extracts the PubKey to *|public_key_info|.
CborMessageStatus ProcessDiceChainEntryPayload(
const std::vector<uint8_t>& payload, std::vector<std::string>& fmt_msgs,
std::string* public_key_bytes);
BccPublicKeyInfo* public_key_info);
// Verifies the raw EC signature |signature| with the public key
// |signing_key|. |signature| extracted from BCC is not ASN.1 DER encoded.
bool VerifySignature(const BccPublicKeyInfo& signing_key,
const std::vector<uint8_t>& message,
const std::vector<uint8_t>& signature);
// Used to generate formatted message.
std::stringstream msg_ss_;
};

View File

@@ -60,6 +60,13 @@ class EccPublicKey {
size_t length);
static std::unique_ptr<EccPublicKey> Load(const std::string& buffer);
static std::unique_ptr<EccPublicKey> Load(const std::vector<uint8_t>& buffer);
// Loads EC public key from the |curve| and |buffer|.
// The provided |buffer| must contain an EC point serialized from raw X9.62
// format. For uncompressed form, it is a 1-byte prefix plus two 32-byte
// integers representing X, Y coordinates.
static std::unique_ptr<EccPublicKey> LoadKeyPoint(EccCurve curve,
const uint8_t* buffer,
size_t length);
// Loads a serialized ECC private key, but only converting the public key.
static std::unique_ptr<EccPublicKey> LoadPrivateKeyInfo(const uint8_t* buffer,
@@ -107,6 +114,15 @@ class EccPublicKey {
const std::string& signature) const;
OEMCryptoResult VerifySignature(const std::vector<uint8_t>& message,
const std::vector<uint8_t>& signature) const;
// Verifies the raw |signature| matches the provided |message| by the
// private equivalent of this public key.
// A raw ECDSA signature consists of a pair of integers (r,s). The |signature|
// is a concatenation of two octet strings resulting from the integer-to-octet
// encoding of the values of r and s, in the order of (r||s).
OEMCryptoResult VerifyRawSignature(const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length) const;
~EccPublicKey();
@@ -125,6 +141,13 @@ class EccPublicKey {
bool InitFromPrivateKeyInfo(const uint8_t* buffer, size_t length);
// Initializes the public key object from a private.
bool InitFromPrivateKey(const EccPrivateKey& private_key);
// Initializes the public key object from the provided curve and key point
// |buffer|.
bool InitFromKeyPoint(EccCurve curve, const uint8_t* buffer, size_t length);
// Digests the |message| and verifies signature against the provided signature
// point.
OEMCryptoResult DigestAndVerify(const uint8_t* message, size_t message_length,
const ECDSA_SIG* sig_point) const;
// OpenSSL/BoringSSL implementation of an ECC key.
// As a public key, this will only have key point initialized.