Merge "Changes to CryptoSession to support big usage tables"

This commit is contained in:
Rahul Frias
2017-01-26 18:40:22 +00:00
committed by Android (Google) Code Review
8 changed files with 386 additions and 4 deletions

View File

@@ -29,6 +29,7 @@ std::string EncodeUint32(unsigned int u) {
}
const uint32_t kRsaSignatureLength = 256;
const size_t kMaximumChunkSize = 100 * 1024; // 100 KiB
const size_t kEstimatedInitialUsageTableHeader = 40;
}
namespace wvcdm {
@@ -509,6 +510,7 @@ CdmResponseType CryptoSession::LoadKeys(
uint8_t* srm_req = NULL;
if (!srm_requirement.empty())
srm_req = const_cast<uint8_t*>(msg) + GetOffset(message, srm_requirement);
LOGV("LoadKeys: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult sts = OEMCrypto_LoadKeys(
oec_session_id_, msg, message.size(),
@@ -1464,6 +1466,243 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
return NO_ERROR;
}
CdmResponseType CryptoSession::CreateUsageTableHeader(
std::string* usage_table_header) {
LOGV("CreateUsageTableHeader: id=%ld", (uint32_t)oec_session_id_);
if (usage_table_header == NULL) {
LOGE("CreateUsageTableHeader: usage_table_header param not provided");
return INVALID_PARAMETERS_ENG_17;
}
usage_table_header->resize(kEstimatedInitialUsageTableHeader);
uint32_t usage_table_header_size = usage_table_header->size();
OEMCryptoResult result = OEMCrypto_CreateUsageTableHeader(
requested_security_level_,
reinterpret_cast<uint8_t*>(const_cast<char*>(usage_table_header->data())),
&usage_table_header_size);
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
usage_table_header->resize(usage_table_header_size);
result = OEMCrypto_CreateUsageTableHeader(
requested_security_level_,
reinterpret_cast<uint8_t*>(
const_cast<char*>(usage_table_header->data())),
&usage_table_header_size);
}
if (result != OEMCrypto_SUCCESS) {
LOGE("CreateUsageTableHeader; usage table header creation failed: %d",
result);
return CREATE_USAGE_TABLE_ERROR;
}
usage_table_header->resize(usage_table_header_size);
return NO_ERROR;
}
CdmResponseType CryptoSession::LoadUsageTableHeader(
const std::string& usage_table_header) {
LOGV("LoadUsageTableHeader: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult result = OEMCrypto_LoadUsageTableHeader(
requested_security_level_,
reinterpret_cast<const uint8_t*>(usage_table_header.data()),
usage_table_header.size());
if (result != OEMCrypto_SUCCESS) {
if (result == OEMCrypto_WARNING_GENERATION_SKEW) {
LOGW(
"LoadUsageTableHeader: OEMCrypto_LoadUsageTableHeader warning: "
"generation skew");
} else {
LOGE("LoadUsageTableHeader: OEMCrypto_LoadUsageTableHeader error: %d",
result);
}
}
switch (result) {
case OEMCrypto_SUCCESS:
case OEMCrypto_WARNING_GENERATION_SKEW:
return NO_ERROR;
case OEMCrypto_ERROR_GENERATION_SKEW:
return LOAD_USAGE_HEADER_GENERATION_SKEW;
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
return LOAD_USAGE_HEADER_SIGNATURE_FAILURE;
case OEMCrypto_ERROR_BAD_MAGIC:
return LOAD_USAGE_HEADER_BAD_MAGIC;
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
default:
return LOAD_USAGE_HEADER_UNKNOWN_ERROR;
}
}
CdmResponseType CryptoSession::CreateUsageEntry(uint32_t* entry_number) {
LOGV("CreateUsageEntry: id=%ld", (uint32_t)oec_session_id_);
if (entry_number == NULL) {
LOGE("CreateUsageEntry: entry_number param not provided");
return INVALID_PARAMETERS_ENG_18;
}
OEMCryptoResult result =
OEMCrypto_CreateNewUsageEntry(oec_session_id_, entry_number);
switch (result) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
LOGE(
"CreateUsageEntry: OEMCrypto_CreateNewUsageEntry error: "
"Insufficient resources");
return INSUFFICIENT_CRYPTO_RESOURCES_3;
default:
LOGE("CreateUsageEntry: OEMCrypto_CreateNewUsageEntry error: %d", result);
return CREATE_USAGE_ENTRY_UNKNOWN_ERROR;
}
}
CdmResponseType CryptoSession::LoadUsageEntry(uint32_t entry_number,
const std::string& usage_entry) {
LOGV("LoadUsageEntry: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult result = OEMCrypto_LoadUsageEntry(
oec_session_id_, entry_number,
reinterpret_cast<const uint8_t*>(usage_entry.data()), usage_entry.size());
if (result != OEMCrypto_SUCCESS) {
if (result == OEMCrypto_WARNING_GENERATION_SKEW) {
LOGW("LoadUsageEntry: OEMCrypto_LoadUsageEntry warning: generation skew");
} else {
LOGE("LoadUsageTableHeader: OEMCrypto_LoadUsageEntry error: %d", result);
}
}
switch (result) {
case OEMCrypto_SUCCESS:
case OEMCrypto_WARNING_GENERATION_SKEW:
return NO_ERROR;
case OEMCrypto_ERROR_GENERATION_SKEW:
return LOAD_USAGE_ENTRY_GENERATION_SKEW;
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
return LOAD_USAGE_ENTRY_SIGNATURE_FAILURE;
default:
return LOAD_USAGE_ENTRY_UNKNOWN_ERROR;
}
}
CdmResponseType CryptoSession::UpdateUsageEntry(std::string* usage_table_header,
std::string* usage_entry) {
LOGV("UpdateUsageEntry: id=%ld", (uint32_t)oec_session_id_);
if (usage_table_header == NULL) {
LOGE("UpdateUsageEntry: usage_table_header param not provided");
return INVALID_PARAMETERS_ENG_19;
}
if (usage_entry == NULL) {
LOGE("UpdateUsageEntry: usage_entry param not provided");
return INVALID_PARAMETERS_ENG_20;
}
size_t usage_table_header_len = 0;
size_t usage_entry_len = 0;
OEMCryptoResult result = OEMCrypto_UpdateUsageEntry(
oec_session_id_, NULL, &usage_table_header_len, NULL, &usage_entry_len);
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
usage_table_header->resize(usage_table_header_len);
usage_entry->resize(usage_entry_len);
result = OEMCrypto_UpdateUsageEntry(
oec_session_id_,
reinterpret_cast<uint8_t*>(
const_cast<char*>(usage_table_header->data())),
&usage_table_header_len,
reinterpret_cast<uint8_t*>(const_cast<char*>(usage_entry->data())),
&usage_entry_len);
}
if (result != OEMCrypto_SUCCESS) {
LOGE("UpdateUsageEntry: OEMCrypto_UpdateUsageEntry error: %d", result);
return UPDATE_USAGE_ENTRY_UNKNOWN_ERROR;
}
usage_table_header->resize(usage_table_header_len);
usage_entry->resize(usage_entry_len);
return NO_ERROR;
}
CdmResponseType CryptoSession::DecrementUsageTableHeaderSize(
uint32_t current_usage_table_size, std::string* usage_table_header) {
LOGV("DecrementUsageTableHeaderSize: id=%ld", (uint32_t)oec_session_id_);
if (usage_table_header == NULL) {
LOGE(
"DecrementUsageTableHeaderSize: usage_table_header param not "
"provided");
return INVALID_PARAMETERS_ENG_21;
}
size_t usage_table_header_len = 0;
OEMCryptoResult result = OEMCrypto_ShrinkUsageTableHeader(
requested_security_level_, current_usage_table_size, NULL,
&usage_table_header_len);
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
usage_table_header->resize(usage_table_header_len);
result = OEMCrypto_ShrinkUsageTableHeader(
requested_security_level_, --current_usage_table_size,
reinterpret_cast<uint8_t*>(
const_cast<char*>(usage_table_header->data())),
&usage_table_header_len);
}
if (result != OEMCrypto_SUCCESS) {
LOGE(
"DecrementUsageTableHeaderSize: OEMCrypto_ShrinkUsageTableHeader "
"error: %d",
result);
return SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR;
}
usage_table_header->resize(usage_table_header_len);
return NO_ERROR;
}
CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) {
LOGV("MoveUsageEntry: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult result =
OEMCrypto_MoveEntry(oec_session_id_, new_entry_number);
if (result != OEMCrypto_SUCCESS) {
LOGE("MoveUsageEntry: OEMCrypto_MoveEntry error: %d", result);
return MOVE_USAGE_ENTRY_UNKNOWN_ERROR;
}
return NO_ERROR;
}
CdmResponseType CryptoSession::CopyOldUsageEntry(
const std::string& provider_session_token) {
LOGV("CopyOldUsageEntry: id=%ld", (uint32_t)oec_session_id_);
OEMCryptoResult result = OEMCrypto_CopyOldUsageEntry(
oec_session_id_,
reinterpret_cast<const uint8_t*>(provider_session_token.data()),
provider_session_token.size());
if (result != OEMCrypto_SUCCESS) {
LOGE("CopyOldUsageEntry: OEMCrypto_CopyOldUsageEntry error: %d", result);
return COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR;
}
return NO_ERROR;
}
OEMCrypto_Algorithm CryptoSession::GenericSigningAlgorithm(
CdmSigningAlgorithm algorithm) {
if (kSigningAlgorithmHmacSha256 == algorithm) {