diff --git a/libwvdrmengine/cdm/core/include/entitlement_key_session.h b/libwvdrmengine/cdm/core/include/entitlement_key_session.h index ff065fde..2c2f9b8c 100644 --- a/libwvdrmengine/cdm/core/include/entitlement_key_session.h +++ b/libwvdrmengine/cdm/core/include/entitlement_key_session.h @@ -44,7 +44,10 @@ class EntitlementKeySession : public ContentKeySession { OEMCrypto_EntitledContentKeyObject MakeOecEntitledKey( const CryptoKey& input_key, std::string& message); - std::map entitled_keys_; + // Find the CryptoKey for the given entitled content key id. + std::map entitled_keys_; + // Find the current entitled content key id for the given entitlement key id. + std::map current_loaded_content_keys_; }; } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp b/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp index cd8650ae..2b4ec9ad 100644 --- a/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp +++ b/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp @@ -5,8 +5,10 @@ #include "entitlement_key_session.h" #include "crypto_key.h" +#include "crypto_session.h" #include "log.h" + namespace wvcdm { EntitlementKeySession::EntitlementKeySession(CryptoSessionId oec_session_id, metrics::CryptoMetrics* metrics) @@ -43,30 +45,40 @@ OEMCryptoResult EntitlementKeySession::LoadEntitledContentKeys( OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id, CdmCipherMode cipher_mode) { - // Before the key can be selected, it must be loaded under its associated - // entitlement key. This could, in theory, be done ahead of time during - // LoadEntitledContentKeys(), but OEMCrypto v14 only supports one content key - // per entitlement key at a time, (b/110266851) so we must swap out for the - // correct key every time SelectKey() is called. if (entitled_keys_.find(key_id) == entitled_keys_.end()) { LOGE("Unknown entitled key ID selected."); return OEMCrypto_ERROR_NO_CONTENT_KEY; } - std::string message; - OEMCrypto_EntitledContentKeyObject entitled_key = - MakeOecEntitledKey(entitled_keys_[key_id], message); + CryptoKey entitled_content_key = entitled_keys_[key_id]; + if (current_loaded_content_keys_[entitled_content_key + .entitlement_key_id()] != key_id) { + // Before the key can be selected, it must be loaded under its associated + // entitlement key. This could, in theory, be done ahead of time during + // LoadEntitledContentKeys(), but OEMCrypto v14 only supports one content + // key per entitlement key at a time, (b/110266851) so we must swap out for + // the correct key every time the current content key id has changed for an + // entitlement key. + std::string message; + OEMCrypto_EntitledContentKeyObject entitled_key = + MakeOecEntitledKey(entitled_content_key, message); + OEMCryptoResult result = OEMCrypto_SUCCESS; + M_TIME( + result = OEMCrypto_LoadEntitledContentKeys( + oec_session_id_, reinterpret_cast(message.data()), + message.size(), 1, &entitled_key), + metrics_, oemcrypto_load_entitled_keys_, result); + if (result != OEMCrypto_SUCCESS) { + return result; + } - OEMCryptoResult result = OEMCrypto_SUCCESS; - M_TIME(result = OEMCrypto_LoadEntitledContentKeys( - oec_session_id_, reinterpret_cast(message.data()), - message.size(), 1, &entitled_key), - metrics_, oemcrypto_load_entitled_keys_, result); - if (result != OEMCrypto_SUCCESS) { - return result; + current_loaded_content_keys_[entitled_content_key.entitlement_key_id()] = + key_id; + + return ContentKeySession::SelectKey(key_id, cipher_mode); + } else { + return OEMCrypto_SUCCESS; } - - return ContentKeySession::SelectKey(key_id, cipher_mode); } OEMCrypto_EntitledContentKeyObject EntitlementKeySession::MakeOecEntitledKey(