OEMCrypto Query Key Control Block
Merge from Widevine repo http://go/wvgerrit/13818 This CL adds the ability to query OEMCrypto about the key control block and duration of a key that has been loaded. There are unit tests and implementation in the level 3 and reference implementation. b/18503541 Change-Id: I8e40d90a3c64c1ce030af6fef9e98c8eac0df1a5
This commit is contained in:
@@ -941,6 +941,25 @@ bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::QueryKeyControlBlock(const KeyId& key_id, uint32_t* data) {
|
||||
const Key* content_key = session_keys_.Find(key_id);
|
||||
if (LogCategoryEnabled(kLoggingTraceDecryption)){
|
||||
LOGI(( "Select Key: key_id = " +
|
||||
wvcdm::b2a_hex(key_id) ).c_str());
|
||||
LOGI(( "Select Key: key = " +
|
||||
wvcdm::b2a_hex(content_key->value()) ).c_str());
|
||||
}
|
||||
if (NULL == content_key) {
|
||||
LOGE("[QueryKeyControlBlock(): No key matches key id]");
|
||||
return false;
|
||||
}
|
||||
data[0] = 0; // verification optional.
|
||||
data[1] = htonl(content_key->control().duration());
|
||||
data[2] = 0; // nonce optional.
|
||||
data[3] = htonl(content_key->control().control_bits());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::SelectContentKey(const KeyId& key_id) {
|
||||
const Key* content_key = session_keys_.Find(key_id);
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ class SessionContext {
|
||||
const std::vector<uint8_t>& key_control_iv);
|
||||
bool UpdateMacKeys(const std::vector<uint8_t>& mac_keys,
|
||||
const std::vector<uint8_t>& iv);
|
||||
bool QueryKeyControlBlock(const KeyId& key_id, uint32_t* data);
|
||||
bool SelectContentKey(const KeyId& key_id);
|
||||
const Key* current_content_key(void) {return current_content_key_;}
|
||||
void set_mac_key_server(const std::vector<uint8_t>& mac_key_server) {
|
||||
|
||||
@@ -451,6 +451,43 @@ OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl(
|
||||
OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length,
|
||||
uint8_t* key_control_block, size_t* key_control_block_length) {
|
||||
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
|
||||
LOGI("-- OEMCryptoResult OEMCrypto_QueryKeyControl"
|
||||
"(const OEMCrypto_SESSION session)\n");
|
||||
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
|
||||
dump_hex("key_id", key_id, key_id_length);
|
||||
}
|
||||
}
|
||||
uint32_t* block = reinterpret_cast<uint32_t*>(key_control_block);
|
||||
if ((key_control_block_length == NULL)
|
||||
|| (*key_control_block_length < wvcdm::KEY_CONTROL_SIZE)) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): OEMCrypto_ERROR_SHORT_BUFFER]");
|
||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||
}
|
||||
*key_control_block_length = wvcdm::KEY_CONTROL_SIZE;
|
||||
if (key_id == NULL) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): key_id null. "
|
||||
"OEMCrypto_ERROR_UNKNOWN_FAILURE]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||
if (!session_ctx || !session_ctx->isValid()) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): ERROR_INVALID_SESSION]");
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
const std::vector<uint8_t> key_id_str =
|
||||
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
||||
if (!session_ctx->QueryKeyControlBlock(key_id_str, block)) {
|
||||
LOGE("[OEMCrypto_QueryKeyControl(): FAIL]");
|
||||
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
|
||||
const uint8_t* key_id,
|
||||
|
||||
Reference in New Issue
Block a user