Do not convert the protection scheme to network byte order
[ Merge of http://go/wvgerrit/19960 ] Protections schemes are specified using a 4CC code {"cbc1", "cbcs", "cenc", "cens"}. A host to network conversion was performed when the PSSH was created and inserted into the license request. A reverse conversion was performed when the code was extracted from the license response. These conversions are problematic if the PSSH is created externally and passed into mediaDrm. To address this, the conversions have been removed and allow protobuf to handle byte ordering. For backward compatibility we allow codes in either ordering. b/30713238 Change-Id: I25f01ecc621549fd3c13b443e4c8b89168463249
This commit is contained in:
@@ -476,9 +476,9 @@ bool InitializationData::ConstructWidevineInitData(
|
||||
cenc_header.set_provider(provider);
|
||||
cenc_header.set_content_id(content_id);
|
||||
if (method == kHlsMethodAes128)
|
||||
cenc_header.set_protection_scheme(htonl(kFourCcCbc1));
|
||||
cenc_header.set_protection_scheme(kFourCcCbc1);
|
||||
else
|
||||
cenc_header.set_protection_scheme(htonl(kFourCcCbcs));
|
||||
cenc_header.set_protection_scheme(kFourCcCbcs);
|
||||
cenc_header.SerializeToString(init_data_proto);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ const unsigned char kServiceCertificateCAPublicKey[] = {
|
||||
}
|
||||
const uint32_t kFourCcCbc1 = 0x63626331;
|
||||
const uint32_t kFourCcCbcs = 0x63626373;
|
||||
const uint32_t kFourCcLittleEndianCbc1 = 0x31636263;
|
||||
const uint32_t kFourCcLittleEndianCbcs = 0x73636263;
|
||||
const uint32_t kFourCcCenc = 0x63656e63;
|
||||
const uint32_t kFourCcCens = 0x63656e73;
|
||||
|
||||
@@ -115,12 +117,23 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
|
||||
}
|
||||
uint32_t four_cc = kFourCcCenc;
|
||||
if (license.has_protection_scheme()) {
|
||||
four_cc = ntohl(license.protection_scheme());
|
||||
four_cc = license.protection_scheme();
|
||||
}
|
||||
switch (four_cc) {
|
||||
// b/30713238: Android N assumed that the "protection scheme" Four
|
||||
// CC code, after being extracted from the protobuf, was host byte
|
||||
// order dependent. Later versions do not assume this, and thus,
|
||||
// for backwards compatibility, must support both byte orders.
|
||||
case kFourCcCbc1:
|
||||
case kFourCcCbcs:
|
||||
case kFourCcLittleEndianCbc1:
|
||||
case kFourCcLittleEndianCbcs:
|
||||
key.set_cipher_mode(kCipherModeCbc);
|
||||
break;
|
||||
default:
|
||||
key.set_cipher_mode(kCipherModeCtr);
|
||||
break;
|
||||
}
|
||||
if (four_cc == kFourCcCbc1 || four_cc == kFourCcCbcs)
|
||||
key.set_cipher_mode(kCipherModeCbc);
|
||||
else
|
||||
key.set_cipher_mode(kCipherModeCtr);
|
||||
key_array.push_back(key);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -624,7 +624,7 @@ TEST_P(HlsConstructionTest, InitData) {
|
||||
case kHlsMethodSampleAes: protection_scheme = kFourCcCbcs; break;
|
||||
default: break;
|
||||
}
|
||||
EXPECT_EQ(protection_scheme, ntohl(cenc_header.protection_scheme()));
|
||||
EXPECT_EQ(protection_scheme, cenc_header.protection_scheme());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -755,6 +755,62 @@ HlsDecryptionInfo kHlsDecryptionTestVectors[] = {
|
||||
{true, 1, &kSampleAes192ByteSegmentInfo[0], kAttributeListSampleAes},
|
||||
{true, 1, &kSampleAes338ByteSegmentInfo[0], kAttributeListSampleAes},
|
||||
};
|
||||
|
||||
const std::string kHlsPsshAes128LittleEndianFourCC = wvcdm::a2bs_hex(
|
||||
"00000060" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"00000040" // pssh data size
|
||||
// pssh data:
|
||||
"08011210AB6531FF6E6EA15E387B019E"
|
||||
"59C2DE0A1A0D7769646576696E655F74"
|
||||
"6573742215686C735F6165735F313238"
|
||||
"5F73747265616D696E6748E3C48D8B03");
|
||||
const std::string kHlsPsshSampleAesLittleEndianFourCC = wvcdm::a2bs_hex(
|
||||
"00000063" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"00000043" // pssh data size
|
||||
// pssh data:
|
||||
"08011210613DB35603320EB8E7EA24BD"
|
||||
"EEA3FDB81A0D7769646576696E655F74"
|
||||
"6573742218686C735F73616D706C655F"
|
||||
"6165735F73747265616D696E6748E3C4"
|
||||
"8D9B07");
|
||||
const std::string kHlsPsshAes128FourCC = wvcdm::a2bs_hex(
|
||||
"00000060" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"00000040" // pssh data size
|
||||
// pssh data:
|
||||
"08011210AB6531FF6E6EA15E387B019E"
|
||||
"59C2DE0A1A0D7769646576696E655F74"
|
||||
"6573742215686C735F6165735F313238"
|
||||
"5F73747265616D696E6748B1C6899B06");
|
||||
const std::string kHlsPsshSampleAesFourCC = wvcdm::a2bs_hex(
|
||||
"00000063" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"00000043" // pssh data size
|
||||
// pssh data:
|
||||
"08011210613DB35603320EB8E7EA24BD"
|
||||
"EEA3FDB81A0D7769646576696E655F74"
|
||||
"6573742218686C735F73616D706C655F"
|
||||
"6165735F73747265616D696E6748F3C6"
|
||||
"899B06");
|
||||
|
||||
HlsDecryptionInfo kHlsFourCCBackwardCompatibilityTestVectors[] = {
|
||||
{false, 2, &kAes128MultiSegmentInfo[0], kHlsPsshAes128LittleEndianFourCC},
|
||||
{true, 1, &kSampleAes160ByteSegmentInfo[0],
|
||||
kHlsPsshSampleAesLittleEndianFourCC},
|
||||
{false, 2, &kAes128MultiSegmentInfo[0], kHlsPsshAes128FourCC},
|
||||
{true, 1, &kSampleAes160ByteSegmentInfo[0], kHlsPsshSampleAesFourCC},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -3313,6 +3369,60 @@ INSTANTIATE_TEST_CASE_P(Cdm, WvHlsDecryptionTest,
|
||||
::testing::Range(&kHlsDecryptionTestVectors[0],
|
||||
&kHlsDecryptionTestVectors[11]));
|
||||
|
||||
class WvHlsFourCCBackwardCompatibilityTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<HlsDecryptionInfo*> {};
|
||||
|
||||
TEST_P(WvHlsFourCCBackwardCompatibilityTest, HlsDecryptionTest) {
|
||||
Provision(kLevel3);
|
||||
TestWvCdmClientPropertySet client_property_set;
|
||||
client_property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3);
|
||||
HlsDecryptionInfo* info = GetParam();
|
||||
|
||||
TestWvCdmHlsEventListener listener;
|
||||
decryptor_.OpenSession(g_key_system, &client_property_set, EMPTY_ORIGIN,
|
||||
&listener, &session_id_);
|
||||
CdmAppParameterMap app_parameters;
|
||||
GenerateKeyRequest(wvcdm::KEY_MESSAGE, ISO_BMFF_VIDEO_MIME_TYPE,
|
||||
info->attribute_list, app_parameters,
|
||||
kLicenseTypeStreaming, NULL);
|
||||
//TODO(rfrias): Remove once we switch to git-on-borg
|
||||
std::string license_server = "https://proxy.uat.widevine.com/proxy";
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, false);
|
||||
CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap();
|
||||
EXPECT_EQ(1u, key_status_map.size());
|
||||
KeyId key_id = key_status_map.begin()->first;
|
||||
EXPECT_EQ(KEY_ID_SIZE, key_id.size());
|
||||
|
||||
for (size_t i = 0; i < info->number_of_segments; ++i) {
|
||||
HlsSegmentInfo* data = info->segment_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(
|
||||
&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 = true;
|
||||
decryption_parameters.is_secure = false;
|
||||
decryption_parameters.cipher_mode = kCipherModeCbc;
|
||||
if (info->sample_aes) {
|
||||
decryption_parameters.pattern_descriptor.encrypt_blocks = 1;
|
||||
decryption_parameters.pattern_descriptor.skip_blocks = 9;
|
||||
}
|
||||
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, WvHlsFourCCBackwardCompatibilityTest,
|
||||
::testing::Range(&kHlsFourCCBackwardCompatibilityTestVectors[0],
|
||||
&kHlsFourCCBackwardCompatibilityTestVectors[4]));
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
void show_menu(char* prog_name) {
|
||||
|
||||
Reference in New Issue
Block a user