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