Merge "Call CopyBuffer in Decrypt if key handle is empty" into main
This commit is contained in:
@@ -43,9 +43,10 @@ class ContentKeySession : public KeySession {
|
||||
CdmCipherMode cipher_mode) override;
|
||||
|
||||
// Decrypt for ContentKeySession
|
||||
OEMCryptoResult Decrypt(
|
||||
const OEMCrypto_SampleDescription* samples, size_t samples_length,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) override;
|
||||
OEMCryptoResult Decrypt(const OEMCrypto_SampleDescription* samples,
|
||||
size_t samples_length,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) override;
|
||||
|
||||
OEMCryptoResult GenericEncrypt(const std::string& in_buffer,
|
||||
const std::string& iv,
|
||||
|
||||
@@ -427,18 +427,22 @@ class CryptoSession {
|
||||
OEMCryptoResult DecryptMultipleSamples(
|
||||
const std::vector<OEMCrypto_SampleDescription>& samples,
|
||||
CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern);
|
||||
OEMCryptoResult DecryptSample(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern);
|
||||
OEMCryptoResult LegacyDecrypt(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern);
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected);
|
||||
OEMCryptoResult DecryptSample(const OEMCrypto_SampleDescription& sample,
|
||||
CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected);
|
||||
OEMCryptoResult LegacyDecrypt(const OEMCrypto_SampleDescription& sample,
|
||||
CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected);
|
||||
OEMCryptoResult LegacyCopyBufferInChunks(
|
||||
const OEMCrypto_SampleDescription& sample, size_t max_chunk_size);
|
||||
OEMCryptoResult LegacyDecryptInChunks(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern, size_t max_chunk_size);
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern, size_t max_chunk_size,
|
||||
bool is_any_subsample_protected);
|
||||
|
||||
// These methods should be used to take the various CryptoSession mutexes in
|
||||
// preference to taking the mutexes directly.
|
||||
|
||||
@@ -36,7 +36,8 @@ class KeySession {
|
||||
CdmCipherMode cipher_mode) = 0;
|
||||
virtual OEMCryptoResult Decrypt(
|
||||
const OEMCrypto_SampleDescription* samples, size_t samples_length,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) = 0;
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) = 0;
|
||||
virtual OEMCryptoResult GenericEncrypt(const std::string& in_buffer,
|
||||
const std::string& iv,
|
||||
OEMCrypto_Algorithm algorithm,
|
||||
|
||||
@@ -52,18 +52,36 @@ OEMCryptoResult ContentKeySession::SelectKey(const std::string& key_id,
|
||||
// Decrypt for ContentKeySession
|
||||
OEMCryptoResult ContentKeySession::Decrypt(
|
||||
const OEMCrypto_SampleDescription* samples, size_t samples_length,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) {
|
||||
size_t total_size = 0;
|
||||
for (size_t i = 0; i < samples_length; ++i) {
|
||||
total_size += samples[i].buffers.input_data_length;
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(sts = OEMCrypto_DecryptCENC(security_level_, key_handle_.data(),
|
||||
key_handle_.size(), samples,
|
||||
samples_length, &pattern),
|
||||
metrics_, oemcrypto_decrypt_cenc_, sts,
|
||||
metrics::Pow2Bucket(total_size));
|
||||
OEMCryptoResult sts = OEMCrypto_SUCCESS;
|
||||
if (key_handle_.size() == 0 && !is_any_subsample_protected) {
|
||||
for (size_t i = 0; i < samples_length; ++i) {
|
||||
if (samples[i].subsamples != nullptr &&
|
||||
samples[i].subsamples_length > 0) {
|
||||
const OEMCrypto_SubSampleDescription& subsample =
|
||||
samples[i].subsamples[0];
|
||||
M_TIME(sts = OEMCrypto_CopyBuffer(oec_session_id_,
|
||||
samples[i].buffers.input_data,
|
||||
samples[i].buffers.input_data_length,
|
||||
&samples[i].buffers.output_descriptor,
|
||||
subsample.subsample_flags),
|
||||
metrics_, oemcrypto_copy_buffer_, sts,
|
||||
metrics::Pow2Bucket(samples[i].buffers.input_data_length));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
M_TIME(sts = OEMCrypto_DecryptCENC(security_level_, key_handle_.data(),
|
||||
key_handle_.size(), samples,
|
||||
samples_length, &pattern),
|
||||
metrics_, oemcrypto_decrypt_cenc_, sts,
|
||||
metrics::Pow2Bucket(total_size));
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
|
||||
@@ -1906,8 +1906,8 @@ CdmResponseType CryptoSession::Decrypt(
|
||||
}
|
||||
|
||||
// Perform decrypt
|
||||
const OEMCryptoResult sts =
|
||||
DecryptMultipleSamples(oec_samples, params.cipher_mode, oec_pattern);
|
||||
const OEMCryptoResult sts = DecryptMultipleSamples(
|
||||
oec_samples, params.cipher_mode, oec_pattern, is_any_sample_protected);
|
||||
|
||||
if (sts != OEMCrypto_SUCCESS && last_decrypt_error_ != sts) {
|
||||
// Decrypt errors and warnings are only logged when the error code
|
||||
@@ -3120,22 +3120,24 @@ bool CryptoSession::GetAnalogOutputCapabilities(bool* can_support_output,
|
||||
|
||||
OEMCryptoResult CryptoSession::DecryptMultipleSamples(
|
||||
const std::vector<OEMCrypto_SampleDescription>& samples,
|
||||
CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
||||
CdmCipherMode cipher_mode, const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) {
|
||||
OEMCryptoResult sts = OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
||||
|
||||
// If there's only one sample, automatically fall through to avoid a redundant
|
||||
// roundtrip through OEMCrypto_DecryptCENC()
|
||||
if (samples.size() > 1) {
|
||||
WithOecSessionLock("DecryptMultipleSamples", [&] {
|
||||
sts = key_session_->Decrypt(samples.data(), samples.size(), pattern);
|
||||
sts = key_session_->Decrypt(samples.data(), samples.size(), pattern,
|
||||
is_any_subsample_protected);
|
||||
});
|
||||
}
|
||||
|
||||
if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE) {
|
||||
// Fall back to sending each sample individually
|
||||
for (const OEMCrypto_SampleDescription& sample : samples) {
|
||||
sts = DecryptSample(sample, cipher_mode, pattern);
|
||||
sts = DecryptSample(sample, cipher_mode, pattern,
|
||||
is_any_subsample_protected);
|
||||
if (sts != OEMCrypto_SUCCESS) break;
|
||||
}
|
||||
}
|
||||
@@ -3145,7 +3147,8 @@ OEMCryptoResult CryptoSession::DecryptMultipleSamples(
|
||||
|
||||
OEMCryptoResult CryptoSession::DecryptSample(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) {
|
||||
OEMCryptoResult sts = OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
||||
|
||||
// If there's only one subsample and it contains only one type of region,
|
||||
@@ -3155,7 +3158,8 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
||||
(sample.subsamples[0].num_bytes_clear > 0 &&
|
||||
sample.subsamples[0].num_bytes_encrypted > 0)) {
|
||||
WithOecSessionLock("DecryptSample", [&] {
|
||||
sts = key_session_->Decrypt(&sample, 1, pattern);
|
||||
sts = key_session_->Decrypt(&sample, 1, pattern,
|
||||
is_any_subsample_protected);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3187,7 +3191,8 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
||||
fake_sample.subsamples = &clear_subsample;
|
||||
fake_sample.subsamples_length = 1;
|
||||
|
||||
sts = LegacyDecrypt(fake_sample, cipher_mode, pattern);
|
||||
sts = LegacyDecrypt(fake_sample, cipher_mode, pattern,
|
||||
is_any_subsample_protected);
|
||||
if (sts != OEMCrypto_SUCCESS) break;
|
||||
|
||||
fake_sample.buffers.input_data += length;
|
||||
@@ -3213,7 +3218,8 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
||||
fake_sample.subsamples = &encrypted_subsample;
|
||||
fake_sample.subsamples_length = 1;
|
||||
|
||||
sts = LegacyDecrypt(fake_sample, cipher_mode, pattern);
|
||||
sts = LegacyDecrypt(fake_sample, cipher_mode, pattern,
|
||||
is_any_subsample_protected);
|
||||
if (sts != OEMCrypto_SUCCESS) break;
|
||||
|
||||
fake_sample.buffers.input_data += length;
|
||||
@@ -3232,7 +3238,8 @@ OEMCryptoResult CryptoSession::DecryptSample(
|
||||
|
||||
OEMCryptoResult CryptoSession::LegacyDecrypt(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern) {
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern,
|
||||
bool is_any_subsample_protected) {
|
||||
const size_t max_chunk_size = GetMaxSubsampleRegionSize();
|
||||
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
@@ -3262,7 +3269,8 @@ OEMCryptoResult CryptoSession::LegacyDecrypt(
|
||||
}
|
||||
if (is_encrypted || sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
WithOecSessionLock("LegacyDecrypt() calling key_session_->Decrypt()", [&] {
|
||||
sts = key_session_->Decrypt(&sample, 1, pattern);
|
||||
sts = key_session_->Decrypt(&sample, 1, pattern,
|
||||
is_any_subsample_protected);
|
||||
});
|
||||
|
||||
if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE) {
|
||||
@@ -3278,7 +3286,8 @@ OEMCryptoResult CryptoSession::LegacyDecrypt(
|
||||
: max_chunk_size;
|
||||
|
||||
if (sample.buffers.input_data_length > chunk_size) {
|
||||
sts = LegacyDecryptInChunks(sample, cipher_mode, pattern, chunk_size);
|
||||
sts = LegacyDecryptInChunks(sample, cipher_mode, pattern, chunk_size,
|
||||
is_any_subsample_protected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3327,7 +3336,8 @@ OEMCryptoResult CryptoSession::LegacyCopyBufferInChunks(
|
||||
|
||||
OEMCryptoResult CryptoSession::LegacyDecryptInChunks(
|
||||
const OEMCrypto_SampleDescription& sample, CdmCipherMode cipher_mode,
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern, size_t max_chunk_size) {
|
||||
const OEMCrypto_CENCEncryptPatternDesc& pattern, size_t max_chunk_size,
|
||||
bool is_any_subsample_protected) {
|
||||
const OEMCrypto_SubSampleDescription& subsample = sample.subsamples[0];
|
||||
|
||||
const bool is_protected = (subsample.num_bytes_encrypted > 0);
|
||||
@@ -3361,7 +3371,8 @@ OEMCryptoResult CryptoSession::LegacyDecryptInChunks(
|
||||
// pattern length long, which is also guaranteed to be an exact number
|
||||
// of AES blocks long.
|
||||
WithOecSessionLock("LegacyDecryptInChunks", [&] {
|
||||
sts = key_session_->Decrypt(&fake_sample, 1, pattern);
|
||||
sts = key_session_->Decrypt(&fake_sample, 1, pattern,
|
||||
is_any_subsample_protected);
|
||||
});
|
||||
|
||||
if (sts != OEMCrypto_SUCCESS) break;
|
||||
|
||||
Reference in New Issue
Block a user