Merge changes Ib41046d0,Ie138f034,If8d8e32e,I0318c532,I498e633a, ...

* changes:
  Remove missing tests from build_all_test script
  Replace PST Report with buffer
  Add InactiveUnused to Usage Report status
  OEMCrypto v13 Header and Stubs
  Log HTTP errors in unit tests
  Rename oemcrypto's CryptoEngine configuration functions.
  Move keybox and root certificate handling into new class.
  Test OEMCrypto with backwards compatible verification
This commit is contained in:
Fred Gylys-Colwell
2017-01-23 19:54:18 +00:00
committed by Android (Google) Code Review
33 changed files with 1732 additions and 749 deletions

View File

@@ -37,6 +37,16 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
uint8_t OEMCrypto_Security_Patch_Level(SecurityLevel level);
OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod(
SecurityLevel level);
uint32_t OEMCrypto_SupportedCertificates(SecurityLevel level);
OEMCryptoResult OEMCrypto_CreateUsageTableHeader(SecurityLevel level);
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(SecurityLevel level,
const uint8_t* buffer,
size_t buffer_length);
OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(SecurityLevel level,
uint32_t new_table_size,
uint8_t* header_buffer,
size_t* header_buffer_length);
} // namespace wvcdm
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_

View File

@@ -13,6 +13,7 @@
#include "crypto_key.h"
#include "log.h"
#include "properties.h"
#include "pst_report.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -505,7 +506,8 @@ CdmResponseType CryptoSession::LoadKeys(
oec_session_id_, msg, message.size(),
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst,
provider_session_token.length());
provider_session_token.length(),
NULL); // TODO(rfrias): http://b/28955520
if (OEMCrypto_SUCCESS == sts) {
if (!provider_session_token.empty()) {
@@ -859,8 +861,10 @@ CdmResponseType CryptoSession::DeactivateUsageInformation(
uint8_t* pst = reinterpret_cast<uint8_t*>(
const_cast<char*>(provider_session_token.data()));
// TODO(fredgc or rfrias): make sure oec_session_id_ is valid.
OEMCryptoResult status =
OEMCrypto_DeactivateUsageEntry(pst, provider_session_token.length());
OEMCrypto_DeactivateUsageEntry((uint32_t)oec_session_id_,
pst, provider_session_token.length());
switch (status) {
case OEMCrypto_SUCCESS:
@@ -902,61 +906,65 @@ CdmResponseType CryptoSession::GenerateUsageReport(
}
}
usage_report->resize(usage_length);
OEMCrypto_PST_Report* report = reinterpret_cast<OEMCrypto_PST_Report*>(
const_cast<char*>(usage_report->data()));
std::vector<uint8_t> buffer(usage_length);
status = OEMCrypto_ReportUsage(oec_session_id_, pst,
provider_session_token.length(), report,
&usage_length);
provider_session_token.length(),
&buffer[0], &usage_length);
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::GenerateUsageReport: Report Usage error=%ld", status);
return UNKNOWN_ERROR;
}
if (usage_length != usage_report->length()) {
usage_report->resize(usage_length);
if (usage_length != buffer.size()) {
buffer.resize(usage_length);
}
(*usage_report) = std::string(reinterpret_cast<const char *>(&buffer[0]),
buffer.size());
OEMCrypto_PST_Report pst_report;
Unpacked_PST_Report pst_report(&buffer[0]);
*usage_duration_status = kUsageDurationsInvalid;
if (usage_length < sizeof(pst_report)) {
if (usage_length < pst_report.report_size()) {
LOGE("CryptoSession::GenerateUsageReport: usage report too small=%ld",
usage_length);
return NO_ERROR; // usage report available but no duration information
}
memcpy(&pst_report, usage_report->data(), sizeof(pst_report));
if (kUnused == pst_report.status) {
if (kUnused == pst_report.status()) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
}
LOGV("OEMCrypto_PST_Report.status: %d\n", pst_report.status);
LOGV("OEMCrypto_PST_Report.status: %d\n", pst_report.status());
LOGV("OEMCrypto_PST_Report.clock_security_level: %d\n",
pst_report.clock_security_level);
LOGV("OEMCrypto_PST_Report.pst_length: %d\n", pst_report.pst_length);
LOGV("OEMCrypto_PST_Report.padding: %d\n", pst_report.padding);
pst_report.clock_security_level());
LOGV("OEMCrypto_PST_Report.pst_length: %d\n",
pst_report.pst_length());
LOGV("OEMCrypto_PST_Report.padding: %d\n", pst_report.padding());
LOGV("OEMCrypto_PST_Report.seconds_since_license_received: %lld\n",
ntohll64(pst_report.seconds_since_license_received));
pst_report.seconds_since_license_received());
LOGV("OEMCrypto_PST_Report.seconds_since_first_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_first_decrypt));
pst_report.seconds_since_first_decrypt());
LOGV("OEMCrypto_PST_Report.seconds_since_last_decrypt: %lld\n",
ntohll64(pst_report.seconds_since_last_decrypt));
pst_report.seconds_since_last_decrypt());
LOGV("OEMCrypto_PST_Report: %s\n", b2a_hex(*usage_report).c_str());
// When usage report state is inactive, we have to deduce whether the
// license was ever used.
if (kInactive == pst_report.status &&
(0 > ntohll64(pst_report.seconds_since_first_decrypt) ||
ntohll64(pst_report.seconds_since_license_received) <
ntohll64(pst_report.seconds_since_first_decrypt))) {
if (kInactiveUnused == pst_report.status()) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
}
// Before OEMCrypto v13, When usage report state is inactive, we have to
// deduce whether the license was ever used.
if (kInactive == pst_report.status() &&
(0 > pst_report.seconds_since_first_decrypt() ||
pst_report.seconds_since_license_received() <
pst_report.seconds_since_first_decrypt())) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
}
*usage_duration_status = kUsageDurationsValid;
*seconds_since_started = ntohll64(pst_report.seconds_since_first_decrypt);
*seconds_since_last_played = ntohll64(pst_report.seconds_since_last_decrypt);
*seconds_since_started = pst_report.seconds_since_first_decrypt();
*seconds_since_last_played = pst_report.seconds_since_last_decrypt();
return NO_ERROR;
}
@@ -1033,7 +1041,7 @@ CdmResponseType CryptoSession::DeleteMultipleUsageInformation(
CdmResponseType CryptoSession::DeleteAllUsageReports() {
LOGV("DeleteAllUsageReports");
OEMCryptoResult status = OEMCrypto_DeleteUsageTable();
OEMCryptoResult status = OEMCrypto_DeleteOldUsageTable();
if (OEMCrypto_SUCCESS != status) {
LOGE("CryptoSession::DeleteAllUsageReports: Delete Usage Table error =%ld",

View File

@@ -66,6 +66,12 @@ typedef OEMCryptoResult (*L1_GenerateSignature_t)(OEMCrypto_SESSION session,
uint8_t* signature,
size_t* signature_length);
typedef OEMCryptoResult (*L1_LoadKeys_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
size_t pst_length, const uint8_t* srm_requirement);
typedef OEMCryptoResult (*L1_LoadKeys_V12_t)(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
@@ -173,12 +179,12 @@ typedef OEMCryptoResult (*L1_Generic_Verify_t)(OEMCrypto_SESSION session,
const uint8_t* signature,
size_t signature_length);
typedef OEMCryptoResult (*L1_UpdateUsageTable_t)();
typedef OEMCryptoResult (*L1_DeactivateUsageEntry_t)(const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_DeactivateUsageEntry_V12_t)(const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_ReportUsage_t)(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
OEMCrypto_PST_Report* buffer,
uint8_t* buffer,
size_t* buffer_length);
typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(
OEMCrypto_SESSION session, const uint8_t* pst, size_t pst_length,
@@ -186,7 +192,7 @@ typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(
size_t signature_length);
typedef OEMCryptoResult (*L1_ForceDeleteUsageEntry_t)(const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_DeleteUsageTable_t)();
typedef OEMCryptoResult (*L1_DeleteOldUsageTable_t)();
typedef OEMCrypto_ProvisioningMethod (*L1_GetProvisioningMethod_t)();
typedef OEMCryptoResult (*L1_GetOEMPublicCertificate_t)(
OEMCrypto_SESSION session,
@@ -202,6 +208,37 @@ typedef OEMCryptoResult (*L1_RewrapDeviceRSAKey30_t)(
const uint8_t* enc_rsa_key_iv,
uint8_t* wrapped_rsa_key,
size_t* wrapped_rsa_key_length);
typedef uint32_t (*L1_SupportedCertificates_t)();
typedef bool (*L1_IsSRMUpdateSupported_t)();
typedef OEMCryptoResult (*L1_GetCurrentSRMVersion_t)(uint16_t* version);
typedef OEMCryptoResult (*L1_LoadSRM_t)(const uint8_t* buffer,
size_t buffer_length);
typedef OEMCryptoResult (*L1_RemoveSRM_t)();
typedef OEMCryptoResult (*L1_CreateUsageTableHeader_t)();
typedef OEMCryptoResult (*L1_LoadUsageTableHeader_t)(const uint8_t* buffer,
size_t buffer_length);
typedef OEMCryptoResult (*L1_CreateNewUsageEntry_t)(OEMCrypto_SESSION session,
uint32_t *usage_entry_number);
typedef OEMCryptoResult (*L1_LoadUsageEntry_t)(OEMCrypto_SESSION session,
uint32_t index,
const uint8_t *buffer,
size_t buffer_size);
typedef OEMCryptoResult (*L1_UpdateUsageEntry_t)(OEMCrypto_SESSION session,
uint8_t* header_buffer,
size_t* header_buffer_length,
uint8_t* entry_buffer,
size_t* entry_buffer_length);
typedef OEMCryptoResult (*L1_DeactivateUsageEntry_t)(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length);
typedef OEMCryptoResult (*L1_ShrinkUsageTableHeader_t)(uint32_t new_table_size,
uint8_t* header_buffer,
size_t* header_buffer_length);
typedef OEMCryptoResult (*L1_MoveEntry_t)(OEMCrypto_SESSION session,
uint32_t new_index);
typedef OEMCryptoResult (*L1_CopyOldUsageEntry_t)(OEMCrypto_SESSION session,
const uint8_t*pst,
size_t pst_length);
struct FunctionPointers {
uint32_t version;
@@ -248,15 +285,30 @@ struct FunctionPointers {
L1_ReportUsage_t ReportUsage;
L1_DeleteUsageEntry_t DeleteUsageEntry;
L1_ForceDeleteUsageEntry_t ForceDeleteUsageEntry;
L1_DeleteUsageTable_t DeleteUsageTable;
L1_DeleteOldUsageTable_t DeleteOldUsageTable;
L1_GetProvisioningMethod_t GetProvisioningMethod;
L1_GetOEMPublicCertificate_t GetOEMPublicCertificate;
L1_RewrapDeviceRSAKey30_t RewrapDeviceRSAKey30;
L1_SupportedCertificates_t SupportedCertificates;
L1_IsSRMUpdateSupported_t IsSRMUpdateSupported;
L1_GetCurrentSRMVersion_t GetCurrentSRMVersion;
L1_LoadSRM_t LoadSRM;
L1_RemoveSRM_t RemoveSRM;
L1_CreateUsageTableHeader_t CreateUsageTableHeader;
L1_LoadUsageTableHeader_t LoadUsageTableHeader;
L1_CreateNewUsageEntry_t CreateNewUsageEntry;
L1_LoadUsageEntry_t LoadUsageEntry;
L1_UpdateUsageEntry_t UpdateUsageEntry;
L1_ShrinkUsageTableHeader_t ShrinkUsageTableHeader;
L1_MoveEntry_t MoveEntry;
L1_CopyOldUsageEntry_t CopyOldUsageEntry;
L1_LoadKeys_V8_t LoadKeys_V8;
L1_GenerateRSASignature_V8_t GenerateRSASignature_V8;
L1_GetHDCPCapability_V9_t GetHDCPCapability_V9;
L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10;
L1_LoadKeys_V12_t LoadKeys_V12;
L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12;
};
// The Cache Flush function is very processor dependent, but is needed by the
@@ -430,11 +482,17 @@ class Adapter {
} else { // version >= 9
LOOKUP(GenerateRSASignature, OEMCrypto_GenerateRSASignature);
LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable);
LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable);
LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry);
// TODO(fredgc): only use these if version < 13.
LOOKUP(ReportUsage, OEMCrypto_ReportUsage);
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable);
LOOKUP(DeleteOldUsageTable, OEMCrypto_DeleteOldUsageTable);
// TODO(fredgc): remove this hack after unit tests have been fixed.
// TODO(fredgc) if (level1_.version < 13) {
LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable);
if (level1_.version < 13 ) {
LOOKUP(DeactivateUsageEntry_V12, OEMCrypto_DeactivateUsageEntry_V12);
}
LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry);
// TODO(fredgc): }
if (level1_.version == 9) {
LOOKUP(LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
LOOKUP(GetHDCPCapability_V9, OEMCrypto_GetHDCPCapability_V9);
@@ -447,18 +505,40 @@ class Adapter {
LOOKUP(IsAntiRollbackHwPresent, OEMCrypto_IsAntiRollbackHwPresent);
LOOKUP(GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions);
LOOKUP(GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions);
LOOKUP(ForceDeleteUsageEntry, OEMCrypto_ForceDeleteUsageEntry);
// TODO(fredgc): if (level1_.version < 13) {
LOOKUP(ForceDeleteUsageEntry, OEMCrypto_ForceDeleteUsageEntry);
// TODO(fredgc): }
if (level1_.version == 10) {
LOOKUP(LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
LOOKUP(DecryptCTR_V10, OEMCrypto_DecryptCTR_V10);
} else { // version >= 11.
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(DecryptCENC, OEMCrypto_DecryptCENC);
LOOKUP(SecurityPatchLevel, OEMCrypto_Security_Patch_Level);
if (level1_.version >= 12) {
if (level1_.version == 11) {
LOOKUP(LoadKeys_V12, OEMCrypto_LoadKeys_V12);
} else { // version >= 12.
LOOKUP(GetProvisioningMethod, OEMCrypto_GetProvisioningMethod);
LOOKUP(GetOEMPublicCertificate, OEMCrypto_GetOEMPublicCertificate);
LOOKUP(RewrapDeviceRSAKey30, OEMCrypto_RewrapDeviceRSAKey30);
if (level1_.version == 12) {
LOOKUP(LoadKeys_V12, OEMCrypto_LoadKeys_V12);
} else { // version >= 13.
LOOKUP(LoadKeys, OEMCrypto_LoadKeys);
LOOKUP(SupportedCertificates, OEMCrypto_SupportedCertificates);
LOOKUP(IsSRMUpdateSupported, OEMCrypto_IsSRMUpdateSupported);
LOOKUP(GetCurrentSRMVersion, OEMCrypto_GetCurrentSRMVersion);
LOOKUP(LoadSRM, OEMCrypto_LoadSRM);
LOOKUP(RemoveSRM, OEMCrypto_RemoveSRM);
LOOKUP(CreateUsageTableHeader, OEMCrypto_CreateUsageTableHeader);
LOOKUP(LoadUsageTableHeader, OEMCrypto_LoadUsageTableHeader);
LOOKUP(CreateNewUsageEntry, OEMCrypto_CreateNewUsageEntry);
LOOKUP(LoadUsageEntry, OEMCrypto_LoadUsageEntry);
LOOKUP(UpdateUsageEntry, OEMCrypto_UpdateUsageEntry);
LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry);
LOOKUP(ShrinkUsageTableHeader, OEMCrypto_ShrinkUsageTableHeader);
LOOKUP(MoveEntry, OEMCrypto_MoveEntry);
LOOKUP(CopyOldUsageEntry, OEMCrypto_CopyOldUsageEntry);
}
}
}
}
@@ -559,10 +639,23 @@ class Adapter {
level3_.ReportUsage = Level3_ReportUsage;
level3_.DeleteUsageEntry = Level3_DeleteUsageEntry;
level3_.ForceDeleteUsageEntry = Level3_ForceDeleteUsageEntry;
level3_.DeleteUsageTable = Level3_DeleteUsageTable;
level3_.DeleteOldUsageTable = Level3_DeleteOldUsageTable;
level3_.GetProvisioningMethod = Level3_GetProvisioningMethod;
level3_.GetOEMPublicCertificate = Level3_GetOEMPublicCertificate;
level3_.RewrapDeviceRSAKey30 = Level3_RewrapDeviceRSAKey30;
level3_.SupportedCertificates = Level3_SupportedCertificates;
level3_.IsSRMUpdateSupported = Level3_IsSRMUpdateSupported;
level3_.GetCurrentSRMVersion = Level3_GetCurrentSRMVersion;
level3_.LoadSRM = Level3_LoadSRM;
level3_.RemoveSRM = Level3_RemoveSRM;
level3_.CreateUsageTableHeader = Level3_CreateUsageTableHeader;
level3_.LoadUsageTableHeader = Level3_LoadUsageTableHeader;
level3_.CreateNewUsageEntry = Level3_CreateNewUsageEntry;
level3_.LoadUsageEntry = Level3_LoadUsageEntry;
level3_.UpdateUsageEntry = Level3_UpdateUsageEntry;
level3_.ShrinkUsageTableHeader = Level3_ShrinkUsageTableHeader;
level3_.MoveEntry = Level3_MoveEntry;
level3_.CopyOldUsageEntry = Level3_CopyOldUsageEntry;
level3_.version = Level3_APIVersion();
}
@@ -792,6 +885,47 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(SecurityLevel level,
if (fcn->version < 10) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->GetMaxNumberOfSessions(maximum);
}
uint32_t OEMCrypto_SupportedCertificates(SecurityLevel level) {
if (!kAdapter) return 0;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return 0;
// Default is to support 2048 bit RSA keys.
if (fcn->version < 13) return OEMCrypto_Supports_RSA_2048bit;
return fcn->SupportedCertificates();
}
OEMCryptoResult OEMCrypto_CreateUsageTableHeader(SecurityLevel level) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (fcn->version < 9) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn->version < 13) return fcn->DeleteOldUsageTable();
return fcn->CreateUsageTableHeader();
}
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(SecurityLevel level,
const uint8_t* buffer,
size_t buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->LoadUsageTableHeader(buffer, buffer_length);
}
OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(SecurityLevel level,
uint32_t new_table_size,
uint8_t* header_buffer,
size_t* header_buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn = kAdapter->get(level);
if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->ShrinkUsageTableHeader(new_table_size, header_buffer,
header_buffer_length);
}
} // namespace wvcdm
extern "C" OEMCryptoResult OEMCrypto_Initialize(void) {
@@ -857,7 +991,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
const uint8_t* signature, size_t signature_length,
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
size_t pst_length) {
size_t pst_length, const uint8_t* srm_requirement) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
@@ -888,9 +1022,17 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
pst, pst_length);
}
} else {
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array, pst, pst_length);
if (pair.fcn->version < 13) {
return pair.fcn->LoadKeys_V12(pair.session, message, message_length,
signature, signature_length, enc_mac_key_iv,
enc_mac_key, num_keys, key_array, pst,
pst_length);
} else {
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
signature_length, enc_mac_key_iv, enc_mac_key,
num_keys, key_array, pst, pst_length,
srm_requirement);
}
}
}
@@ -1134,6 +1276,10 @@ extern "C" OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* maximum) {
return OEMCrypto_GetMaxNumberOfSessions(kLevelDefault, maximum);
}
extern "C" uint32_t OEMCrypto_SupportedCertificates() {
return OEMCrypto_SupportedCertificates(kLevelDefault);
}
extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(
OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length,
const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) {
@@ -1208,37 +1354,96 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Verify(
algorithm, signature, signature_length);
}
// TODO(fredgc): remove this function when cdm layer doesn't need it.
extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn3 && fcn3->version > 8) sts = fcn3->UpdateUsageTable();
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) sts = fcn1->UpdateUsageTable();
if (fcn3 && fcn3->version > 8 && fcn3->version < 13) {
sts = fcn3->UpdateUsageTable();
}
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8 && fcn1->version < 13) {
sts = fcn1->UpdateUsageTable();
} else {
// TODO(fredgc): Remove this after unit tests, haystack, and mock
// have been updated to v13. RED: REMOVE BEFORE FLIGHT -->
if (fcn1) sts = fcn1->UpdateUsageTable();
}
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst,
extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn1 && fcn1->version > 8) {
sts = fcn1->DeactivateUsageEntry(pst, pst_length);
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) {
// TODO(fredgc): remove before flight!
// return OEMCrypto_ERROR_INVALID_SESSION;
LOGE("TODO(fredgc): remove temporary DeactivateUsageEntry.");
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_INVALID_SESSION;
if (fcn1) {
if(fcn1->version < 13) {
if (fcn1->DeactivateUsageEntry_V12) {
sts = fcn1->DeactivateUsageEntry_V12(pst, pst_length);
} else {
LOGE("TODO(fredgc): Fred screwed up temporary code for v12!\n");
}
} else {
if (fcn1->DeactivateUsageEntry) {
sts = fcn1->DeactivateUsageEntry(0, pst, pst_length);
} else {
LOGE("TODO(fredgc): Fred screwed up temporary code for v13!\n");
}
}
}
if (OEMCrypto_SUCCESS != sts) {
if (fcn3 && fcn1 != fcn3) {
if(fcn3->version < 13) {
if (fcn3->DeactivateUsageEntry_V12) {
sts = fcn3->DeactivateUsageEntry_V12(pst, pst_length);
} else {
LOGE("TODO(fredgc): Fred screwed up temporary code for L3 v12!\n");
}
} else {
if (fcn3->DeactivateUsageEntry) {
sts = fcn3->DeactivateUsageEntry(0, pst, pst_length);
} else {
LOGE("TODO(fredgc): Fred screwed up temporary code for L3 v13!\n");
}
}
}
}
return sts;
// All of the hacky code above should be removed once the unit tests and
// cdm codde use the new deactivate usage entry.
}
if (OEMCrypto_SUCCESS != sts) {
if (fcn3 && fcn1 != fcn3 && fcn3->version > 8) {
sts = fcn3->DeactivateUsageEntry(pst, pst_length);
if (pair.fcn->version < 9) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
if(pair.fcn->version < 13) {
if (pair.fcn->DeactivateUsageEntry_V12 ) {
return pair.fcn->DeactivateUsageEntry_V12(pst, pst_length);
} else {
LOGE("TODO(fredgc): problem picking function!\n");
return OEMCrypto_ERROR_INVALID_SESSION;
}
}
return sts;
if (pair.fcn->DeactivateUsageEntry) {
return pair.fcn->DeactivateUsageEntry(pair.session, pst, pst_length);
} else {
LOGE("TODO(fredgc): problem picking function!\n");
return OEMCrypto_ERROR_INVALID_SESSION;
}
}
extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
const uint8_t* pst,
size_t pst_length,
OEMCrypto_PST_Report* buffer,
uint8_t* buffer,
size_t* buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
@@ -1255,6 +1460,7 @@ 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) {
LOGE("TODO(fredgc): remove DeleteUsageEntry.");
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
@@ -1269,6 +1475,7 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(
extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(
const uint8_t* pst, size_t pst_length) {
LOGE("TODO(fredgc): remove ForceDeleteUsageEntry.");
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
@@ -1285,12 +1492,143 @@ extern "C" OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(
return sts;
}
extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() {
extern "C" OEMCryptoResult OEMCrypto_DeleteOldUsageTable() {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault);
const FunctionPointers* fcn3 = kAdapter->get(kLevel3);
OEMCryptoResult sts = OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn3 && fcn3->version > 8) sts = fcn3->DeleteUsageTable();
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) sts = fcn1->DeleteUsageTable();
if (fcn3 && fcn3->version > 8) sts = fcn3->DeleteOldUsageTable();
if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) sts = fcn1->DeleteOldUsageTable();
return sts;
}
extern "C"
bool OEMCrypto_IsSRMUpdateSupported() {
if (!kAdapter) return false;
// Level 3 can't load an SRM, so this just checkes Level 1.
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return false;
if (fcn->version < 13) return false;
return fcn->IsSRMUpdateSupported();
}
extern "C"
OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
// Level 3 can't load an SRM, so this just checkes Level 1.
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->GetCurrentSRMVersion(version);
}
extern "C"
OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer,
size_t buffer_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
// Level 3 can't load an SRM, so this just checkes Level 1.
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->LoadSRM(buffer, buffer_length);
}
extern "C"
OEMCryptoResult OEMCrypto_RemoveSRM() {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
// Level 3 can't load an SRM, so this just checkes Level 1.
const FunctionPointers* fcn = kAdapter->get(kLevelDefault);
if (!fcn) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
if (fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return fcn->RemoveSRM();
}
extern "C"
OEMCryptoResult OEMCrypto_CreateUsageTableHeader() {
return OEMCrypto_CreateUsageTableHeader(kLevelDefault);
}
extern "C"
OEMCryptoResult OEMCrypto_LoadUsageTableHeader(const uint8_t* buffer,
size_t buffer_length) {
return OEMCrypto_LoadUsageTableHeader(kLevelDefault, buffer, buffer_length);
}
extern "C"
OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session,
uint32_t *usage_entry_number) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->CreateNewUsageEntry(pair.session, usage_entry_number);
}
extern "C"
OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session,
uint32_t index,
const uint8_t *buffer,
size_t buffer_size) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadUsageEntry(pair.session, index, buffer, buffer_size);
}
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) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->UpdateUsageEntry(pair.session, 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_ShrinkUsageTableHeader(kLevelDefault, new_table_size,
header_buffer, header_buffer_length);
}
extern "C"
OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session,
uint32_t new_index) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->MoveEntry(pair.session, new_index);
}
extern "C"
OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session,
const uint8_t*pst,
size_t pst_length) {
if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
LevelSession pair = kAdapter->get(session);
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
if (pair.fcn->version < 13) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->CopyOldUsageEntry(pair.session, pst, pst_length);
}
extern "C"
OEMCryptoResult Level3_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) {
// TODO(fredgc): add this.
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}

View File

@@ -147,7 +147,8 @@ class WvCdmEngineTest : public testing::Test {
EXPECT_TRUE(ok);
int status_code = url_request.GetStatusCode(response);
if (expect_success) EXPECT_EQ(kHttpOk, status_code);
if (expect_success) EXPECT_EQ(kHttpOk, status_code)
<< "Error response: " << response;
if (status_code != kHttpOk) {
return "";

View File

@@ -17,6 +17,7 @@
#include "oemcrypto_adapter.h"
#include "OEMCryptoCENC.h"
#include "properties.h"
#include "pst_report.h"
#include "string_conversions.h"
#include "test_base.h"
#include "url_request.h"
@@ -566,25 +567,25 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
EXPECT_TRUE(!existing_license.session_usage_table_entry().empty());
// Verify usage report
OEMCrypto_PST_Report usage_report;
memcpy(&usage_report, existing_license.session_usage_table_entry().data(),
sizeof(usage_report));
EXPECT_EQ(sizeof(usage_report) + usage_report.pst_length,
uint8_t *buffer = reinterpret_cast<uint8_t *>(
const_cast<char *>(existing_license.session_usage_table_entry().data()));
Unpacked_PST_Report usage_report(buffer);
EXPECT_EQ(usage_report.report_size(),
existing_license.session_usage_table_entry().size());
EXPECT_EQ(kInactive, usage_report.status);
EXPECT_EQ(id.provider_session_token().size(), usage_report.pst_length);
std::string pst(existing_license.session_usage_table_entry().data() +
sizeof(OEMCrypto_PST_Report),
usage_report.pst_length);
EXPECT_EQ(kInactiveUsed, usage_report.status());
EXPECT_EQ(id.provider_session_token().size(),
usage_report.pst_length());
std::string pst(reinterpret_cast<char *>(usage_report.pst()),
usage_report.pst_length());
EXPECT_EQ(id.provider_session_token(), pst);
EXPECT_LE(kInsecureClock, usage_report.clock_security_level);
EXPECT_LE(kInsecureClock, usage_report.clock_security_level());
int64_t seconds_since_license_received =
htonll64(usage_report.seconds_since_license_received);
int64_t seconds_since_license_received
= usage_report.seconds_since_license_received();
int64_t seconds_since_first_decrypt =
htonll64(usage_report.seconds_since_first_decrypt);
usage_report.seconds_since_first_decrypt();
int64_t seconds_since_last_decrypt =
htonll64(usage_report.seconds_since_last_decrypt);
usage_report.seconds_since_last_decrypt();
// Detect licenses that were never used
if (seconds_since_first_decrypt < 0 ||
seconds_since_first_decrypt > seconds_since_license_received) {