Snap for 4598635 from 928ae5639e to pi-release
Change-Id: Ib3917521dd2cbad97f8e1dc4ab613dac39a9be21
This commit is contained in:
@@ -39,6 +39,10 @@ class PolicyEngine {
|
|||||||
// out why a key is not usable.
|
// out why a key is not usable.
|
||||||
virtual CdmKeyStatus GetKeyStatus(const KeyId& key_id);
|
virtual CdmKeyStatus GetKeyStatus(const KeyId& key_id);
|
||||||
|
|
||||||
|
// Verifies whether the policy allows use of the specified key of
|
||||||
|
// a given security level for content decryption.
|
||||||
|
virtual bool CanUseKey(const KeyId& key_id, CdmSecurityLevel security_level);
|
||||||
|
|
||||||
// OnTimerEvent is called when a timer fires. It notifies the Policy Engine
|
// OnTimerEvent is called when a timer fires. It notifies the Policy Engine
|
||||||
// that the timer has fired and dispatches the relevant events through
|
// that the timer has fired and dispatches the relevant events through
|
||||||
// |event_listener_|.
|
// |event_listener_|.
|
||||||
|
|||||||
@@ -78,12 +78,14 @@ static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2";
|
|||||||
static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3";
|
static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3";
|
||||||
static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown";
|
static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown";
|
||||||
static const std::string QUERY_VALUE_SECURITY_LEVEL_DEFAULT = "Default";
|
static const std::string QUERY_VALUE_SECURITY_LEVEL_DEFAULT = "Default";
|
||||||
static const std::string QUERY_VALUE_DISCONNECTED = "Disconnected";
|
static const std::string QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT =
|
||||||
static const std::string QUERY_VALUE_UNPROTECTED = "Unprotected";
|
"HDCP-NoDigitalOutput";
|
||||||
|
static const std::string QUERY_VALUE_HDCP_NONE = "HDCP-None";
|
||||||
static const std::string QUERY_VALUE_HDCP_V1 = "HDCP-1.x";
|
static const std::string QUERY_VALUE_HDCP_V1 = "HDCP-1.x";
|
||||||
static const std::string QUERY_VALUE_HDCP_V2_0 = "HDCP-2.0";
|
static const std::string QUERY_VALUE_HDCP_V2_0 = "HDCP-2.0";
|
||||||
static const std::string QUERY_VALUE_HDCP_V2_1 = "HDCP-2.1";
|
static const std::string QUERY_VALUE_HDCP_V2_1 = "HDCP-2.1";
|
||||||
static const std::string QUERY_VALUE_HDCP_V2_2 = "HDCP-2.2";
|
static const std::string QUERY_VALUE_HDCP_V2_2 = "HDCP-2.2";
|
||||||
|
static const std::string QUERY_VALUE_HDCP_LEVEL_UNKNOWN = "HDCP-LevelUnknown";
|
||||||
|
|
||||||
static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4";
|
static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4";
|
||||||
static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4";
|
static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4";
|
||||||
|
|||||||
@@ -428,6 +428,16 @@ struct CdmUsageEntryInfo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CdmKeySecurityLevel {
|
||||||
|
kKeySecurityLevelUnset,
|
||||||
|
kSoftwareSecureCrypto,
|
||||||
|
kSoftwareSecureDecode,
|
||||||
|
kHardwareSecureCrypto,
|
||||||
|
kHardwareSecureDecode,
|
||||||
|
kHardwareSecureAll,
|
||||||
|
kKeySecurityLevelUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
class CdmKeyAllowedUsage {
|
class CdmKeyAllowedUsage {
|
||||||
public:
|
public:
|
||||||
CdmKeyAllowedUsage() {
|
CdmKeyAllowedUsage() {
|
||||||
@@ -444,6 +454,7 @@ class CdmKeyAllowedUsage {
|
|||||||
generic_decrypt = false;
|
generic_decrypt = false;
|
||||||
generic_sign = false;
|
generic_sign = false;
|
||||||
generic_verify = false;
|
generic_verify = false;
|
||||||
|
key_security_level_ = kKeySecurityLevelUnset;
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +465,8 @@ class CdmKeyAllowedUsage {
|
|||||||
generic_encrypt != other.generic_encrypt ||
|
generic_encrypt != other.generic_encrypt ||
|
||||||
generic_decrypt != other.generic_decrypt ||
|
generic_decrypt != other.generic_decrypt ||
|
||||||
generic_sign != other.generic_sign ||
|
generic_sign != other.generic_sign ||
|
||||||
generic_verify != other.generic_verify) {
|
generic_verify != other.generic_verify ||
|
||||||
|
key_security_level_ != other.key_security_level_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -466,6 +478,7 @@ class CdmKeyAllowedUsage {
|
|||||||
bool generic_decrypt;
|
bool generic_decrypt;
|
||||||
bool generic_sign;
|
bool generic_sign;
|
||||||
bool generic_verify;
|
bool generic_verify;
|
||||||
|
CdmKeySecurityLevel key_security_level_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool valid_;
|
bool valid_;
|
||||||
|
|||||||
@@ -1621,7 +1621,7 @@ std::string CdmEngine::MapHdcpVersion(
|
|||||||
CryptoSession::HdcpCapability version) {
|
CryptoSession::HdcpCapability version) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case HDCP_NONE:
|
case HDCP_NONE:
|
||||||
return QUERY_VALUE_UNPROTECTED;
|
return QUERY_VALUE_HDCP_NONE;
|
||||||
case HDCP_V1:
|
case HDCP_V1:
|
||||||
return QUERY_VALUE_HDCP_V1;
|
return QUERY_VALUE_HDCP_V1;
|
||||||
case HDCP_V2:
|
case HDCP_V2:
|
||||||
@@ -1631,9 +1631,10 @@ std::string CdmEngine::MapHdcpVersion(
|
|||||||
case HDCP_V2_2:
|
case HDCP_V2_2:
|
||||||
return QUERY_VALUE_HDCP_V2_2;
|
return QUERY_VALUE_HDCP_V2_2;
|
||||||
case HDCP_NO_DIGITAL_OUTPUT:
|
case HDCP_NO_DIGITAL_OUTPUT:
|
||||||
return QUERY_VALUE_DISCONNECTED;
|
return QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT;
|
||||||
|
default:
|
||||||
|
return QUERY_VALUE_HDCP_LEVEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdmEngine::CloseExpiredReleaseSessions() {
|
void CdmEngine::CloseExpiredReleaseSessions() {
|
||||||
|
|||||||
@@ -557,6 +557,9 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
|||||||
return NEED_KEY;
|
return NEED_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!policy_engine_->CanUseKey(*params.key_id, security_level_))
|
||||||
|
return KEY_PROHIBITED_FOR_SECURITY_LEVEL;
|
||||||
|
|
||||||
CdmResponseType status = crypto_session_->Decrypt(params);
|
CdmResponseType status = crypto_session_->Decrypt(params);
|
||||||
|
|
||||||
if (status == NO_ERROR) {
|
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_clear_buffer = true;
|
||||||
allowed_usage_.decrypt_to_secure_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();
|
allowed_usage_.SetValid();
|
||||||
|
|
||||||
if (key.video_resolution_constraints_size() > 0) {
|
if (key.video_resolution_constraints_size() > 0) {
|
||||||
|
|||||||
@@ -1368,7 +1368,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
key_array_v13[i].key_data_length = key_array[i].key_data_length;
|
key_array_v13[i].key_data_length = key_array[i].key_data_length;
|
||||||
key_array_v13[i].key_control_iv = key_array[i].key_control_iv;
|
key_array_v13[i].key_control_iv = key_array[i].key_control_iv;
|
||||||
key_array_v13[i].key_control = key_array[i].key_control;
|
key_array_v13[i].key_control = key_array[i].key_control;
|
||||||
key_array_v13[i].cipher_mode == OEMCrypto_CipherMode_CTR;
|
key_array_v13[i].cipher_mode = OEMCrypto_CipherMode_CTR;
|
||||||
}
|
}
|
||||||
OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL;
|
OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL;
|
||||||
if (num_keys > 0) key_array_v13_ptr = &key_array_v13[0];
|
if (num_keys > 0) key_array_v13_ptr = &key_array_v13[0];
|
||||||
|
|||||||
@@ -309,6 +309,32 @@ CdmResponseType PolicyEngine::QueryKeyAllowedUsage(
|
|||||||
return KEY_NOT_FOUND_1;
|
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) {
|
bool PolicyEngine::GetSecondsSinceStarted(int64_t* seconds_since_started) {
|
||||||
if (playback_start_time_ == 0) return false;
|
if (playback_start_time_ == 0) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -157,9 +157,11 @@ class LicenseKeysTest : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void ExpectAllowedUsageContent(
|
virtual void ExpectAllowedUsageContent(
|
||||||
const CdmKeyAllowedUsage& key_usage, KeyFlag secure, KeyFlag clear) {
|
const CdmKeyAllowedUsage& key_usage, KeyFlag secure, KeyFlag clear,
|
||||||
|
CdmKeySecurityLevel key_security_level) {
|
||||||
EXPECT_EQ(key_usage.decrypt_to_secure_buffer, secure == kKeyFlagTrue);
|
EXPECT_EQ(key_usage.decrypt_to_secure_buffer, secure == kKeyFlagTrue);
|
||||||
EXPECT_EQ(key_usage.decrypt_to_clear_buffer, clear == kKeyFlagTrue);
|
EXPECT_EQ(key_usage.decrypt_to_clear_buffer, clear == kKeyFlagTrue);
|
||||||
|
EXPECT_EQ(key_usage.key_security_level_, key_security_level);
|
||||||
EXPECT_FALSE(key_usage.generic_encrypt);
|
EXPECT_FALSE(key_usage.generic_encrypt);
|
||||||
EXPECT_FALSE(key_usage.generic_decrypt);
|
EXPECT_FALSE(key_usage.generic_decrypt);
|
||||||
EXPECT_FALSE(key_usage.generic_sign);
|
EXPECT_FALSE(key_usage.generic_sign);
|
||||||
@@ -420,36 +422,41 @@ TEST_F(LicenseKeysTest, AllowedUsageNull) {
|
|||||||
|
|
||||||
CdmKeyAllowedUsage usage_2;
|
CdmKeyAllowedUsage usage_2;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(c_key, &usage_2));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(c_key, &usage_2));
|
||||||
ExpectAllowedUsageContent(usage_2, kContentClearTrue, kContentSecureTrue);
|
ExpectAllowedUsageContent(usage_2, kContentClearTrue, kContentSecureTrue,
|
||||||
|
kKeySecurityLevelUnset);
|
||||||
|
|
||||||
CdmKeyAllowedUsage usage_3;
|
CdmKeyAllowedUsage usage_3;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(os_key, &usage_3));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(os_key, &usage_3));
|
||||||
ExpectAllowedUsageContent(usage_3, kContentClearFalse, kContentSecureFalse);
|
ExpectAllowedUsageContent(usage_3, kContentClearFalse, kContentSecureFalse,
|
||||||
|
kKeySecurityLevelUnset);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LicenseKeysTest, AllowedUsageContent) {
|
TEST_F(LicenseKeysTest, AllowedUsageContent) {
|
||||||
StageContentKeys();
|
StageContentKeys();
|
||||||
CdmKeyAllowedUsage u_sw_crypto;
|
CdmKeyAllowedUsage u_sw_crypto;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_sw_crypto, &u_sw_crypto));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_sw_crypto, &u_sw_crypto));
|
||||||
ExpectAllowedUsageContent(u_sw_crypto, kContentSecureTrue, kContentClearTrue);
|
ExpectAllowedUsageContent(u_sw_crypto, kContentSecureTrue, kContentClearTrue,
|
||||||
|
kSoftwareSecureCrypto);
|
||||||
|
|
||||||
CdmKeyAllowedUsage u_sw_decode;
|
CdmKeyAllowedUsage u_sw_decode;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_sw_decode, &u_sw_decode));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_sw_decode, &u_sw_decode));
|
||||||
ExpectAllowedUsageContent(u_sw_decode, kContentSecureTrue, kContentClearTrue);
|
ExpectAllowedUsageContent(u_sw_decode, kContentSecureTrue, kContentClearTrue,
|
||||||
|
kSoftwareSecureDecode);
|
||||||
|
|
||||||
CdmKeyAllowedUsage u_hw_crypto;
|
CdmKeyAllowedUsage u_hw_crypto;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_crypto, &u_hw_crypto));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_crypto, &u_hw_crypto));
|
||||||
ExpectAllowedUsageContent(u_hw_crypto, kContentSecureTrue, kContentClearTrue);
|
ExpectAllowedUsageContent(u_hw_crypto, kContentSecureTrue, kContentClearTrue,
|
||||||
|
kHardwareSecureCrypto);
|
||||||
|
|
||||||
CdmKeyAllowedUsage u_hw_decode;
|
CdmKeyAllowedUsage u_hw_decode;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_decode, &u_hw_decode));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_decode, &u_hw_decode));
|
||||||
ExpectAllowedUsageContent(u_hw_decode, kContentSecureTrue,
|
ExpectAllowedUsageContent(u_hw_decode, kContentSecureTrue,
|
||||||
kContentClearFalse);
|
kContentClearFalse, kHardwareSecureDecode);
|
||||||
|
|
||||||
CdmKeyAllowedUsage u_hw_secure;
|
CdmKeyAllowedUsage u_hw_secure;
|
||||||
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_secure, &u_hw_secure));
|
EXPECT_TRUE(license_keys_.GetAllowedUsage(ck_hw_secure, &u_hw_secure));
|
||||||
ExpectAllowedUsageContent(u_hw_secure, kContentSecureTrue,
|
ExpectAllowedUsageContent(u_hw_secure, kContentSecureTrue,
|
||||||
kContentClearFalse);
|
kContentClearFalse, kHardwareSecureAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LicenseKeysTest, AllowedUsageOperatorSession) {
|
TEST_F(LicenseKeysTest, AllowedUsageOperatorSession) {
|
||||||
|
|||||||
@@ -1568,6 +1568,63 @@ TEST_F(PolicyEngineTest, PlaybackOk_CanStoreGracePeriod) {
|
|||||||
EXPECT_EQ(kPlaybackStartTime, policy_engine_->GetGracePeriodEndTime());
|
EXPECT_EQ(kPlaybackStartTime, policy_engine_->GetGracePeriodEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct KeySecurityLevelParams {
|
||||||
|
bool is_security_level_set;
|
||||||
|
License::KeyContainer::SecurityLevel security_level;
|
||||||
|
bool expect_can_L1_use_key;
|
||||||
|
bool expect_can_L2_use_key;
|
||||||
|
bool expect_can_L3_use_key;
|
||||||
|
bool expect_can_level_unknown_use_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
KeySecurityLevelParams key_security_test_vectors[] = {
|
||||||
|
{ false, License::KeyContainer::HW_SECURE_ALL, true, true, true, true },
|
||||||
|
{ true, License::KeyContainer::SW_SECURE_CRYPTO, true, true, true, false },
|
||||||
|
{ true, License::KeyContainer::SW_SECURE_DECODE, true, true, true, false },
|
||||||
|
{ true, License::KeyContainer::HW_SECURE_CRYPTO, true, true, false, false },
|
||||||
|
{ true, License::KeyContainer::HW_SECURE_DECODE, true, false, false, false },
|
||||||
|
{ true, License::KeyContainer::HW_SECURE_ALL, true, false, false, false },
|
||||||
|
};
|
||||||
|
|
||||||
|
class PolicyEngineKeySecurityLevelTest
|
||||||
|
: public PolicyEngineTest,
|
||||||
|
public ::testing::WithParamInterface<KeySecurityLevelParams*> {};
|
||||||
|
|
||||||
|
TEST_P(PolicyEngineKeySecurityLevelTest, CanUseKey) {
|
||||||
|
|
||||||
|
KeySecurityLevelParams* param = GetParam();
|
||||||
|
|
||||||
|
license_.clear_key();
|
||||||
|
|
||||||
|
License::KeyContainer* content_key = license_.add_key();
|
||||||
|
content_key->set_type(License::KeyContainer::CONTENT);
|
||||||
|
content_key->set_id(kKeyId);
|
||||||
|
if (param->is_security_level_set)
|
||||||
|
content_key->set_level(param->security_level);
|
||||||
|
|
||||||
|
EXPECT_CALL(*mock_clock_, GetCurrentTime())
|
||||||
|
.WillOnce(Return(kLicenseStartTime + 1));
|
||||||
|
|
||||||
|
ExpectSessionKeysChange(kKeyStatusUsable, true);
|
||||||
|
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(_, _));
|
||||||
|
|
||||||
|
policy_engine_->SetLicense(license_);
|
||||||
|
|
||||||
|
EXPECT_EQ(param->expect_can_L1_use_key,
|
||||||
|
policy_engine_->CanUseKey(kKeyId, kSecurityLevelL1));
|
||||||
|
EXPECT_EQ(param->expect_can_L2_use_key,
|
||||||
|
policy_engine_->CanUseKey(kKeyId, kSecurityLevelL2));
|
||||||
|
EXPECT_EQ(param->expect_can_L3_use_key,
|
||||||
|
policy_engine_->CanUseKey(kKeyId, kSecurityLevelL3));
|
||||||
|
EXPECT_EQ(param->expect_can_level_unknown_use_key,
|
||||||
|
policy_engine_->CanUseKey(kKeyId, kSecurityLevelUnknown));
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
PolicyEngine, PolicyEngineKeySecurityLevelTest,
|
||||||
|
::testing::Range(&key_security_test_vectors[0],
|
||||||
|
&key_security_test_vectors[5]));
|
||||||
|
|
||||||
class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
|
class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
|
||||||
protected:
|
protected:
|
||||||
enum KeyFlag {
|
enum KeyFlag {
|
||||||
@@ -1596,9 +1653,11 @@ class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
|
|||||||
|
|
||||||
|
|
||||||
void ExpectAllowedContentKeySettings(const CdmKeyAllowedUsage& key_usage,
|
void ExpectAllowedContentKeySettings(const CdmKeyAllowedUsage& key_usage,
|
||||||
KeyFlag secure, KeyFlag clear) {
|
KeyFlag secure, KeyFlag clear,
|
||||||
|
CdmKeySecurityLevel key_security_level) {
|
||||||
EXPECT_EQ(key_usage.decrypt_to_secure_buffer, secure == kKeyFlagTrue);
|
EXPECT_EQ(key_usage.decrypt_to_secure_buffer, secure == kKeyFlagTrue);
|
||||||
EXPECT_EQ(key_usage.decrypt_to_clear_buffer, clear == kKeyFlagTrue);
|
EXPECT_EQ(key_usage.decrypt_to_clear_buffer, clear == kKeyFlagTrue);
|
||||||
|
EXPECT_EQ(key_usage.key_security_level_, key_security_level);
|
||||||
EXPECT_FALSE(key_usage.generic_encrypt);
|
EXPECT_FALSE(key_usage.generic_encrypt);
|
||||||
EXPECT_FALSE(key_usage.generic_decrypt);
|
EXPECT_FALSE(key_usage.generic_decrypt);
|
||||||
EXPECT_FALSE(key_usage.generic_sign);
|
EXPECT_FALSE(key_usage.generic_sign);
|
||||||
@@ -1616,22 +1675,24 @@ class PolicyEngineKeyAllowedUsageTest : public PolicyEngineTest {
|
|||||||
EXPECT_EQ(key_usage.generic_verify, verify == kKeyFlagTrue);
|
EXPECT_EQ(key_usage.generic_verify, verify == kKeyFlagTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectSecureContentKey(const KeyId& key_id) {
|
void ExpectSecureContentKey(const KeyId& key_id,
|
||||||
|
CdmKeySecurityLevel key_security_level) {
|
||||||
CdmKeyAllowedUsage key_usage;
|
CdmKeyAllowedUsage key_usage;
|
||||||
EXPECT_EQ(NO_ERROR,
|
EXPECT_EQ(NO_ERROR,
|
||||||
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
|
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
|
||||||
|
|
||||||
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
|
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
|
||||||
kContentSecureFalse);
|
kContentSecureFalse, key_security_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectLessSecureContentKey(const KeyId& key_id) {
|
void ExpectLessSecureContentKey(const KeyId& key_id,
|
||||||
|
CdmKeySecurityLevel key_security_level) {
|
||||||
CdmKeyAllowedUsage key_usage;
|
CdmKeyAllowedUsage key_usage;
|
||||||
EXPECT_EQ(NO_ERROR,
|
EXPECT_EQ(NO_ERROR,
|
||||||
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
|
policy_engine_->QueryKeyAllowedUsage(key_id, &key_usage));
|
||||||
|
|
||||||
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
|
ExpectAllowedContentKeySettings(key_usage, kContentSecureTrue,
|
||||||
kContentSecureTrue);
|
kContentSecureTrue, key_security_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectOperatorSessionKey(const KeyId& key_id, KeyFlag encrypt,
|
void ExpectOperatorSessionKey(const KeyId& key_id, KeyFlag encrypt,
|
||||||
@@ -1702,8 +1763,8 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageBasic) {
|
|||||||
|
|
||||||
policy_engine_->SetLicense(license_);
|
policy_engine_->SetLicense(license_);
|
||||||
|
|
||||||
ExpectSecureContentKey(kKeyId);
|
ExpectSecureContentKey(kKeyId, kHardwareSecureAll);
|
||||||
ExpectLessSecureContentKey(kAnotherKeyId);
|
ExpectLessSecureContentKey(kAnotherKeyId, kKeySecurityLevelUnset);
|
||||||
ExpectOperatorSessionKey(kGenericKeyId, kEncryptNull, kDecryptNull,
|
ExpectOperatorSessionKey(kGenericKeyId, kEncryptNull, kDecryptNull,
|
||||||
kSignTrue, kVerifyNull);
|
kSignTrue, kVerifyNull);
|
||||||
|
|
||||||
@@ -1762,8 +1823,8 @@ TEST_F(PolicyEngineKeyAllowedUsageTest, AllowedUsageGeneric) {
|
|||||||
|
|
||||||
policy_engine_->SetLicense(license_);
|
policy_engine_->SetLicense(license_);
|
||||||
|
|
||||||
ExpectSecureContentKey(kKeyId);
|
ExpectSecureContentKey(kKeyId, kHardwareSecureDecode);
|
||||||
ExpectLessSecureContentKey(kAnotherKeyId);
|
ExpectLessSecureContentKey(kAnotherKeyId, kHardwareSecureCrypto);
|
||||||
ExpectOperatorSessionKey(kGenericEncryptKeyId, kEncryptTrue, kDecryptFalse,
|
ExpectOperatorSessionKey(kGenericEncryptKeyId, kEncryptTrue, kDecryptFalse,
|
||||||
kSignFalse, kVerifyFalse);
|
kSignFalse, kVerifyFalse);
|
||||||
ExpectOperatorSessionKey(kGenericDecryptKeyId, kEncryptFalse, kDecryptTrue,
|
ExpectOperatorSessionKey(kGenericDecryptKeyId, kEncryptFalse, kDecryptTrue,
|
||||||
|
|||||||
@@ -62,5 +62,3 @@ void AmiAdapter::UpdateDouble(const std::string& metric_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -881,6 +881,17 @@ const std::string kFullCencPssh = wvcdm::a2bs_hex(
|
|||||||
"74657374220a323031355f7465617273"
|
"74657374220a323031355f7465617273"
|
||||||
"2a024844");
|
"2a024844");
|
||||||
|
|
||||||
|
const std::string kFullCensPssh = wvcdm::a2bs_hex(
|
||||||
|
"00000053" // blob size
|
||||||
|
"70737368" // "pssh"
|
||||||
|
"00000000" // flags
|
||||||
|
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||||
|
"00000033" // pssh data size
|
||||||
|
"12103030303030303030303030303030" // pssh data
|
||||||
|
"30321a0d7769646576696e655f746573"
|
||||||
|
"74220a323031355f746561727348f3dc"
|
||||||
|
"959b06");
|
||||||
|
|
||||||
const std::string kFullCbc1Pssh = wvcdm::a2bs_hex(
|
const std::string kFullCbc1Pssh = wvcdm::a2bs_hex(
|
||||||
"00000053" // blob size
|
"00000053" // blob size
|
||||||
"70737368" // "pssh"
|
"70737368" // "pssh"
|
||||||
@@ -892,6 +903,18 @@ const std::string kFullCbc1Pssh = wvcdm::a2bs_hex(
|
|||||||
"74220a323031355f746561727348b1c6"
|
"74220a323031355f746561727348b1c6"
|
||||||
"899b06");
|
"899b06");
|
||||||
|
|
||||||
|
|
||||||
|
const std::string kFullCbcsPssh = wvcdm::a2bs_hex(
|
||||||
|
"00000053" // blob size
|
||||||
|
"70737368" // "pssh"
|
||||||
|
"00000000" // flags
|
||||||
|
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||||
|
"00000033" // pssh data size
|
||||||
|
"12103030303030303030303030303030"
|
||||||
|
"30321a0d7769646576696e655f746573"
|
||||||
|
"74220a323031355f746561727348f3c6"
|
||||||
|
"899b06");
|
||||||
|
|
||||||
struct Cenc30SampleInfo {
|
struct Cenc30SampleInfo {
|
||||||
bool is_encrypted;
|
bool is_encrypted;
|
||||||
wvcdm::KeyId key_id;
|
wvcdm::KeyId key_id;
|
||||||
@@ -952,6 +975,31 @@ Cenc30SampleInfo kCenc30CencKey32Sample = {
|
|||||||
wvcdm::kCipherModeCtr,
|
wvcdm::kCipherModeCtr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Cenc30SampleInfo kCenc30CensKey33Sample = {
|
||||||
|
true, wvcdm::a2bs_hex("30303030303030303030303030303033"),
|
||||||
|
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
|
||||||
|
wvcdm::a2bs_hex(
|
||||||
|
"011E88387D58EBB8E5CDCC38D431EEF4B6094B9201F200932F8EB5E1A94FB0B977"
|
||||||
|
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
|
||||||
|
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
|
||||||
|
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
|
||||||
|
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC868701CB8BE038"
|
||||||
|
"15BBFFB95FD3A86F142127720A35234070799173B37219127141922CBA8CB2DC48"
|
||||||
|
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
|
||||||
|
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
|
||||||
|
wvcdm::a2bs_hex(
|
||||||
|
"E7C566D86E98C36D2DCA54A966E7B469B6094B9201F200932F8EB5E1A94FB0B977"
|
||||||
|
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
|
||||||
|
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
|
||||||
|
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
|
||||||
|
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC8687B3A4AD15AD"
|
||||||
|
"A2ABBB84D8E3CBEC3E8771720A35234070799173B37219127141922CBA8CB2DC48"
|
||||||
|
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
|
||||||
|
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
|
||||||
|
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample,
|
||||||
|
wvcdm::kCipherModeCtr,
|
||||||
|
};
|
||||||
|
|
||||||
Cenc30SampleInfo kCenc30Cbc1Key33Sample = {
|
Cenc30SampleInfo kCenc30Cbc1Key33Sample = {
|
||||||
true, wvcdm::a2bs_hex("30303030303030303030303030303033"),
|
true, wvcdm::a2bs_hex("30303030303030303030303030303033"),
|
||||||
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
|
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
|
||||||
@@ -1002,12 +1050,49 @@ Cenc30SampleInfo kCenc30Cbc1Key32Sample = {
|
|||||||
wvcdm::kCipherModeCbc,
|
wvcdm::kCipherModeCbc,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cenc30SwitchCipherInfo {
|
Cenc30SampleInfo kCenc30CbcsKey33Sample = {
|
||||||
|
true, wvcdm::a2bs_hex("30303030303030303030303030303033"),
|
||||||
|
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
|
||||||
|
wvcdm::a2bs_hex(
|
||||||
|
"4392E38BAE263267ED15394DE349AD1577F37B7D906C3A61536EE5A288F66F22F2"
|
||||||
|
"F5098964B7F2860A848C3C4FD30E538B3BCD2E700DC3FBC1657A6E9EAE44DE97C4"
|
||||||
|
"6F27C82A49198EE185D92931F093C3342FDBF6CF8203E18CCDC4B88E79C95EC052"
|
||||||
|
"3FD10F9409945349169FAA8F6A37179D2BEDC04A158A09BCBF742DA05245428788"
|
||||||
|
"E972B9B465FED5849AEDDB74B8919673C0C8829B5B062A38B3146CB8D497F03A4D"
|
||||||
|
"5C0A1D463504C1F116A811EF32503695B8FF78D9E93CDF7B2F7493E8043D4DE110"
|
||||||
|
"FE1D342D1C0175BF1466A544FC0D02DD0E314098256DD65B48098323C3AED9B7E0"
|
||||||
|
"CF260DBC5A0F09A46E39AE5E26A66ABFA52CBA26FBA83975E4"),
|
||||||
|
wvcdm::a2bs_hex(
|
||||||
|
"E7C566D86E98C36D2DCA54A966E7B469B6094B9201F200932F8EB5E1A94FB0B977"
|
||||||
|
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
|
||||||
|
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
|
||||||
|
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
|
||||||
|
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC8687B3A4AD15AD"
|
||||||
|
"A2ABBB84D8E3CBEC3E8771720A35234070799173B37219127141922CBA8CB2DC48"
|
||||||
|
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
|
||||||
|
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
|
||||||
|
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample,
|
||||||
|
wvcdm::kCipherModeCbc,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SingleSampleDecryptionInfo {
|
||||||
|
const std::string pssh;
|
||||||
|
Cenc30SampleInfo sample_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
SingleSampleDecryptionInfo kCenc30DecryptionData[4] = {
|
||||||
|
{ kFullCencPssh, kCenc30CencKey33Sample },
|
||||||
|
{ kFullCensPssh, kCenc30CensKey33Sample },
|
||||||
|
{ kFullCbc1Pssh, kCenc30Cbc1Key33Sample },
|
||||||
|
{ kFullCbcsPssh, kCenc30CbcsKey33Sample },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FourSampleDecryptionInfo {
|
||||||
const std::string pssh;
|
const std::string pssh;
|
||||||
Cenc30SampleInfo sample_info[4];
|
Cenc30SampleInfo sample_info[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
Cenc30SwitchCipherInfo kCenc30SwitchCipherData[8] = {
|
FourSampleDecryptionInfo kCenc30SwitchCipherData[8] = {
|
||||||
// Switch between cipher modes
|
// Switch between cipher modes
|
||||||
{ kFullCencPssh, { kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample,
|
{ kFullCencPssh, { kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample,
|
||||||
kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, } },
|
kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, } },
|
||||||
@@ -3067,17 +3152,19 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
|
|||||||
decryptor_.QueryStatus(
|
decryptor_.QueryStatus(
|
||||||
kLevelDefault, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL, &value));
|
kLevelDefault, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL, &value));
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
|
value == QUERY_VALUE_HDCP_NONE || value == QUERY_VALUE_HDCP_V1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
|
value == QUERY_VALUE_HDCP_V2_2 ||
|
||||||
|
value == QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT);
|
||||||
|
|
||||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||||
decryptor_.QueryStatus(kLevelDefault,
|
decryptor_.QueryStatus(kLevelDefault,
|
||||||
wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
|
wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
|
value == QUERY_VALUE_HDCP_NONE || value == QUERY_VALUE_HDCP_V1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
|
value == QUERY_VALUE_HDCP_V2_2 ||
|
||||||
|
value == QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT);
|
||||||
|
|
||||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||||
decryptor_.QueryStatus(kLevelDefault,
|
decryptor_.QueryStatus(kLevelDefault,
|
||||||
@@ -3167,17 +3254,19 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) {
|
|||||||
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL,
|
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL,
|
||||||
&value));
|
&value));
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
|
value == QUERY_VALUE_HDCP_NONE || value == QUERY_VALUE_HDCP_V1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
|
value == QUERY_VALUE_HDCP_V2_2 ||
|
||||||
|
value == QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT);
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
wvcdm::NO_ERROR,
|
wvcdm::NO_ERROR,
|
||||||
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
|
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
|
value == QUERY_VALUE_HDCP_NONE || value == QUERY_VALUE_HDCP_V1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
|
||||||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
|
value == QUERY_VALUE_HDCP_V2_2 ||
|
||||||
|
value == QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT);
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
wvcdm::NO_ERROR,
|
wvcdm::NO_ERROR,
|
||||||
@@ -3860,9 +3949,74 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
::testing::Range(&kHlsFourCCBackwardCompatibilityTestVectors[0],
|
::testing::Range(&kHlsFourCCBackwardCompatibilityTestVectors[0],
|
||||||
&kHlsFourCCBackwardCompatibilityTestVectors[4]));
|
&kHlsFourCCBackwardCompatibilityTestVectors[4]));
|
||||||
|
|
||||||
|
class WvCenc30Test
|
||||||
|
: public WvCdmRequestLicenseTest,
|
||||||
|
public ::testing::WithParamInterface<SingleSampleDecryptionInfo*> {};
|
||||||
|
|
||||||
|
TEST_P(WvCenc30Test, DecryptionTest) {
|
||||||
|
Provision(kLevel3);
|
||||||
|
TestWvCdmClientPropertySet client_property_set;
|
||||||
|
client_property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||||
|
|
||||||
|
std::string value;
|
||||||
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||||
|
decryptor_.QueryStatus(
|
||||||
|
kLevel3, wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION, &value));
|
||||||
|
std::istringstream ss(value);
|
||||||
|
uint32_t api_version;
|
||||||
|
ss >> api_version;
|
||||||
|
ASSERT_FALSE(ss.fail());
|
||||||
|
EXPECT_TRUE(ss.eof());
|
||||||
|
|
||||||
|
// Ability to switch between cipher modes without re-requesting a license
|
||||||
|
// was introduced in OEMCrypto v14
|
||||||
|
if (api_version < 14u)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SingleSampleDecryptionInfo* info = GetParam();
|
||||||
|
|
||||||
|
TestWvCdmHlsEventListener listener;
|
||||||
|
decryptor_.OpenSession(g_key_system, &client_property_set,
|
||||||
|
kDefaultCdmIdentifier, &listener, &session_id_);
|
||||||
|
CdmAppParameterMap app_parameters;
|
||||||
|
GenerateKeyRequest(info->pssh, app_parameters,
|
||||||
|
kLicenseTypeStreaming, NULL);
|
||||||
|
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||||
|
CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap();
|
||||||
|
EXPECT_EQ(8u, key_status_map.size());
|
||||||
|
|
||||||
|
Cenc30SampleInfo* data = &info->sample_info;
|
||||||
|
std::vector<uint8_t> output_buffer(data->encrypted_data.size(), 0);
|
||||||
|
std::vector<uint8_t> iv(data->iv.begin(), data->iv.end());
|
||||||
|
CdmDecryptionParameters decryption_parameters(
|
||||||
|
&data->key_id,
|
||||||
|
reinterpret_cast<const uint8_t*>(data->encrypted_data.c_str()),
|
||||||
|
data->encrypted_data.size(), &iv, 0, &output_buffer[0]);
|
||||||
|
decryption_parameters.is_encrypted = data->is_encrypted;
|
||||||
|
decryption_parameters.is_secure = false;
|
||||||
|
decryption_parameters.cipher_mode = data->cipher_mode;
|
||||||
|
if (data->cipher_mode == kCipherModeCtr) {
|
||||||
|
decryption_parameters.pattern_descriptor.encrypt_blocks = 1;
|
||||||
|
decryption_parameters.pattern_descriptor.skip_blocks = 9;
|
||||||
|
}
|
||||||
|
decryption_parameters.subsample_flags = data->subsample_flags;
|
||||||
|
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, false,
|
||||||
|
decryption_parameters));
|
||||||
|
EXPECT_EQ(data->clear_data,
|
||||||
|
std::string(reinterpret_cast<const char*>(&output_buffer[0]),
|
||||||
|
output_buffer.size()));
|
||||||
|
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
Cdm, WvCenc30Test,
|
||||||
|
::testing::Range(&kCenc30DecryptionData[0],
|
||||||
|
&kCenc30DecryptionData[4]));
|
||||||
|
|
||||||
class WvCenc30SwitchCipherModeTest
|
class WvCenc30SwitchCipherModeTest
|
||||||
: public WvCdmRequestLicenseTest,
|
: public WvCdmRequestLicenseTest,
|
||||||
public ::testing::WithParamInterface<Cenc30SwitchCipherInfo*> {};
|
public ::testing::WithParamInterface<FourSampleDecryptionInfo*> {};
|
||||||
|
|
||||||
TEST_P(WvCenc30SwitchCipherModeTest, DecryptionTest) {
|
TEST_P(WvCenc30SwitchCipherModeTest, DecryptionTest) {
|
||||||
Provision(kLevel3);
|
Provision(kLevel3);
|
||||||
@@ -3884,7 +4038,7 @@ TEST_P(WvCenc30SwitchCipherModeTest, DecryptionTest) {
|
|||||||
if (api_version < 14)
|
if (api_version < 14)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Cenc30SwitchCipherInfo* info = GetParam();
|
FourSampleDecryptionInfo* info = GetParam();
|
||||||
|
|
||||||
TestWvCdmHlsEventListener listener;
|
TestWvCdmHlsEventListener listener;
|
||||||
decryptor_.OpenSession(g_key_system, &client_property_set,
|
decryptor_.OpenSession(g_key_system, &client_property_set,
|
||||||
|
|||||||
@@ -323,9 +323,14 @@ status_t WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
|
|||||||
"Error decrypting data: unspecified error");
|
"Error decrypting data: unspecified error");
|
||||||
break;
|
break;
|
||||||
case wvcdm::INSUFFICIENT_OUTPUT_PROTECTION:
|
case wvcdm::INSUFFICIENT_OUTPUT_PROTECTION:
|
||||||
|
case wvcdm::ANALOG_OUTPUT_ERROR:
|
||||||
errorDetailMsg->setTo(
|
errorDetailMsg->setTo(
|
||||||
"Error decrypting data: insufficient output protection");
|
"Error decrypting data: insufficient output protection");
|
||||||
break;
|
break;
|
||||||
|
case wvcdm::KEY_PROHIBITED_FOR_SECURITY_LEVEL:
|
||||||
|
errorDetailMsg->setTo(
|
||||||
|
"Error decrypting data: key prohibited for security level");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
actionableError = false;
|
actionableError = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -365,9 +365,14 @@ Status WVCryptoPlugin::attemptDecrypt(const CdmDecryptionParameters& params,
|
|||||||
"Error decrypting data: unspecified error");
|
"Error decrypting data: unspecified error");
|
||||||
break;
|
break;
|
||||||
case wvcdm::INSUFFICIENT_OUTPUT_PROTECTION:
|
case wvcdm::INSUFFICIENT_OUTPUT_PROTECTION:
|
||||||
|
case wvcdm::ANALOG_OUTPUT_ERROR:
|
||||||
errorDetailMsg->assign(
|
errorDetailMsg->assign(
|
||||||
"Error decrypting data: insufficient output protection");
|
"Error decrypting data: insufficient output protection");
|
||||||
break;
|
break;
|
||||||
|
case wvcdm::KEY_PROHIBITED_FOR_SECURITY_LEVEL:
|
||||||
|
errorDetailMsg->assign(
|
||||||
|
"Error decrypting data: key prohibited for security level");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
actionableError = false;
|
actionableError = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user