diff --git a/oemcrypto/ref/src/oemcrypto_entitled_key_session.cpp b/oemcrypto/ref/src/oemcrypto_entitled_key_session.cpp index 779d631..956fc43 100644 --- a/oemcrypto/ref/src/oemcrypto_entitled_key_session.cpp +++ b/oemcrypto/ref/src/oemcrypto_entitled_key_session.cpp @@ -69,13 +69,13 @@ void UnlockAndCloseHardwareKeySlot(int fd) { EntitledKeySession::~EntitledKeySession() { ClearKeySlot(); } -const Key* EntitledKeySession::GetEntitlementKey( +KeyId EntitledKeySession::GetEntitlementKeyId( const KeyId& content_key_id) const { - if (content_key_info_map_.find(content_key_id) == - content_key_info_map_.end()) { - return nullptr; + auto content_key_info_iter = content_key_info_map_.find(content_key_id); + if (content_key_info_iter == content_key_info_map_.end()) { + return {}; } - return content_key_info_map_.at(content_key_id)->entitlement_key; + return content_key_info_iter->second->entitlement_key_id; } EntitledKey* EntitledKeySession::GetContentKey( @@ -88,18 +88,18 @@ EntitledKey* EntitledKeySession::GetContentKey( } bool EntitledKeySession::AddOrUpdateContentKey( - Key* entitlement_key, const KeyId& content_key_id, + const KeyId& entitlement_key_id, const KeyId& content_key_id, std::unique_ptr content_key) { - if (entitlement_key == nullptr || content_key_id.empty() || + if (entitlement_key_id.empty() || content_key_id.empty() || content_key == nullptr) { return false; } - // Remove the entry if |entitlement_key| already referenced by a content key - // with the same parity. Each entitlement key can only be referred by one + // Remove the entry if |entitlement_key_id| is already referenced by a content + // key with the same parity. Each entitlement key can only be referred by one // even and one odd content key within an entitled key session. for (auto const& content_key_entry : content_key_info_map_) { const ContentKeyInfo* const key_info = content_key_entry.second.get(); - if (key_info->entitlement_key == entitlement_key && + if (key_info->entitlement_key_id == entitlement_key_id && key_info->content_key->is_even_key() == content_key->is_even_key()) { RemoveContentKey(content_key_entry.first); break; @@ -114,7 +114,8 @@ bool EntitledKeySession::AddOrUpdateContentKey( content_key_info_map_[content_key_id] = std::unique_ptr(new ContentKeyInfo()); content_key_info_map_[content_key_id]->content_key = std::move(content_key); - content_key_info_map_[content_key_id]->entitlement_key = entitlement_key; + content_key_info_map_[content_key_id]->entitlement_key_id = + entitlement_key_id; return true; } diff --git a/oemcrypto/ref/src/oemcrypto_entitled_key_session.h b/oemcrypto/ref/src/oemcrypto_entitled_key_session.h index 332a2b8..8f7f8e5 100644 --- a/oemcrypto/ref/src/oemcrypto_entitled_key_session.h +++ b/oemcrypto/ref/src/oemcrypto_entitled_key_session.h @@ -22,35 +22,37 @@ typedef uint32_t SessionId; class EntitledKeySession { public: - explicit EntitledKeySession(SessionId key_sid) - : key_sid_(key_sid), - current_content_key_(nullptr), - current_entitlement_key_(nullptr){}; + explicit EntitledKeySession(SessionId key_sid) : key_sid_(key_sid){}; EntitledKeySession(const EntitledKeySession&) = delete; EntitledKeySession(EntitledKeySession&&) = delete; ~EntitledKeySession(); // Get id of this entitled key session . SessionId GetSessionId() const { return key_sid_; } - // Get reference of the entitlement key that entitles |content_key_id|. - const Key* GetEntitlementKey(const KeyId& content_key_id) const; + // Get ID of the entitlement key that entitles |content_key_id|. An empty ID + // will be returned in case of error. + KeyId GetEntitlementKeyId(const KeyId& content_key_id) const; // Get content key whose id is |content_key_id|. EntitledKey* GetContentKey(const KeyId& content_key_id) const; - // Select current content key to |content_key_id|, and current entitlement - // key to its corresponding entitlement key. + // Select current content key to |content_key_id|. void SetCurrentKey(const KeyId& content_key_id) { - current_content_key_ = GetContentKey(content_key_id); - current_entitlement_key_ = GetEntitlementKey(content_key_id); + current_content_key_id_ = content_key_id; } // Return the current content key selected, nullptr if none is selected. - const EntitledKey* CurrentContentKey() const { return current_content_key_; } - // Return the current entitlement key selected, nullptr if none is selected. - const Key* CurrentEntitlementKey() const { return current_entitlement_key_; } - - // Update the content key that refers to |entitlement_key| or insert a new - // entry that refers to |entitlement_key|. |entitlement_key| must not be null. - bool AddOrUpdateContentKey(Key* entitlement_key, const KeyId& content_key_id, + const EntitledKey* CurrentContentKey() const { + return GetContentKey(current_content_key_id_); + } + // Return the current entitlement key id selected, empty if none is selected. + KeyId CurrentEntitlementKeyId() const { + return GetEntitlementKeyId(current_content_key_id_); + } + // If the specified |entitlement_key_id| has already been referenced by a + // content key with the same parity (even/odd), it will replace it with the + // new |content key| passed in. Otherwise, insert a new entry that refers to + // |entitlement_key_id|. + bool AddOrUpdateContentKey(const KeyId& entitlement_key_id, + const KeyId& content_key_id, std::unique_ptr content_key); // Remove a content key |content_key_id|. bool RemoveContentKey(const KeyId& content_key_id); @@ -68,7 +70,7 @@ class EntitledKeySession { private: struct ContentKeyInfo { std::unique_ptr content_key; - Key* entitlement_key; + KeyId entitlement_key_id; }; // Must have the same exact definition on the tuner hal side. @@ -92,8 +94,7 @@ class EntitledKeySession { ContentKeySlot* key_slot) const; const SessionId key_sid_; - EntitledKey* current_content_key_; - const Key* current_entitlement_key_; + KeyId current_content_key_id_; // Map from content key id to content key info. std::map> content_key_info_map_; }; diff --git a/oemcrypto/ref/src/oemcrypto_ref.cpp b/oemcrypto/ref/src/oemcrypto_ref.cpp index 5bcfd1f..27aa9fa 100644 --- a/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -631,18 +631,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl( LOGE("[OEMCrypto_QueryKeyControl(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } - EntitledKeySession* entitled_key_session = nullptr; + + std::vector key_id_str(key_id, key_id + key_id_length); + // |key_id| is the content key id in case of entitlement license. In this + // case, get the corresponding entitlement key which holds the key control + // block. if (crypto_engine->SessionTypeBits(session) == kSessionTypeEntitledKey) { - entitled_key_session = crypto_engine->FindEntitledKeySession(session); + EntitledKeySession* entitled_key_session = + crypto_engine->FindEntitledKeySession(session); if (entitled_key_session == nullptr) { LOGE("OEMCrypto_QueryKeyControl(): can not find the key session."); return OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION; } + key_id_str = entitled_key_session->GetEntitlementKeyId(key_id_str); } - const std::vector key_id_str = - std::vector(key_id, key_id + key_id_length); - if (!session_ctx->QueryKeyControlBlock(entitled_key_session, key_id_str, - block)) { + + if (!session_ctx->QueryKeyControlBlock(key_id_str, block)) { LOGE("[OEMCrypto_QueryKeyControl(): FAIL]"); return OEMCrypto_ERROR_NO_CONTENT_KEY; } diff --git a/oemcrypto/ref/src/oemcrypto_session.cpp b/oemcrypto/ref/src/oemcrypto_session.cpp index 5774c14..1b312c9 100644 --- a/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/oemcrypto/ref/src/oemcrypto_session.cpp @@ -830,7 +830,7 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys( } if (!key_session->AddOrUpdateContentKey( - entitlement_key, content_key_id, + entitlement_key_id, content_key_id, std::unique_ptr(new EntitledKey(content_key)))) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -909,7 +909,7 @@ OEMCryptoResult SessionContext::LoadEntitledCasKeys( content_key_obj->set_cipher_mode(key_data->cipher_mode); content_key_obj->set_is_even_key(i % 2 == 0); - if (!key_session->AddOrUpdateContentKey(entitlement_key, content_key_id, + if (!key_session->AddOrUpdateContentKey(entitlement_key_id, content_key_id, std::move(content_key_obj))) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1400,22 +1400,11 @@ bool SessionContext::UpdateMacKeys(const std::vector& enc_mac_keys, return true; } -bool SessionContext::QueryKeyControlBlock(EntitledKeySession* key_session, - const KeyId& key_id, uint32_t* data) { +bool SessionContext::QueryKeyControlBlock(const KeyId& key_id, uint32_t* data) { if (session_keys_ == nullptr) { return false; } - if ((session_keys_->type() == OEMCrypto_EntitlementLicense && - key_session == nullptr) || - (session_keys_->type() == OEMCrypto_ContentLicense && - key_session != nullptr)) { - return false; - } - - // For entitlement license, |key_id| here refers to the content key id. - const Key* control_key = key_session != nullptr - ? key_session->GetEntitlementKey(key_id) - : session_keys_->Find(key_id); + const Key* control_key = session_keys_->Find(key_id); if (control_key == nullptr) { LOGE("[QueryKeyControlBlock(): No key matches key id]"); return false; @@ -1657,20 +1646,13 @@ OEMCryptoResult SessionContext::DecryptSubsample( // Compute hash for FDPT. if (compute_hash_) { - bool has_key_control = false; - uint32_t key_control_bits = 0; - if (key_session != nullptr && - key_session->CurrentEntitlementKey() != nullptr) { - has_key_control = true; - key_control_bits = - key_session->CurrentEntitlementKey()->control().control_bits(); - } else if (key_session == nullptr && current_content_key() != nullptr) { - has_key_control = true; - key_control_bits = current_content_key()->control().control_bits(); - } - - if (!has_key_control || - (key_control_bits & wvoec::kControlAllowHashVerification) == 0) { + const Key* current_control_key = + key_session == nullptr + ? current_content_key() + : session_keys_->Find(key_session->CurrentEntitlementKeyId()); + if (current_control_key == nullptr || + (current_control_key->control().control_bits() & + wvoec::kControlAllowHashVerification) == 0) { LOGE("[DecryptCENC(): OEMCrypto_ERROR_UNKNOWN_FAILURE]"); hash_error_ = OEMCrypto_ERROR_UNKNOWN_FAILURE; compute_hash_ = false; @@ -1714,10 +1696,15 @@ OEMCryptoResult SessionContext::ChooseDecrypt( LOGE("[ChooseDecrypt(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); return OEMCrypto_ERROR_DECRYPT_FAILED; } - - const KeyControlBlock& key_control_block = - key_session == nullptr ? current_content_key()->control() - : key_session->CurrentEntitlementKey()->control(); + const Key* current_control_key = + key_session == nullptr + ? current_content_key() + : session_keys_->Find(key_session->CurrentEntitlementKeyId()); + if (current_control_key == nullptr) { + LOGE("[ChooseDecrypt(): Can not find key control block.]"); + return OEMCrypto_ERROR_DECRYPT_FAILED; + } + const KeyControlBlock& key_control_block = current_control_key->control(); OEMCryptoResult result = CheckKeyControlBlockUse(key_control_block, "DecryptCENC", 0, buffer_type); if (result != OEMCrypto_SUCCESS) return result; diff --git a/oemcrypto/ref/src/oemcrypto_session.h b/oemcrypto/ref/src/oemcrypto_session.h index 7fbf030..8aa6859 100644 --- a/oemcrypto/ref/src/oemcrypto_session.h +++ b/oemcrypto/ref/src/oemcrypto_session.h @@ -142,8 +142,8 @@ class SessionContext { const std::vector& key_control_iv); virtual bool UpdateMacKeys(const std::vector& mac_keys, const std::vector& iv); - virtual bool QueryKeyControlBlock(EntitledKeySession* key_session, - const KeyId& key_id, uint32_t* data); + // |key_id| must be the key that holds the key control block. + virtual bool QueryKeyControlBlock(const KeyId& key_id, uint32_t* data); virtual OEMCryptoResult SelectEntitledContentKey( EntitledKeySession* key_session, const KeyId& key_id, OEMCryptoCipherMode cipher_mode); diff --git a/plugin/src/device_files.cpp b/plugin/src/device_files.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/wvutil/src/android_properties.cpp b/wvutil/src/android_properties.cpp index 6aa5a57..115300c 100644 --- a/wvutil/src/android_properties.cpp +++ b/wvutil/src/android_properties.cpp @@ -10,7 +10,7 @@ namespace { // Version format: OEMCrypto_major.OEMCrypto_minor.Plugin_version -constexpr char kWvCasPluginVersion[] = "16.4.1"; +constexpr char kWvCasPluginVersion[] = "16.4.2"; bool GetAndroidProperty(const char* key, std::string* value) { char val[PROPERTY_VALUE_MAX];