From 43a47a60c0c938c963f9c9e12567419d77baa6e0 Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Mon, 12 Nov 2018 14:15:00 -0800 Subject: [PATCH] Add session parameter to OEMCrypto_CopyBuffer Merge from master branch of Widevine repo of http://go/wvgerrit/66070 Merge from oemcrypto-v15 branch of Widevine repo of http://go/wvgerrit/63662 To make the threading model more clear, CopyBuffer is now a session function. This means we need to pass in which session the current thread locks. Test: unit tests. Test: tested as part of http://go/ag/5501993 Bug: 113680369 Change-Id: I2fdd2cfcaab99f3793950b3845941463675f5e4c --- .../cdm/core/include/oemcrypto_adapter.h | 3 -- .../cdm/core/src/crypto_session.cpp | 18 ++++----- .../core/src/oemcrypto_adapter_dynamic.cpp | 39 +++++++++++-------- .../oemcrypto/include/OEMCryptoCENC.h | 6 ++- .../oemcrypto/ref/src/oemcrypto_ref.cpp | 2 +- .../oemcrypto/test/oemcrypto_test.cpp | 32 +++++++++------ 6 files changed, 56 insertions(+), 44 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 52d662d6..680cb5ae 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -14,9 +14,6 @@ namespace wvcdm { // If one level is not available, the other will be used instead. OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session, SecurityLevel level); -OEMCryptoResult OEMCrypto_CopyBuffer( - SecurityLevel level, const uint8_t* data_addr, size_t data_length, - OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags); OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, size_t keyBoxLength, SecurityLevel level); diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 43c43fb2..872a0221 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -1117,12 +1117,11 @@ CdmResponseType CryptoSession::Decrypt(const CdmDecryptionParameters& params) { if (!params.is_encrypted && params.subsample_flags == (OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)) { - M_TIME( - sts = OEMCrypto_CopyBuffer(requested_security_level_, - params.encrypt_buffer, params.encrypt_length, - &buffer_descriptor, params.subsample_flags), - metrics_, oemcrypto_copy_buffer_, sts, - metrics::Pow2Bucket(params.encrypt_length)); + M_TIME(sts = OEMCrypto_CopyBuffer(oec_session_id_, params.encrypt_buffer, + params.encrypt_length, &buffer_descriptor, + params.subsample_flags), + metrics_, oemcrypto_copy_buffer_, sts, + metrics::Pow2Bucket(params.encrypt_length)); if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE && params.encrypt_length > kMaximumChunkSize) { @@ -2435,10 +2434,9 @@ OEMCryptoResult CryptoSession::CopyBufferInChunks( } OEMCryptoResult sts; - M_TIME(sts = OEMCrypto_CopyBuffer(requested_security_level_, - params.encrypt_buffer + additional_offset, - chunk_size, &buffer_descriptor, - subsample_flags), + M_TIME(sts = OEMCrypto_CopyBuffer( + oec_session_id_, params.encrypt_buffer + additional_offset, + chunk_size, &buffer_descriptor, subsample_flags), metrics_, oemcrypto_copy_buffer_, sts, metrics::Pow2Bucket(chunk_size)); diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index b5a3009d..23a708b2 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -122,7 +122,12 @@ typedef OEMCryptoResult (*L1_DecryptCENC_t)( bool is_encrypted, const uint8_t* iv, size_t offset, OEMCrypto_DestBufferDesc* out_buffer, const OEMCrypto_CENCEncryptPatternDesc* pattern, uint8_t subsample_flags); -typedef OEMCryptoResult (*L1_CopyBuffer_t)(const uint8_t* data_addr, +typedef OEMCryptoResult (*L1_CopyBuffer_V14_t)(const uint8_t* data_addr, + size_t data_length, + OEMCrypto_DestBufferDesc* out_buffer, + uint8_t subsample_flags); +typedef OEMCryptoResult (*L1_CopyBuffer_t)(OEMCrypto_SESSION session, + const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags); @@ -282,6 +287,7 @@ struct FunctionPointers { L1_SelectKey_t SelectKey; L1_DecryptCTR_V10_t DecryptCTR_V10; L1_DecryptCENC_t DecryptCENC; + L1_CopyBuffer_V14_t CopyBuffer_V14; L1_CopyBuffer_t CopyBuffer; L1_WrapKeybox_t WrapKeybox; L1_InstallKeyboxOrOEMCert_t InstallKeyboxOrOEMCert; @@ -660,7 +666,8 @@ class Adapter { // clang-format off LOOKUP_ALL( 8, CloseSession, OEMCrypto_CloseSession); - LOOKUP_ALL(10, CopyBuffer, OEMCrypto_CopyBuffer); + LOOKUP(10, 14, CopyBuffer_V14, OEMCrypto_CopyBuffer_V14); + LOOKUP_ALL(15, CopyBuffer, OEMCrypto_CopyBuffer); LOOKUP_ALL(13, CopyOldUsageEntry, OEMCrypto_CopyOldUsageEntry); LOOKUP_ALL(13, CreateNewUsageEntry, OEMCrypto_CreateNewUsageEntry); LOOKUP_ALL(13, CreateOldUsageEntry, OEMCrypto_CreateOldUsageEntry); @@ -813,7 +820,8 @@ class Adapter { level3_.QueryKeyControl = Level3_QueryKeyControl; level3_.SelectKey = Level3_SelectKey; level3_.DecryptCENC = Level3_DecryptCENC; - level3_.CopyBuffer = Level3_CopyBuffer; + // TODO(srujzs) level3_.CopyBuffer = Level3_CopyBuffer; + level3_.CopyBuffer_V14 = Level3_CopyBuffer; level3_.WrapKeybox = Level3_WrapKeybox; level3_.InstallKeyboxOrOEMCert = Level3_InstallKeybox; level3_.LoadTestKeybox = Level3_LoadTestKeybox; @@ -961,17 +969,6 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session, return gAdapter->OpenSession(session, level); } -OEMCryptoResult OEMCrypto_CopyBuffer( - SecurityLevel level, const uint8_t* data_addr, size_t data_length, - OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags) { - if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = gAdapter->GetFunctionPointers(level); - if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; - if (fcn->version < 10) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - if (fcn->CopyBuffer == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - return fcn->CopyBuffer(data_addr, data_length, out_buffer, subsample_flags); -} - OEMCryptoResult OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox, size_t keyBoxLength, SecurityLevel level) { @@ -1510,9 +1507,19 @@ extern "C" OEMCryptoResult OEMCrypto_DecryptCENC( } extern "C" OEMCryptoResult OEMCrypto_CopyBuffer( - const uint8_t* data_addr, size_t data_length, + OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags) { - return OEMCrypto_CopyBuffer(kLevelDefault, data_addr, data_length, out_buffer, + if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + LevelSession pair = gAdapter->GetSession(session); + if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if (pair.fcn->version < 15) { + if (pair.fcn->CopyBuffer_V14 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->CopyBuffer_V14(data_addr, data_length, out_buffer, + subsample_flags); + } + if (pair.fcn->CopyBuffer == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->CopyBuffer(session, data_addr, data_length, out_buffer, subsample_flags); } diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 39fd0351..fcc5a3c7 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -478,7 +478,7 @@ const uint32_t OEMCrypto_Partner_Defined_Hash = 2; #define OEMCrypto_GetMaxNumberOfSessions _oecc37 #define OEMCrypto_GetNumberOfOpenSessions _oecc38 #define OEMCrypto_IsAntiRollbackHwPresent _oecc39 -#define OEMCrypto_CopyBuffer _oecc40 +#define OEMCrypto_CopyBuffer_v14 _oecc40 #define OEMCrypto_QueryKeyControl _oecc41 #define OEMCrypto_LoadTestKeybox_V13 _oecc42 #define OEMCrypto_ForceDeleteUsageEntry _oecc43 @@ -521,6 +521,7 @@ const uint32_t OEMCrypto_Partner_Defined_Hash = 2; #define OEMCrypto_BuildInformation _oecc90 #define OEMCrypto_RefreshKeys _oecc91 #define OEMCrypto_LoadEntitledContentKeys _oecc92 +#define OEMCrypto_CopyBuffer _oecc93 /* * OEMCrypto_SetSandbox @@ -1846,7 +1847,8 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * Version: * This method is changed in API version 15. */ -OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr, +OEMCryptoResult OEMCrypto_CopyBuffer(OEMCrypto_SESSION session, + const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index 98ae24f7..daaf7356 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -523,7 +523,7 @@ extern "C" OEMCryptoResult OEMCrypto_DecryptCENC( } extern "C" OEMCryptoResult OEMCrypto_CopyBuffer( - const uint8_t* data_addr, size_t data_length, + OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, uint8_t subsample_flags) { if (!crypto_engine) { LOGE("OEMCrypto_CopyBuffer: OEMCrypto Not Initialized."); diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index befba38f..53098452 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -398,6 +398,8 @@ TEST_F(OEMCryptoClientTest, PreventNonceFlood3API09) { } TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); const int kDataSize = 256; vector input_buffer(kDataSize); GetRandBytes(&input_buffer[0], input_buffer.size()); @@ -408,31 +410,36 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestAPI10) { dest_buffer.buffer.clear.max_length = output_buffer.size(); ASSERT_EQ( OEMCrypto_SUCCESS, - OEMCrypto_CopyBuffer(&input_buffer[0], input_buffer.size(), &dest_buffer, + OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); ASSERT_EQ(input_buffer, output_buffer); - ASSERT_EQ( - OEMCrypto_ERROR_INVALID_CONTEXT, - OEMCrypto_CopyBuffer(NULL, input_buffer.size(), &dest_buffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); - ASSERT_EQ( - OEMCrypto_ERROR_INVALID_CONTEXT, - OEMCrypto_CopyBuffer(&input_buffer[0], input_buffer.size(), NULL, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, + OEMCrypto_CopyBuffer( + s.session_id(), NULL, input_buffer.size(), &dest_buffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); + ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, + OEMCrypto_CopyBuffer( + s.session_id(), &input_buffer[0], input_buffer.size(), NULL, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); dest_buffer.buffer.clear.address = NULL; ASSERT_EQ( OEMCrypto_ERROR_INVALID_CONTEXT, - OEMCrypto_CopyBuffer(&input_buffer[0], input_buffer.size(), &dest_buffer, + OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); dest_buffer.buffer.clear.address = &output_buffer[0]; dest_buffer.buffer.clear.max_length = output_buffer.size() - 1; ASSERT_EQ( OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_CopyBuffer(&input_buffer[0], input_buffer.size(), &dest_buffer, + OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); } TEST_F(OEMCryptoClientTest, ClearCopyTestLargeBufferAPI10) { + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); vector input_buffer(kMaxDecryptSize); GetRandBytes(&input_buffer[0], input_buffer.size()); vector output_buffer(kMaxDecryptSize); @@ -442,7 +449,8 @@ TEST_F(OEMCryptoClientTest, ClearCopyTestLargeBufferAPI10) { dest_buffer.buffer.clear.max_length = output_buffer.size(); ASSERT_EQ( OEMCrypto_SUCCESS, - OEMCrypto_CopyBuffer(&input_buffer[0], input_buffer.size(), &dest_buffer, + OEMCrypto_CopyBuffer(s.session_id(), &input_buffer[0], + input_buffer.size(), &dest_buffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample)); ASSERT_EQ(input_buffer, output_buffer); }