Reject partial clear subsamples when keys are not loaded

[ Merge of http://go/wvgerrit/96514 ]

The combined decryption call feature was introduced in android R.
In earlier releases, subsamples were passed one at a time for
decryption within the plugin. A decryption request that consists
entirely of clear data should be passed on to OEMCrypto even if
no keys are loaded.

A sample might consist of subsamples of clear and protected data.
In legacy mode, this proved to be an issue for OEMCrypto if the clear
subsamples were passed on but the protected ones were rejected (b/110251447).

For legacy mode and in the absence of keys being loaded, the subsample will
be passed to OEMCrypto only if the clear lead/frame is in a single subsample
and not broken up across multiple subsamples.

Bug: 150316417
Test: WV android unit/integration tests
Change-Id: Iff8ae8f58530cb9c5d31ce388742443ae807c16f
This commit is contained in:
Rahul Frias
2020-03-26 17:12:01 -07:00
parent d035d76ed6
commit 734aea940b

View File

@@ -313,8 +313,6 @@ CdmResponseType WvContentDecryptionModule::DecryptV16(
bool status =
cdm_engine->FindSessionForKey(parameters.key_id, &local_session_id);
if (!status) {
// A key does not need to be loaded if the content consists entirely of
// clear data.
bool is_any_protected = std::any_of(
std::begin(parameters.samples), std::end(parameters.samples),
[](const CdmDecryptionSample& sample) -> bool {
@@ -325,7 +323,22 @@ CdmResponseType WvContentDecryptionModule::DecryptV16(
});
});
if (is_any_protected) {
// A key does not need to be loaded if
// (a) the content consists of one or more samples and is entirely
// clear data
// (b) (legacy) the content consists of clear lead/frame in a single
// subsample. In earlier releases content was presented for decryption
// as individual subsamples. If the clear frame is broken up across
// multiple subsamples decryption, requests should be rejected
// (b/110251447)
// TODO(b/149524614): Remove support for the legacy case
if (is_any_protected ||
(parameters.observe_legacy_fields && parameters.samples.size() == 1 &&
parameters.samples[0].subsamples.size() == 1 &&
!(parameters.samples[0].subsamples[0].flags &
OEMCrypto_FirstSubsample &&
parameters.samples[0].subsamples[0].flags &
OEMCrypto_LastSubsample))) {
return KEY_NOT_FOUND_IN_SESSION;
}
}