Files
ce_cdm/oemcrypto/util/include/bcc_validator.h
2024-11-27 00:07:23 +00:00

177 lines
7.0 KiB
C++

// 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 <sstream>
#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<FieldStatus, int> key_type;
std::pair<FieldStatus, BccSignatureAlgorithm> signature_algorithm;
std::pair<FieldStatus, BccCurve> curve;
// Raw EC key bytes extracted from BCC
std::pair<FieldStatus, std::vector<uint8_t>> key_bytes;
std::string ToString() const;
CborMessageStatus Validate(
std::vector<std::pair<CborMessageStatus, std::string>>& msgs) const;
};
// protected : bstr .cbor { 1 : AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384
// }
struct BccEntryProtected {
std::pair<FieldStatus, int64_t> algorithm;
std::string ToString() const;
CborMessageStatus Validate(
std::vector<std::pair<CborMessageStatus, std::string>>& msgs) const;
};
// See ConfigurationDescriptor in BCC definition.
struct ConfigurationDescriptor {
std::pair<FieldStatus, std::string> component_name;
std::pair<FieldStatus, std::string> component_version;
std::pair<FieldStatus, std::string> resettable; // null string
std::pair<FieldStatus, uint64_t> security_version;
std::pair<FieldStatus, std::string> 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<std::pair<CborMessageStatus, std::string>>& msgs,
bool* is_widevine_entry) const;
};
// See DiceChainEntryPayload in BCC definition.
struct BccEntryPayload {
std::pair<FieldStatus, std::string> issuer;
std::pair<FieldStatus, std::string> subject;
std::pair<FieldStatus, std::string> profile_name;
std::pair<FieldStatus, BccPublicKeyInfo> subject_public_key;
std::pair<FieldStatus, std::vector<uint8_t>> key_usage;
std::pair<FieldStatus, std::vector<uint8_t>> code_hash;
std::pair<FieldStatus, std::vector<uint8_t>> code_descriptor;
std::pair<FieldStatus, std::vector<uint8_t>> config_hash;
std::pair<FieldStatus, ConfigurationDescriptor> config_descriptor;
std::pair<FieldStatus, std::vector<uint8_t>> authority_hash;
std::pair<FieldStatus, std::vector<uint8_t>> authority_descriptor;
std::pair<FieldStatus, std::vector<uint8_t>> 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<std::pair<CborMessageStatus, std::string>>& msgs,
bool is_degenerated, bool* is_widevine_entry) const;
};
// See DiceChainEntry in BCC definition.
struct BccEntry {
std::pair<FieldStatus, BccEntryProtected> protected_data;
std::pair<FieldStatus, std::string> unprotected;
std::pair<FieldStatus, BccEntryPayload> payload;
std::pair<FieldStatus, std::vector<uint8_t>> 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<std::pair<CborMessageStatus, std::string>>& msgs,
bool is_degenerated, bool* is_widevine_entry) const;
};
struct Bcc {
BccPublicKeyInfo dk_pub;
std::vector<BccEntry> entries;
std::string ToString() const;
CborMessageStatus Validate(
std::vector<std::pair<CborMessageStatus, std::string>>& 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<uint8_t>& message,
const std::vector<uint8_t>& signature);
// Used to generate formatted message.
std::stringstream msg_ss_;
}; // class BccValidator
} // namespace util
} // namespace wvoec
#endif // WVOEC_UTIL_BCC_VALIDATOR_H_