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:
Fred Gylys-Colwell
2015-03-30 15:38:52 -07:00
parent 10cc0a5ddb
commit 582eb32661
5 changed files with 115 additions and 0 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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,