Reference Code for Big Usage Tables

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

This CL adds some big usage table functionality to the oemcrypto
mock and unit tests.

Still missing are: backwards compatibility, defragging the table,
haystack code, and lots of new unit tests.

The haystack now reports it doesn't support usage tables, so that
the unit tests will pass.  This will be fixed in a future CL.

b/31458046
b/32554171
b/34173776
b/34174907

Change-Id: I6e08e76f7612ffb77e413151e00f830339298c62
This commit is contained in:
Fred Gylys-Colwell
2017-01-25 18:56:01 -08:00
parent 1c5b4175aa
commit 3d977d999c
9 changed files with 1259 additions and 1061 deletions

View File

@@ -45,7 +45,14 @@ extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("------------------------- OEMCrypto_Initialize(void)\n");
}
if (crypto_engine) {
LOGE("------------------------- Calling Initialize without Terminate\n");
if (crypto_engine->Initialized()) {
crypto_engine->Terminate();
}
delete crypto_engine;
crypto_engine = NULL;
}
// NOTE: This requires a compatible Filesystem implementation.
wvcdm::FileSystem* fs = new wvcdm::FileSystem();
crypto_engine = new CryptoEngine(fs);
@@ -1400,6 +1407,13 @@ extern "C" bool OEMCrypto_IsAntiRollbackHwPresent() {
}
extern "C" uint32_t OEMCrypto_SupportedCertificates() {
if (!crypto_engine) {
LOGE("OEMCrypto_GetProvisioningMethod: OEMCrypto Not Initialized.");
return 0;
}
if (crypto_engine->config_provisioning_method() == OEMCrypto_DrmCertificate) {
return 0;
}
return OEMCrypto_Supports_RSA_2048bit | OEMCrypto_Supports_RSA_3072bit |
OEMCrypto_Supports_RSA_CAST;
if (!crypto_engine) {
@@ -1575,14 +1589,7 @@ extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_UpdateUsageTable();\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_UpdateUsageTable: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
return crypto_engine->usage_table()->UpdateTable();
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(
@@ -1600,8 +1607,13 @@ extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_DeactivateUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
return crypto_engine->usage_table()->DeactivateEntry(pstv);
return session_ctx->DeactivateUsageEntry(pstv);
}
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
@@ -1622,20 +1634,16 @@ extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if (!buffer_length) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_ReportUsage(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
UsageTableEntry* entry = crypto_engine->usage_table()->FindEntry(pstv);
if (!entry) {
LOGE("[OEMCrypto_ReportUsage(): Usage Table Entry not found]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
OEMCryptoResult sts =
entry->ReportUsage(session_ctx, pstv, buffer, buffer_length);
crypto_engine->usage_table()->UpdateTable();
OEMCryptoResult sts = session_ctx->ReportUsage(pstv, buffer, buffer_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("usage buffer", buffer, *buffer_length);
@@ -1648,68 +1656,14 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
const uint8_t* message, size_t message_length, const uint8_t* signature,
size_t signature_length) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DeleteUsageEntry(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("pst", pst, pst_length);
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
}
}
if (!crypto_engine) {
LOGE("OEMCrypto_DeleteUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_DeleteUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (message == NULL || message_length == 0 || signature == NULL ||
signature_length == 0 || pst == NULL || pst_length == 0) {
LOGE("[OEMCrypto_DeleteUsageEntry(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (!RangeCheck(message, message_length, pst, pst_length, false)) {
LOGE("[OEMCrypto_DeleteUsageEntry(): range check.]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Validate message signature
if (!session_ctx->ValidateMessage(message, message_length, signature,
signature_length)) {
LOGE("[OEMCrypto_DeleteUsageEntry(): OEMCrypto_ERROR_SIGNATURE_FAILURE.]");
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
if (crypto_engine->usage_table()->DeleteEntry(pstv)) {
return OEMCrypto_SUCCESS;
}
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
// TODO(fredgc): delete this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
size_t pst_length) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry()\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("pst", pst, pst_length);
}
}
if (!crypto_engine) {
LOGE("OEMCrypto_ForceDeleteUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
if (crypto_engine->usage_table()->DeleteEntry(pstv)) {
return OEMCrypto_SUCCESS;
}
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
// TODO(fredgc): delete this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
extern "C" OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
@@ -1723,9 +1677,7 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
crypto_engine->usage_table()->Clear();
crypto_engine->usage_table()->UpdateTable();
return OEMCrypto_SUCCESS;
return crypto_engine->usage_table().DeleteOldUsageTable();
}
extern "C" bool OEMCrypto_IsSRMUpdateSupported() { return false; }
@@ -1744,48 +1696,183 @@ extern "C" OEMCryptoResult OEMCrypto_RemoveSRM() {
}
extern "C" OEMCryptoResult OEMCrypto_CreateUsageTableHeader(
uint8_t* header_buffer, size_t* header_buffer_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
uint8_t* header_buffer,
size_t* header_buffer_length) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_CreateUsageTableHeader()\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_CreateUsageTableHeader: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
LOGE("OEMCrypto_CreateUsageTableHeader: Configured without Usage Tables.");
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
return crypto_engine->usage_table()
.CreateUsageTableHeader(header_buffer, header_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_LoadUsageTableHeader(
const uint8_t* buffer, size_t buffer_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_LoadUsageTableHeader()\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_LoadUsageTableHeader: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if (!buffer) {
LOGE("OEMCrypto_LoadUsageTableHeader: buffer null.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
std::vector<uint8_t> bufferv(buffer, buffer + buffer_length);
return crypto_engine->usage_table().LoadUsageTableHeader(bufferv);
}
extern "C" OEMCryptoResult OEMCrypto_CreateNewUsageEntry(
OEMCrypto_SESSION session, uint32_t* usage_entry_number) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_CreateNewUsageEntry(\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_CreateNewUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_CreateNewUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (!usage_entry_number) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
OEMCryptoResult sts = session_ctx->CreateNewUsageEntry(usage_entry_number);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- usage_entry_number = %d", *usage_entry_number);
}
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session,
uint32_t index,
const uint8_t* buffer,
size_t buffer_size) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_LoadUsageEntry(\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_LoadUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_LoadUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (!buffer) {
LOGE("[OEMCrypto_LoadUsageEntry(): buffer null]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
std::vector<uint8_t> bufferv(buffer, buffer + buffer_size);
return session_ctx->LoadUsageEntry(index, bufferv);
}
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageEntry(
OEMCrypto_SESSION session, uint8_t* header_buffer,
size_t* header_buffer_length, uint8_t* entry_buffer,
size_t* entry_buffer_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_UpdateUsageEntry(\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_UpdateUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if (!header_buffer_length || !entry_buffer_length) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_UpdateUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->UpdateUsageEntry(header_buffer, header_buffer_length,
entry_buffer, entry_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(
uint32_t new_table_size, uint8_t* header_buffer,
size_t* header_buffer_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader()\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_ShrinkUsageTableHeader: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if (!header_buffer) {
LOGE("OEMCrypto_ShrinkUsageTableHeader: buffer null.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return crypto_engine->usage_table().ShrinkUsageTableHeader(
new_table_size, header_buffer, header_buffer_length);
}
extern "C" OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
uint32_t new_index) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_MoveEntry(\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_MoveEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_MoveEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->MoveEntry(new_index);
}
extern "C" OEMCryptoResult OEMCrypto_CopyOldUsageEntry(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_CopyOldUsageEntry(\n");
}
if (!crypto_engine) {
LOGE("OEMCrypto_CopyOldUsageEntry: OEMCrypto Not Initialized.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->config_supports_usage_table()) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[OEMCrypto_CopyOldUsageEntry(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
return session_ctx->CopyOldUsageEntry(pstv);
}
} // namespace wvoec_mock