Detect when unable to meet policy requirements
[ Merged of http://go/wvgerrit/39766 ] The security level (software/hardware, decryption/decode) in the policy that specified how the key was to be used was not being respected for L3. Playback would either continue or a vendor specific error would be thrown. If the device cannot use the key as permitted by the policy CryptoException#ERROR_INSUFFICIENT_OUTPUT_PROTECTION will be thrown. Bug: 31913737 Bug: 31913439 Test: WV unit/integration tests Test: Playback using playmovies and netflix. Cast playback using playmovies. Change-Id: If25735ab0f789108431115623cb236687c5ef818
This commit is contained in:
@@ -557,6 +557,9 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
||||
return NEED_KEY;
|
||||
}
|
||||
|
||||
if (!policy_engine_->CanUseKey(*params.key_id, security_level_))
|
||||
return KEY_PROHIBITED_FOR_SECURITY_LEVEL;
|
||||
|
||||
CdmResponseType status = crypto_session_->Decrypt(params);
|
||||
|
||||
if (status == NO_ERROR) {
|
||||
|
||||
@@ -178,6 +178,31 @@ void LicenseKeyStatus::ParseContentKey(const KeyContainer& key) {
|
||||
allowed_usage_.decrypt_to_clear_buffer = true;
|
||||
allowed_usage_.decrypt_to_secure_buffer = true;
|
||||
}
|
||||
|
||||
if (key.has_level()) {
|
||||
switch (key.level()) {
|
||||
case KeyContainer::SW_SECURE_CRYPTO:
|
||||
allowed_usage_.key_security_level_ = kSoftwareSecureCrypto;
|
||||
break;
|
||||
case KeyContainer::SW_SECURE_DECODE:
|
||||
allowed_usage_.key_security_level_ = kSoftwareSecureDecode;
|
||||
break;
|
||||
case KeyContainer::HW_SECURE_CRYPTO:
|
||||
allowed_usage_.key_security_level_ = kHardwareSecureCrypto;
|
||||
break;
|
||||
case KeyContainer::HW_SECURE_DECODE:
|
||||
allowed_usage_.key_security_level_ = kHardwareSecureDecode;
|
||||
break;
|
||||
case KeyContainer::HW_SECURE_ALL:
|
||||
allowed_usage_.key_security_level_ = kHardwareSecureAll;
|
||||
break;
|
||||
default:
|
||||
allowed_usage_.key_security_level_ = kKeySecurityLevelUnknown;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
allowed_usage_.key_security_level_ = kKeySecurityLevelUnset;
|
||||
}
|
||||
allowed_usage_.SetValid();
|
||||
|
||||
if (key.video_resolution_constraints_size() > 0) {
|
||||
|
||||
@@ -309,6 +309,32 @@ CdmResponseType PolicyEngine::QueryKeyAllowedUsage(
|
||||
return KEY_NOT_FOUND_1;
|
||||
}
|
||||
|
||||
bool PolicyEngine::CanUseKey(
|
||||
const KeyId& key_id,
|
||||
CdmSecurityLevel security_level) {
|
||||
|
||||
if (security_level == kSecurityLevelL1) return true;
|
||||
|
||||
CdmKeyAllowedUsage key_usage;
|
||||
CdmResponseType status = QueryKeyAllowedUsage(key_id, &key_usage);
|
||||
|
||||
if (status != NO_ERROR) return false;
|
||||
|
||||
// L1 has already been addressed so verify that L2/3 are allowed
|
||||
switch (key_usage.key_security_level_) {
|
||||
case kKeySecurityLevelUnset:
|
||||
return true;
|
||||
case kSoftwareSecureCrypto:
|
||||
case kSoftwareSecureDecode:
|
||||
return security_level == kSecurityLevelL2 ||
|
||||
security_level == kSecurityLevelL3;
|
||||
case kHardwareSecureCrypto:
|
||||
return security_level == kSecurityLevelL2;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PolicyEngine::GetSecondsSinceStarted(int64_t* seconds_since_started) {
|
||||
if (playback_start_time_ == 0) return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user