Merge "Correct request_license_test failures"

This commit is contained in:
Rahul Frias
2018-02-07 17:06:57 +00:00
committed by Android (Google) Code Review
7 changed files with 279 additions and 33 deletions

View File

@@ -10,7 +10,9 @@ class ContentKeySession : public KeySession {
public:
ContentKeySession(CryptoSessionId oec_session_id,
metrics::CryptoMetrics* metrics)
: KeySession(metrics), oec_session_id_(oec_session_id) {}
: KeySession(metrics),
oec_session_id_(oec_session_id),
cipher_mode_(kCipherModeCtr) {}
virtual ~ContentKeySession() {}
KeySessionType Type() { return kDefault; }
@@ -32,7 +34,7 @@ class ContentKeySession : public KeySession {
CdmCipherMode* cipher_mode,
const std::string& srm_requirement);
OEMCryptoResult LoadEntitledContentKeys(const std::vector<CryptoKey>& keys) {
OEMCryptoResult LoadEntitledContentKeys(const std::vector<CryptoKey>&) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
@@ -56,6 +58,7 @@ class ContentKeySession : public KeySession {
private:
KeyId cached_key_id_;
CdmCipherMode cipher_mode_;
};
} // namespace wvcdm

View File

@@ -29,6 +29,7 @@ void GenerateMacContext(const std::string& input_context,
void GenerateEncryptContext(const std::string& input_context,
std::string* deriv_context);
size_t GetOffset(std::string message, std::string field);
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode);
class CryptoSession {
public:
@@ -272,8 +273,6 @@ class CryptoSession {
bool is_destination_buffer_type_valid_;
SecurityLevel requested_security_level_;
KeyId cached_key_id_;
bool is_usage_support_type_valid_;
CdmUsageSupportType usage_support_type_;
UsageTableHeader* usage_table_header_;
@@ -284,6 +283,7 @@ class CryptoSession {
static uint64_t request_id_index_;
CdmCipherMode cipher_mode_;
uint32_t api_version_;
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession);
};

View File

@@ -74,12 +74,14 @@ OEMCryptoResult ContentKeySession::LoadKeys(
OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id,
CdmCipherMode cipher_mode) {
// Crypto session lock already locked.
if (!cached_key_id_.empty() && cached_key_id_ == key_id) {
// Already using the desired key.
if (!cached_key_id_.empty() && cached_key_id_ == key_id &&
cipher_mode_ == cipher_mode) {
// Already using the desired key and cipher mode.
return OEMCrypto_SUCCESS;
}
cached_key_id_ = key_id;
cipher_mode_ = cipher_mode;
const uint8_t* key_id_string =
reinterpret_cast<const uint8_t*>(cached_key_id_.data());
@@ -87,7 +89,7 @@ OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id,
OEMCryptoResult sts;
M_TIME(sts = OEMCrypto_SelectKey(
oec_session_id_, key_id_string, cached_key_id_.size(),
static_cast<OEMCryptoCipherMode>(cipher_mode)),
ToOEMCryptoCipherMode(cipher_mode)),
metrics_, oemcrypto_select_key_, sts);
if (OEMCrypto_SUCCESS != sts) {
@@ -120,16 +122,17 @@ OEMCryptoResult ContentKeySession::LoadKeys(
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
const uint8_t* enc_mac_key = NULL;
const uint8_t* enc_mac_key_iv = NULL;
cached_key_id_.clear();
if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) {
enc_mac_key = msg + GetOffset(message, mac_key);
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
} else {
LOGV("ContentKeySession::LoadKeys: enc_mac_key not set");
}
std::vector<OEMCrypto_KeyObject> load_keys(keys.size());
std::vector<OEMCrypto_KeyObject_V13> load_keys(keys.size());
for (size_t i = 0; i < keys.size(); ++i) {
const CryptoKey* ki = &keys[i];
OEMCrypto_KeyObject* ko = &load_keys[i];
OEMCrypto_KeyObject_V13* ko = &load_keys[i];
ko->key_id = msg + GetOffset(message, ki->key_id());
ko->key_id_length = ki->key_id().length();
ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv());
@@ -144,6 +147,8 @@ OEMCryptoResult ContentKeySession::LoadKeys(
ko->key_control_iv = NULL;
ko->key_control = NULL;
}
ko->cipher_mode = ToOEMCryptoCipherMode(ki->cipher_mode());
// TODO(jfore): Is returning the cipher needed. If not drop this.
*cipher_mode = ki->cipher_mode();
}
@@ -162,7 +167,7 @@ OEMCryptoResult ContentKeySession::LoadKeys(
LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult sts;
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = ::OEMCrypto_LoadKeys_Back_Compat(
oec_session_id_, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst,

View File

@@ -41,6 +41,9 @@ const uint32_t kRsaSignatureLength = 256;
const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB
const size_t kEstimatedInitialUsageTableHeader = 40;
const size_t kOemCryptoApiVersionSupportsBigUsageTables = 13;
// Ability to switch cipher modes in SelectKey() was introduced in this
// OEMCrypto version
const size_t kOemCryptoApiVersionSupportsSwitchingCipherMode = 14;
// Constants and utility objects relating to OEM Certificates
const int kExtensionOidSize = 64;
@@ -126,6 +129,11 @@ OEMCrypto_LicenseType OEMCryptoLicenseType(CdmLicenseKeyType cdm_license_type) {
: OEMCrypto_EntitlementLicense;
}
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode) {
return cipher_mode == kCipherModeCtr
? OEMCrypto_CipherMode_CTR : OEMCrypto_CipherMode_CBC;
}
CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
: metrics_(metrics),
system_id_(-1),
@@ -137,7 +145,8 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
usage_support_type_(kUnknownUsageSupport),
usage_table_header_(NULL),
request_id_base_(0),
cipher_mode_(kCipherModeCtr) {
cipher_mode_(kCipherModeCtr),
api_version_(0) {
assert(metrics);
Init();
life_span_.Start();
@@ -664,6 +673,11 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
metrics_->oemcrypto_get_random_.Increment(random_sts);
++request_id_index_;
if (!GetApiVersion(&api_version_)) {
LOGE("CryptoSession::Open: GetApiVersion failed");
return USAGE_SUPPORT_GET_API_FAILED;
}
CdmUsageSupportType usage_support_type;
CdmResponseType result = GetUsageSupportType(&usage_support_type);
if (result == NO_ERROR) {
@@ -1071,8 +1085,10 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) {
sts = CopyBufferInChunks(params, buffer_descriptor);
}
}
if (params.is_encrypted && params.cipher_mode != cipher_mode_) {
return INCORRECT_CRYPTO_MODE;
if (api_version_ < kOemCryptoApiVersionSupportsSwitchingCipherMode) {
if (params.is_encrypted && params.cipher_mode != cipher_mode_) {
return INCORRECT_CRYPTO_MODE;
}
}
if (params.is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
OEMCrypto_CENCEncryptPatternDesc pattern_descriptor;
@@ -1928,14 +1944,8 @@ CdmResponseType CryptoSession::GetUsageSupportType(
return NO_ERROR;
}
uint32_t api_version = 0;
if (!GetApiVersion(&api_version)) {
LOGE("GetUsageSupportType: GetApiVersion failed");
return USAGE_SUPPORT_GET_API_FAILED;
}
*usage_support_type = usage_support_type_ =
(api_version >= kOemCryptoApiVersionSupportsBigUsageTables)
(api_version_ >= kOemCryptoApiVersionSupportsBigUsageTables)
? kUsageEntrySupport
: kUsageTableSupport;
return NO_ERROR;

View File

@@ -955,6 +955,8 @@ bool CdmLicense::RestoreLicenseForRelease(
if (!crypto_session_->GenerateDerivedKeys(key_request_,
signed_response.session_key()))
return false;
} else {
return KEY_ADDED == HandleKeyResponse(license_response);
}
if (license.policy().has_renewal_server_url())

View File

@@ -100,7 +100,7 @@ OEMCryptoResult SubLicenseKeySession::SelectKey(const std::string& key_id,
it->second,
reinterpret_cast<const uint8_t*>(keys_[i].key_id().data()),
keys_[i].key_id().size(),
static_cast<OEMCryptoCipherMode>(cipher_mode)),
ToOEMCryptoCipherMode(cipher_mode)),
metrics_, oemcrypto_select_key_, status);
if (OEMCrypto_SUCCESS != status) {
return status;
@@ -184,7 +184,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
}
for (size_t i = 0; i < keys.size(); i++) {
OEMCrypto_KeyObject key_object;
OEMCrypto_KeyObject_V13 key_object;
const CryptoKey& key_data = keys[i];
key_object.key_id = msg + GetOffset(message, key_data.key_id());
key_object.key_id_length = key_data.key_id().length();
@@ -201,6 +201,8 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
key_object.key_control_iv = NULL;
key_object.key_control = NULL;
}
key_object.cipher_mode = ToOEMCryptoCipherMode(key_data.cipher_mode());
// TODO(jfore): Does returning the cipher mode serve any purpose?
// If not drop.
*cipher_mode = key_data.cipher_mode();
@@ -215,7 +217,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
OEMCryptoResult sts;
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = OEMCrypto_LoadKeys_Back_Compat(
oec_session_id->second, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()),
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
@@ -230,7 +232,7 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
oec_session_id->second,
reinterpret_cast<const uint8_t*>(key_data.key_id().data()),
key_data.key_id().size(),
static_cast<OEMCryptoCipherMode>(key_data.cipher_mode())),
ToOEMCryptoCipherMode(key_data.cipher_mode())),
metrics_, oemcrypto_select_key_, sts);
if (sts != OEMCrypto_SUCCESS) {
@@ -312,7 +314,7 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
return sts;
}
OEMCrypto_KeyObject key_object;
OEMCrypto_KeyObject_V13 key_object;
key_object.key_id = msg + GetOffset(message, keys_[key_index].key_id());
key_object.key_id_length = keys_[key_index].key_id().length();
key_object.key_data_iv =
@@ -325,9 +327,11 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
key_object.key_control =
msg + GetOffset(message, keys_[key_index].key_control());
}
key_object.cipher_mode =
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode());
M_TIME(
sts = OEMCrypto_LoadKeys(
sts = OEMCrypto_LoadKeys_Back_Compat(
it->second, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
@@ -342,7 +346,7 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
it->second,
reinterpret_cast<const uint8_t*>(keys_[key_index].key_id().data()),
keys_[key_index].key_id().size(),
static_cast<OEMCryptoCipherMode>(keys_[key_index].cipher_mode())),
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode())),
metrics_, oemcrypto_select_key_, sts);
return sts;

View File

@@ -871,6 +871,165 @@ HlsDecryptionInfo kHlsFourCCBackwardCompatibilityTestVectors[] = {
{true, 1, &kSampleAes160ByteSegmentInfo[0], kHlsPsshSampleAesFourCC},
};
const std::string kFullCencPssh = wvcdm::a2bs_hex(
"00000044" // blob size
"70737368" // "pssh"
"00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000024" // pssh data size
"08011201321a0d7769646576696e655f" // pssh data
"74657374220a323031355f7465617273"
"2a024844");
const std::string kFullCbc1Pssh = wvcdm::a2bs_hex(
"00000053" // blob size
"70737368" // "pssh"
"00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000033" // pssh data size
"12103030303030303030303030303030" // pssh data
"30321a0d7769646576696e655f746573"
"74220a323031355f746561727348b1c6"
"899b06");
struct Cenc30SampleInfo {
bool is_encrypted;
wvcdm::KeyId key_id;
std::string iv;
std::string clear_data;
std::string encrypted_data;
uint8_t subsample_flags;
wvcdm::CdmCipherMode cipher_mode;
};
Cenc30SampleInfo kCenc30CencKey33Sample = {
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 kCenc30CencKey32Sample = {
true, wvcdm::a2bs_hex("30303030303030303030303030303032"),
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
wvcdm::a2bs_hex(
"1B605E32B31D6245BCCC01C4E7720725B6094B9201F200932F8EB5E1A94FB0B977"
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC8687DBFDF7F684"
"3A552DCB7C38E461EDF5F3720A35234070799173B37219127141922CBA8CB2DC48"
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
wvcdm::a2bs_hex(
"E7C566D86E98C36D2DCA54A966E7B469B6094B9201F200932F8EB5E1A94FB0B977"
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC8687B3A4AD15AD"
"A2ABBB84D8E3CBEC3E8771720A35234070799173B37219127141922CBA8CB2DC48"
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample,
wvcdm::kCipherModeCtr,
};
Cenc30SampleInfo kCenc30Cbc1Key33Sample = {
true, wvcdm::a2bs_hex("30303030303030303030303030303033"),
wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"),
wvcdm::a2bs_hex(
"E300F37FEB0CDD9F276E67B971FF423003F3BF21DCF6100BA453A473A4522A19A8"
"2E098AA25511011D386FC7092FE3B407DF2BEB3AD57D5E1178F041E3FCABE25193"
"3F5EE35670CEB96BA3DAF922484F9A37773EF75D4B17FACC80B475004A6229AB4C"
"DFFA426468E578DE6A0285D942CDE476E06FF907D03F382552C2E14399C3FC2D21"
"9A59819FFF837EBC88A9F83A42D37F48ED8564EB40AC3BA8A6D2634A81F04FC2F1"
"379A45869036FD72B39C88222646AB7486A8416D78AB75951EB87ED1E16DF69209"
"A6966AC93C7BB65B85E429357A732CBC75F6EFB1781859FB771D60D11EB381D9CA"
"63F793507B02207810773FCABED0240E5BEEAD30116014E481"),
wvcdm::a2bs_hex(
"E7C566D86E98C36D2DCA54A966E7B469B6094B9201F200932F8EB5E1A94FB0B977"
"FAB8DFDAD57C677E279615F4EAFA872CA8EFF83179E4DE2AB78E6B41A860C42203"
"4B875AC282406E03AC01F2E407A55DE38C6C35707F34B3319646FA016A01CE9056"
"E55D28C48ED72F10FA6625656ED62B758CBADA757DDC52533C9CBD54FC1A46F827"
"CC7B69BA66AE19A15D725FCBB972B23C83F95C0F00F481A7C9AC8687B3A4AD15AD"
"A2ABBB84D8E3CBEC3E8771720A35234070799173B37219127141922CBA8CB2DC48"
"EC2477832D1AE477942DCDA93C0886AF72D71E56DA3D7737E49670B024639A195B"
"7377C7F45A797C6E5DBB1BB2843DA3FC76043E33687BEF3172"),
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample,
wvcdm::kCipherModeCbc,
};
Cenc30SampleInfo kCenc30Cbc1Key32Sample = {
true, wvcdm::a2bs_hex("30303030303030303030303030303032"),
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 Cenc30SwitchCipherInfo {
const std::string pssh;
Cenc30SampleInfo sample_info[4];
};
Cenc30SwitchCipherInfo kCenc30SwitchCipherData[8] = {
// Switch between cipher modes
{ kFullCencPssh, { kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample,
kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, } },
{ kFullCbc1Pssh, { kCenc30Cbc1Key33Sample, kCenc30CencKey33Sample,
kCenc30Cbc1Key33Sample, kCenc30CencKey33Sample, } },
// Switch between cipher modes, but the first sample has a cipher mode
// that differs with the protection scheme in the pssh
{ kFullCencPssh, { kCenc30Cbc1Key33Sample, kCenc30CencKey33Sample,
kCenc30Cbc1Key33Sample, kCenc30CencKey33Sample, } },
{ kFullCbc1Pssh, { kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample,
kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, } },
// Switch between cipher modes and keys
{ kFullCencPssh, { kCenc30CencKey33Sample, kCenc30CencKey32Sample,
kCenc30Cbc1Key33Sample, kCenc30Cbc1Key32Sample, } },
{ kFullCencPssh, { kCenc30Cbc1Key33Sample, kCenc30Cbc1Key32Sample,
kCenc30CencKey33Sample, kCenc30CencKey32Sample, } },
{ kFullCbc1Pssh, { kCenc30Cbc1Key33Sample, kCenc30Cbc1Key32Sample,
kCenc30CencKey33Sample, kCenc30CencKey32Sample, } },
{ kFullCbc1Pssh, { kCenc30CencKey33Sample, kCenc30CencKey32Sample,
kCenc30Cbc1Key33Sample, kCenc30Cbc1Key32Sample, } },
};
} // namespace
namespace wvcdm {
@@ -1055,7 +1214,6 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
// when appropriate.
std::string init_data;
wvcdm::CdmAppParameterMap app_parameters;
wvcdm::CdmKeyRequestType key_request_type;
CdmKeyRequest key_request;
EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest(
@@ -2496,7 +2654,6 @@ TEST_P(WvCdmUsageTest, WithClientId) {
decrypt_buffer.begin()));
decryptor_.CloseSession(session_id_);
uint32_t num_usage_info = 0;
CdmUsageInfo usage_info;
CdmUsageInfoReleaseMessage release_msg;
CdmResponseType status = decryptor_.GetUsageInfo(
@@ -2582,7 +2739,6 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
decrypt_buffer.begin()));
decryptor_.CloseSession(session_id_);
uint32_t num_usage_info = 0;
CdmUsageInfo usage_info;
CdmUsageInfoReleaseMessage release_msg;
CdmResponseType status = decryptor_.GetUsageInfo(
@@ -2680,7 +2836,6 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
decryptor_.CloseSession(session_id_);
}
uint32_t num_usage_info = 0;
CdmUsageInfo usage_info;
CdmUsageInfoReleaseMessage release_msg;
CdmResponseType status =
@@ -3705,6 +3860,73 @@ INSTANTIATE_TEST_CASE_P(
::testing::Range(&kHlsFourCCBackwardCompatibilityTestVectors[0],
&kHlsFourCCBackwardCompatibilityTestVectors[4]));
class WvCenc30SwitchCipherModeTest
: public WvCdmRequestLicenseTest,
public ::testing::WithParamInterface<Cenc30SwitchCipherInfo*> {};
TEST_P(WvCenc30SwitchCipherModeTest, 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 < 14)
return;
Cenc30SwitchCipherInfo* 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());
for (size_t i = 0; i < N_ELEM(info->sample_info); ++i) {
Cenc30SampleInfo* data = &info->sample_info[i];
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, WvCenc30SwitchCipherModeTest,
::testing::Range(&kCenc30SwitchCipherData[0],
&kCenc30SwitchCipherData[8]));
} // namespace wvcdm
void show_menu(char* prog_name) {