From 5a4a8fdede4398fb9c12c4f3858022fcf7a10a5f Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Wed, 21 Aug 2024 05:10:09 +0000 Subject: [PATCH 1/3] Remove OEMCryptoLicenseTest.RejectCbc1API16 This test should have been removed in v17, when we allowed this pattern to be used with cbcs. Although we can't start enforcing the correct behavior until v20 now, we can remove enforcement of the incorrect behavior. Bug: 356173926 Merged from https://widevine-internal-review.googlesource.com/204832 Merged from https://widevine-internal-review.googlesource.com/204870 Change-Id: Idc6e3109286daabb83874d52ad3abaff5e14badb --- .../oemcrypto/test/oemcrypto_decrypt_test.cpp | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_decrypt_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_decrypt_test.cpp index b9868d02..6dcf901c 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_decrypt_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_decrypt_test.cpp @@ -121,38 +121,6 @@ TEST_P(OEMCryptoLicenseTest, RejectCensAPI16) { EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); } -// 'cbc1' mode is no longer supported in v16 -TEST_P(OEMCryptoLicenseTest, RejectCbc1API16) { - ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); - ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); - ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse()); - ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse()); - - vector key_handle; - OEMCryptoResult sts; - sts = GetKeyHandleIntoVector(session_.session_id(), - session_.license().keys[0].key_id, - session_.license().keys[0].key_id_length, - OEMCrypto_CipherMode_CBCS, key_handle); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - vector in_buffer(256); - vector out_buffer(in_buffer.size()); - OEMCrypto_SampleDescription sample_description; - OEMCrypto_SubSampleDescription subsample_description; - - GenerateSimpleSampleDescription(in_buffer, out_buffer, &sample_description, - &subsample_description); - - // Create a zero pattern to indicate this is 'cbc1' - OEMCrypto_CENCEncryptPatternDesc pattern = {0, 0}; - - // Try to decrypt the data - sts = OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), - &sample_description, 1, &pattern); - EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); -} - TEST_P(OEMCryptoLicenseTest, RejectCbcsWithBlockOffset) { ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest()); ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse()); From a5bce8122e5cf3b2ecc0d89ed4d04e9226662040 Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Wed, 21 Aug 2024 05:11:49 +0000 Subject: [PATCH 2/3] Limit output buffer size during decrypt fallback This is based on a patch submitted by Amlogic. When we're doing decrypt fallback, either in the CDM or the OEMCrypto tests, we sometimes fall back to a point where we're synthesizing new samples and/or subsamples for the content being decrypted. When this happens and the output buffer is clear, we should limit the size of the output buffer to only the space needed to hold the output. Previously, we've been passing the entire output buffer to every call. This can create a problem if the reason for the fallback is a lack of enough memory to communicate the buffers to the TA, since the output buffer will remain the same size as the total output. Restricting the buffer passed to each call to only the space needed by that call will reduce the memory requirement. Bug: 354834629 Test: x86-64 Merged from https://widevine-internal-review.googlesource.com/204810 Merged from https://widevine-internal-review.googlesource.com/204953 Change-Id: I412f43d8f88c72072ef1dd5293436bdb58e500b3 --- .../cdm/core/src/crypto_session.cpp | 20 ++++++++++++++++++- .../test/oec_decrypt_fallback_chain.cpp | 16 ++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 939af6dd..f7f2b9e5 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -161,7 +161,6 @@ void AdvanceDestBuffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { switch (dest_buffer->type) { case OEMCrypto_BufferType_Clear: dest_buffer->buffer.clear.clear_buffer += bytes; - dest_buffer->buffer.clear.clear_buffer_length -= bytes; return; case OEMCrypto_BufferType_Secure: @@ -3254,6 +3253,11 @@ OEMCryptoResult CryptoSession::DecryptSample( } fake_sample.buffers.input_data_length = length; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear + .clear_buffer_length = length; + } fake_sample.subsamples = &clear_subsample; fake_sample.subsamples_length = 1; @@ -3281,6 +3285,11 @@ OEMCryptoResult CryptoSession::DecryptSample( } fake_sample.buffers.input_data_length = length; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear + .clear_buffer_length = length; + } fake_sample.subsamples = &encrypted_subsample; fake_sample.subsamples_length = 1; @@ -3373,6 +3382,10 @@ OEMCryptoResult CryptoSession::LegacyCopyBufferInChunks( // Calculate the size of the next chunk. const size_t chunk_size = std::min(remaining_input_data, max_chunk_size); + if (output_descriptor.type == OEMCrypto_BufferType_Clear) { + output_descriptor.buffer.clear.clear_buffer_length = chunk_size; + } + // Re-add "last subsample" flag if this is the last subsample. if (chunk_size == remaining_input_data) { subsample_flags |= OEMCrypto_LastSubsample; @@ -3420,6 +3433,11 @@ OEMCryptoResult CryptoSession::LegacyDecryptInChunks( // Calculate the size of the next chunk. const size_t chunk_size = std::min(remaining_input_data, max_chunk_size); fake_sample.buffers.input_data_length = chunk_size; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + chunk_size; + } if (is_protected) { fake_subsample.num_bytes_encrypted = chunk_size; } else { diff --git a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp b/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp index 6cb7aac0..fe303fc6 100644 --- a/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_decrypt_fallback_chain.cpp @@ -17,7 +17,6 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { switch (dest_buffer->type) { case OEMCrypto_BufferType_Clear: dest_buffer->buffer.clear.clear_buffer += bytes; - dest_buffer->buffer.clear.clear_buffer_length -= bytes; break; case OEMCrypto_BufferType_Secure: @@ -99,6 +98,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample( const size_t length = subsample.num_bytes_clear + subsample.num_bytes_encrypted; fake_sample.buffers.input_data_length = length; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + length; + } fake_sample.subsamples = &subsample; fake_sample.subsamples_length = 1; @@ -144,6 +148,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( if (subsample.num_bytes_clear > 0) { fake_sample.buffers.input_data_length = subsample.num_bytes_clear; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + subsample.num_bytes_clear; + } fake_subsample.num_bytes_clear = subsample.num_bytes_clear; fake_subsample.num_bytes_encrypted = 0; fake_subsample.block_offset = 0; @@ -167,6 +176,11 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample( if (subsample.num_bytes_encrypted > 0) { fake_sample.buffers.input_data_length = subsample.num_bytes_encrypted; + if (fake_sample.buffers.output_descriptor.type == + OEMCrypto_BufferType_Clear) { + fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = + subsample.num_bytes_encrypted; + } fake_subsample.num_bytes_clear = 0; fake_subsample.num_bytes_encrypted = subsample.num_bytes_encrypted; fake_subsample.block_offset = subsample.block_offset; From 0b47bd6a50f7c24504fac3f043ec60da8ddf7b7f Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Wed, 21 Aug 2024 05:12:51 +0000 Subject: [PATCH 3/3] Increase size of BCC buffer in OEC tests We are receiving reports from partners in the field that they are failing the OEMCrypto tests only because the tests assume the BCC will fit into 5k of memory but their BCC is nearly 8k in size. This patch increases the buffer to 10k. Bug: 354834629 Test: x86-64 Merged from https://widevine-internal-review.googlesource.com/204773 Change-Id: I360196518b7651139c003505253d1aed6a0c3907 --- libwvdrmengine/oemcrypto/test/oec_session_util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index 4ffb714e..6d325605 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -567,7 +567,7 @@ void ProvisioningRoundTrip::VerifyLoadFailed() { } void Provisioning40RoundTrip::PrepareSession(bool is_oem_key) { - const size_t buffer_size = 5000; // Make sure it is large enough. + const size_t buffer_size = 10240; // Make sure it is large enough. std::vector public_key(buffer_size); size_t public_key_size = buffer_size; std::vector public_key_signature(buffer_size); @@ -629,7 +629,7 @@ OEMCryptoResult Provisioning40RoundTrip::LoadDRMCertResponse() { } void Provisioning40CastRoundTrip::PrepareSession() { - const size_t buffer_size = 5000; // Make sure it is large enough. + const size_t buffer_size = 10240; // Make sure it is large enough. std::vector public_key(buffer_size); size_t public_key_size = buffer_size; std::vector public_key_signature(buffer_size);