diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 8cf33cc7..3e4429f8 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -881,6 +881,17 @@ const std::string kFullCencPssh = wvcdm::a2bs_hex( "74657374220a323031355f7465617273" "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( "00000053" // blob size "70737368" // "pssh" @@ -892,6 +903,18 @@ const std::string kFullCbc1Pssh = wvcdm::a2bs_hex( "74220a323031355f746561727348b1c6" "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 { bool is_encrypted; wvcdm::KeyId key_id; @@ -952,6 +975,31 @@ Cenc30SampleInfo kCenc30CencKey32Sample = { 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 = { true, wvcdm::a2bs_hex("30303030303030303030303030303033"), wvcdm::a2bs_hex("9FBE45DD47DA7EBA09A3E24CBA95C9AF"), @@ -1002,12 +1050,49 @@ Cenc30SampleInfo kCenc30Cbc1Key32Sample = { 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; Cenc30SampleInfo sample_info[4]; }; -Cenc30SwitchCipherInfo kCenc30SwitchCipherData[8] = { +FourSampleDecryptionInfo kCenc30SwitchCipherData[8] = { // Switch between cipher modes { kFullCencPssh, { kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, kCenc30CencKey33Sample, kCenc30Cbc1Key33Sample, } }, @@ -3860,9 +3945,74 @@ INSTANTIATE_TEST_CASE_P( ::testing::Range(&kHlsFourCCBackwardCompatibilityTestVectors[0], &kHlsFourCCBackwardCompatibilityTestVectors[4])); +class WvCenc30Test + : public WvCdmRequestLicenseTest, + public ::testing::WithParamInterface {}; + +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 output_buffer(data->encrypted_data.size(), 0); + std::vector iv(data->iv.begin(), data->iv.end()); + CdmDecryptionParameters decryption_parameters( + &data->key_id, + reinterpret_cast(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(&output_buffer[0]), + output_buffer.size())); + + decryptor_.CloseSession(session_id_); +} + +INSTANTIATE_TEST_CASE_P( + Cdm, WvCenc30Test, + ::testing::Range(&kCenc30DecryptionData[0], + &kCenc30DecryptionData[4])); + class WvCenc30SwitchCipherModeTest : public WvCdmRequestLicenseTest, - public ::testing::WithParamInterface {}; + public ::testing::WithParamInterface {}; TEST_P(WvCenc30SwitchCipherModeTest, DecryptionTest) { Provision(kLevel3); @@ -3884,7 +4034,7 @@ TEST_P(WvCenc30SwitchCipherModeTest, DecryptionTest) { if (api_version < 14) return; - Cenc30SwitchCipherInfo* info = GetParam(); + FourSampleDecryptionInfo* info = GetParam(); TestWvCdmHlsEventListener listener; decryptor_.OpenSession(g_key_system, &client_property_set,