Changes to CryptoSession to support big usage tables

[ Merge of http://go/wvgerrit/23167 ]

This allows CryptoSession to support the new functionality added to
OEMCrypto to support big usage tables. No changes in behavior yet.
Code that calls these methods will be in a subsequent CL.

b/34327459

* Minor changes to cdm/Android.mk and cdm/test/unit-test.mk to remove
  profiler changes that were missed in previous releases.

Test: All unittests other than some oemcrypto, request_license_test
passed. Those tests failed with or without this CL.

Change-Id: I9becd97c5a8ddf74d30fabd1251e796b534c010f
This commit is contained in:
Rahul Frias
2017-01-25 11:39:06 -08:00
parent a24acfa928
commit d29886f184
8 changed files with 386 additions and 4 deletions

View File

@@ -18,7 +18,6 @@ LOCAL_STATIC_LIBRARIES := libcdm_protos libcrypto_static
SRC_DIR := src
CORE_SRC_DIR := core/src
PROFILER_SRC_DIR := profiler/src
LOCAL_SRC_FILES := \
$(CORE_SRC_DIR)/buffer_reader.cpp \
@@ -36,6 +35,7 @@ LOCAL_SRC_FILES := \
$(CORE_SRC_DIR)/service_certificate.cpp \
$(SRC_DIR)/wv_content_decryption_module.cpp \
LOCAL_MODULE := libcdm
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_TARGET_ARCH := arm x86 mips

View File

@@ -138,6 +138,22 @@ class CryptoSession {
CdmSigningAlgorithm algorithm,
const std::string& signature);
// Usage table header and usage entry related methods
virtual CdmResponseType CreateUsageTableHeader(
std::string* usage_table_header);
virtual CdmResponseType LoadUsageTableHeader(
const std::string& usage_table_header);
virtual CdmResponseType CreateUsageEntry(uint32_t* entry_number);
virtual CdmResponseType LoadUsageEntry(uint32_t entry_number,
const std::string& usage_entry);
virtual CdmResponseType UpdateUsageEntry(std::string* usage_table_header,
std::string* usage_entry);
virtual CdmResponseType DecrementUsageTableHeaderSize(
uint32_t current_usage_table_size, std::string* usage_table_header);
virtual CdmResponseType MoveUsageEntry(uint32_t new_entry_number);
virtual CdmResponseType CopyOldUsageEntry(
const std::string& provider_session_token);
private:
bool GetProvisioningMethod(CdmClientTokenType* token_type);
void Init();

View File

@@ -252,6 +252,25 @@ enum CdmResponseType {
ANALOG_OUTPUT_ERROR,
UNKNOWN_SELECT_KEY_ERROR_1,
UNKNOWN_SELECT_KEY_ERROR_2,
CREATE_USAGE_TABLE_ERROR, /* 215 */
LOAD_USAGE_HEADER_GENERATION_SKEW,
LOAD_USAGE_HEADER_SIGNATURE_FAILURE,
LOAD_USAGE_HEADER_BAD_MAGIC,
LOAD_USAGE_HEADER_UNKNOWN_ERROR,
INVALID_PARAMETERS_ENG_17, /* 220 */
INVALID_PARAMETERS_ENG_18,
INSUFFICIENT_CRYPTO_RESOURCES_3,
CREATE_USAGE_ENTRY_UNKNOWN_ERROR,
LOAD_USAGE_ENTRY_GENERATION_SKEW,
LOAD_USAGE_ENTRY_SIGNATURE_FAILURE, /* 225 */
LOAD_USAGE_ENTRY_UNKNOWN_ERROR,
INVALID_PARAMETERS_ENG_19,
INVALID_PARAMETERS_ENG_20,
UPDATE_USAGE_ENTRY_UNKNOWN_ERROR,
INVALID_PARAMETERS_ENG_21, /* 230 */
SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR,
MOVE_USAGE_ENTRY_UNKNOWN_ERROR,
COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR,
};
enum CdmKeyStatus {

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 {
@@ -507,6 +508,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(),
@@ -1462,6 +1464,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) {

View File

@@ -463,6 +463,57 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
break;
case UNKNOWN_SELECT_KEY_ERROR_2: *os << "UNKNOWN_SELECT_KEY_ERROR_2";
break;
case CREATE_USAGE_TABLE_ERROR: *os << "CREATE_USAGE_TABLE_ERROR";
break;
case LOAD_USAGE_HEADER_GENERATION_SKEW:
*os << "LOAD_USAGE_HEADER_GENERATION_SKEW";
break;
case LOAD_USAGE_HEADER_SIGNATURE_FAILURE:
*os << "LOAD_USAGE_HEADER_SIGNATURE_FAILURE";
break;
case LOAD_USAGE_HEADER_BAD_MAGIC: *os << "LOAD_USAGE_HEADER_BAD_MAGIC";
break;
case LOAD_USAGE_HEADER_UNKNOWN_ERROR:
*os << "LOAD_USAGE_HEADER_UNKNOWN_ERROR";
break;
case INVALID_PARAMETERS_ENG_17: *os << "INVALID_PARAMETERS_ENG_17";
break;
case INVALID_PARAMETERS_ENG_18: *os << "INVALID_PARAMETERS_ENG_18";
break;
case INSUFFICIENT_CRYPTO_RESOURCES_3:
*os << "INSUFFICIENT_CRYPTO_RESOURCES_3";
break;
case CREATE_USAGE_ENTRY_UNKNOWN_ERROR:
*os << "CREATE_USAGE_ENTRY_UNKNOWN_ERROR";
break;
case LOAD_USAGE_ENTRY_GENERATION_SKEW:
*os << "LOAD_USAGE_ENTRY_GENERATION_SKEW";
break;
case LOAD_USAGE_ENTRY_SIGNATURE_FAILURE:
*os << "LOAD_USAGE_ENTRY_SIGNATURE_FAILURE";
break;
case LOAD_USAGE_ENTRY_UNKNOWN_ERROR:
*os << "LOAD_USAGE_ENTRY_UNKNOWN_ERROR";
break;
case INVALID_PARAMETERS_ENG_19: *os << "INVALID_PARAMETERS_ENG_19";
break;
case INVALID_PARAMETERS_ENG_20: *os << "INVALID_PARAMETERS_ENG_20";
break;
case UPDATE_USAGE_ENTRY_UNKNOWN_ERROR:
*os << "UPDATE_USAGE_ENTRY_UNKNOWN_ERROR";
break;
case INVALID_PARAMETERS_ENG_21: *os << "INVALID_PARAMETERS_ENG_21";
break;
case SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR:
*os << "SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR";
break;
case MOVE_USAGE_ENTRY_UNKNOWN_ERROR:
*os << "MOVE_USAGE_ENTRY_UNKNOWN_ERROR";
break;
case COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR:
*os << "COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR";
break;
default:
*os << "Unknown CdmResponseType";
break;

View File

@@ -21,8 +21,6 @@ LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/android/cdm/test \
vendor/widevine/libwvdrmengine/cdm/core/include \
vendor/widevine/libwvdrmengine/cdm/core/test \
vendor/widevine/libwvdrmengine/cdm/profiler/include \
vendor/widevine/libwvdrmengine/cdm/profiler/test \
vendor/widevine/libwvdrmengine/cdm/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \

View File

@@ -219,9 +219,29 @@ enum {
kLicensingClientTokenError1 = ERROR_DRM_VENDOR_MIN + 205,
kUnknownSelectKeyError1 = ERROR_DRM_VENDOR_MIN + 206,
kUnknownSelectKeyError2 = ERROR_DRM_VENDOR_MIN + 207,
kCreateUsageTableError = ERROR_DRM_VENDOR_MIN + 208,
kLoadUsageHeaderGenerationSkew = ERROR_DRM_VENDOR_MIN + 209,
kLoadUsageHeaderSignatureFailure = ERROR_DRM_VENDOR_MIN + 210,
kLoadUsageHeaderBadMagic = ERROR_DRM_VENDOR_MIN + 211,
kLoadUsageHeaderUnknownError = ERROR_DRM_VENDOR_MIN + 212,
kInvalidParametersEng17 = ERROR_DRM_VENDOR_MIN + 213,
kInvalidParametersEng18 = ERROR_DRM_VENDOR_MIN + 214,
kInsufficientCryptoResources3 = ERROR_DRM_VENDOR_MIN + 215,
kCreateUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 216,
kLoadUsageEntryGenerationSkew = ERROR_DRM_VENDOR_MIN + 217,
kLoadUsageEntrySignatureFailure = ERROR_DRM_VENDOR_MIN + 218,
kLoadUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 219,
kInvalidParametersEng19 = ERROR_DRM_VENDOR_MIN + 220,
kInvalidParametersEng20 = ERROR_DRM_VENDOR_MIN + 221,
kUpdateUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 222,
kInvalidParametersEng21 = ERROR_DRM_VENDOR_MIN + 223,
kShrinkUsageTablerHeaderUnknownError = ERROR_DRM_VENDOR_MIN + 224,
kMoveUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 225,
kCopyOldUsageEntryUnknownError = ERROR_DRM_VENDOR_MIN + 226,
// This should always follow the last error code.
// The offset value should be updated each time a new error code is added.
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 207,
kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 226,
// Used by crypto test mode
kErrorTestMode = ERROR_DRM_VENDOR_MAX,

View File

@@ -429,6 +429,45 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
return kUnknownSelectKeyError1;
case wvcdm::UNKNOWN_SELECT_KEY_ERROR_2:
return kUnknownSelectKeyError2;
case wvcdm::CREATE_USAGE_TABLE_ERROR:
return kCreateUsageTableError;
case wvcdm::LOAD_USAGE_HEADER_GENERATION_SKEW:
return kLoadUsageHeaderGenerationSkew;
case wvcdm::LOAD_USAGE_HEADER_SIGNATURE_FAILURE:
return kLoadUsageHeaderSignatureFailure;
case wvcdm::LOAD_USAGE_HEADER_BAD_MAGIC:
return kLoadUsageHeaderBadMagic;
case wvcdm::LOAD_USAGE_HEADER_UNKNOWN_ERROR:
return kLoadUsageHeaderUnknownError;
case wvcdm::INVALID_PARAMETERS_ENG_17:
return kInvalidParametersEng17;
case wvcdm::INVALID_PARAMETERS_ENG_18:
return kInvalidParametersEng18;
case wvcdm::INSUFFICIENT_CRYPTO_RESOURCES_3:
return kInsufficientCryptoResources3;
case wvcdm::CREATE_USAGE_ENTRY_UNKNOWN_ERROR:
return kCreateUsageEntryUnknownError;
case wvcdm::LOAD_USAGE_ENTRY_GENERATION_SKEW:
return kLoadUsageEntryGenerationSkew;
case wvcdm::LOAD_USAGE_ENTRY_SIGNATURE_FAILURE:
return kLoadUsageEntrySignatureFailure;
case wvcdm::LOAD_USAGE_ENTRY_UNKNOWN_ERROR:
return kLoadUsageEntryUnknownError;
case wvcdm::INVALID_PARAMETERS_ENG_19:
return kInvalidParametersEng19;
case wvcdm::INVALID_PARAMETERS_ENG_20:
return kInvalidParametersEng20;
case wvcdm::UPDATE_USAGE_ENTRY_UNKNOWN_ERROR:
return kUpdateUsageEntryUnknownError;
case wvcdm::INVALID_PARAMETERS_ENG_21:
return kInvalidParametersEng21;
case wvcdm::SHRINK_USAGE_TABLER_HEADER_UNKNOWN_ERROR:
return kShrinkUsageTablerHeaderUnknownError;
case wvcdm::MOVE_USAGE_ENTRY_UNKNOWN_ERROR:
return kMoveUsageEntryUnknownError;
case wvcdm::COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR:
return kCopyOldUsageEntryUnknownError;
case wvcdm::UNUSED_1:
case wvcdm::UNUSED_2:
case wvcdm::UNUSED_3: