// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine License // Agreement. // // Reference implementation utilities of OEMCrypto APIs // #ifndef WVOEC_UTIL_BCC_VALIDATOR_H_ #define WVOEC_UTIL_BCC_VALIDATOR_H_ #include #include "cbor_validator.h" #include "prov4_validation_helper.h" 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 }; // Android/Widevine Dice Attestation allows two signing models. This is // identified using MAP_KEY_DEVICE_KEY_ALGORITHM. enum { DEVICE_KEY_ALGORITHM_ES256 = -7, // EC key with SHA-256 DEVICE_KEY_ALGORITHM_EDDSA = -8, // Pure ED25519. DEVICE_KEY_ALGORITHM_ES384 = -35, // EC key with SHA-384 }; // BCC definition: // https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl // See PubKeyEd25519/PubKeyECDSA256/PubKeyECDSA384 in BCC definition. struct BccPublicKeyInfo { std::pair key_type; std::pair signature_algorithm; std::pair curve; // Raw EC key bytes extracted from BCC std::pair> key_bytes; std::string ToString() const; CborMessageStatus Validate( std::vector>& msgs) const; }; // protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 // } struct BccEntryProtected { std::pair algorithm; std::string ToString() const; CborMessageStatus Validate( std::vector>& msgs) const; }; // See ConfigurationDescriptor in BCC definition. struct ConfigurationDescriptor { std::pair component_name; std::pair component_version; std::pair resettable; // null string std::pair security_version; std::pair vm_marker; // null string std::string ToString() const; // Validate ConfigurationDescriptor and set |is_widevine_entry| to true if the // component_name is "widevine". Caller ensures that |is_widevine_entry| is // not null. CborMessageStatus Validate( std::vector>& msgs, bool* is_widevine_entry) const; }; // See DiceChainEntryPayload in BCC definition. struct BccEntryPayload { std::pair issuer; std::pair subject; std::pair profile_name; std::pair subject_public_key; std::pair> key_usage; std::pair> code_hash; std::pair> code_descriptor; std::pair> config_hash; std::pair config_descriptor; std::pair> authority_hash; std::pair> authority_descriptor; std::pair> mode; std::string ToString() const; // Validate BccEntryPayload and set |is_widevine_entry| to true if the payload // contains a Widevine certificate. Caller ensures that |is_widevine_entry| is // not null. CborMessageStatus Validate( std::vector>& msgs, bool is_degenerated, bool* is_widevine_entry) const; }; // See DiceChainEntry in BCC definition. struct BccEntry { std::pair protected_data; std::pair unprotected; std::pair payload; std::pair> signature; std::string ToString() const; // Validate BccEntryPayload and set |is_widevine_entry| to true if the BCC // entry contains a Widevine certificate. Caller ensures that // |is_widevine_entry| is not null. CborMessageStatus Validate( std::vector>& msgs, bool is_degenerated, bool* is_widevine_entry) const; }; struct Bcc { BccPublicKeyInfo dk_pub; std::vector entries; std::string ToString() const; CborMessageStatus Validate( std::vector>& msgs, bool is_degenerated) const; }; // BccValidator processes a Provisioning 4.0 device root of trust. It extracts // and validates relevant pieces of information of BCC. // Relevant documents: // Android definition: go/remote-provisioning-hal#bcc. // Google Dice Profile: go/dice-profile class BccValidator : public CborValidator { public: BccValidator() = default; virtual ~BccValidator() override = default; WVCDM_DISALLOW_COPY_AND_MOVE(BccValidator); // Verifies the Cbor struct of a client generated root of trust. virtual CborMessageStatus Validate() override; // Outputs formatted BCC. virtual std::string GetFormattedMessage() const override; private: // Processes CoseKey PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384, which // contains subject public key, and extracts the PubKey to *|public_key_info|. // Caller ensures that all pointers are not null. CborMessageStatus ProcessSubjectPublicKeyInfo( const cppbor::Map* public_key_map, BccPublicKeyInfo* public_key_info); // Processes protected field in Bcc entry and extracts it *|protected_data|. // Caller ensures that all pointers are not null. CborMessageStatus ProcessBccEntryProtected(const cppbor::Map* protected_map, BccEntryProtected* protected_data); // Processes DiceChainEntryPayload and extracts the payload to *|payload|. // Caller ensures that all pointers are not null. CborMessageStatus ProcessDiceChainEntryPayload(const cppbor::Map* payload_map, BccEntryPayload* payload); // Processes ConfigurationDescriptor in DiceChainEntryPayload and extracts the // ConfigurationDescriptor to *|cd|. Caller ensures that all pointers are not // null. CborMessageStatus ProcessConfigurationDescriptor( const cppbor::Map* config_descriptor_map, ConfigurationDescriptor* cd); // 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& message, const std::vector& signature); // Used to generate formatted message. std::stringstream msg_ss_; }; // class BccValidator } // namespace util } // namespace wvoec #endif // WVOEC_UTIL_BCC_VALIDATOR_H_