OEMCrypto Backwards Compatible Usage Table

Merge from widevine of http://go/wvgerrit/23283

This CL adds the backwards compatiblity functions to the new usage
tables in the oemcrypto mock reference code.

b/31458046
b/32554171

Change-Id: I04901d95aceb8910406f7c514c26c29c2c575322
This commit is contained in:
Fred Gylys-Colwell
2017-01-27 15:22:55 -08:00
parent d06fa606c7
commit 9e153438db
14 changed files with 1151 additions and 350 deletions

View File

@@ -19,11 +19,13 @@
#include "log.h"
#include "oemcrypto_engine_mock.h"
#include "oemcrypto_logging.h"
#include "oemcrypto_old_usage_table_mock.h"
#include "properties.h"
#include "pst_report.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
namespace wvoec_mock {
namespace {
const size_t kMagicLength = 8;
const char* kEntryVerification = "USEENTRY";
@@ -31,13 +33,15 @@ const char* kHeaderVerification = "USEHEADR";
// Offset into a signed block where we start encrypting. We need to
// skip the signature and the iv.
const size_t kEncryptionOffset = SHA256_DIGEST_LENGTH + SHA256_DIGEST_LENGTH;
// A structure that holds an usage entry and its signature.
struct SignedEntryBlock {
uint8_t signature[SHA256_DIGEST_LENGTH];
uint8_t iv[SHA256_DIGEST_LENGTH];
uint8_t verification[kMagicLength];
wvoec_mock::StoredUsageEntry data;
StoredUsageEntry data;
};
// This has the data in the header of constant size. There is also an array
// of generation numbers.
struct SignedHeaderBlock {
@@ -50,8 +54,6 @@ struct SignedHeaderBlock {
} // namespace
namespace wvoec_mock {
UsageTableEntry::UsageTableEntry(UsageTable* table, uint32_t index,
int64_t generation)
: usage_table_(table), recent_decrypt_(false), forbid_report_(true) {
@@ -286,6 +288,37 @@ OEMCryptoResult UsageTableEntry::LoadData(CryptoEngine* ce, uint32_t index,
return OEMCrypto_SUCCESS;
}
OEMCryptoResult UsageTableEntry::CopyOldUsageEntry(
const std::vector<uint8_t>& pst) {
OldUsageTableEntry* old_entry = usage_table_->FindOldUsageEntry(pst);
if (!old_entry) return OEMCrypto_ERROR_WRONG_PST;
data_.time_of_license_received = old_entry->time_of_license_received_;
data_.time_of_first_decrypt = old_entry->time_of_first_decrypt_;
data_.time_of_last_decrypt = old_entry->time_of_last_decrypt_;
data_.status = old_entry->status_;
if (old_entry->mac_key_server_.size() != wvcdm::MAC_KEY_SIZE) {
LOGE("CopyOldEntry: Old entry has bad server mac key.");
} else {
memcpy(data_.mac_key_server, &(old_entry->mac_key_server_[0]),
wvcdm::MAC_KEY_SIZE);
}
if (old_entry->mac_key_client_.size() != wvcdm::MAC_KEY_SIZE) {
LOGE("CopyOldEntry: Old entry has bad client mac key.");
} else {
memcpy(data_.mac_key_client, &(old_entry->mac_key_client_[0]),
wvcdm::MAC_KEY_SIZE);
}
if (pst.size() > kMaxPSTLength) {
LOGE("CopyOldEntry: PST Length was too large. Truncating.");
data_.pst_length = kMaxPSTLength;
} else {
data_.pst_length = pst.size();
}
memcpy(data_.pst, &pst[0], wvcdm::MAC_KEY_SIZE);
return OEMCrypto_SUCCESS;
}
size_t UsageTableEntry::SignedEntrySize() {
size_t base = sizeof(SignedEntryBlock);
// round up to make even number of blocks:
@@ -293,6 +326,13 @@ size_t UsageTableEntry::SignedEntrySize() {
return blocks * wvcdm::KEY_IV_SIZE;
}
UsageTable::~UsageTable() {
if (old_table_) {
delete old_table_;
old_table_ = NULL;
}
}
size_t UsageTable::SignedHeaderSize(size_t count) {
size_t base = sizeof(SignedHeaderBlock) + count * sizeof(int64_t);
// round up to make even number of blocks:
@@ -329,7 +369,10 @@ OEMCryptoResult UsageTable::UpdateUsageEntry(SessionContext* session,
OEMCryptoResult UsageTable::CreateNewUsageEntry(SessionContext* session,
UsageTableEntry** entry,
uint32_t* usage_entry_number) {
if (!header_loaded_) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (!header_loaded_) {
LOGE("CreateNewUsageEntry: Header not loaded.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!entry) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (!usage_entry_number) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
uint32_t index = generation_numbers_.size();
@@ -347,7 +390,10 @@ OEMCryptoResult UsageTable::LoadUsageEntry(SessionContext* session,
UsageTableEntry** entry,
uint32_t index,
const std::vector<uint8_t>& buffer) {
if (!header_loaded_) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (!header_loaded_) {
LOGE("CreateNewUsageEntry: Header not loaded.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!entry) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (index >= generation_numbers_.size())
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -389,6 +435,10 @@ OEMCryptoResult UsageTable::ShrinkUsageTableHeader(
return OEMCrypto_ERROR_SHORT_BUFFER;
}
*header_buffer_length = signed_header_size;
if (!header_buffer) {
LOGE("OEMCrypto_ShrinkUsageTableHeader: buffer null.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
for (size_t i = new_table_size; i < sessions_.size(); i++) {
if (sessions_[i]) {
LOGE("ShrinkUsageTableHeader: session open for %d", i);
@@ -544,7 +594,7 @@ OEMCryptoResult UsageTable::MoveEntry(UsageTableEntry* entry,
}
if (sessions_[new_index]) {
LOGE("MoveEntry: session open for %d", new_index);
return OEMCrypto_ERROR_INVALID_CONTEXT;
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (!entry) {
LOGE("MoveEntry: null entry");
@@ -636,15 +686,41 @@ OEMCryptoResult UsageTable::CreateUsageTableHeader(
return SaveUsageTableHeader(header_buffer, *header_buffer_length);
}
OEMCryptoResult UsageTable::CopyOldUsageEntry(UsageTableEntry* entry,
const std::vector<uint8_t>& pst) {
// TODO(fredgc): add this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
OldUsageTableEntry* UsageTable::FindOldUsageEntry(
const std::vector<uint8_t>& pst) {
if (!old_table_) old_table_ = new OldUsageTable(ce_);
return old_table_->FindEntry(pst);
}
OEMCryptoResult UsageTable::DeleteOldUsageTable() {
// TODO(fredgc): add this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (old_table_) {
old_table_->Clear();
delete old_table_;
old_table_ = NULL;
}
OldUsageTable::DeleteFile(ce_);
return OEMCrypto_SUCCESS;
}
OEMCryptoResult UsageTable::CreateOldUsageEntry(
uint64_t time_since_license_received, uint64_t time_since_first_decrypt,
uint64_t time_since_last_decrypt, OEMCrypto_Usage_Entry_Status status,
uint8_t* server_mac_key, uint8_t* client_mac_key, const uint8_t* pst,
size_t pst_length) {
if (!old_table_) old_table_ = new OldUsageTable(ce_);
std::vector<uint8_t> pstv(pst, pst+pst_length);
OldUsageTableEntry *old_entry = old_table_->CreateEntry(pstv);
int64_t now = time(NULL);
old_entry->time_of_license_received_ = now - time_since_license_received;
old_entry->time_of_first_decrypt_ = now - time_since_first_decrypt;
old_entry->time_of_last_decrypt_ = now - time_since_last_decrypt;
old_entry->status_ = status;
old_entry->mac_key_server_.assign(server_mac_key,
server_mac_key + wvcdm::MAC_KEY_SIZE);
old_entry->mac_key_client_.assign(client_mac_key,
client_mac_key + wvcdm::MAC_KEY_SIZE);
return OEMCrypto_SUCCESS;
}
} // namespace wvoec_mock