Source release 19.1.0

This commit is contained in:
Matt Feddersen
2024-03-28 19:21:54 -07:00
parent 28ec8548c6
commit b8bdfccebe
182 changed files with 10645 additions and 2040 deletions

View File

@@ -276,7 +276,7 @@ class ProvisioningRoundTrip
const std::vector<uint8_t>& encoded_rsa_key)
: RoundTrip(session),
allowed_schemes_(kSign_RSASSA_PSS),
encryptor_(),
keybox_(nullptr),
encoded_rsa_key_(encoded_rsa_key) {}
// Prepare the session for signing the request.
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);
@@ -317,9 +317,9 @@ class ProvisioningRoundTrip
uint32_t allowed_schemes_;
Encryptor encryptor_;
std::vector<uint8_t> request_;
const wvoec::WidevineKeybox* keybox_;
// The message key used for Prov 3.0.
std::vector<uint8_t> message_key_;
std::vector<uint8_t> encrypted_message_key_;
std::vector<uint8_t> encoded_rsa_key_;
std::vector<uint8_t> wrapped_rsa_key_;
};
@@ -337,8 +337,8 @@ class Provisioning40RoundTrip
// Not used. Use Load*CertResponse() below to load OEM/DRM response
// respectively.
void CreateDefaultResponse() override{};
void EncryptAndSignResponse() override{};
void CreateDefaultResponse() override {};
void EncryptAndSignResponse() override {};
OEMCryptoResult LoadResponse(Session* session) override {
(void)session;
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
@@ -383,8 +383,10 @@ class Provisioning40CastRoundTrip
/* ResponseData */ RSAPrivateKeyMessage> {
public:
Provisioning40CastRoundTrip(Session* session,
const std::vector<uint8_t>& encoded_rsa_key)
: RoundTrip(session), encryptor_(),
const std::vector<uint8_t>& encoded_rsa_key)
: RoundTrip(session),
allowed_schemes_(kSign_RSASSA_PSS),
encryptor_(),
encoded_rsa_key_(encoded_rsa_key) {}
void PrepareSession();
@@ -394,7 +396,8 @@ class Provisioning40CastRoundTrip
void EncryptAndSignResponse() override;
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
OEMCryptoResult LoadResponse(Session* session) override;
OEMCryptoResult LoadResponseNoRetry(Session* session, size_t* wrapped_key_length) ;
OEMCryptoResult LoadResponseNoRetry(Session* session,
size_t* wrapped_key_length);
// Returned
const std::vector<uint8_t>& wrapped_drm_key() { return wrapped_drm_key_; }
@@ -442,6 +445,7 @@ class LicenseRoundTrip
update_mac_keys_(true),
api_version_(kCurrentAPI),
expect_request_has_correct_nonce_(true),
skip_request_hash_(global_features.api_version < 19),
license_type_(OEMCrypto_ContentLicense),
request_hash_() {}
void CreateDefaultResponse() override;
@@ -516,6 +520,8 @@ class LicenseRoundTrip
}
// Skip the nonce check when verifying the license request.
void skip_nonce_check() { expect_request_has_correct_nonce_ = false; }
// Skip hashing license request before signing/KDF.
void skip_request_hash() { skip_request_hash_ = true; }
// This sets the key id of the specified key to the specified string.
// This is used to test with different key id lengths.
void SetKeyId(size_t index, const string& key_id);
@@ -547,6 +553,9 @@ class LicenseRoundTrip
// session. This is usually true, but when we are testing how OEMCrypto
// handles a bad nonce, we don't want to.
bool expect_request_has_correct_nonce_;
// Whether to skip hashing the request before signing and KDF; this is used
// for license protocol 2.2.
bool skip_request_hash_;
// Whether this is a content license or an entitlement license. Used in
// CreateDefaultResponse.
OEMCrypto_LicenseType license_type_;
@@ -601,6 +610,48 @@ class RenewalRoundTrip
bool is_release_; // If this is a license release, and not a real renewal.
};
class ReleaseRoundTrip
: public RoundTrip<
/* CoreRequest */ oemcrypto_core_message::ODK_ReleaseRequest,
OEMCrypto_PrepAndSignReleaseRequest,
// Release response info is same as request:
/* CoreResponse */ oemcrypto_core_message::ODK_ReleaseRequest,
/* ResponseData */ MessageData> {
public:
ReleaseRoundTrip(LicenseRoundTrip* license_messages)
: RoundTrip(license_messages->session()),
license_messages_(license_messages) {}
void CreateDefaultResponse() override;
void EncryptAndSignResponse() override;
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
OEMCryptoResult LoadResponse(Session* session) override;
int64_t seconds_since_license_received() const {
return seconds_since_license_received_;
}
void set_seconds_since_license_received(
int64_t seconds_since_license_received) {
seconds_since_license_received_ = seconds_since_license_received;
}
int64_t seconds_since_first_decrypt() const {
return seconds_since_first_decrypt_;
}
void set_seconds_since_first_decrypt(int64_t seconds_since_first_decrypt) {
seconds_since_first_decrypt_ = seconds_since_first_decrypt;
}
protected:
bool RequestHasNonce() override { return false; }
void VerifyRequestSignature(const vector<uint8_t>& data,
const vector<uint8_t>& generated_signature,
size_t core_message_length) override;
// Verify the values of the core response.
virtual void FillAndVerifyCoreRequest(
const std::string& core_message_string) override;
LicenseRoundTrip* license_messages_;
int64_t seconds_since_license_received_;
int64_t seconds_since_first_decrypt_;
};
class EntitledMessage {
public:
EntitledMessage(LicenseRoundTrip* license_messages)
@@ -671,15 +722,17 @@ class Session {
// and try again if a nonce flood has been detected. If error_counter is
// not null, it will be incremented when a nonce flood is detected.
void GenerateNonce(int* error_counter = nullptr);
// Fill the vectors with test context which generate known mac and enc keys.
void FillDefaultContext(vector<uint8_t>* mac_context,
vector<uint8_t>* enc_context);
// Fill the vector with test context which generate known mac and enc keys.
std::vector<uint8_t> GetDefaultContext(bool do_hash = false);
// Generate known mac and enc keys using OEMCrypto_GenerateDerivedKeys and
// also fill out enc_key_, mac_key_server_, and mac_key_client_.
void GenerateDerivedKeysFromKeybox(const wvoec::WidevineKeybox& keybox);
void GenerateDerivedKeysFromKeybox(const wvoec::WidevineKeybox& keybox,
const std::vector<uint8_t>& context);
// Generate known mac and enc keys using OEMCrypto_DeriveKeysFromSessionKey
// and also fill out enc_key_, mac_key_server_, and mac_key_client_.
void GenerateDerivedKeysFromSessionKey();
void GenerateDerivedKeysFromSessionKey(const std::vector<uint8_t>& context);
// Encrypt some data and pass to OEMCrypto_DecryptCENC to verify decryption.
void TestDecryptCTR(bool get_fresh_key_handle_first = true,
OEMCryptoResult expected_result = OEMCrypto_SUCCESS,
@@ -745,17 +798,14 @@ class Session {
// Encrypts a known session key with public_rsa_ for use in future calls to
// OEMCrypto_DeriveKeysFromSessionKey or OEMCrypto_RewrapDeviceRSAKey30.
// The unencrypted session key is stored in session_key.
bool GenerateRsaSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key);
bool GenerateRsaSessionKey();
// Derives a session key with public_ec_ and a ephemeral "server" ECC key
// for use in future calls to OEMCrypto_DeriveKeysFromSessionKey.
// The unencrypted session key is stored in session_key.
bool GenerateEccSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* ecdh_public_key_data);
bool GenerateEccSessionKey();
// Based on the key type installed, call GenerateRsaSessionKey or
// GenerateEccSessionKey.
bool GenerateSessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* key_material);
bool GenerateSessionKey();
// Calls OEMCrypto_RewrapDeviceRSAKey30 with the given provisioning response
// message. If force is true, we assert that the key loads successfully.
@@ -838,6 +888,11 @@ class Session {
// functions.
vector<uint8_t>& key_handle() { return key_handle_; }
const std::vector<uint8_t>& session_key() const { return session_key_; }
const std::vector<uint8_t>& enc_session_key() const {
return enc_session_key_;
}
const KeyDeriver& key_deriver() const { return key_deriver_; }
void set_mac_keys(const uint8_t* mac_keys) {
key_deriver_.set_mac_keys(mac_keys);
@@ -880,6 +935,8 @@ class Session {
vector<uint8_t> pst_report_buffer_;
MessageData license_ = {};
vector<uint8_t> key_handle_;
std::vector<uint8_t> session_key_;
std::vector<uint8_t> enc_session_key_;
vector<uint8_t> encrypted_usage_entry_;
uint32_t usage_entry_number_ = 0;