diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index a3ab2149..da193f01 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -81,11 +81,12 @@ class CdmEngine : public TimerHandler { CdmResponseType Decrypt(const CdmSessionId& session_id, bool is_encrypted, const KeyId& key_id, - const uint8_t* encrypted_buffer, - size_t encrypted_size, + const uint8_t* encrypt_buffer, + size_t encrypt_length, const std::vector& iv, size_t block_offset, - uint8_t* decrypted_buffer); + void* decrypt_buffer, + bool is_video); // Is the key known to any session? bool IsKeyValid(const KeyId& key_id); diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index b5f9c2c6..3ddb3f2e 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -18,7 +18,9 @@ namespace wvcdm { class CdmSession { public: - CdmSession() : state_(INITIAL), session_id_(GenerateSessionId()) {} + CdmSession() : session_id_(GenerateSessionId()), + license_received_(false), + properties_valid_(false) {} ~CdmSession() {} bool Init(); @@ -46,12 +48,14 @@ class CdmSession { CdmResponseType QueryKeyStatus(CdmQueryMap* key_info); // Decrypt() - Accept encrypted buffer and return decrypted data. - CdmResponseType Decrypt(const uint8_t* encrypted_buffer, - size_t encrypted_size, - size_t block_offset, - const std::vector& iv, + CdmResponseType Decrypt(bool is_encrypted, const KeyId& key_id, - uint8_t* decrypted_buffer); + const uint8_t* encrypt_buffer, + size_t encrypt_length, + const std::vector& iv, + size_t block_offset, + void* decrypt_buffer, + bool is_video); // License renewal // GenerateRenewalRequest() - Construct valid renewal request for the current @@ -73,22 +77,18 @@ class CdmSession { // Generate unique ID for each new session. CdmSessionId GenerateSessionId(); - typedef enum { - INITIAL, - LICENSE_REQUESTED, - LICENSE_RESPONSE_DONE, - RENEWAL_ENABLED, - RENEWAL_REQUESTED, - LICENSE_EXPIRED - } CdmSessionState; - // instance variables - CdmSessionState state_; const CdmSessionId session_id_; CdmKeySystem key_system_; CdmLicense license_parser_; CryptoSession* crypto_session_; PolicyEngine policy_engine_; + bool license_received_; + + bool properties_valid_; + bool require_explicit_renew_request_; + + KeyId key_id_; std::set listeners_; diff --git a/libwvdrmengine/cdm/core/include/crypto_engine.h b/libwvdrmengine/cdm/core/include/crypto_engine.h index a7789a44..7ff3cd64 100644 --- a/libwvdrmengine/cdm/core/include/crypto_engine.h +++ b/libwvdrmengine/cdm/core/include/crypto_engine.h @@ -38,7 +38,21 @@ class CryptoEngine { bool GetToken(std::string* token); - CdmResponseType Query(CdmQueryMap* info); + typedef enum { + kSecurityLevelL1, + kSecurityLevelL2, + kSecurityLevelL3, + kSecurityLevelUnknown + } SecurityLevel; + + SecurityLevel GetSecurityLevel(); + + bool properties_valid() const { return properties_valid_; } + bool oem_crypto_use_secure_buffers() const + { return oem_crypto_use_secure_buffers_; } + bool oem_crypto_use_fifo() const { return oem_crypto_use_fifo_; } + bool oem_crypto_use_userspace_buffers() const + { return oem_crypto_use_userspace_buffers_; } private: @@ -55,6 +69,11 @@ private: mutable Lock sessions_lock_; CryptoSessionMap sessions_; + bool properties_valid_; + bool oem_crypto_use_secure_buffers_; + bool oem_crypto_use_fifo_; + bool oem_crypto_use_userspace_buffers_; + CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine); }; diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index c084725c..c0e27d37 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -9,16 +9,13 @@ #include #include "crypto_key.h" +#include "OEMCryptoCENC.h" #include "wv_cdm_types.h" namespace wvcdm { typedef std::map CryptoKeyMap; -// TODO(gmorgan): fill out input and output descriptors -typedef void* InputDescriptor; -typedef void* OutputDescriptor; - class CryptoSession { public: CryptoSession(); @@ -55,12 +52,13 @@ class CryptoSession { // Media data path bool SelectKey(const std::string& key_id); - bool Decrypt(const InputDescriptor input, OutputDescriptor output); - bool Decrypt(const uint8_t* encrypted_buffer, - size_t encrypted_size, - size_t block_offset, - const std::vector& iv, - uint8_t* decrypted_buffer); + CdmResponseType Decrypt(bool is_encrypted, + const uint8_t* encrypt_buffer, + size_t encrypt_length, + const std::vector& iv, + size_t block_offset, + void* decrypt_buffer, + bool is_video); private: @@ -69,6 +67,7 @@ class CryptoSession { void GenerateEncryptContext(const std::string& input_context, std::string* deriv_context); size_t GetOffset(std::string message, std::string field); + bool SetDestinationBufferType(); bool valid_; bool open_; @@ -76,6 +75,9 @@ class CryptoSession { CryptoSessionId oec_session_id_; CryptoResult session_status_; + OEMCryptoBufferType destination_buffer_type_; + bool is_destination_buffer_type_valid_; + CryptoKeyMap keys_; CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession); diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index 97958395..ac8c6ec5 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -19,7 +19,20 @@ static const size_t MAC_KEY_SIZE = 32; // define boolean property keys here // If false begin license usage on first playback static std::string kPropertyKeyBeginLicenseUsageWhenReceived = - "WVBeginLicenseUsageWhenReceived"; + "WVBeginLicenseUsageWhenReceived"; +// If false, calls to Generate Key request, after the first one, +// will result in a renewal request being generated +static std::string kPropertyKeyRequireExplicitRenewRequest = + "WVRequireExplicitRenewRequest"; +// Set only one of the three below to true. If secure buffer +// is selected, fallback to userspace buffers may occur +// if L1/L2 OEMCrypto APIs fail +static std::string kPropertyKeyOemCryptoUseSecureBuffers = + "WVBeginLicenseOemCryptoUseSecureBuffer"; +static std::string kPropertyKeyOemCryptoUseFifo = + "WVBeginLicenseOemCryptoUseFifo"; +static std::string kPropertyKeyOemCryptoUseUserSpaceBuffers = + "WVBeginLicenseOemCryptoUseUserSpaceBuffers"; // define query keys, values here static const std::string QUERY_KEY_LICENSE_TYPE = "LicenseType"; @@ -38,6 +51,7 @@ static const std::string QUERY_KEY_RENEWAL_SERVER_URL = "RenewalServerUrl"; // url static const std::string QUERY_KEY_SECURITY_LEVEL = "SecurityLevel"; // "L1", "L3" + static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; static const std::string QUERY_VALUE_STREAMING = "Streaming"; @@ -45,7 +59,7 @@ static const std::string QUERY_VALUE_OFFLINE = "Offline"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3"; - +static const std::string QUERY_VALUE_SECURITY_LEVEL_Unknown = "Unknown"; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index b4e723a2..b2713553 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -278,10 +278,28 @@ CdmResponseType CdmEngine::RenewKey( CdmResponseType CdmEngine::QueryStatus(CdmQueryMap* key_info) { LOGI("CdmEngine::QueryStatus"); CryptoEngine* crypto_engine = CryptoEngine::GetInstance(); - if (crypto_engine) { - return crypto_engine->Query(key_info); + if (!crypto_engine) { + return KEY_ERROR; } - return KEY_ERROR; + + switch (crypto_engine->GetSecurityLevel()) { + case CryptoEngine::kSecurityLevelL1: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L1; + break; + case CryptoEngine::kSecurityLevelL2: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L2; + break; + case CryptoEngine::kSecurityLevelL3: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3; + break; + case CryptoEngine::kSecurityLevelUnknown: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_Unknown; + break; + default: + return KEY_ERROR; + } + + return NO_ERROR; } CdmResponseType CdmEngine::QueryKeyStatus( @@ -325,23 +343,21 @@ CdmResponseType CdmEngine::Decrypt( const CdmSessionId& session_id, bool is_encrypted, const KeyId& key_id, - const uint8_t* encrypted_buffer, - size_t encrypted_size, + const uint8_t* encrypt_buffer, + size_t encrypt_length, const std::vector& iv, size_t block_offset, - uint8_t* decrypted_buffer) { + void* decrypt_buffer, + bool is_video) { CdmSessionIter iter = sessions_.find(session_id); if (iter == sessions_.end()) { LOGW("CdmEngine::Decrypt: session_id not found = %s", session_id.c_str()); return KEY_ERROR; } - if (NO_ERROR != iter->second->Decrypt(encrypted_buffer, encrypted_size, - block_offset, iv, key_id, - decrypted_buffer)) - return UNKNOWN_ERROR; - - return NO_ERROR; + return iter->second->Decrypt(is_encrypted, key_id, encrypt_buffer, + encrypt_length, iv, block_offset, + decrypt_buffer, is_video); } bool CdmEngine::IsKeyValid(const KeyId& key_id) { diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index a7bab9ff..6568b85a 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -5,10 +5,11 @@ #include +#include "clock.h" #include "crypto_engine.h" #include "log.h" +#include "properties.h" #include "string_conversions.h" -#include "clock.h" #include "wv_cdm_constants.h" namespace wvcdm { @@ -30,6 +31,15 @@ bool CdmSession::Init() { std::string token; if (!crypto_engine->GetToken(&token)) return false; + if (!Properties::GetInstance()->GetProperty( + kPropertyKeyRequireExplicitRenewRequest, + require_explicit_renew_request_)) { + LOGE("CdmSession::Init: Unable to access property - require explicit renew"); + } + else { + properties_valid_ = true; + } + return license_parser_.Init(token, crypto_session_, &policy_engine_); } @@ -50,20 +60,57 @@ bool CdmSession::VerifySession(const CdmKeySystem& key_system, CdmResponseType CdmSession::GenerateKeyRequest(const CdmInitData& init_data, CdmKeyMessage* key_request) { - crypto_session_->Open(); - if(!license_parser_.PrepareKeyRequest(init_data, key_request)) { - return KEY_ERROR; - } else { - return KEY_MESSAGE; + if (!properties_valid_) { + LOGW("CdmSession::GenerateKeyRequest: Unable to access properties"); + return UNKNOWN_ERROR; + } + + if (!crypto_session_) { + LOGW("CdmSession::GenerateKeyRequest: Invalid crypto session"); + return UNKNOWN_ERROR; + } + + if (!crypto_session_->IsOpen()) { + LOGW("CdmSession::GenerateKeyRequest: Crypto session not open"); + return UNKNOWN_ERROR; + } + + if (license_received_) { + return require_explicit_renew_request_ ? + UNKNOWN_ERROR : GenerateRenewalRequest(key_request); + } + else { + if(!license_parser_.PrepareKeyRequest(init_data, key_request)) { + return KEY_ERROR; + } else { + return KEY_MESSAGE; + } } } // AddKey() - Accept license response and extract key info. CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) { - if (!license_parser_.HandleKeyResponse(key_response)) { - return KEY_ERROR; - } else { - return KEY_ADDED; + if (!crypto_session_) { + LOGW("CdmSession::AddKey: Invalid crypto session"); + return UNKNOWN_ERROR; + } + + if (!crypto_session_->IsOpen()) { + LOGW("CdmSession::AddKey: Crypto session not open"); + return UNKNOWN_ERROR; + } + + if (license_received_) { + return require_explicit_renew_request_ ? + UNKNOWN_ERROR : RenewKey(key_response); + } + else { + if (!license_parser_.HandleKeyResponse(key_response)) { + return KEY_ERROR; + } else { + license_received_ = true; + return KEY_ADDED; + } } } @@ -79,23 +126,29 @@ CdmResponseType CdmSession::CancelKeyRequest() { } // Decrypt() - Accept encrypted buffer and return decrypted data. -CdmResponseType CdmSession::Decrypt(const uint8_t* encrypted_buffer, - size_t encrypted_size, - size_t block_offset, - const std::vector& iv, +CdmResponseType CdmSession::Decrypt(bool is_encrypted, const KeyId& key_id, - uint8_t* decrypted_buffer) { - if (!crypto_session_) + const uint8_t* encrypt_buffer, + size_t encrypt_length, + const std::vector& iv, + size_t block_offset, + void* decrypt_buffer, + bool is_video) { + if (!crypto_session_ || !crypto_session_->IsOpen()) return UNKNOWN_ERROR; - if (!crypto_session_->SelectKey(key_id)) - return UNKNOWN_ERROR; + // Check if key needs to be selected + if (key_id_.compare(key_id) != 0) { + if (crypto_session_->SelectKey(key_id)) { + key_id_ = key_id; + } + else { + return UNKNOWN_ERROR; + } + } - if (!crypto_session_->Decrypt(encrypted_buffer, encrypted_size, - block_offset, iv, decrypted_buffer)) - return UNKNOWN_ERROR; - - return NO_ERROR; + return crypto_session_->Decrypt(is_encrypted, encrypt_buffer, encrypt_length, + iv, block_offset, decrypt_buffer, is_video); } // License renewal diff --git a/libwvdrmengine/cdm/core/src/crypto_engine.cpp b/libwvdrmengine/cdm/core/src/crypto_engine.cpp index dc40e643..79ea0835 100644 --- a/libwvdrmengine/cdm/core/src/crypto_engine.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_engine.cpp @@ -9,6 +9,7 @@ #include "log.h" #include "OEMCryptoCENC.h" +#include "properties.h" #include "wv_cdm_constants.h" namespace wvcdm { @@ -23,7 +24,11 @@ Lock CryptoEngine::crypto_engine_lock_; // CryptoEngine methods -CryptoEngine::CryptoEngine() : initialized_(false) {} +CryptoEngine::CryptoEngine() : initialized_(false), + properties_valid_(false), + oem_crypto_use_secure_buffers_(false), + oem_crypto_use_fifo_(false), + oem_crypto_use_userspace_buffers_(false) {} CryptoEngine::~CryptoEngine() { if (initialized_) { @@ -61,6 +66,29 @@ void CryptoEngine::DeleteInstance() { } bool CryptoEngine::Init() { + properties_valid_ = true; + + if (!Properties::GetInstance()->GetProperty( + kPropertyKeyOemCryptoUseSecureBuffers, + oem_crypto_use_secure_buffers_)) { + LOGW("CryptoEngine::CryptoEngine: Unable to access property - oemcrypto use secure buffers"); + properties_valid_ = false; + } + + if (!Properties::GetInstance()->GetProperty( + kPropertyKeyOemCryptoUseFifo, + oem_crypto_use_fifo_)) { + LOGW("CryptoEngine::CryptoEngine: Unable to access property - oemcrypto use fifos"); + properties_valid_ = false; + } + + if (!Properties::GetInstance()->GetProperty( + kPropertyKeyOemCryptoUseUserSpaceBuffers, + oem_crypto_use_userspace_buffers_)) { + LOGW("CryptoEngine::CryptoEngine: Unable to access property - oemcrypto use userspace buffers"); + properties_valid_ = false; + } + LOGV("CryptoEngine::Init: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) { @@ -175,10 +203,22 @@ bool CryptoEngine::GetToken(std::string* token) { return true; } -CdmResponseType CryptoEngine::Query(CdmQueryMap* key_info) { - LOGV("CryptoEngine::GetToken: Query"); - (*key_info)[QUERY_KEY_SECURITY_LEVEL] = OEMCrypto_SecurityLevel(); - return NO_ERROR; +CryptoEngine::SecurityLevel CryptoEngine::GetSecurityLevel() { + std::string security_level = OEMCrypto_SecurityLevel(); + + if ((security_level.size() != 2) || + (security_level.at(0) != 'L')) { + return kSecurityLevelUnknown; + } + + switch (security_level.at(1)) { + case '1': return kSecurityLevelL1; + case '2': return kSecurityLevelL2; + case '3': return kSecurityLevelL3; + default : return kSecurityLevelUnknown; + } + + return kSecurityLevelUnknown; } }; // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 995b1c81..535f76cd 100755 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -35,10 +35,16 @@ namespace wvcdm { // CryptoSession methods -CryptoSession::CryptoSession() : valid_(false), open_(false) {} +CryptoSession::CryptoSession() : + valid_(false), + open_(false), + is_destination_buffer_type_valid_(false) {} -CryptoSession::CryptoSession(const std::string& sname) : valid_(true), - open_(false), cdm_session_id_(sname) {} +CryptoSession::CryptoSession(const std::string& sname) : + valid_(true), + open_(false), + cdm_session_id_(sname), + is_destination_buffer_type_valid_(false) {} CryptoSession::~CryptoSession() { if (open_) { @@ -222,7 +228,7 @@ bool CryptoSession::LoadKeys(const std::string& message, enc_mac_key = msg + GetOffset(message, mac_key); enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); } - OEMCrypto_KeyObject load_key_array[num_keys]; + std::vector load_key_array(num_keys); for (int i=0; i(signature.data()), signature.size(), enc_mac_key_iv, enc_mac_key, - num_keys, load_key_array)); + num_keys, &load_key_array[0])); } bool CryptoSession::RefreshKeys(const std::string& message, @@ -258,7 +264,7 @@ bool CryptoSession::RefreshKeys(const std::string& message, AutoLock auto_lock(crypto_engine->crypto_lock_); const uint8_t* msg = reinterpret_cast(message.data()); - OEMCrypto_KeyRefreshObject load_key_array[num_keys]; + std::vector load_key_array(num_keys); for (int i=0; i(signature.data()), signature.size(), - num_keys, load_key_array)); + num_keys, &load_key_array[0])); } bool CryptoSession::SelectKey(const std::string& key_id) { @@ -304,55 +310,49 @@ bool CryptoSession::SelectKey(const std::string& key_id) { return true; } -bool CryptoSession::Decrypt(const InputDescriptor input, - const OutputDescriptor output) { - LOGV("CryptoSession::Decrypt: Lock"); - CryptoEngine* crypto_engine = CryptoEngine::GetInstance(); - AutoLock auto_lock(crypto_engine->crypto_lock_); - // TODO(gmorgan): handle inputs and outputs to decrypt call - const uint8_t* data_addr = NULL; - uint32_t data_length = 0; - bool is_encrypted = false; - uint8_t* iv = NULL; - uint32_t offset = 0; - const OEMCrypto_DestBufferDesc* out_buffer = NULL; - OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, data_addr, - data_length, is_encrypted, iv, - offset, out_buffer); - if (OEMCrypto_SUCCESS != sts) { - return false; +CdmResponseType CryptoSession::Decrypt(bool is_encrypted, + const uint8_t* encrypt_buffer, + size_t encrypt_length, + const std::vector& iv, + size_t block_offset, + void* decrypt_buffer, + bool is_video) { + if (!is_destination_buffer_type_valid_) { + if (!SetDestinationBufferType()) + return UNKNOWN_ERROR; } - return true; -} -// TODO(jfore): Define InputDescriptor and OutputDecriptor and -// remove this method. For now this is a level 3 decrypt. -bool CryptoSession::Decrypt(const uint8_t* encrypted_buffer, - size_t encrypted_size, - size_t block_offset, - const std::vector& iv, - uint8_t* decrypted_buffer) { - LOGV("CryptoSession::Decrypt: Lock"); - CryptoEngine* crypto_engine = CryptoEngine::GetInstance(); - AutoLock auto_lock(crypto_engine->crypto_lock_); - // TODO(gmorgan): handle inputs and outputs to decrypt call - const uint8_t* data_addr = NULL; - uint32_t data_length = 0; - bool is_encrypted = false; - uint32_t offset = block_offset; - OEMCrypto_DestBufferDesc out_buffer; + OEMCrypto_DestBufferDesc buffer_descriptor; + buffer_descriptor.type = destination_buffer_type_; - out_buffer.type = OEMCrypto_BufferType_Clear; - out_buffer.buffer.clear.address = decrypted_buffer; - out_buffer.buffer.clear.max_length = encrypted_size; + if (!is_encrypted) + buffer_descriptor.type = OEMCrypto_BufferType_Clear; - OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, encrypted_buffer, - encrypted_size, true, &iv[0], - offset, &out_buffer); - if (OEMCrypto_SUCCESS != sts) { - return false; + switch (buffer_descriptor.type) { + case OEMCrypto_BufferType_Clear: + buffer_descriptor.buffer.clear.address = + static_cast(decrypt_buffer); + buffer_descriptor.buffer.clear.max_length = encrypt_length; + break; + case OEMCrypto_BufferType_Secure: + buffer_descriptor.buffer.secure.handle = decrypt_buffer; + buffer_descriptor.buffer.secure.max_length = encrypt_length; + break; + case OEMCrypto_BufferType_Direct: + buffer_descriptor.type = OEMCrypto_BufferType_Direct; + buffer_descriptor.buffer.direct.is_video = is_video; + break; } - return true; + + OEMCryptoResult sts = OEMCrypto_DecryptCTR(oec_session_id_, encrypt_buffer, + encrypt_length, is_encrypted, + &iv[0], block_offset, + &buffer_descriptor); + + if (OEMCrypto_SUCCESS != sts) { + return UNKNOWN_ERROR; + } + return NO_ERROR; } bool CryptoSession::GenerateNonce(uint32_t* nonce) { @@ -366,4 +366,33 @@ bool CryptoSession::GenerateNonce(uint32_t* nonce) { AutoLock auto_lock(crypto_engine->crypto_lock_); return(OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(oec_session_id_, nonce)); } + +bool CryptoSession::SetDestinationBufferType() { + CryptoEngine* crypto_engine = CryptoEngine::GetInstance(); + + if (!crypto_engine->properties_valid()) + return false; + + if (crypto_engine->oem_crypto_use_secure_buffers()) { + if (crypto_engine->GetSecurityLevel() == CryptoEngine::kSecurityLevelL1) { + destination_buffer_type_ = OEMCrypto_BufferType_Secure; + } + else { + destination_buffer_type_ = OEMCrypto_BufferType_Clear; + } + } + else if (crypto_engine->oem_crypto_use_fifo()) { + destination_buffer_type_ = OEMCrypto_BufferType_Direct; + } + else if (crypto_engine->oem_crypto_use_userspace_buffers()) { + destination_buffer_type_ = OEMCrypto_BufferType_Clear; + } + else { + return false; + } + + is_destination_buffer_type_valid_ = true; + return true; +} + }; // namespace wvcdm diff --git a/libwvdrmengine/cdm/include/properties_configuration.h b/libwvdrmengine/cdm/include/properties_configuration.h index 2b222c62..2f2413a5 100644 --- a/libwvdrmengine/cdm/include/properties_configuration.h +++ b/libwvdrmengine/cdm/include/properties_configuration.h @@ -10,7 +10,11 @@ namespace wvcdm { // set property values below static CdmBooleanProperties kCdmBooleanProperties[] = { - { .name = kPropertyKeyBeginLicenseUsageWhenReceived, .value = false } + { kPropertyKeyBeginLicenseUsageWhenReceived, false }, + { kPropertyKeyRequireExplicitRenewRequest, false }, + { kPropertyKeyOemCryptoUseSecureBuffers, true }, + { kPropertyKeyOemCryptoUseFifo, false }, + { kPropertyKeyOemCryptoUseUserSpaceBuffers, false }, }; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 1801aaf0..cf13938e 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -60,11 +60,11 @@ class WvContentDecryptionModule { virtual CdmResponseType Decrypt(const CdmSessionId& session_id, bool is_encrypted, const KeyId& key_id, - const uint8_t* encrypted_buffer, - size_t encrypted_size, + const uint8_t* encrypt_buffer, + size_t encrypt_length, const std::vector& iv, size_t block_offset, - uint8_t* decrypted_buffer); + void* decrypt_buffer); // Event listener related methods virtual bool AttachEventListener(CdmSessionId& session_id, diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 97515b3c..b4ef9166 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -92,14 +92,14 @@ CdmResponseType WvContentDecryptionModule::Decrypt( const CdmSessionId& session_id, bool is_encrypted, const KeyId& key_id, - const uint8_t* encrypted_buffer, - size_t encrypted_size, + const uint8_t* encrypt_buffer, + size_t encrypt_length, const std::vector& iv, size_t block_offset, - uint8_t* decrypted_buffer) { + void* decrypt_buffer) { return cdm_engine_->Decrypt(session_id, is_encrypted, key_id, - encrypted_buffer, encrypted_size, iv, - block_offset, decrypted_buffer); + encrypt_buffer, encrypt_length, iv, + block_offset, decrypt_buffer, true); } bool WvContentDecryptionModule::AttachEventListener( diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index d5ddd7f0..d1e2a1ce 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -26,6 +26,15 @@ int g_use_full_path = 0; // cannot use boolean in getopt_long namespace wvcdm { +typedef struct DecryptionData { + bool is_encrypted; + wvcdm::KeyId key_id; + std::vector encrypt_data; + std::vector iv; + size_t block_offset; + std::vector decrypt_data; +} DecryptionData; + class WvCdmRequestLicenseTest : public testing::Test { public: WvCdmRequestLicenseTest() {} @@ -101,12 +110,7 @@ class WvCdmRequestLicenseTest : public testing::Test { if (is_renewal) { // TODO application makes a license request, CDM will renew the license // when appropriate - wvcdm::CdmAppParameterMap app_parameters; - EXPECT_EQ(decryptor_.GenerateKeyRequest(session_id_, - init_data, - kLicenseTypeStreaming, - app_parameters, - &key_msg_), wvcdm::KEY_ADDED); + EXPECT_EQ(decryptor_.AddKey(session_id_, resp), wvcdm::KEY_ADDED); } else { EXPECT_EQ(decryptor_.AddKey(session_id_, resp), wvcdm::KEY_ADDED); @@ -134,15 +138,13 @@ TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) { decryptor_.CloseSession(session_id_); } -TEST_F(WvCdmRequestLicenseTest, NormalDecryption) { +TEST_F(WvCdmRequestLicenseTest, AddKeyTest) { decryptor_.OpenSession(g_key_system, &session_id_); GenerateKeyRequest(g_key_system, g_key_id); VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); decryptor_.CloseSession(session_id_); } -#if 0 -// TODO License renewal is not yet implented TEST_F(WvCdmRequestLicenseTest, LicenseRenewal) { decryptor_.OpenSession(g_key_system, &session_id_); GenerateKeyRequest(g_key_system, g_key_id); @@ -152,7 +154,6 @@ TEST_F(WvCdmRequestLicenseTest, LicenseRenewal) { VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, true); decryptor_.CloseSession(session_id_); } -#endif TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) { decryptor_.OpenSession(g_key_system, &session_id_); @@ -198,6 +199,313 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) { decryptor_.CloseSession(session_id_); } +TEST_F(WvCdmRequestLicenseTest, ClearDecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + // key 1, clear, 256b + DecryptionData data; + data.is_encrypted = false; + data.key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E"); + data.encrypt_data = wvcdm::a2b_hex( + "9da401105ab8da443e93e6fe089dfc69e00a9a51690d406872f338c5fa7dd3d5" + "abf8dfd660aaff3e327850a56eedf707c03e2d1a00f9f0371e3e19ea32b13267" + "7bc083ccbb83e6d9c03794ee97f50081221a8e5eb123f6dfa895e7a971166483" + "cdadd61cd8d0f859501e750e9d356d57252ecd9f7388459f5470de9d92198c44" + "0b520055b3b9a1c6b2c9d21e78dce99622d9d031fc7dee28a6d1d6dfb81502eb" + "463c4c189555f496d9aa529b3f5522e9f46dcf70b2bfe8df47daf02b6a267f93" + "f80d871786eb4bd7f08f9c52079c034a9534d885ba4c00cbe2234cfbb5205a56" + "41dd760f83d0f09f27881ad490efa8b99b7ab24b34311a2e8416b1a80d736ad7"); + data.iv = wvcdm::a2b_hex("50a6c61c3f7c2b37e72b0c047000dd4a"); + data.block_offset = 0; + data.decrypt_data = wvcdm::a2b_hex( + "9da401105ab8da443e93e6fe089dfc69e00a9a51690d406872f338c5fa7dd3d5" + "abf8dfd660aaff3e327850a56eedf707c03e2d1a00f9f0371e3e19ea32b13267" + "7bc083ccbb83e6d9c03794ee97f50081221a8e5eb123f6dfa895e7a971166483" + "cdadd61cd8d0f859501e750e9d356d57252ecd9f7388459f5470de9d92198c44" + "0b520055b3b9a1c6b2c9d21e78dce99622d9d031fc7dee28a6d1d6dfb81502eb" + "463c4c189555f496d9aa529b3f5522e9f46dcf70b2bfe8df47daf02b6a267f93" + "f80d871786eb4bd7f08f9c52079c034a9534d885ba4c00cbe2234cfbb5205a56" + "41dd760f83d0f09f27881ad490efa8b99b7ab24b34311a2e8416b1a80d736ad7"); + + std::vector decrypt_buffer; + size_t encrypt_length = data.encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data.is_encrypted, + data.key_id, + &data.encrypt_data.front(), + encrypt_length, + data.iv, + data.block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); +} + +TEST_F(WvCdmRequestLicenseTest, DecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + // key 1, encrypted, 256b + DecryptionData data; + data.is_encrypted = true; + data.key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E"); + data.encrypt_data = wvcdm::a2b_hex( + "3b2cbde084973539329bd5656da22d20396249bf4a18a51c38c4743360cc9fea" + "a1c78d53de1bd7e14dc5d256fd20a57178a98b83804258c239acd7aa38f2d7d2" + "eca614965b3d22049e19e236fc1800e60965d8b36415677bf2f843d50a6943c4" + "683c07c114a32f5e5fbc9939c483c3a1b2ecd3d82b554d649798866191724283" + "f0ab082eba2da79aaca5c4eaf186f9ee9a0c568f621f705a578f30e4e2ef7b96" + "5e14cc046ce6dbf272ee5558b098f332333e95fc879dea6c29bf34acdb649650" + "f08201b9e649960f2493fd7677cc3abf5ae70e5445845c947ba544456b431646" + "d95a133bff5f57614dda5e4446cd8837901d074149dadf4b775b5b07bb88ca20"); + data.iv = wvcdm::a2b_hex("4cca615fc013102892f91efee936639b"); + data.block_offset = 0; + data.decrypt_data = wvcdm::a2b_hex( + "5a36c0b633b58faf22156d78fdfb608e54a8095788b2b0463ef78d030b4abf82" + "eff34b8d9b7b6352e7d72de991b599662aa475da355033620152e2356ebfadee" + "06172be9e1058fa177e223b9fdd191380cff53c3ea810c6fd852a1df4967b799" + "415179a2276ec388ef763bab89605b9c6952c28dc8d6bf86b03fabbb46b392a3" + "1dad15be602eeeeabb45070b3e25d6bb0217073b1fc44c9fe848594121fd6a91" + "304d605e21f69615e1b57db18312b6b948725724b74e91d8aea7371e99532469" + "1b358bdee873f1936b63efe83d190a53c2d21754d302d63ff285174023473755" + "58b938c2e3ca4c2ce48942da97f9e45797f2c074ac6004734e93784a48af6160"); + + std::vector decrypt_buffer; + size_t encrypt_length = data.encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data.is_encrypted, + data.key_id, + &data.encrypt_data.front(), + encrypt_length, + data.iv, + data.block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); +} + +TEST_F(WvCdmRequestLicenseTest, SwitchKeyDecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + uint8_t data_blocks = 2; + DecryptionData data[data_blocks]; + + // block 0, key 1, encrypted, 256b + data[0].is_encrypted = true; + data[0].key_id = wvcdm::a2bs_hex("E02562E04CD55351B14B3D748D36ED8E"); + data[0].encrypt_data = wvcdm::a2b_hex( + "3b2cbde084973539329bd5656da22d20396249bf4a18a51c38c4743360cc9fea" + "a1c78d53de1bd7e14dc5d256fd20a57178a98b83804258c239acd7aa38f2d7d2" + "eca614965b3d22049e19e236fc1800e60965d8b36415677bf2f843d50a6943c4" + "683c07c114a32f5e5fbc9939c483c3a1b2ecd3d82b554d649798866191724283" + "f0ab082eba2da79aaca5c4eaf186f9ee9a0c568f621f705a578f30e4e2ef7b96" + "5e14cc046ce6dbf272ee5558b098f332333e95fc879dea6c29bf34acdb649650" + "f08201b9e649960f2493fd7677cc3abf5ae70e5445845c947ba544456b431646" + "d95a133bff5f57614dda5e4446cd8837901d074149dadf4b775b5b07bb88ca20"); + data[0].iv = wvcdm::a2b_hex("4cca615fc013102892f91efee936639b"); + data[0].block_offset = 0; + data[0].decrypt_data = wvcdm::a2b_hex( + "5a36c0b633b58faf22156d78fdfb608e54a8095788b2b0463ef78d030b4abf82" + "eff34b8d9b7b6352e7d72de991b599662aa475da355033620152e2356ebfadee" + "06172be9e1058fa177e223b9fdd191380cff53c3ea810c6fd852a1df4967b799" + "415179a2276ec388ef763bab89605b9c6952c28dc8d6bf86b03fabbb46b392a3" + "1dad15be602eeeeabb45070b3e25d6bb0217073b1fc44c9fe848594121fd6a91" + "304d605e21f69615e1b57db18312b6b948725724b74e91d8aea7371e99532469" + "1b358bdee873f1936b63efe83d190a53c2d21754d302d63ff285174023473755" + "58b938c2e3ca4c2ce48942da97f9e45797f2c074ac6004734e93784a48af6160"); + + // block 1, key 3, encrypted, 256b + data[1].is_encrypted = true; + data[1].key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62"); + data[1].encrypt_data = wvcdm::a2b_hex( + "337f294addb4c16d1015fd839e80314472432eda503bd0529422318bec7d2b34" + "2b28d24b2c0bf999fd31711901a2b90e03373cb9553ffd4b2e6e655b80a39fe8" + "61718220948f0031a37fe277f943409d09c83ff1c19fe8d601f5b4d139821750" + "47170006db5f38cb84706a9beeaa455fca3b17d8de90c143eb36aaaac3f4670a" + "7194064f4d59996c95992a3e6a848d4da8adddae3ad03c8d28110fda3e5c1d0a" + "35d175c816481275a02d2da96c7fc313864ae076f03887309cdf00ca856bad28" + "2146141964b7f7972e9b253b1fbed6d74ffedcfc51bb91fa78a602479b0b757f" + "53a16cca15c381a4eab3034ee38e12280982d575fe3de23dd65cf8ba240daa88"); + data[1].iv = wvcdm::a2b_hex("6d4ee851e563b951119cd33c52aadbf5"); + data[1].block_offset = 0; + data[1].decrypt_data = wvcdm::a2b_hex( + "c397c1c9bc6782cd859e92f7158e3ff2a54ee984869582b942b400c22ebb6843" + "7c50f999f73831fa12040f6aab607f57280189ff1db1ab1d0046ffaa55ce1790" + "3baf0f9c983351b2ff15cc4f61f0f8db6922804e74a207e1e5baaeca67b427c7" + "2dd7883ee8232041a9c4e56ccfb8bdc3016602c73fa8944e734ee34c41cf1a17" + "b009b404fd924d23dfee1f494b5e374c9e87c2910de36826044bff89939a70d2" + "47ff1a8a0baa7643026b8d9442fda69dde6802816ddd4b6e3b18f0a95e788d6d" + "166ed7435ef663ef019b4438d3e203734eb95d68758e028f29cd623f35cde4bd" + "edfea33ade378a92a356020bcf3fbba01c9ab16ad448ce6ebe708f768c6676a7"); + std::vector decrypt_buffer; + + for (int i = 0; i < data_blocks; ++i) { + size_t encrypt_length = data[i].encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data[i].is_encrypted, + data[i].key_id, + &data[i].encrypt_data.front(), + encrypt_length, + data[i].iv, + data[i].block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data[i].decrypt_data.begin(), + data[i].decrypt_data.end(), + decrypt_buffer.begin())); + } + decryptor_.CloseSession(session_id_); +} + +TEST_F(WvCdmRequestLicenseTest, PartialBlockDecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + // key 3, encrypted, 125b, offset 0 + DecryptionData data; + data.is_encrypted = true; + data.key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62"); + data.encrypt_data = wvcdm::a2b_hex( + "337f294addb4c16d1015fd839e80314472432eda503bd0529422318bec7d2b34" + "2b28d24b2c0bf999fd31711901a2b90e03373cb9553ffd4b2e6e655b80a39fe8" + "61718220948f0031a37fe277f943409d09c83ff1c19fe8d601f5b4d139821750" + "47170006db5f38cb84706a9beeaa455fca3b17d8de90c143eb36aaaac3"); + data.iv = wvcdm::a2b_hex("6d4ee851e563b951119cd33c52aadbf5"); + data.block_offset = 0; + data.decrypt_data = wvcdm::a2b_hex( + "c397c1c9bc6782cd859e92f7158e3ff2a54ee984869582b942b400c22ebb6843" + "7c50f999f73831fa12040f6aab607f57280189ff1db1ab1d0046ffaa55ce1790" + "3baf0f9c983351b2ff15cc4f61f0f8db6922804e74a207e1e5baaeca67b427c7" + "2dd7883ee8232041a9c4e56ccfb8bdc3016602c73fa8944e734ee34c41"); + + std::vector decrypt_buffer; + size_t encrypt_length = data.encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data.is_encrypted, + data.key_id, + &data.encrypt_data.front(), + encrypt_length, + data.iv, + data.block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), + decrypt_buffer.begin())); + decryptor_.CloseSession(session_id_); +} + +TEST_F(WvCdmRequestLicenseTest, PartialBlockWithOffsetDecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + // key 3, encrypted, 123b, offset 5 + DecryptionData data; + data.is_encrypted = true; + data.key_id = wvcdm::a2bs_hex("0065901A64A25899A5193664ABF9AF62"); + data.encrypt_data = wvcdm::a2b_hex( + "97f39b919ba56f3c3a51ecdcd7318bc130f054320c74db3990f925" + "054734c03ec79ee0da68938dc4f8c2d91e46ec2342ef24f9328294a9475f7ead" + "8ad3e71db62d6328e826e4ab375f4796aa2bc8b9266551e3007fb3c253780293" + "31fbc32ed29afcb9e7152cf072712c5a22c6b52d60e381eb53eeb58d36528746"); + data.iv = wvcdm::a2b_hex("43ba341482212c70f79d81c0f4faef8a"); + data.block_offset = 5; + data.decrypt_data = wvcdm::a2b_hex( + "d36911b44f470ff05d152a7bc69ea6b68aa812cd3676964acb4597" + "b518fe4b7ec0fe44469b1e4f8806922af9ac998d3e23349cea0e68f833564c15" + "e49584f94ef16b7ab6cd2d0b152430f1fb4d7644a0f591980388ac02012d3d42" + "73d6c9604517b1a622b66b8f4e8414e40b00351cc9859061bde810190c7b5df8"); + + std::vector decrypt_buffer; + size_t encrypt_length = data.encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data.is_encrypted, + data.key_id, + &data.encrypt_data.front(), + encrypt_length, + data.iv, + data.block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data.decrypt_data.begin(), data.decrypt_data.end(), + decrypt_buffer.begin())); + + decryptor_.CloseSession(session_id_); +} + +// TODO(rfrias, edwinwong): pending L1 OEMCrypto due to key block handling +/* +TEST_F(WvCdmRequestLicenseTest, KeyControlBlockDecryptionTest) { + decryptor_.OpenSession(g_key_system, &session_id_); + GenerateKeyRequest(g_key_system, g_key_id); + VerifyKeyRequestResponse(g_license_server, g_client_auth, g_key_id, false); + + DecryptionData data; + + // block 4, key 2, encrypted + data.is_encrypted = true; + data.key_id = wvcdm::a2bs_hex("0915007CAA9B5931B76A3A85F046523E"); + data.encrypt_data = wvcdm::a2b_hex( + "6758ac1c6ccf5d08479e3bfc62bbc0fd154aff4415aa7ed53d89e3983248d117" + "ab5137ae7cedd9f9d7321d4cf35a7013237afbcc2d893d1d928efa94e9f7e2ed" + "1855463cf75ff07ecc0246b90d0734f42d98aeea6a0a6d2618a8339bd0aca368" + "4fb4a4670c0385e5bd5de9e2d8b9226851b8f8955adfbab968793b46fd152f5e" + "e608467bb2695836f8f76c32731f5e208176d05e4b07020d58f6282c477f3840" + "b8079c02e8bd1d03191d190cc505ddfbb2e9bacc794534c91fe409d62f5389b9" + "35ed66134bd30f09f8da9dbfe6b8cf53d13cae34dae6e89109216e3a02233d5c" + "2f66aef74313aae4a99b654b485b5cc207b2dc8d44a8b99a4dc196a9820eccef"); + data.iv = wvcdm::a2b_hex("c8f2d133ec357fe727cd233b3bfa755f"); + data.block_offset = 0; + data.decrypt_data = wvcdm::a2b_hex( + "34bab89185f1be990dfc454410c7c9093d008bc783908838b02a65b26db28759" + "dca9dc5f117b3c8c3898358722d1b4c490e5a5d168ba0f9f8a3d4371b8fd1057" + "2d6dd65f3f9d1850de8d76dc71bd6dc6c23da4e1223fcc3e47162033a6f82890" + "e2bd6e9d6ddbe453830afc89064ed18078c786f8f746fcbafd88e83e7160cce5" + "62fa7a7d699ef8421bda020d242ae4f61a786213b707c3b17b83d77510f9a07e" + "d9d7e47d8f8fa2aff86eb26d61ddf384a27513e3facf6b1f5fe6c0d063b8856c" + "c486d930393ea79ba73ba293eda39059e2ce9ee7bd5d31ab11f35e55dc35dfe0" + "ea5e2ec684014852add6e29ce7d88a1595641ae4c0dd10155526b5a87560ec9d"); + + std::vector decrypt_buffer; + size_t encrypt_length = data[i].encrypt_data.size(); + decrypt_buffer.resize(encrypt_length); + + EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, + data.is_encrypted, + data.key_id, + &data.encrypt_data.front(), + encrypt_length, + data.iv, + data.block_offset, + &decrypt_buffer.front())); + + EXPECT_TRUE(std::equal(data.decrypt_data.begin(), + data.decrypt_data.end(), + decrypt_buffer.begin())); + } + decryptor_.CloseSession(session_id_); +} +*/ } // namespace wvcdm int main(int argc, char **argv) { diff --git a/libwvdrmengine/cdm/test/unit-test.mk b/libwvdrmengine/cdm/test/unit-test.mk index 921336e2..82160ab9 100644 --- a/libwvdrmengine/cdm/test/unit-test.mk +++ b/libwvdrmengine/cdm/test/unit-test.mk @@ -24,7 +24,8 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/test/gmock/include \ vendor/widevine/libwvdrmengine/cdm/core/include \ vendor/widevine/libwvdrmengine/cdm/core/test \ - vendor/widevine/libwvdrmengine/cdm/include + vendor/widevine/libwvdrmengine/cdm/include \ + vendor/widevine/libwvdrmengine/oemcrypto/include LOCAL_C_INCLUDES += \ external/protobuf/src