V16.4.2
Changes include: - Let entitled key sessions hold entitlement key id
This commit is contained in:
@@ -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<EntitledKey> 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<ContentKeyInfo>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<EntitledKey> 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<EntitledKey> 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<KeyId, std::unique_ptr<ContentKeyInfo>> content_key_info_map_;
|
||||
};
|
||||
|
||||
@@ -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<uint8_t> 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<uint8_t> key_id_str =
|
||||
std::vector<uint8_t>(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;
|
||||
}
|
||||
|
||||
@@ -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<EntitledKey>(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<uint8_t>& 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;
|
||||
|
||||
@@ -142,8 +142,8 @@ class SessionContext {
|
||||
const std::vector<uint8_t>& key_control_iv);
|
||||
virtual bool UpdateMacKeys(const std::vector<uint8_t>& mac_keys,
|
||||
const std::vector<uint8_t>& 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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user