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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user