diff --git a/libwvdrmengine/build_and_run_all_unit_tests.sh b/libwvdrmengine/build_and_run_all_unit_tests.sh index 96071867..b9f26aa8 100755 --- a/libwvdrmengine/build_and_run_all_unit_tests.sh +++ b/libwvdrmengine/build_and_run_all_unit_tests.sh @@ -67,8 +67,6 @@ try_adb_push $OUT/system/bin/device_files_unittest try_adb_push $OUT/system/bin/timer_unittest try_adb_push $OUT/system/bin/libwvdrmengine_test try_adb_push $OUT/system/bin/buffer_reader_test -try_adb_push $OUT/system/bin/circular_buffer_test -try_adb_push $OUT/system/bin/entry_writer_test adb install -r $OUT/system/app/MediaDrmAPITest/MediaDrmAPITest.apk cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index cbff211d..1f208aaf 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -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_ diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 96929dc1..5697f5a1 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -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(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( const_cast(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( - const_cast(usage_report->data())); + std::vector 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(&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", diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index d74d58bf..43fca619 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -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; +} diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index aa44c262..a70109ed 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -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 ""; diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 6b2a1b2f..e9888f19 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -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( + const_cast(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(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) { diff --git a/libwvdrmengine/docs/WidevineModularDRMSecurityIntegrationGuideforCENC.pdf b/libwvdrmengine/docs/WidevineModularDRMSecurityIntegrationGuideforCENC.pdf deleted file mode 100644 index 9cf40c18..00000000 Binary files a/libwvdrmengine/docs/WidevineModularDRMSecurityIntegrationGuideforCENC.pdf and /dev/null differ diff --git a/libwvdrmengine/docs/WidevineSecurityIntegrationGuideforCENCAndroidSupplement.pdf b/libwvdrmengine/docs/WidevineSecurityIntegrationGuideforCENCAndroidSupplement.pdf deleted file mode 100644 index 3933298b..00000000 Binary files a/libwvdrmengine/docs/WidevineSecurityIntegrationGuideforCENCAndroidSupplement.pdf and /dev/null differ diff --git a/libwvdrmengine/level3/arm/libwvlevel3.a b/libwvdrmengine/level3/arm/libwvlevel3.a index caffe61f..e2f674da 100644 Binary files a/libwvdrmengine/level3/arm/libwvlevel3.a and b/libwvdrmengine/level3/arm/libwvlevel3.a differ diff --git a/libwvdrmengine/level3/mips/libwvlevel3.a b/libwvdrmengine/level3/mips/libwvlevel3.a index f57b94d1..5d27332d 100644 Binary files a/libwvdrmengine/level3/mips/libwvlevel3.a and b/libwvdrmengine/level3/mips/libwvlevel3.a differ diff --git a/libwvdrmengine/level3/x86/libwvlevel3.a b/libwvdrmengine/level3/x86/libwvlevel3.a index ddbeec1f..9bb13db8 100644 Binary files a/libwvdrmengine/level3/x86/libwvlevel3.a and b/libwvdrmengine/level3/x86/libwvlevel3.a differ diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 6c224320..0df48229 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -6,9 +6,9 @@ * Reference APIs needed to support Widevine's crypto algorithms. * * See the document "WV Modular DRM Security Integration Guide for Common - * Encryption (CENC) -- version 12" for a description of this API. You + * Encryption (CENC) -- version 13" for a description of this API. You * can find this document in the widevine repository as - * docs/WidevineModularDRMSecurityIntegrationGuideforCENC.pdf + * docs/WidevineModularDRMSecurityIntegrationGuideforCENC_v13.pdf * Changes between different versions of this API are documented in the files * docs/Widevine_Modular_DRM_Version_*_Delta.pdf * @@ -33,10 +33,10 @@ typedef enum OEMCryptoResult { OEMCrypto_ERROR_TERMINATE_FAILED = 2, OEMCrypto_ERROR_OPEN_FAILURE = 3, OEMCrypto_ERROR_CLOSE_FAILURE = 4, - OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5, - OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, + OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5, // deprecated + OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, // deprecated OEMCrypto_ERROR_SHORT_BUFFER = 7, - OEMCrypto_ERROR_NO_DEVICE_KEY = 8, + OEMCrypto_ERROR_NO_DEVICE_KEY = 8, // no keybox device key. OEMCrypto_ERROR_NO_ASSET_KEY = 9, OEMCrypto_ERROR_KEYBOX_INVALID = 10, OEMCrypto_ERROR_NO_KEYDATA = 11, @@ -68,6 +68,13 @@ typedef enum OEMCryptoResult { OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37, OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38, OEMCrypto_ERROR_BUFFER_TOO_LARGE = 39, + OEMCrypto_WARNING_GENERATION_SKEW = 40, // Warning, not an error. + OEMCrypto_ERROR_GENERATION_SKEW = 41, + OEMCrypto_LOCAL_DISPLAY_ONLY = 42, // Info, not an error. + OEMCrypto_ERROR_ANALOG_OUTPUT = 43, + OEMCrypto_ERROR_WRONG_PST = 44, + OEMCrypto_ERROR_WRONG_KEYS = 45, + OEMCrypto_ERROR_MISSING_MASTER = 46, } OEMCryptoResult; /* @@ -235,12 +242,19 @@ typedef struct { typedef enum OEMCrypto_Usage_Entry_Status { kUnused = 0, kActive = 1, - kInactive = 2 + kInactive = 2, // Deprecated. Used kInactiveUsed or kInactiveUnused. + kInactiveUsed = 3, + kInactiveUnused = 4, } OEMCrypto_Usage_Entry_Status; /* * OEMCrypto_PST_Report is used to report an entry from the Usage Table. + * + * Platforms that have compilers that support packed structures, may use the + * following definition. Other platforms may use the header pst_report.h which + * defines a wrapper class. */ +#if 0 // If your compiler supports __attribute__((packed)). typedef struct { uint8_t signature[20]; // -- HMAC SHA1 of the rest of the report. uint8_t status; // current status of entry. (OEMCrypto_Usage_Entry_Status) @@ -252,6 +266,7 @@ typedef struct { int64_t seconds_since_last_decrypt; // now - time_of_last_decrypt uint8_t pst[]; } __attribute__((packed)) OEMCrypto_PST_Report; +#endif /* * OEMCrypto_Clock_Security_Level. @@ -274,12 +289,12 @@ typedef enum RSA_Padding_Scheme { * level, and in GetHDCPCapability for reporting. */ typedef enum OEMCrypto_HDCP_Capability { - HDCP_NONE = 0, // No HDCP supported, no secure data path. - HDCP_V1 = 1, // HDCP version 1.0 - HDCP_V2 = 2, // HDCP version 2.0 - HDCP_V2_1 = 3, // HDCP version 2.1 - HDCP_V2_2 = 4, // HDCP version 2.2 Type 1. - HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output. + HDCP_NONE = 0, // No HDCP supported, no secure data path. + HDCP_V1 = 1, // HDCP version 1.0 + HDCP_V2 = 2, // HDCP version 2.0 Type 1. + HDCP_V2_1 = 3, // HDCP version 2.1 Type 1. + HDCP_V2_2 = 4, // HDCP version 2.2 Type 1. + HDCP_NO_DIGITAL_OUTPUT = 0xff // No digital output. } OEMCrypto_HDCP_Capability; /* Return value for OEMCrypto_GetProvisioningMethod(). */ @@ -291,6 +306,19 @@ typedef enum OEMCrypto_ProvisioningMethod { OEMCrypto_OEMCertificate = 3 // Device has factory installed OEM certificate. } OEMCrypto_ProvisioningMethod; +/* + * Flags indicating RSA keys supported. + */ +#define OEMCrypto_Supports_RSA_2048bit 0x1 +#define OEMCrypto_Supports_RSA_3072bit 0x2 +#define OEMCrypto_Supports_RSA_CAST 0x10 + +/* + * Flags indicating full decrypt path hash supported. + */ +#define OEMCrypto_Hash_Not_Supported 0 +#define OEMCrypto_HMAC_Clear_Buffer 1 + /* * Obfuscation Renames. */ @@ -324,10 +352,10 @@ typedef enum OEMCrypto_ProvisioningMethod { #define OEMCrypto_GetHDCPCapability_V9 _oecc28 #define OEMCrypto_SupportsUsageTable _oecc29 #define OEMCrypto_UpdateUsageTable _oecc30 -#define OEMCrypto_DeactivateUsageEntry _oecc31 +#define OEMCrypto_DeactivateUsageEntry_V12 _oecc31 #define OEMCrypto_ReportUsage _oecc32 #define OEMCrypto_DeleteUsageEntry _oecc33 -#define OEMCrypto_DeleteUsageTable _oecc34 +#define OEMCrypto_DeleteOldUsageTable _oecc34 #define OEMCrypto_LoadKeys_V9_or_V10 _oecc35 #define OEMCrypto_GenerateRSASignature _oecc36 #define OEMCrypto_GetMaxNumberOfSessions _oecc37 @@ -340,11 +368,30 @@ typedef enum OEMCrypto_ProvisioningMethod { #define OEMCrypto_GetHDCPCapability _oecc44 #define OEMCrypto_LoadTestRSAKey _oecc45 #define OEMCrypto_Security_Patch_Level _oecc46 -#define OEMCrypto_LoadKeys _oecc47 +#define OEMCrypto_LoadKeys_V12 _oecc47 #define OEMCrypto_DecryptCENC _oecc48 #define OEMCrypto_GetProvisioningMethod _oecc49 #define OEMCrypto_GetOEMPublicCertificate _oecc50 #define OEMCrypto_RewrapDeviceRSAKey30 _oecc51 +#define OEMCrypto_SupportedCertificates _oecc52 +#define OEMCrypto_IsSRMUpdateSupported _oecc53 +#define OEMCrypto_GetCurrentSRMVersion _oecc54 +#define OEMCrypto_LoadSRM _oecc55 +#define OEMCrypto_LoadKeys _oecc56 +#define OEMCrypto_RemoveSRM _oecc57 +#define OEMCrypto_SupportsDecryptHash _oecc58 +#define OEMCrypto_SetDecryptHash _oecc59 +#define OEMCrypto_VerifyDecryptHash _oecc60 +#define OEMCrypto_CreateUsageTableHeader _oecc61 +#define OEMCrypto_LoadUsageTableHeader _oecc62 +#define OEMCrypto_CreateNewUsageEntry _oecc63 +#define OEMCrypto_LoadUsageEntry _oecc64 +#define OEMCrypto_UpdateUsageEntry _oecc65 +#define OEMCrypto_DeactivateUsageEntry _oecc66 +#define OEMCrypto_ShrinkUsageTableHeader _oecc67 +#define OEMCrypto_MoveEntry _oecc68 +#define OEMCrypto_CopyOldUsageEntry _oecc69 +#define OEMCrypto_CreateOldUsageEntry _oecc70 /* @@ -442,6 +489,7 @@ OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session); * Version: * This method changed in API version 5. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session); /* @@ -774,12 +822,14 @@ OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session, * Version: * This method changed in API version 11. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ + OEMCryptoResult OEMCrypto_LoadKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, 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); /* * OEMCrypto_RefreshKeys @@ -1001,6 +1051,7 @@ OEMCryptoResult OEMCrypto_QueryKeyControl(OEMCrypto_SESSION session, * Version: * This method changed in API version 8. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length); @@ -1177,6 +1228,7 @@ OEMCryptoResult OEMCrypto_SelectKey(OEMCrypto_SESSION session, * This method changed in API version 11. * This method changed its name in API version 11. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ OEMCryptoResult OEMCrypto_DecryptCENC( OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, bool is_encrypted, const uint8_t* iv, size_t block_offset, @@ -1252,6 +1304,7 @@ OEMCryptoResult OEMCrypto_DecryptCENC( * Version * This method is added in API version 10. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr, size_t data_length, OEMCrypto_DestBufferDesc* out_buffer, @@ -2237,6 +2290,9 @@ OEMCryptoResult OEMCrypto_GetNumberOfOpenSessions(size_t* count); */ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* max); +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +uint32_t OEMCrypto_SupportedCertificates(); + /* * OEMCrypto_Generic_Encrypt * @@ -2508,7 +2564,8 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, * OEMCrypto_ERROR_UNKNOWN_FAILURE * * Version: - * This method changed in API version 9. + * This method is deprecated in API version 13. + * TODO(fredgc): remove this. */ OEMCryptoResult OEMCrypto_UpdateUsageTable(); @@ -2548,9 +2605,15 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable(); * too large. * * Version: - * This method changed in API version 9. + * This method is deprecated in API version 13. + * TODO(fredgc): remove this. */ -OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst, +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_DeactivateUsageEntry_12(const uint8_t* pst, + size_t pst_length); +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, + const uint8_t* pst, size_t pst_length); /* @@ -2576,7 +2639,9 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst, * Valid values for status are: * 0 = kUnused -- the keys have not been used to decrypt. * 1 = kActive -- the keys have been used, and have not been deactivated. - * 2 = kInactive -- the keys have been marked inactive. + * 2 = kInactive -- deprecated. Use kInactiveUsed or kInactiveUnused. + * 3 = kInactiveUsed -- the keys have been marked inactive after a decrypt. + * 4 = kInactiveUnused -- the keys have been marked inactive, no decrypt. * * The clock_security_level is reported as follows: * 0 = Insecure Clock - clock just uses system time. @@ -2634,9 +2699,10 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t* pst, * Version: * This method changed in API version 9. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ 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); /* @@ -2700,6 +2766,8 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, * Version: * This method changed in API version 9. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +/* TODO(fredgc): remove this. */ 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, @@ -2746,6 +2814,8 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry( * Version * This method changed in API version 10. */ +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +/* TODO(fredgc): remove this. */ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, size_t pst_length); @@ -2772,7 +2842,70 @@ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, * Version: * This method changed in API version 9. */ -OEMCryptoResult OEMCrypto_DeleteUsageTable(); +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_DeleteOldUsageTable(); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_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): copy text from http://go/wvgerrit/22887 */ +bool OEMCrypto_IsSRMUpdateSupported(); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version); + + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, + size_t buffer_length); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_RemoveSRM(); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_CreateUsageTableHeader(); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_LoadUsageTableHeader(const uint8_t* buffer, + size_t buffer_length); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session, + uint32_t* usage_entry_number); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session, + uint32_t index, + const uint8_t* buffer, + size_t buffer_size); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_UpdateUsageEntry(OEMCrypto_SESSION session, + uint8_t* header_buffer, + size_t* header_buffer_length, + uint8_t* entry_buffer, + size_t* entry_buffer_length); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(uint32_t new_entry_count, + uint8_t* header_buffer, + size_t* header_buffer_length); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session, + uint32_t new_index); + +/* TODO(fredgc): copy text from http://go/wvgerrit/22887 */ +OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session, + const uint8_t*pst, + size_t pst_length); #ifdef __cplusplus } diff --git a/libwvdrmengine/oemcrypto/include/level3.h b/libwvdrmengine/oemcrypto/include/level3.h index e3509ac4..8dc57801 100644 --- a/libwvdrmengine/oemcrypto/include/level3.h +++ b/libwvdrmengine/oemcrypto/include/level3.h @@ -31,7 +31,6 @@ namespace wvoec3 { #define Level3_GenerateDerivedKeys _lcc12 #define Level3_GenerateSignature _lcc13 #define Level3_GenerateNonce _lcc14 -#define Level3_LoadKeys _lcc15 #define Level3_RefreshKeys _lcc16 #define Level3_SelectKey _lcc17 #define Level3_RewrapDeviceRSAKey _lcc18 @@ -50,7 +49,7 @@ namespace wvoec3 { #define Level3_DeactivateUsageEntry _lcc31 #define Level3_ReportUsage _lcc32 #define Level3_DeleteUsageEntry _lcc33 -#define Level3_DeleteUsageTable _lcc34 +#define Level3_DeleteOldUsageTable _lcc34 #define Level3_GetMaxNumberOfSessions _lcc37 #define Level3_GetNumberOfOpenSessions _lcc38 #define Level3_IsAntiRollbackHwPresent _lcc39 @@ -63,7 +62,24 @@ namespace wvoec3 { #define Level3_GetProvisioningMethod _lcc49 #define Level3_GetOEMPublicCertificate _lcc50 #define Level3_RewrapDeviceRSAKey30 _lcc51 - +#define Level3_SupportedCertificates _lcc52 +#define Level3_IsSRMUpdateSupported _lcc53 +#define Level3_GetCurrentSRMVersion _lcc54 +#define Level3_LoadSRM _lcc55 +#define Level3_LoadKeys _lcc56 +#define Level3_RemoveSRM _lcc57 +#define Level3_SupportsDecryptHash _lcc58 +#define Level3_SetDecryptHash _lcc59 +#define Level3_VerifyDecryptHash _lcc60 +#define Level3_CreateUsageTableHeader _lcc61 +#define Level3_LoadUsageTableHeader _lcc62 +#define Level3_CreateNewUsageEntry _lcc63 +#define Level3_LoadUsageEntry _lcc64 +#define Level3_UpdateUsageEntry _lcc65 +#define Level3_ShrinkUsageTableHeader _lcc67 +#define Level3_MoveEntry _lcc68 +#define Level3_CopyOldUsageEntry _lcc69 +#define Level3_CreateOldUsageEntry _lcc70 extern "C" { bool Level3_IsInApp(const char* path); @@ -83,17 +99,12 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session, size_t message_length, uint8_t* signature, size_t* signature_length); -OEMCryptoResult Level3_LoadKeys(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); +OEMCryptoResult Level3_LoadKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, + const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, const uint8_t* pst, + size_t pst_length, const uint8_t* srm_requirement); OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, @@ -188,6 +199,7 @@ bool Level3_SupportsUsageTable(); bool Level3_IsAntiRollbackHwPresent(); OEMCryptoResult Level3_GetNumberOfOpenSessions(size_t* count); OEMCryptoResult Level3_GetMaxNumberOfSessions(size_t* maximum); +uint32_t Level3_SupportedCertificates(); OEMCryptoResult Level3_Generic_Encrypt(OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, @@ -213,12 +225,13 @@ OEMCryptoResult Level3_Generic_Verify(OEMCrypto_SESSION session, const uint8_t* signature, size_t signature_length); OEMCryptoResult Level3_UpdateUsageTable(); -OEMCryptoResult Level3_DeactivateUsageEntry(const uint8_t *pst, +OEMCryptoResult Level3_DeactivateUsageEntry(OEMCrypto_SESSION session, + const uint8_t *pst, size_t pst_length); OEMCryptoResult Level3_ReportUsage(OEMCrypto_SESSION session, const uint8_t *pst, size_t pst_length, - OEMCrypto_PST_Report *buffer, + uint8_t *buffer, size_t *buffer_length); OEMCryptoResult Level3_DeleteUsageEntry(OEMCrypto_SESSION session, const uint8_t* pst, @@ -229,7 +242,48 @@ OEMCryptoResult Level3_DeleteUsageEntry(OEMCrypto_SESSION session, size_t signature_length); OEMCryptoResult Level3_ForceDeleteUsageEntry(const uint8_t* pst, size_t pst_length); -OEMCryptoResult Level3_DeleteUsageTable(); +OEMCryptoResult Level3_DeleteOldUsageTable(); +bool Level3_IsSRMUpdateSupported(); +OEMCryptoResult Level3_GetCurrentSRMVersion(uint16_t* version); +OEMCryptoResult Level3_LoadSRM(const uint8_t* buffer, + size_t buffer_length); +OEMCryptoResult Level3_RemoveSRM(); +uint32_t Level3_SupportsDecryptHash(); +OEMCryptoResult Level3_SetDecryptHash(OEMCrypto_SESSION session, + const uint8_t* hash, + size_t hash_length); +OEMCryptoResult Level3_VerifyDecryptHash(OEMCrypto_SESSION session, + uint64_t* failure_data); +OEMCryptoResult Level3_CreateUsageTableHeader(); +OEMCryptoResult Level3_LoadUsageTableHeader(const uint8_t* buffer, + size_t buffer_length); +OEMCryptoResult Level3_CreateNewUsageEntry(OEMCrypto_SESSION session, + uint32_t *usage_entry_number); +OEMCryptoResult Level3_LoadUsageEntry(OEMCrypto_SESSION session, + uint32_t index, + const uint8_t *buffer, + size_t buffer_size); +OEMCryptoResult Level3_UpdateUsageEntry(OEMCrypto_SESSION session, + uint8_t* header_buffer, + size_t* header_buffer_length, + uint8_t* entry_buffer, + size_t* entry_buffer_length); +OEMCryptoResult Level3_ShrinkUsageTableHeader(uint32_t new_table_size, + uint8_t* header_buffer, + size_t* header_buffer_length); +OEMCryptoResult Level3_MoveEntry(OEMCrypto_SESSION session, + uint32_t new_index); +OEMCryptoResult Level3_CopyOldUsageEntry(OEMCrypto_SESSION session, + const uint8_t*pst, + size_t pst_length); +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); } // extern "C" } // namespace wvoec3 diff --git a/libwvdrmengine/oemcrypto/include/pst_report.h b/libwvdrmengine/oemcrypto/include/pst_report.h new file mode 100644 index 00000000..cd21e234 --- /dev/null +++ b/libwvdrmengine/oemcrypto/include/pst_report.h @@ -0,0 +1,146 @@ +// Copyright 2017 Google Inc. All Rights Reserved. + +/********************************************************************* + * pst_report.h + * + * Reference APIs needed to support Widevine's crypto algorithms. + *********************************************************************/ + +#ifndef PST_REPORT_H_ +#define PST_REPORT_H_ + +#include +#include +#include + +#include "OEMCryptoCENC.h" +#include "string_conversions.h" // needed for htonll64. + +namespace wvcdm { + +class Unpacked_PST_Report { + public: + // This object does not own the buffer, and does not check that buffer + // is not null. + Unpacked_PST_Report(uint8_t *buffer) : buffer_(buffer) {} + + // Copy and move semantics of this class is like that of a pointer. + Unpacked_PST_Report(const Unpacked_PST_Report& other) : + buffer_(other.buffer_) {} + + Unpacked_PST_Report& operator=(const Unpacked_PST_Report& other) { + buffer_ = other.buffer_; + return *this; + } + + size_t report_size() const { + return pst_length() + kraw_pst_report_size; + } + + static size_t report_size(size_t pst_length) { + return pst_length + kraw_pst_report_size; + } + + uint8_t status() const { + return static_cast(* (buffer_ + kstatus_offset)); + } + + void set_status(uint8_t value) { + buffer_[kstatus_offset] = value; + } + + uint8_t* signature() { + return buffer_ + ksignature_offset; + } + + uint8_t clock_security_level() const { + return static_cast(* (buffer_ + kclock_security_level_offset)); + } + + void set_clock_security_level(uint8_t value) { + buffer_[kclock_security_level_offset] = value; + } + + uint8_t pst_length() const { + return static_cast(* (buffer_ + kpst_length_offset)); + } + + void set_pst_length(uint8_t value) { + buffer_[kpst_length_offset] = value; + } + + uint8_t padding() const { + return static_cast(* (buffer_ + kpadding_offset)); + } + + void set_padding(uint8_t value) { + buffer_[kpadding_offset] = value; + } + + // In host byte order. + int64_t seconds_since_license_received() const { + int64_t time; + memcpy(&time, buffer_ + kseconds_since_license_received_offset, + sizeof(int64_t)); + return wvcdm::ntohll64(time); + } + + // Parameter time is in host byte order. + void set_seconds_since_license_received(int64_t time) const { + time = wvcdm::ntohll64(time); + memcpy(buffer_ + kseconds_since_license_received_offset, &time, + sizeof(int64_t)); + } + + // In host byte order. + int64_t seconds_since_first_decrypt() const { + int64_t time; + memcpy(&time, buffer_ + kseconds_since_first_decrypt_offset, + sizeof(int64_t)); + return wvcdm::ntohll64(time); + } + + // Parameter time is in host byte order. + void set_seconds_since_first_decrypt(int64_t time) const { + time = wvcdm::ntohll64(time); + memcpy(buffer_ + kseconds_since_first_decrypt_offset, &time, + sizeof(int64_t)); + } + + // In host byte order. + int64_t seconds_since_last_decrypt() const { + int64_t time; + memcpy(&time, buffer_ + kseconds_since_last_decrypt_offset, + sizeof(int64_t)); + return wvcdm::ntohll64(time); + } + + // Parameter time is in host byte order. + void set_seconds_since_last_decrypt(int64_t time) const { + time = wvcdm::ntohll64(time); + memcpy(buffer_ + kseconds_since_last_decrypt_offset, &time, + sizeof(int64_t)); + } + + uint8_t* pst() { + return (buffer_ + kpst_offset); + } + + private: + uint8_t *buffer_; + + // Size of the PST_Report without the pst string. + static const size_t kraw_pst_report_size = 48; + static const size_t ksignature_offset = 0; + static const size_t kstatus_offset = 20; + static const size_t kclock_security_level_offset = 21; + static const size_t kpst_length_offset = 22; + static const size_t kpadding_offset = 23; + static const size_t kseconds_since_license_received_offset = 24; + static const size_t kseconds_since_first_decrypt_offset = 32; + static const size_t kseconds_since_last_decrypt_offset = 40; + static const size_t kpst_offset = 48; +}; +} // namespace wvcdm + +#endif // PST_REPORT_H_ diff --git a/libwvdrmengine/oemcrypto/mock/src/oem_cert.cpp b/libwvdrmengine/oemcrypto/mock/src/oem_cert.cpp index 8e111f82..e33d85ae 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oem_cert.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oem_cert.cpp @@ -32,7 +32,7 @@ const uint8_t kOEMPublicCert[] = "-----BEGIN CERTIFICATE-----\n" const size_t kOEMPublicCertSize = sizeof(kOEMPublicCert); -// TODO(fredgc): get the private key that goes with the certificat above. +// TODO(fredgc): get the private key that goes with the certificate above. const uint8_t kOEMPrivateKey[] = { 0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.cpp new file mode 100644 index 00000000..1eef5606 --- /dev/null +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.cpp @@ -0,0 +1,203 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Mock implementation of OEMCrypto APIs +// +#include "oemcrypto_auth_mock.h" + +#include + +#include "keys.h" +#include "log.h" +#include "oemcrypto_key_mock.h" +#include "oemcrypto_logging.h" +#include "oemcrypto_rsa_key_shared.h" +#include "wv_cdm_constants.h" + +namespace { + +// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format +// This is the RSA Test Key. +static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = { + 0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, + 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, + 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, + 0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, + 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, + 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57, 0x67, 0x5e, + 0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, + 0x2a, 0xaa, 0x9d, 0xb4, 0x4e, 0xfa, 0xa7, 0x6a, + 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3, + 0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, + 0x28, 0xda, 0x3f, 0xce, 0x31, 0x7b, 0xfd, 0x06, + 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb, + 0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, + 0x29, 0xf2, 0x73, 0x9e, 0x39, 0xd8, 0xf6, 0x6f, + 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4, + 0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, + 0xcd, 0x9a, 0x13, 0x8b, 0x54, 0x73, 0x54, 0x25, + 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda, + 0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, + 0x98, 0x56, 0x57, 0x54, 0x71, 0xcd, 0x12, 0x7f, + 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03, + 0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, + 0xc9, 0x83, 0x06, 0x51, 0x5a, 0x88, 0x65, 0x13, + 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b, + 0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, + 0x2d, 0x5f, 0xf8, 0x12, 0x7f, 0xa2, 0xfc, 0xbb, + 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01, + 0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, + 0x82, 0x46, 0x0b, 0x3a, 0x77, 0x8f, 0xc0, 0x72, + 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed, + 0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, + 0xd3, 0x5b, 0x3d, 0xdb, 0x9c, 0x5e, 0x1b, 0x7b, + 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb, + 0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x5e, + 0x79, 0x65, 0x49, 0xa5, 0x76, 0x79, 0xf9, 0x05, + 0x45, 0x0f, 0xf4, 0x03, 0xbd, 0xa4, 0x7d, 0x29, + 0xd5, 0xde, 0x33, 0x63, 0xd8, 0xb8, 0xac, 0x97, + 0xeb, 0x3f, 0x5e, 0x55, 0xe8, 0x7d, 0xf3, 0xe7, + 0x3b, 0x5c, 0x2d, 0x54, 0x67, 0x36, 0xd6, 0x1d, + 0x46, 0xf5, 0xca, 0x2d, 0x8b, 0x3a, 0x7e, 0xdc, + 0x45, 0x38, 0x79, 0x7e, 0x65, 0x71, 0x5f, 0x1c, + 0x5e, 0x79, 0xb1, 0x40, 0xcd, 0xfe, 0xc5, 0xe1, + 0xc1, 0x6b, 0x78, 0x04, 0x4e, 0x8e, 0x79, 0xf9, + 0x0a, 0xfc, 0x79, 0xb1, 0x5e, 0xb3, 0x60, 0xe3, + 0x68, 0x7b, 0xc6, 0xef, 0xcb, 0x71, 0x4c, 0xba, + 0xa7, 0x79, 0x5c, 0x7a, 0x81, 0xd1, 0x71, 0xe7, + 0x00, 0x21, 0x13, 0xe2, 0x55, 0x69, 0x0e, 0x75, + 0xbe, 0x09, 0xc3, 0x4f, 0xa9, 0xc9, 0x68, 0x22, + 0x0e, 0x97, 0x8d, 0x89, 0x6e, 0xf1, 0xe8, 0x88, + 0x7a, 0xd1, 0xd9, 0x09, 0x5d, 0xd3, 0x28, 0x78, + 0x25, 0x0b, 0x1c, 0x47, 0x73, 0x25, 0xcc, 0x21, + 0xb6, 0xda, 0xc6, 0x24, 0x5a, 0xd0, 0x37, 0x14, + 0x46, 0xc7, 0x94, 0x69, 0xe4, 0x43, 0x6f, 0x47, + 0xde, 0x00, 0x33, 0x4d, 0x8f, 0x95, 0x72, 0xfa, + 0x68, 0x71, 0x17, 0x66, 0x12, 0x1a, 0x87, 0x27, + 0xf7, 0xef, 0x7e, 0xe0, 0x35, 0x58, 0xf2, 0x4d, + 0x6f, 0x35, 0x01, 0xaa, 0x96, 0xe2, 0x3d, 0x51, + 0x13, 0x86, 0x9c, 0x79, 0xd0, 0xb7, 0xb6, 0x64, + 0xe8, 0x86, 0x65, 0x50, 0xbf, 0xcc, 0x27, 0x53, + 0x1f, 0x51, 0xd4, 0xca, 0xbe, 0xf5, 0xdd, 0x77, + 0x70, 0x98, 0x0f, 0xee, 0xa8, 0x96, 0x07, 0x5f, + 0x45, 0x6a, 0x7a, 0x0d, 0x03, 0x9c, 0x4f, 0x29, + 0xf6, 0x06, 0xf3, 0x5d, 0x58, 0x6c, 0x47, 0xd0, + 0x96, 0xa9, 0x03, 0x17, 0xbb, 0x4e, 0xc9, 0x21, + 0xe0, 0xac, 0xcd, 0x78, 0x78, 0xb2, 0xfe, 0x81, + 0xb2, 0x51, 0x53, 0xa6, 0x1f, 0x98, 0x45, 0x02, + 0x81, 0x81, 0x00, 0xcf, 0x73, 0x8c, 0xbe, 0x6d, + 0x45, 0x2d, 0x0c, 0x0b, 0x5d, 0x5c, 0x6c, 0x75, + 0x78, 0xcc, 0x35, 0x48, 0xb6, 0x98, 0xf1, 0xb9, + 0x64, 0x60, 0x8c, 0x43, 0xeb, 0x85, 0xab, 0x04, + 0xb6, 0x7d, 0x1b, 0x71, 0x75, 0x06, 0xe2, 0xda, + 0x84, 0x68, 0x2e, 0x7f, 0x4c, 0xe3, 0x73, 0xb4, + 0xde, 0x51, 0x4b, 0xb6, 0x51, 0x86, 0x7b, 0xd0, + 0xe6, 0x4d, 0xf3, 0xd1, 0xcf, 0x1a, 0xfe, 0x7f, + 0x3a, 0x83, 0xba, 0xb3, 0xe1, 0xff, 0x54, 0x13, + 0x93, 0xd7, 0x9c, 0x27, 0x80, 0xb7, 0x1e, 0x64, + 0x9e, 0xf7, 0x32, 0x2b, 0x46, 0x29, 0xf7, 0xf8, + 0x18, 0x6c, 0xf7, 0x4a, 0xbe, 0x4b, 0xee, 0x96, + 0x90, 0x8f, 0xa2, 0x16, 0x22, 0x6a, 0xcc, 0x48, + 0x06, 0x74, 0x63, 0x43, 0x7f, 0x27, 0x22, 0x44, + 0x3c, 0x2d, 0x3b, 0x62, 0xf1, 0x1c, 0xb4, 0x27, + 0x33, 0x85, 0x26, 0x60, 0x48, 0x16, 0xcb, 0xef, + 0xf8, 0xcd, 0x37, 0x02, 0x81, 0x81, 0x00, 0xce, + 0x15, 0x43, 0x6e, 0x4b, 0x0f, 0xf9, 0x3f, 0x87, + 0xc3, 0x41, 0x45, 0x97, 0xb1, 0x49, 0xc2, 0x19, + 0x23, 0x87, 0xe4, 0x24, 0x1c, 0x64, 0xe5, 0x28, + 0xcb, 0x43, 0x10, 0x14, 0x14, 0x0e, 0x19, 0xcb, + 0xbb, 0xdb, 0xfd, 0x11, 0x9d, 0x17, 0x68, 0x78, + 0x6d, 0x61, 0x70, 0x63, 0x3a, 0xa1, 0xb3, 0xf3, + 0xa7, 0x5b, 0x0e, 0xff, 0xb7, 0x61, 0x11, 0x54, + 0x91, 0x99, 0xe5, 0x91, 0x32, 0x2d, 0xeb, 0x3f, + 0xd8, 0x3e, 0xf7, 0xd4, 0xcb, 0xd2, 0xa3, 0x41, + 0xc1, 0xee, 0xc6, 0x92, 0x13, 0xeb, 0x7f, 0x42, + 0x58, 0xf4, 0xd0, 0xb2, 0x74, 0x1d, 0x8e, 0x87, + 0x46, 0xcd, 0x14, 0xb8, 0x16, 0xad, 0xb5, 0xbd, + 0x0d, 0x6c, 0x95, 0x5a, 0x16, 0xbf, 0xe9, 0x53, + 0xda, 0xfb, 0xed, 0x83, 0x51, 0x67, 0xa9, 0x55, + 0xab, 0x54, 0x02, 0x95, 0x20, 0xa6, 0x68, 0x17, + 0x53, 0xa8, 0xea, 0x43, 0xe5, 0xb0, 0xa3, 0x02, + 0x81, 0x80, 0x67, 0x9c, 0x32, 0x83, 0x39, 0x57, + 0xff, 0x73, 0xb0, 0x89, 0x64, 0x8b, 0xd6, 0xf0, + 0x0a, 0x2d, 0xe2, 0xaf, 0x30, 0x1c, 0x2a, 0x97, + 0xf3, 0x90, 0x9a, 0xab, 0x9b, 0x0b, 0x1b, 0x43, + 0x79, 0xa0, 0xa7, 0x3d, 0xe7, 0xbe, 0x8d, 0x9c, + 0xeb, 0xdb, 0xad, 0x40, 0xdd, 0xa9, 0x00, 0x80, + 0xb8, 0xe1, 0xb3, 0xa1, 0x6c, 0x25, 0x92, 0xe4, + 0x33, 0xb2, 0xbe, 0xeb, 0x4d, 0x74, 0x26, 0x5f, + 0x37, 0x43, 0x9c, 0x6c, 0x17, 0x76, 0x0a, 0x81, + 0x20, 0x82, 0xa1, 0x48, 0x2c, 0x2d, 0x45, 0xdc, + 0x0f, 0x62, 0x43, 0x32, 0xbb, 0xeb, 0x59, 0x41, + 0xf9, 0xca, 0x58, 0xce, 0x4a, 0x66, 0x53, 0x54, + 0xc8, 0x28, 0x10, 0x1e, 0x08, 0x71, 0x16, 0xd8, + 0x02, 0x71, 0x41, 0x58, 0xd4, 0x56, 0xcc, 0xf5, + 0xb1, 0x31, 0xa3, 0xed, 0x00, 0x85, 0x09, 0xbf, + 0x35, 0x95, 0x41, 0x29, 0x40, 0x19, 0x83, 0x35, + 0x24, 0x69, 0x02, 0x81, 0x80, 0x55, 0x10, 0x0b, + 0xcc, 0x3b, 0xa9, 0x75, 0x3d, 0x16, 0xe1, 0xae, + 0x50, 0x76, 0x63, 0x94, 0x49, 0x4c, 0xad, 0x10, + 0xcb, 0x47, 0x68, 0x7c, 0xf0, 0xe5, 0xdc, 0xb8, + 0x6a, 0xab, 0x8e, 0xf7, 0x9f, 0x08, 0x2c, 0x1b, + 0x8a, 0xa2, 0xb9, 0x8f, 0xce, 0xec, 0x5e, 0x61, + 0xa8, 0xcd, 0x1c, 0x87, 0x60, 0x4a, 0xc3, 0x1a, + 0x5f, 0xdf, 0x87, 0x26, 0xc6, 0xcb, 0x7c, 0x69, + 0xe4, 0x8b, 0x01, 0x06, 0x59, 0x22, 0xfa, 0x34, + 0x4b, 0x81, 0x87, 0x3c, 0x03, 0x6d, 0x02, 0x0a, + 0x77, 0xe6, 0x15, 0xd8, 0xcf, 0xa7, 0x68, 0x26, + 0x6c, 0xfa, 0x2b, 0xd9, 0x83, 0x5a, 0x2d, 0x0c, + 0x3b, 0x70, 0x1c, 0xd4, 0x48, 0xbe, 0xa7, 0x0a, + 0xd9, 0xbe, 0xdc, 0xc3, 0x0c, 0x21, 0x33, 0xb3, + 0x66, 0xff, 0x1c, 0x1b, 0xc8, 0x96, 0x76, 0xe8, + 0x6f, 0x44, 0x74, 0xbc, 0x9b, 0x1c, 0x7d, 0xc8, + 0xac, 0x21, 0xa8, 0x6e, 0x37, 0x02, 0x81, 0x80, + 0x2c, 0x7c, 0xad, 0x1e, 0x75, 0xf6, 0x69, 0x1d, + 0xe7, 0xa6, 0xca, 0x74, 0x7d, 0x67, 0xc8, 0x65, + 0x28, 0x66, 0xc4, 0x43, 0xa6, 0xbd, 0x40, 0x57, + 0xae, 0xb7, 0x65, 0x2c, 0x52, 0xf9, 0xe4, 0xc7, + 0x81, 0x7b, 0x56, 0xa3, 0xd2, 0x0d, 0xe8, 0x33, + 0x70, 0xcf, 0x06, 0x84, 0xb3, 0x4e, 0x44, 0x50, + 0x75, 0x61, 0x96, 0x86, 0x4b, 0xb6, 0x2b, 0xad, + 0xf0, 0xad, 0x57, 0xd0, 0x37, 0x0d, 0x1d, 0x35, + 0x50, 0xcb, 0x69, 0x22, 0x39, 0x29, 0xb9, 0x3a, + 0xd3, 0x29, 0x23, 0x02, 0x60, 0xf7, 0xab, 0x30, + 0x40, 0xda, 0x8e, 0x4d, 0x45, 0x70, 0x26, 0xf4, + 0xa2, 0x0d, 0xd0, 0x64, 0x5d, 0x47, 0x3c, 0x18, + 0xf4, 0xd4, 0x52, 0x95, 0x00, 0xae, 0x84, 0x6b, + 0x47, 0xb2, 0x3c, 0x82, 0xd3, 0x72, 0x53, 0xde, + 0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, + 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 +}; + +} // namespace + +namespace wvoec_mock { + +AuthenticationRoot::AuthenticationRoot(OEMCrypto_ProvisioningMethod method) : + provisioning_method_(method), + use_test_keybox_(false) { + if ((provisioning_method_ == OEMCrypto_DrmCertificate) && + !rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize)) { + // This error message is OK in unit tests which use test certificate. + LOGE("FATAL ERROR: Platform uses a baked-in certificate instead of a " + "keybox, but the certificate could not be loaded."); + } +} + +KeyboxError AuthenticationRoot::ValidateKeybox() { + return keybox().Validate(); +} + +bool AuthenticationRoot::LoadTestRsaKey() { + return rsa_key_.LoadPkcs8RsaKey(kTestRSAPKCS8PrivateKeyInfo2_2048, + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); +} + +bool AuthenticationRoot::Validate() { + return NO_ERROR == ValidateKeybox(); +} + +} // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h new file mode 100644 index 00000000..98e78dc4 --- /dev/null +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_auth_mock.h @@ -0,0 +1,73 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Mock implementation of OEMCrypto APIs +// +#ifndef OEMCRYPTO_AUTH_MOCK_H_ +#define OEMCRYPTO_AUTH_MOCK_H_ + +#include +#include + +#include + +#include "OEMCryptoCENC.h" // Needed for enums only. +#include "oemcrypto_key_mock.h" +#include "oemcrypto_keybox_mock.h" +#include "oemcrypto_rsa_key_shared.h" +#include "wv_cdm_types.h" + +namespace wvoec_mock { + +class AuthenticationRoot { + public: + explicit AuthenticationRoot(OEMCrypto_ProvisioningMethod method); + ~AuthenticationRoot() {} + + bool Validate(); + + KeyboxError ValidateKeybox(); + + bool InstallKeybox(const uint8_t* keybox_data, size_t keybox_length) { + return keybox().InstallKeybox(keybox_data, keybox_length); + } + + const std::vector& DeviceKey(bool use_real_keybox = false) { + return use_real_keybox ? real_keybox().device_key() : + keybox().device_key(); + } + + const std::vector& DeviceId() { + return keybox().device_id(); + } + + size_t DeviceTokenLength() { + return keybox().key_data_length(); + } + + const uint8_t* const DeviceToken() { + return keybox().key_data(); + } + + WvKeybox& keybox() { return use_test_keybox_ ? test_keybox_ : keybox_; } + void UseTestKeybox() { use_test_keybox_ = true; } + + RSA_shared_ptr& SharedRsaKey() { return rsa_key_; } + RSA* rsa_key() { return rsa_key_.get(); } + bool LoadTestRsaKey(); + + private: + OEMCrypto_ProvisioningMethod provisioning_method_; + WvKeybox& real_keybox() { return keybox_; } + + WvKeybox keybox_; + WvTestKeybox test_keybox_; + bool use_test_keybox_; + + RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate. + + CORE_DISALLOW_COPY_AND_ASSIGN(AuthenticationRoot); +}; + +} // namespace wvoec_mock + +#endif // OEMCRYPTO_AUTH_MOCK_H_ diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp index 6f9c67db..b7e1ab64 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties.cpp @@ -6,40 +6,42 @@ namespace wvoec_mock { -// If local_display() returns true, we pretend we are using a built-in display, -// instead of HDMI or WiFi output. -bool CryptoEngine::local_display() { +// Configuration constants for CryptoEngine behavior + +// If config_local_display_only() returns true, we pretend we are using a +// built-in display, instead of HDMI or WiFi output. +bool CryptoEngine::config_local_display_only() { return false; } // A closed platform is permitted to use clear buffers. -bool CryptoEngine::closed_platform() { +bool CryptoEngine::config_closed_platform() { return false; } // Returns the HDCP version currently in use. -OEMCrypto_HDCP_Capability CryptoEngine::current_hdcp_capability() { - return local_display() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; +OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() { + return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; } // Returns the max HDCP version supported. -OEMCrypto_HDCP_Capability CryptoEngine::maximum_hdcp_capability() { +OEMCrypto_HDCP_Capability CryptoEngine::config_maximum_hdcp_capability() { return HDCP_V2; } // Returns true if the client supports persistent storage of // offline usage table information. -bool CryptoEngine::supports_storage() { +bool CryptoEngine::config_supports_usage_table() { return true; } // Returns true if the client uses a keybox as the root of trust. -bool CryptoEngine::supports_keybox() { +bool CryptoEngine::config_supports_keybox() { return true; } // This version uses a keybox. -OEMCrypto_ProvisioningMethod CryptoEngine::provisioning_method() { +OEMCrypto_ProvisioningMethod CryptoEngine::config_provisioning_method() { return OEMCrypto_Keybox; } @@ -51,19 +53,19 @@ OEMCryptoResult CryptoEngine::get_oem_certificate(SessionContext *session, // Returns false for mock library to indicate the client does not support // anti-rollback hardware. -bool CryptoEngine::is_anti_rollback_hw_present() { +bool CryptoEngine::config_is_anti_rollback_hw_present() { return false; } // Returns "L3" for a software only library. L1 is for hardware protected // data paths. -const char* CryptoEngine::security_level() { +const char* CryptoEngine::config_security_level() { return "L3"; } // This should start at 0, and be incremented only when a security patch has // been applied to the device that fixes a security bug. -uint8_t CryptoEngine::security_patch_level() { +uint8_t CryptoEngine::config_security_patch_level() { return 0; } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp index 5ffc068a..c6c99a3c 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_L1.cpp @@ -8,40 +8,40 @@ namespace wvoec_mock { -// If local_display() returns true, we pretend we are using a built-in display, -// instead of HDMI or WiFi output. -bool CryptoEngine::local_display() { +// If config_local_display_only() returns true, we pretend we are using a +// built-in display, instead of HDMI or WiFi output. +bool CryptoEngine::config_local_display_only() { return true; } // A closed platform is permitted to use clear buffers. -bool CryptoEngine::closed_platform() { +bool CryptoEngine::config_closed_platform() { return false; } // Returns the HDCP version currently in use. -OEMCrypto_HDCP_Capability CryptoEngine::current_hdcp_capability() { - return local_display() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; +OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() { + return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; } // Returns the max HDCP version supported. -OEMCrypto_HDCP_Capability CryptoEngine::maximum_hdcp_capability() { +OEMCrypto_HDCP_Capability CryptoEngine::config_maximum_hdcp_capability() { return HDCP_NO_DIGITAL_OUTPUT; } // Returns true if the client supports persistent storage of // offline usage table information. -bool CryptoEngine::supports_storage() { +bool CryptoEngine::config_supports_usage_table() { return true; } // Returns true if the client uses a keybox as the root of trust. -bool CryptoEngine::supports_keybox() { +bool CryptoEngine::config_supports_keybox() { return true; } // This version uses a keybox. -OEMCrypto_ProvisioningMethod CryptoEngine::provisioning_method() { +OEMCrypto_ProvisioningMethod CryptoEngine::config_provisioning_method() { return OEMCrypto_Keybox; } @@ -52,19 +52,19 @@ OEMCryptoResult CryptoEngine::get_oem_certificate(SessionContext *session, } // Returns true to indicate the client does support anti-rollback hardware. -bool CryptoEngine::is_anti_rollback_hw_present() { +bool CryptoEngine::config_is_anti_rollback_hw_present() { return true; } // Returns "L3" for a software only library. L1 is for hardware protected // data paths. -const char* CryptoEngine::security_level() { +const char* CryptoEngine::config_security_level() { return "L1"; } // This should start at 0, and be incremented only when a security patch has // been applied to the device that fixes a security bug. -uint8_t CryptoEngine::security_patch_level() { +uint8_t CryptoEngine::config_security_patch_level() { return 3; } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp index 2a4dec2b..aed87e64 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_cert.cpp @@ -9,40 +9,40 @@ namespace wvoec_mock { -// If local_display() returns true, we pretend we are using a built-in display, -// instead of HDMI or WiFi output. -bool CryptoEngine::local_display() { +// If config_local_display_only() returns true, we pretend we are using a +// built-in display, instead of HDMI or WiFi output. +bool CryptoEngine::config_local_display_only() { return true; } // A closed platform is permitted to use clear buffers. -bool CryptoEngine::closed_platform() { +bool CryptoEngine::config_closed_platform() { return false; } // Returns the HDCP version currently in use. -OEMCrypto_HDCP_Capability CryptoEngine::current_hdcp_capability() { - return local_display() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; +OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() { + return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; } // Returns the max HDCP version supported. -OEMCrypto_HDCP_Capability CryptoEngine::maximum_hdcp_capability() { +OEMCrypto_HDCP_Capability CryptoEngine::config_maximum_hdcp_capability() { return HDCP_NO_DIGITAL_OUTPUT; } // Returns true if the client supports persistent storage of // offline usage table information. -bool CryptoEngine::supports_storage() { +bool CryptoEngine::config_supports_usage_table() { return false; } // Returns true if the client uses a keybox as the root of trust. -bool CryptoEngine::supports_keybox() { +bool CryptoEngine::config_supports_keybox() { return false; } // This version uses a baked in DRM certificate. -OEMCrypto_ProvisioningMethod CryptoEngine::provisioning_method() { +OEMCrypto_ProvisioningMethod CryptoEngine::config_provisioning_method() { return OEMCrypto_DrmCertificate; } @@ -53,20 +53,20 @@ OEMCryptoResult CryptoEngine::get_oem_certificate(SessionContext *session, } // Returns true to indicate the client does support anti-rollback hardware. -bool CryptoEngine::is_anti_rollback_hw_present() { +bool CryptoEngine::config_is_anti_rollback_hw_present() { return false; } // Returns "L3" for a software only library. L1 is for hardware protected keys // and data paths. L2 is for hardware protected keys but no data path // protection. -const char* CryptoEngine::security_level() { +const char* CryptoEngine::config_security_level() { return "L2"; } // This should start at 0, and be incremented only when a security patch has // been applied to the device that fixes a security bug. -uint8_t CryptoEngine::security_patch_level() { +uint8_t CryptoEngine::config_security_patch_level() { return 0; } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp index 1d783f80..a55e316c 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_device_properties_prov30.cpp @@ -14,40 +14,40 @@ namespace wvoec_mock { -// If local_display() returns true, we pretend we are using a built-in display, -// instead of HDMI or WiFi output. -bool CryptoEngine::local_display() { +// If config_local_display_only() returns true, we pretend we are using a +// built-in display, instead of HDMI or WiFi output. +bool CryptoEngine::config_local_display_only() { return true; } // A closed platform is permitted to use clear buffers. -bool CryptoEngine::closed_platform() { +bool CryptoEngine::config_closed_platform() { return false; } // Returns the HDCP version currently in use. -OEMCrypto_HDCP_Capability CryptoEngine::current_hdcp_capability() { - return local_display() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; +OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() { + return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1; } // Returns the max HDCP version supported. -OEMCrypto_HDCP_Capability CryptoEngine::maximum_hdcp_capability() { +OEMCrypto_HDCP_Capability CryptoEngine::config_maximum_hdcp_capability() { return HDCP_NO_DIGITAL_OUTPUT; } // Returns true if the client supports persistent storage of // offline usage table information. -bool CryptoEngine::supports_storage() { +bool CryptoEngine::config_supports_usage_table() { return false; } // Returns true if the client uses a keybox as the root of trust. -bool CryptoEngine::supports_keybox() { +bool CryptoEngine::config_supports_keybox() { return false; } // This version uses a keybox. -OEMCrypto_ProvisioningMethod CryptoEngine::provisioning_method() { +OEMCrypto_ProvisioningMethod CryptoEngine::config_provisioning_method() { return OEMCrypto_OEMCertificate; } @@ -77,20 +77,20 @@ OEMCryptoResult CryptoEngine::get_oem_certificate(SessionContext *session, } // Returns true to indicate the client does support anti-rollback hardware. -bool CryptoEngine::is_anti_rollback_hw_present() { +bool CryptoEngine::config_is_anti_rollback_hw_present() { return false; } // Returns "L3" for a software only library. L1 is for hardware protected keys // and data paths. L2 is for hardware protected keys but no data path // protection. -const char* CryptoEngine::security_level() { +const char* CryptoEngine::config_security_level() { return "L2"; } // This should start at 0, and be incremented only when a security patch has // been applied to the device that fixes a security bug. -uint8_t CryptoEngine::security_patch_level() { +uint8_t CryptoEngine::config_security_patch_level() { return 0; } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp index e87bfe92..04570fca 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp @@ -26,6 +26,7 @@ #include "log.h" #include "oemcrypto_key_mock.h" #include "oemcrypto_logging.h" +#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_usage_table_mock.h" #include "string_conversions.h" #include "wv_cdm_constants.h" @@ -33,6 +34,7 @@ static const int kPssSaltLength = 20; namespace { + // Increment counter for AES-CTR. The CENC spec specifies we increment only // the low 64 bits of the IV counter, and leave the high 64 bits alone. void ctr128_inc64(uint8_t* counter) { @@ -41,6 +43,7 @@ void ctr128_inc64(uint8_t* counter) { if (++counter[--n] != 0) return; } while (n > 8); } + void dump_openssl_error() { while (unsigned long err = ERR_get_error()) { char buffer[120]; @@ -48,162 +51,7 @@ void dump_openssl_error() { err, ERR_error_string(err, buffer)); } } -// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format -// This is the RSA Test Key. -static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = { - 0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, - 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, - 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, - 0x40, 0xb4, 0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, - 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, - 0xe0, 0x88, 0x09, 0x29, 0x61, 0x57, 0x67, 0x5e, - 0x56, 0x7e, 0xee, 0x27, 0x8f, 0x59, 0x34, 0x9a, - 0x2a, 0xaa, 0x9d, 0xb4, 0x4e, 0xfa, 0xa7, 0x6a, - 0xd4, 0xc9, 0x7a, 0x53, 0xc1, 0x4e, 0x9f, 0xe3, - 0x34, 0xf7, 0x3d, 0xb7, 0xc9, 0x10, 0x47, 0x4f, - 0x28, 0xda, 0x3f, 0xce, 0x31, 0x7b, 0xfd, 0x06, - 0x10, 0xeb, 0xf7, 0xbe, 0x92, 0xf9, 0xaf, 0xfb, - 0x3e, 0x68, 0xda, 0xee, 0x1a, 0x64, 0x4c, 0xf3, - 0x29, 0xf2, 0x73, 0x9e, 0x39, 0xd8, 0xf6, 0x6f, - 0xd8, 0xb2, 0x80, 0x82, 0x71, 0x8e, 0xb5, 0xa4, - 0xf2, 0xc2, 0x3e, 0xcd, 0x0a, 0xca, 0xb6, 0x04, - 0xcd, 0x9a, 0x13, 0x8b, 0x54, 0x73, 0x54, 0x25, - 0x54, 0x8c, 0xbe, 0x98, 0x7a, 0x67, 0xad, 0xda, - 0xb3, 0x4e, 0xb3, 0xfa, 0x82, 0xa8, 0x4a, 0x67, - 0x98, 0x56, 0x57, 0x54, 0x71, 0xcd, 0x12, 0x7f, - 0xed, 0xa3, 0x01, 0xc0, 0x6a, 0x8b, 0x24, 0x03, - 0x96, 0x88, 0xbe, 0x97, 0x66, 0x2a, 0xbc, 0x53, - 0xc9, 0x83, 0x06, 0x51, 0x5a, 0x88, 0x65, 0x13, - 0x18, 0xe4, 0x3a, 0xed, 0x6b, 0xf1, 0x61, 0x5b, - 0x4c, 0xc8, 0x1e, 0xf4, 0xc2, 0xae, 0x08, 0x5e, - 0x2d, 0x5f, 0xf8, 0x12, 0x7f, 0xa2, 0xfc, 0xbb, - 0x21, 0x18, 0x30, 0xda, 0xfe, 0x40, 0xfb, 0x01, - 0xca, 0x2e, 0x37, 0x0e, 0xce, 0xdd, 0x76, 0x87, - 0x82, 0x46, 0x0b, 0x3a, 0x77, 0x8f, 0xc0, 0x72, - 0x07, 0x2c, 0x7f, 0x9d, 0x1e, 0x86, 0x5b, 0xed, - 0x27, 0x29, 0xdf, 0x03, 0x97, 0x62, 0xef, 0x44, - 0xd3, 0x5b, 0x3d, 0xdb, 0x9c, 0x5e, 0x1b, 0x7b, - 0x39, 0xb4, 0x0b, 0x6d, 0x04, 0x6b, 0xbb, 0xbb, - 0x2c, 0x5f, 0xcf, 0xb3, 0x7a, 0x05, 0x02, 0x03, - 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x5e, - 0x79, 0x65, 0x49, 0xa5, 0x76, 0x79, 0xf9, 0x05, - 0x45, 0x0f, 0xf4, 0x03, 0xbd, 0xa4, 0x7d, 0x29, - 0xd5, 0xde, 0x33, 0x63, 0xd8, 0xb8, 0xac, 0x97, - 0xeb, 0x3f, 0x5e, 0x55, 0xe8, 0x7d, 0xf3, 0xe7, - 0x3b, 0x5c, 0x2d, 0x54, 0x67, 0x36, 0xd6, 0x1d, - 0x46, 0xf5, 0xca, 0x2d, 0x8b, 0x3a, 0x7e, 0xdc, - 0x45, 0x38, 0x79, 0x7e, 0x65, 0x71, 0x5f, 0x1c, - 0x5e, 0x79, 0xb1, 0x40, 0xcd, 0xfe, 0xc5, 0xe1, - 0xc1, 0x6b, 0x78, 0x04, 0x4e, 0x8e, 0x79, 0xf9, - 0x0a, 0xfc, 0x79, 0xb1, 0x5e, 0xb3, 0x60, 0xe3, - 0x68, 0x7b, 0xc6, 0xef, 0xcb, 0x71, 0x4c, 0xba, - 0xa7, 0x79, 0x5c, 0x7a, 0x81, 0xd1, 0x71, 0xe7, - 0x00, 0x21, 0x13, 0xe2, 0x55, 0x69, 0x0e, 0x75, - 0xbe, 0x09, 0xc3, 0x4f, 0xa9, 0xc9, 0x68, 0x22, - 0x0e, 0x97, 0x8d, 0x89, 0x6e, 0xf1, 0xe8, 0x88, - 0x7a, 0xd1, 0xd9, 0x09, 0x5d, 0xd3, 0x28, 0x78, - 0x25, 0x0b, 0x1c, 0x47, 0x73, 0x25, 0xcc, 0x21, - 0xb6, 0xda, 0xc6, 0x24, 0x5a, 0xd0, 0x37, 0x14, - 0x46, 0xc7, 0x94, 0x69, 0xe4, 0x43, 0x6f, 0x47, - 0xde, 0x00, 0x33, 0x4d, 0x8f, 0x95, 0x72, 0xfa, - 0x68, 0x71, 0x17, 0x66, 0x12, 0x1a, 0x87, 0x27, - 0xf7, 0xef, 0x7e, 0xe0, 0x35, 0x58, 0xf2, 0x4d, - 0x6f, 0x35, 0x01, 0xaa, 0x96, 0xe2, 0x3d, 0x51, - 0x13, 0x86, 0x9c, 0x79, 0xd0, 0xb7, 0xb6, 0x64, - 0xe8, 0x86, 0x65, 0x50, 0xbf, 0xcc, 0x27, 0x53, - 0x1f, 0x51, 0xd4, 0xca, 0xbe, 0xf5, 0xdd, 0x77, - 0x70, 0x98, 0x0f, 0xee, 0xa8, 0x96, 0x07, 0x5f, - 0x45, 0x6a, 0x7a, 0x0d, 0x03, 0x9c, 0x4f, 0x29, - 0xf6, 0x06, 0xf3, 0x5d, 0x58, 0x6c, 0x47, 0xd0, - 0x96, 0xa9, 0x03, 0x17, 0xbb, 0x4e, 0xc9, 0x21, - 0xe0, 0xac, 0xcd, 0x78, 0x78, 0xb2, 0xfe, 0x81, - 0xb2, 0x51, 0x53, 0xa6, 0x1f, 0x98, 0x45, 0x02, - 0x81, 0x81, 0x00, 0xcf, 0x73, 0x8c, 0xbe, 0x6d, - 0x45, 0x2d, 0x0c, 0x0b, 0x5d, 0x5c, 0x6c, 0x75, - 0x78, 0xcc, 0x35, 0x48, 0xb6, 0x98, 0xf1, 0xb9, - 0x64, 0x60, 0x8c, 0x43, 0xeb, 0x85, 0xab, 0x04, - 0xb6, 0x7d, 0x1b, 0x71, 0x75, 0x06, 0xe2, 0xda, - 0x84, 0x68, 0x2e, 0x7f, 0x4c, 0xe3, 0x73, 0xb4, - 0xde, 0x51, 0x4b, 0xb6, 0x51, 0x86, 0x7b, 0xd0, - 0xe6, 0x4d, 0xf3, 0xd1, 0xcf, 0x1a, 0xfe, 0x7f, - 0x3a, 0x83, 0xba, 0xb3, 0xe1, 0xff, 0x54, 0x13, - 0x93, 0xd7, 0x9c, 0x27, 0x80, 0xb7, 0x1e, 0x64, - 0x9e, 0xf7, 0x32, 0x2b, 0x46, 0x29, 0xf7, 0xf8, - 0x18, 0x6c, 0xf7, 0x4a, 0xbe, 0x4b, 0xee, 0x96, - 0x90, 0x8f, 0xa2, 0x16, 0x22, 0x6a, 0xcc, 0x48, - 0x06, 0x74, 0x63, 0x43, 0x7f, 0x27, 0x22, 0x44, - 0x3c, 0x2d, 0x3b, 0x62, 0xf1, 0x1c, 0xb4, 0x27, - 0x33, 0x85, 0x26, 0x60, 0x48, 0x16, 0xcb, 0xef, - 0xf8, 0xcd, 0x37, 0x02, 0x81, 0x81, 0x00, 0xce, - 0x15, 0x43, 0x6e, 0x4b, 0x0f, 0xf9, 0x3f, 0x87, - 0xc3, 0x41, 0x45, 0x97, 0xb1, 0x49, 0xc2, 0x19, - 0x23, 0x87, 0xe4, 0x24, 0x1c, 0x64, 0xe5, 0x28, - 0xcb, 0x43, 0x10, 0x14, 0x14, 0x0e, 0x19, 0xcb, - 0xbb, 0xdb, 0xfd, 0x11, 0x9d, 0x17, 0x68, 0x78, - 0x6d, 0x61, 0x70, 0x63, 0x3a, 0xa1, 0xb3, 0xf3, - 0xa7, 0x5b, 0x0e, 0xff, 0xb7, 0x61, 0x11, 0x54, - 0x91, 0x99, 0xe5, 0x91, 0x32, 0x2d, 0xeb, 0x3f, - 0xd8, 0x3e, 0xf7, 0xd4, 0xcb, 0xd2, 0xa3, 0x41, - 0xc1, 0xee, 0xc6, 0x92, 0x13, 0xeb, 0x7f, 0x42, - 0x58, 0xf4, 0xd0, 0xb2, 0x74, 0x1d, 0x8e, 0x87, - 0x46, 0xcd, 0x14, 0xb8, 0x16, 0xad, 0xb5, 0xbd, - 0x0d, 0x6c, 0x95, 0x5a, 0x16, 0xbf, 0xe9, 0x53, - 0xda, 0xfb, 0xed, 0x83, 0x51, 0x67, 0xa9, 0x55, - 0xab, 0x54, 0x02, 0x95, 0x20, 0xa6, 0x68, 0x17, - 0x53, 0xa8, 0xea, 0x43, 0xe5, 0xb0, 0xa3, 0x02, - 0x81, 0x80, 0x67, 0x9c, 0x32, 0x83, 0x39, 0x57, - 0xff, 0x73, 0xb0, 0x89, 0x64, 0x8b, 0xd6, 0xf0, - 0x0a, 0x2d, 0xe2, 0xaf, 0x30, 0x1c, 0x2a, 0x97, - 0xf3, 0x90, 0x9a, 0xab, 0x9b, 0x0b, 0x1b, 0x43, - 0x79, 0xa0, 0xa7, 0x3d, 0xe7, 0xbe, 0x8d, 0x9c, - 0xeb, 0xdb, 0xad, 0x40, 0xdd, 0xa9, 0x00, 0x80, - 0xb8, 0xe1, 0xb3, 0xa1, 0x6c, 0x25, 0x92, 0xe4, - 0x33, 0xb2, 0xbe, 0xeb, 0x4d, 0x74, 0x26, 0x5f, - 0x37, 0x43, 0x9c, 0x6c, 0x17, 0x76, 0x0a, 0x81, - 0x20, 0x82, 0xa1, 0x48, 0x2c, 0x2d, 0x45, 0xdc, - 0x0f, 0x62, 0x43, 0x32, 0xbb, 0xeb, 0x59, 0x41, - 0xf9, 0xca, 0x58, 0xce, 0x4a, 0x66, 0x53, 0x54, - 0xc8, 0x28, 0x10, 0x1e, 0x08, 0x71, 0x16, 0xd8, - 0x02, 0x71, 0x41, 0x58, 0xd4, 0x56, 0xcc, 0xf5, - 0xb1, 0x31, 0xa3, 0xed, 0x00, 0x85, 0x09, 0xbf, - 0x35, 0x95, 0x41, 0x29, 0x40, 0x19, 0x83, 0x35, - 0x24, 0x69, 0x02, 0x81, 0x80, 0x55, 0x10, 0x0b, - 0xcc, 0x3b, 0xa9, 0x75, 0x3d, 0x16, 0xe1, 0xae, - 0x50, 0x76, 0x63, 0x94, 0x49, 0x4c, 0xad, 0x10, - 0xcb, 0x47, 0x68, 0x7c, 0xf0, 0xe5, 0xdc, 0xb8, - 0x6a, 0xab, 0x8e, 0xf7, 0x9f, 0x08, 0x2c, 0x1b, - 0x8a, 0xa2, 0xb9, 0x8f, 0xce, 0xec, 0x5e, 0x61, - 0xa8, 0xcd, 0x1c, 0x87, 0x60, 0x4a, 0xc3, 0x1a, - 0x5f, 0xdf, 0x87, 0x26, 0xc6, 0xcb, 0x7c, 0x69, - 0xe4, 0x8b, 0x01, 0x06, 0x59, 0x22, 0xfa, 0x34, - 0x4b, 0x81, 0x87, 0x3c, 0x03, 0x6d, 0x02, 0x0a, - 0x77, 0xe6, 0x15, 0xd8, 0xcf, 0xa7, 0x68, 0x26, - 0x6c, 0xfa, 0x2b, 0xd9, 0x83, 0x5a, 0x2d, 0x0c, - 0x3b, 0x70, 0x1c, 0xd4, 0x48, 0xbe, 0xa7, 0x0a, - 0xd9, 0xbe, 0xdc, 0xc3, 0x0c, 0x21, 0x33, 0xb3, - 0x66, 0xff, 0x1c, 0x1b, 0xc8, 0x96, 0x76, 0xe8, - 0x6f, 0x44, 0x74, 0xbc, 0x9b, 0x1c, 0x7d, 0xc8, - 0xac, 0x21, 0xa8, 0x6e, 0x37, 0x02, 0x81, 0x80, - 0x2c, 0x7c, 0xad, 0x1e, 0x75, 0xf6, 0x69, 0x1d, - 0xe7, 0xa6, 0xca, 0x74, 0x7d, 0x67, 0xc8, 0x65, - 0x28, 0x66, 0xc4, 0x43, 0xa6, 0xbd, 0x40, 0x57, - 0xae, 0xb7, 0x65, 0x2c, 0x52, 0xf9, 0xe4, 0xc7, - 0x81, 0x7b, 0x56, 0xa3, 0xd2, 0x0d, 0xe8, 0x33, - 0x70, 0xcf, 0x06, 0x84, 0xb3, 0x4e, 0x44, 0x50, - 0x75, 0x61, 0x96, 0x86, 0x4b, 0xb6, 0x2b, 0xad, - 0xf0, 0xad, 0x57, 0xd0, 0x37, 0x0d, 0x1d, 0x35, - 0x50, 0xcb, 0x69, 0x22, 0x39, 0x29, 0xb9, 0x3a, - 0xd3, 0x29, 0x23, 0x02, 0x60, 0xf7, 0xab, 0x30, - 0x40, 0xda, 0x8e, 0x4d, 0x45, 0x70, 0x26, 0xf4, - 0xa2, 0x0d, 0xd0, 0x64, 0x5d, 0x47, 0x3c, 0x18, - 0xf4, 0xd4, 0x52, 0x95, 0x00, 0xae, 0x84, 0x6b, - 0x47, 0xb2, 0x3c, 0x82, 0xd3, 0x72, 0x53, 0xde, - 0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, - 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 -}; + } // namespace namespace wvoec_mock { @@ -242,69 +90,6 @@ void SessionKeyTable::UpdateDuration(const KeyControlBlock& control) { } } -void RSA_shared_ptr::reset() { - if (rsa_key_ && key_owned_) { - RSA_free(rsa_key_); - } - key_owned_ = false; - rsa_key_ = NULL; -} - -bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) { - assert(buffer != NULL); - reset(); - key_owned_ = true; - uint8_t* pkcs8_rsa_key = const_cast(buffer); - BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length); - if (bio == NULL) { - LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]"); - return false; - } - bool success = true; - PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); - if (pkcs8_pki == NULL) { - LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]"); - success = false; - } - EVP_PKEY* evp = NULL; - if (success) { - evp = EVP_PKCS82PKEY(pkcs8_pki); - if (evp == NULL) { - LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned NULL]"); - success = false; - } - } - if (success) { - rsa_key_ = EVP_PKEY_get1_RSA(evp); - if (rsa_key_ == NULL) { - LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]"); - success = false; - } - } - if (evp != NULL) { - EVP_PKEY_free(evp); - } - if (pkcs8_pki != NULL) { - PKCS8_PRIV_KEY_INFO_free(pkcs8_pki); - } - BIO_free(bio); - if (!success) { - return false; - } - switch (RSA_check_key(rsa_key_)) { - case 1: // valid. - return true; - case 0: // not valid. - LOGE("[LoadPkcs8RsaKey(): rsa key not valid]"); - dump_openssl_error(); - return false; - default: // -1 == check failed. - LOGE("[LoadPkcs8RsaKey(): error checking rsa key]"); - dump_openssl_error(); - return false; - } -} - SessionContext::~SessionContext() { if (usage_entry_) usage_entry_->set_session(NULL); } @@ -596,13 +381,13 @@ bool SessionContext::CheckNonceOrEntry(const KeyControlBlock& key_control_block, if (!usage_entry_) { usage_entry_ = ce_->usage_table()->FindEntry(pst); if (usage_entry_) { - if (usage_entry_->status() == kInactive) return false; + if (usage_entry_->inactive()) return false; } else { if (!CheckNonce(key_control_block.nonce())) return false; usage_entry_ = ce_->usage_table()->CreateEntry(pst, this); } } else { - if (usage_entry_->status() == kInactive) return false; + if (usage_entry_->inactive()) return false; } break; // Usage table not required. Look at nonce enabled bit. default: @@ -746,7 +531,7 @@ bool SessionContext::InstallKey(const KeyId& key_id, } if ((key_control_block.control_bits() & kControlRequireAntiRollbackHardware) && - !ce_->is_anti_rollback_hw_present()) { + !ce_->config_is_anti_rollback_hw_present()) { LOGE("Anti-rollback hardware is required but hardware not present."); return false; } @@ -988,7 +773,7 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.control_bits() & kControlDataPathSecure) { - if (!ce_->closed_platform()) { + if (!ce_->config_closed_platform()) { LOGE("[Generic_Decrypt(): control bit says secure path only."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1213,18 +998,11 @@ bool SessionContext::IsUsageEntryValid() { void SessionContext::ReleaseUsageEntry() { usage_entry_ = NULL; } -CryptoEngine::CryptoEngine(wvcdm::FileSystem* file_system) - : use_test_keybox_(false), - file_system_(file_system), - usage_table_(new UsageTable(this)) { +CryptoEngine::CryptoEngine(wvcdm::FileSystem* file_system) : + root_of_trust_(config_provisioning_method()), + file_system_(file_system), + usage_table_(new UsageTable(this)) { ERR_load_crypto_strings(); - - if ((provisioning_method() == OEMCrypto_DrmCertificate) && - !rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize)) { - // This error message is OK in unit tests which use test certificate. - LOGE("FATAL ERROR: Platform uses a baked-in certificate instead of a " - "keybox, but the certificate could not be loaded."); - } } CryptoEngine::~CryptoEngine() { @@ -1234,18 +1012,12 @@ CryptoEngine::~CryptoEngine() { void CryptoEngine::Terminate() {} -KeyboxError CryptoEngine::ValidateKeybox() { return keybox().Validate(); } - -bool CryptoEngine::LoadTestRSAKey() { - return rsa_key_.LoadPkcs8RsaKey(kTestRSAPKCS8PrivateKeyInfo2_2048, - sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); -} - SessionId CryptoEngine::CreateSession() { wvcdm::AutoLock lock(session_table_lock_); static int unique_id = 1; SessionId sid = (SessionId)++unique_id; - SessionContext* sctx = new SessionContext(this, sid, rsa_key_); + SessionContext* sctx = new SessionContext(this, sid, + root_of_trust_.SharedRsaKey()); sessions_[sid] = sctx; return sid; } @@ -1313,7 +1085,8 @@ OEMCryptoResult SessionContext::DecryptCENC( } const KeyControlBlock& control = current_content_key()->control(); if (control.control_bits() & kControlDataPathSecure) { - if (!ce_->closed_platform() && buffer_type == OEMCrypto_BufferType_Clear) { + if (!ce_->config_closed_platform() && + buffer_type == OEMCrypto_BufferType_Clear) { LOGE("[DecryptCTR(): Secure key with insecure buffer]"); return OEMCrypto_ERROR_DECRYPT_FAILED; } @@ -1330,16 +1103,16 @@ OEMCryptoResult SessionContext::DecryptCENC( return OEMCrypto_ERROR_UNKNOWN_FAILURE; } } - if (!ce_->local_display()) { // Only look at HDCP if the display is not - // local. + if (!ce_->config_local_display_only()) { + // Only look at HDCP if the display is non-local. if (control.control_bits() & kControlHDCPRequired) { uint8_t required_hdcp = (control.control_bits() & kControlHDCPVersionMask) >> kControlHDCPVersionShift; // For reference implementation, we pretend we can handle the current // HDCP version. - if (required_hdcp > ce_->current_hdcp_capability() || - ce_->current_hdcp_capability() == 0) { + if (required_hdcp > ce_->config_current_hdcp_capability() || + ce_->config_current_hdcp_capability() == 0) { return OEMCrypto_ERROR_INSUFFICIENT_HDCP; } } diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index 684a04d4..8cee1b72 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -15,8 +15,9 @@ #include "OEMCryptoCENC.h" // Needed for enums only. #include "file_store.h" #include "lock.h" +#include "oemcrypto_auth_mock.h" #include "oemcrypto_key_mock.h" -#include "oemcrypto_keybox_mock.h" +#include "oemcrypto_rsa_key_shared.h" #include "wv_cdm_types.h" namespace wvoec_mock { @@ -73,27 +74,6 @@ class NonceTable { uint32_t nonces_[kTableSize]; }; -// Shared pointer with specialized destructor. This pointer is only shared -// from a CryptoEngine to a Session -- so we don't have to use full reference -// counting. -class RSA_shared_ptr { - public: - RSA_shared_ptr() : rsa_key_(NULL), key_owned_(false) {} - ~RSA_shared_ptr() { reset(); }; - // Explicitly allow copy as share. - explicit RSA_shared_ptr(const RSA_shared_ptr& other) : - rsa_key_(other.rsa_key_), key_owned_(false) {} - RSA* get() { return rsa_key_; } - void reset(); - bool LoadPkcs8RsaKey(const uint8_t* buffer, size_t length); - - private: - void operator=(const RSA_shared_ptr); // disallow assign. - - RSA* rsa_key_; - bool key_owned_; -}; - class SessionContext { private: SessionContext() {} @@ -260,14 +240,35 @@ class CryptoEngine { bool Initialized() { return true; } - void Terminate(); + bool ValidRootOfTrust() { return root_of_trust_.Validate(); } - KeyboxError ValidateKeybox(); - WvKeybox& keybox() { return use_test_keybox_ ? test_keybox_ : keybox_; } - WvKeybox& real_keybox() { return keybox_; } - void UseTestKeybox() { use_test_keybox_ = true; } - RSA* rsa_key() { return rsa_key_.get(); } - bool LoadTestRSAKey(); + bool InstallKeybox(const uint8_t* keybox, size_t keybox_length) { + return root_of_trust_.InstallKeybox(keybox, keybox_length); + } + + void UseTestKeybox() { root_of_trust_.UseTestKeybox(); } + + bool LoadTestRsaKey() { return root_of_trust_.LoadTestRsaKey(); } + + KeyboxError ValidateKeybox() { return root_of_trust_.ValidateKeybox(); } + + const std::vector& DeviceRootKey(bool override_to_real = false) { + return root_of_trust_.DeviceKey(override_to_real); + } + + const std::vector& DeviceRootId() { + return root_of_trust_.DeviceId(); + } + + size_t DeviceRootTokenLength() { + return root_of_trust_.DeviceTokenLength(); + } + + const uint8_t* const DeviceRootToken() { + return root_of_trust_.DeviceToken(); + } + + void Terminate(); SessionId CreateSession(); @@ -283,32 +284,31 @@ class CryptoEngine { return kMaxSupportedOEMCryptoSessions; } - OEMCrypto_HDCP_Capability current_hdcp_capability(); - OEMCrypto_HDCP_Capability maximum_hdcp_capability(); + // Configuration constants - controls behavior of this CryptoEngine + OEMCrypto_HDCP_Capability config_current_hdcp_capability(); + OEMCrypto_HDCP_Capability config_maximum_hdcp_capability(); UsageTable* usage_table() { return usage_table_; } wvcdm::FileSystem* file_system() { return file_system_; } - bool local_display(); - bool closed_platform(); - bool supports_storage(); - bool supports_keybox(); - OEMCrypto_ProvisioningMethod provisioning_method(); + + bool config_local_display_only(); + bool config_closed_platform(); + bool config_supports_usage_table(); + bool config_supports_keybox(); + OEMCrypto_ProvisioningMethod config_provisioning_method(); OEMCryptoResult get_oem_certificate(SessionContext* session, uint8_t* public_cert, size_t* public_cert_length); - bool is_anti_rollback_hw_present(); - const char* security_level(); - uint8_t security_patch_level(); + bool config_is_anti_rollback_hw_present(); + const char* config_security_level(); + uint8_t config_security_patch_level(); private: ActiveSessions sessions_; - WvKeybox keybox_; - WvTestKeybox test_keybox_; - bool use_test_keybox_; + AuthenticationRoot root_of_trust_; wvcdm::Lock session_table_lock_; wvcdm::FileSystem* file_system_; UsageTable* usage_table_; - RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate. CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine); }; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp index b163b392..af0c949e 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp @@ -18,7 +18,8 @@ bool KeyControlBlock::Validate() { memcmp(verification_, "kc09", 4) && // add in version 9 api memcmp(verification_, "kc10", 4) && // add in version 10 api memcmp(verification_, "kc11", 4) && // add in version 11 api - memcmp(verification_, "kc12", 4)) { // add in version 12 api + memcmp(verification_, "kc12", 4) && // add in version 11 api + memcmp(verification_, "kc13", 4)) { // add in version 13 api LOGE("KCB: BAD verification string: %4.4s", verification_); valid_ = false; } else { diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 3ebf1f36..d4c82d56 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -149,10 +149,10 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session, LOGE("OEMCrypto_GenerateDerivedKeys: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -169,7 +169,7 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session, enc_ctx_str(enc_key_context, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str, enc_ctx_str)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -305,7 +305,8 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, 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 (!crypto_engine) { LOGE("OEMCrypto_LoadKeys: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -337,7 +338,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, } } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_LoadKeys(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -410,7 +411,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys( return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_RefreshKeys(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -543,7 +544,7 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session, } } #ifndef NDEBUG - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_SelectKey(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -631,7 +632,7 @@ OEMCryptoResult OEMCrypto_DecryptCENC(OEMCrypto_SESSION session, if (sts != OEMCrypto_SUCCESS) return sts; #ifndef NDEBUG - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_DecryptCENC(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -691,7 +692,7 @@ OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox, if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox,\n"); } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } if (!keybox || !wrappedKeybox || !wrappedKeyBoxLength @@ -714,10 +715,10 @@ OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, LOGE("OEMCrypto_InstallKeybox: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - if (crypto_engine->keybox().InstallKeybox(keybox, keyBoxLength)) { + if (crypto_engine->InstallKeybox(keybox, keyBoxLength)) { return OEMCrypto_SUCCESS; } return OEMCrypto_ERROR_WRITE_KEYBOX; @@ -732,7 +733,7 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox() { LOGE("OEMCrypto_LoadTestKeybox: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } crypto_engine->UseTestKeybox(); @@ -748,7 +749,7 @@ OEMCryptoResult OEMCrypto_IsKeyboxValid(void) { LOGE("OEMCrypto_IsKeyboxValid: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } switch(crypto_engine->ValidateKeybox()) { @@ -769,7 +770,7 @@ OEMCrypto_ProvisioningMethod OEMCrypto_GetProvisioningMethod() { LOGE("OEMCrypto_GetProvisioningMethod: OEMCrypto Not Initialized."); return OEMCrypto_ProvisioningError; } - return crypto_engine->provisioning_method(); + return crypto_engine->config_provisioning_method(); } extern "C" @@ -784,10 +785,9 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(OEMCrypto_SESSION session, LOGE("OEMCrypto_GetOEMPublicCertificate: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (crypto_engine->provisioning_method() != OEMCrypto_OEMCertificate) { + if (crypto_engine->config_provisioning_method() != OEMCrypto_OEMCertificate) { LOGE("OEMCrypto_GetOEMPublicCertificate: Provisioning method = %d.", - crypto_engine->provisioning_method() - ); + crypto_engine->config_provisioning_method()); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } SessionContext* session_ctx = crypto_engine->FindSession(session); @@ -809,12 +809,12 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, LOGE("OEMCrypto_GetDeviceID: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } // Devices that do not support a keybox should use some other method to // store the device id. - std::vector dev_id_string = crypto_engine->keybox().device_id(); + const std::vector& dev_id_string = crypto_engine->DeviceRootId(); if (dev_id_string.empty()) { LOGE("[OEMCrypto_GetDeviceId(): Keybox Invalid]"); return OEMCrypto_ERROR_KEYBOX_INVALID; @@ -845,10 +845,10 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, LOGE("OEMCrypto_GetKeyData: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - size_t length = crypto_engine->keybox().key_data_length(); + size_t length = crypto_engine->DeviceRootTokenLength(); if (keyDataLength == NULL) { LOGE("[OEMCrypto_GetKeyData(): null pointer. ERROR_UNKNOWN_FAILURE]"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -863,7 +863,7 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } memset(keyData, 0, *keyDataLength); - memcpy(keyData, crypto_engine->keybox().key_data(), length); + memcpy(keyData, crypto_engine->DeviceRootToken(), length); *keyDataLength = length; if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGD("[OEMCrypto_GetKeyData(): success]"); @@ -924,7 +924,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( return OEMCrypto_ERROR_SHORT_BUFFER; } *wrapped_rsa_key_length = buffer_size; // Tell caller how much space we used. - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -947,7 +947,8 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( if(!session_ctx->InstallRSAEncryptedKey(encrypted_message_key, encrypted_message_key_length)) { - LOGE("OEMCrypto_RewrapDeviceRSAKey30: Error loading encrypted_message_key."); + LOGE("OEMCrypto_RewrapDeviceRSAKey30: " + "Error loading encrypted_message_key."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -959,7 +960,8 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( } size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1]; if (padding > 16) { - LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): Encrypted RSA has bad padding: %d]", + LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): " + "Encrypted RSA has bad padding: %d]", padding); return OEMCrypto_ERROR_INVALID_RSA_KEY; } @@ -984,7 +986,7 @@ extern "C" OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( const std::vector context(wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), context, + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context)) { LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -1043,7 +1045,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, LOGE("OEMCrypto_RewrapDeviceRSAKey: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_keybox()) { + if (!crypto_engine->config_supports_keybox()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } if (wrapped_rsa_key_length == NULL) { @@ -1064,7 +1066,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, return OEMCrypto_ERROR_SHORT_BUFFER; } *wrapped_rsa_key_length = buffer_size; // Tell caller how much space we used. - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_RewrapDeviceRSAKey(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1132,7 +1134,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, const std::vector context(wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), context, + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1174,7 +1176,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, LOGE("OEMCrypto_LoadDeviceRSAKey: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (crypto_engine->provisioning_method() == OEMCrypto_DrmCertificate) { + if (crypto_engine->config_provisioning_method() == OEMCrypto_DrmCertificate) { // If we are using a baked in cert, the "wrapped RSA key" should actually be // the magic value for baked-in certificates. if (wrapped_rsa_key_length != sizeof(kBakedInCertificateMagicBytes) || @@ -1198,7 +1200,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, } } // TODO(fredgc): Don't use the keybox to encrypt the wrapped RSA key. - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1211,7 +1213,7 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, const std::vector context(wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), context, + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1252,7 +1254,7 @@ OEMCryptoResult OEMCrypto_LoadTestRSAKey() { LOGE("OEMCrypto_LoadTestRSAKey: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (crypto_engine->LoadTestRSAKey()) return OEMCrypto_SUCCESS; + if (crypto_engine->LoadTestRsaKey()) return OEMCrypto_SUCCESS; return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1337,7 +1339,7 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( LOGE("OEMCrypto_DeriveKeysFromSessionKey: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1379,12 +1381,12 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( extern "C" uint32_t OEMCrypto_APIVersion() { - return 12; + return 13; } extern "C" uint8_t OEMCrypto_Security_Patch_Level() { - uint8_t security_patch_level = crypto_engine->security_patch_level(); + uint8_t security_patch_level = crypto_engine->config_security_patch_level(); if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- uint8_t OEMCrypto_Security_Patch_Level(); // returns %d.\n", security_patch_level); @@ -1394,7 +1396,7 @@ uint8_t OEMCrypto_Security_Patch_Level() { extern "C" const char* OEMCrypto_SecurityLevel() { - const char* security_level = crypto_engine->security_level(); + const char* security_level = crypto_engine->config_security_level(); if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- const char* OEMCrypto_SecurityLevel(); // returns %s.\n", security_level); } @@ -1415,14 +1417,14 @@ OEMCryptoResult OEMCrypto_GetHDCPCapability( } if (current == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - *current = crypto_engine->current_hdcp_capability(); - *maximum = crypto_engine->maximum_hdcp_capability(); + *current = crypto_engine->config_current_hdcp_capability(); + *maximum = crypto_engine->config_maximum_hdcp_capability(); return OEMCrypto_SUCCESS; } extern "C" bool OEMCrypto_SupportsUsageTable() { - bool supports_usage = crypto_engine->supports_storage(); + bool supports_usage = crypto_engine->config_supports_usage_table(); if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- bool OEMCrypto_SupportsUsageTable(); // returns %s.\n", (supports_usage ? "true" : "false")); @@ -1460,7 +1462,8 @@ OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t* maximum) { extern "C" bool OEMCrypto_IsAntiRollbackHwPresent() { - bool anti_rollback_hw_present = crypto_engine->is_anti_rollback_hw_present(); + bool anti_rollback_hw_present = + crypto_engine->config_is_anti_rollback_hw_present(); if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- bool OEMCrypto_IsAntiRollbackHwPresent(): %d\n", @@ -1469,6 +1472,12 @@ bool OEMCrypto_IsAntiRollbackHwPresent() { return anti_rollback_hw_present; } +extern "C" +uint32_t OEMCrypto_SupportedCertificates() { + return OEMCrypto_Supports_RSA_2048bit | OEMCrypto_Supports_RSA_3072bit + | OEMCrypto_Supports_RSA_CAST; +} + extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, const uint8_t* in_buffer, @@ -1488,7 +1497,7 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, LOGE("OEMCrypto_Generic_Encrypt: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_Generic_Encrypt(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1532,7 +1541,7 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, LOGE("OEMCrypto_Generic_Decrypt: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1575,7 +1584,7 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, LOGE("OEMCrypto_Generic_Sign: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_Generic_Sign(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1622,7 +1631,7 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, LOGE("OEMCrypto_Generic_Verify: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (NO_ERROR != crypto_engine->ValidateKeybox()) { + if (!crypto_engine->ValidRootOfTrust()) { LOGE("[OEMCrypto_Generic_Verify(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; } @@ -1651,14 +1660,15 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable() { LOGE("OEMCrypto_UpdateUsageTable: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } return crypto_engine->usage_table()->UpdateTable(); } extern "C" -OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, +OEMCryptoResult OEMCrypto_DeactivateUsageEntry(OEMCrypto_SESSION session, + const uint8_t *pst, size_t pst_length) { if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- OEMCryptoResult OEMCrypto_DeactivateUsageEntry(\n"); @@ -1670,7 +1680,7 @@ OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst, LOGE("OEMCrypto_DeactivateUsageEntry: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } std::vector pstv(pst, pst + pst_length); @@ -1681,7 +1691,7 @@ 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 (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { LOGI("-- OEMCryptoResult OEMCrypto_ReportUsage(\n"); @@ -1693,7 +1703,7 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, LOGE("OEMCrypto_ReportUsage: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } SessionContext* session_ctx = crypto_engine->FindSession(session); @@ -1712,8 +1722,7 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, crypto_engine->usage_table()->UpdateTable(); if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) { - dump_hex("usage buffer", reinterpret_cast(buffer), - *buffer_length); + dump_hex("usage buffer", buffer, *buffer_length); } } return sts; @@ -1739,7 +1748,7 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, LOGE("OEMCrypto_DeleteUsageEntry: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } SessionContext* session_ctx = crypto_engine->FindSession(session); @@ -1782,7 +1791,7 @@ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, LOGE("OEMCrypto_ForceDeleteUsageEntry: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } std::vector pstv(pst, pst + pst_length); @@ -1793,15 +1802,15 @@ OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, } extern "C" -OEMCryptoResult OEMCrypto_DeleteUsageTable() { +OEMCryptoResult OEMCrypto_DeleteOldUsageTable() { if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { - LOGI("-- OEMCryptoResult OEMCrypto_DeleteUsageTable()\n"); + LOGI("-- OEMCryptoResult OEMCrypto_DeleteOldUsageTable()\n"); } if (!crypto_engine) { - LOGE("OEMCrypto_DeleteUsageTable: OEMCrypto Not Initialized."); + LOGE("OEMCrypto_DeleteOldUsageTable: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - if (!crypto_engine->supports_storage()) { + if (!crypto_engine->config_supports_usage_table()) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; } crypto_engine->usage_table()->Clear(); @@ -1809,4 +1818,79 @@ OEMCryptoResult OEMCrypto_DeleteUsageTable() { return OEMCrypto_SUCCESS; } +extern "C" +bool OEMCrypto_IsSRMUpdateSupported() { + return false; +} + +extern "C" +OEMCryptoResult OEMCrypto_GetCurrentSRMVersion(uint16_t* version) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, + size_t buffer_length) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_RemoveSRM() { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_CreateUsageTableHeader() { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_LoadUsageTableHeader(const uint8_t* buffer, + size_t buffer_length) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_CreateNewUsageEntry(OEMCrypto_SESSION session, + uint32_t *usage_entry_number) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_LoadUsageEntry(OEMCrypto_SESSION session, + uint32_t index, + const uint8_t *buffer, + size_t buffer_size) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +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; +} + +extern "C" +OEMCryptoResult OEMCrypto_ShrinkUsageTableHeader(uint32_t new_table_size, + uint8_t* header_buffer, + size_t* header_buffer_length) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_MoveEntry(OEMCrypto_SESSION session, + uint32_t new_index) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + +extern "C" +OEMCryptoResult OEMCrypto_CopyOldUsageEntry(OEMCrypto_SESSION session, + const uint8_t* pst, + size_t pst_length) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; +} + } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp new file mode 100644 index 00000000..e5b07118 --- /dev/null +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.cpp @@ -0,0 +1,94 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Mock implementation of OEMCrypto APIs +// +#include "oemcrypto_rsa_key_shared.h" + +#include + +#include +#include +#include +#include +#include + +#include "oemcrypto_logging.h" + +namespace { + +void dump_openssl_error() { + while (unsigned long err = ERR_get_error()) { + char buffer[120]; + LOGE("openssl error -- %lu -- %s", + err, ERR_error_string(err, buffer)); + } +} + +} // namespace + +namespace wvoec_mock { + +void RSA_shared_ptr::reset() { + if (rsa_key_ && key_owned_) { + RSA_free(rsa_key_); + } + key_owned_ = false; + rsa_key_ = NULL; +} + +bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) { + assert(buffer != NULL); + reset(); + uint8_t* pkcs8_rsa_key = const_cast(buffer); + BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length); + if (bio == NULL) { + LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]"); + return false; + } + bool success = true; + PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); + if (pkcs8_pki == NULL) { + LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned NULL]"); + success = false; + } + EVP_PKEY* evp = NULL; + if (success) { + evp = EVP_PKCS82PKEY(pkcs8_pki); + if (evp == NULL) { + LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned NULL]"); + success = false; + } + } + if (success) { + rsa_key_ = EVP_PKEY_get1_RSA(evp); + if (rsa_key_ == NULL) { + LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]"); + success = false; + } + key_owned_ = true; + } + if (evp != NULL) { + EVP_PKEY_free(evp); + } + if (pkcs8_pki != NULL) { + PKCS8_PRIV_KEY_INFO_free(pkcs8_pki); + } + BIO_free(bio); + if (!success) { + return false; + } + switch (RSA_check_key(rsa_key_)) { + case 1: // valid. + return true; + case 0: // not valid. + LOGE("[LoadPkcs8RsaKey(): rsa key not valid]"); + dump_openssl_error(); + return false; + default: // -1 == check failed. + LOGE("[LoadPkcs8RsaKey(): error checking rsa key]"); + dump_openssl_error(); + return false; + } +} + +} // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.h new file mode 100644 index 00000000..4a815e99 --- /dev/null +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_rsa_key_shared.h @@ -0,0 +1,37 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Mock implementation of OEMCrypto APIs +// +#ifndef OEMCRYPTO_RSA_KEY_SHARED_H_ +#define OEMCRYPTO_RSA_KEY_SHARED_H_ + +#include + +#include + +namespace wvoec_mock { + +// Shared pointer with specialized destructor. This pointer is only shared +// from a CryptoEngine to a Session -- so we don't have to use full reference +// counting. +class RSA_shared_ptr { + public: + RSA_shared_ptr() : rsa_key_(NULL), key_owned_(false) {} + ~RSA_shared_ptr() { reset(); }; + // Explicitly allow copy as share. + explicit RSA_shared_ptr(const RSA_shared_ptr& other) : + rsa_key_(other.rsa_key_), key_owned_(false) {} + RSA* get() { return rsa_key_; } + void reset(); + bool LoadPkcs8RsaKey(const uint8_t* buffer, size_t length); + + private: + void operator=(const RSA_shared_ptr); // disallow assign. + + RSA* rsa_key_; + bool key_owned_; +}; + +} // namespace wvoec_mock + +#endif // OEMCRYPTO_RSA_KEY_SHARED_H_ diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp index d0fd6154..ee27f61b 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.cpp @@ -20,6 +20,7 @@ #include "oemcrypto_engine_mock.h" #include "oemcrypto_logging.h" #include "properties.h" +#include "pst_report.h" #include "string_conversions.h" #include "wv_cdm_constants.h" @@ -66,7 +67,11 @@ void UsageTableEntry::SaveToBuffer(StoredUsageEntry *buffer) { } void UsageTableEntry::Deactivate() { - status_ = kInactive; + if (status_ == kUnused) { + status_ = kInactiveUnused; + } else if (status_ == kActive) { + status_ = kInactiveUsed; + } if (session_) { session_->ReleaseUsageEntry(); session_ = NULL; @@ -85,6 +90,8 @@ bool UsageTableEntry::UpdateTime() { time_of_last_decrypt_ = now; return true; case kInactive: + case kInactiveUsed: + case kInactiveUnused: return false; } return false; @@ -92,9 +99,9 @@ bool UsageTableEntry::UpdateTime() { OEMCryptoResult UsageTableEntry::ReportUsage(SessionContext *session, const std::vector &pst, - OEMCrypto_PST_Report *buffer, + uint8_t *buffer, size_t *buffer_length) { - size_t length_needed = sizeof(OEMCrypto_PST_Report) + pst.size(); + size_t length_needed = wvcdm::Unpacked_PST_Report::report_size(pst.size()); if (*buffer_length < length_needed) { *buffer_length = length_needed; return OEMCrypto_ERROR_SHORT_BUFFER; @@ -103,21 +110,19 @@ OEMCryptoResult UsageTableEntry::ReportUsage(SessionContext *session, LOGE("ReportUsage: buffer was null pointer."); return OEMCrypto_ERROR_INVALID_CONTEXT; } + wvcdm::Unpacked_PST_Report pst_report(buffer); int64_t now = time(NULL); - buffer->seconds_since_license_received = - wvcdm::htonll64(now - time_of_license_received_); - buffer->seconds_since_first_decrypt = - wvcdm::htonll64(now - time_of_first_decrypt_); - buffer->seconds_since_last_decrypt = - wvcdm::htonll64(now - time_of_last_decrypt_); - buffer->status = status_; - buffer->clock_security_level = kSecureTimer; - buffer->pst_length = static_cast(pst.size()); - memcpy(buffer->pst, &pst[0], length_needed - sizeof(OEMCrypto_PST_Report)); - unsigned int md_len = sizeof(buffer->signature); + pst_report.set_seconds_since_license_received(now - time_of_license_received_); + pst_report.set_seconds_since_first_decrypt(now - time_of_first_decrypt_); + pst_report.set_seconds_since_last_decrypt(now - time_of_last_decrypt_); + pst_report.set_status(status_); + pst_report.set_clock_security_level(kSecureTimer); + pst_report.set_pst_length(static_cast(pst.size())); + memcpy(pst_report.pst(), &pst[0], pst.size()); + unsigned int md_len = SHA_DIGEST_LENGTH; if (!HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(), - reinterpret_cast(buffer) + SHA_DIGEST_LENGTH, - length_needed - SHA_DIGEST_LENGTH, buffer->signature, &md_len)) { + buffer + SHA_DIGEST_LENGTH, length_needed - SHA_DIGEST_LENGTH, + pst_report.signature(), &md_len)) { LOGE("UsageTableEntry: could not compute signature."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -179,8 +184,13 @@ UsageTable::UsageTable(CryptoEngine *ce) { file->Read(reinterpret_cast(&encrypted_buffer[0]), file_size); file->Close(); - // First, verify the signature of the usage table file. - std::vector &key = ce_->real_keybox().device_key(); + // Verify the signature of the usage table file. + + // This should be encrypted and signed with a device specific key. + // For the reference implementation, I'm just going to use the keybox key. + const bool override_to_real = true; + const std::vector &key = ce_->DeviceRootKey(override_to_real); + uint8_t computed_signature[SHA256_DIGEST_LENGTH]; unsigned int sig_length = sizeof(computed_signature); if (!HMAC(EVP_sha256(), &key[0], key.size(), @@ -276,7 +286,8 @@ bool UsageTable::SaveToFile() { // This should be encrypted and signed with a device specific key. // For the reference implementation, I'm just going to use the keybox key. - std::vector &key = ce_->real_keybox().device_key(); + const bool override_to_real = true; + const std::vector &key = ce_->DeviceRootKey(override_to_real); // Encrypt the table. RAND_bytes(encrypted_table->iv, wvcdm::KEY_IV_SIZE); diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h index 093c6e61..03c0f8e2 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_usage_table_mock.h @@ -50,11 +50,12 @@ class UsageTableEntry { ~UsageTableEntry(); void SaveToBuffer(StoredUsageEntry *buffer); OEMCrypto_Usage_Entry_Status status() const { return status_; } + bool inactive() const { return status_ >= kInactive; } void Deactivate(); bool UpdateTime(); OEMCryptoResult ReportUsage(SessionContext *session, const std::vector &pst, - OEMCrypto_PST_Report *buffer, + uint8_t *buffer, size_t *buffer_length); // Set them if not set, verify if already set. bool VerifyOrSetMacKeys(const std::vector &server, diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index f6c0f72f..9657c34f 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -222,7 +222,8 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) { &signature_[0], signature_.size(), encrypted_license().mac_key_iv, encrypted_license().mac_keys, num_keys_, - key_array_, pst_ptr, pst.length())); + key_array_, pst_ptr, pst.length(), + NULL)); // Update new generated keys. memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE); memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE, @@ -231,7 +232,8 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_, &signature_[0], signature_.size(), NULL, NULL, - num_keys_, key_array_, pst_ptr, pst.length())); + num_keys_, key_array_, pst_ptr, pst.length(), + NULL)); } VerifyTestKeys(); } @@ -817,17 +819,17 @@ void Session::GenerateReport(const std::string& pst, bool expect_success, size_t length = 0; OEMCryptoResult sts = OEMCrypto_ReportUsage( session_id(), reinterpret_cast(pst.c_str()), pst.length(), - pst_report(), &length); + &pst_report_buffer_[0], &length); if (expect_success) { ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); } if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - ASSERT_LE(sizeof(OEMCrypto_PST_Report), length); + ASSERT_EQ(wvcdm::Unpacked_PST_Report::report_size(pst.length()), length); pst_report_buffer_.resize(length); } sts = OEMCrypto_ReportUsage(session_id(), reinterpret_cast(pst.c_str()), - pst.length(), pst_report(), &length); + pst.length(), &pst_report_buffer_[0], &length); if (!expect_success) { ASSERT_NE(OEMCrypto_SUCCESS, sts); return; @@ -836,18 +838,14 @@ void Session::GenerateReport(const std::string& pst, bool expect_success, vector computed_signature(SHA_DIGEST_LENGTH); unsigned int sig_len = SHA_DIGEST_LENGTH; HMAC(EVP_sha1(), &mac_key_client_[0], mac_key_client_.size(), - reinterpret_cast(pst_report()) + SHA_DIGEST_LENGTH, + &pst_report_buffer_[SHA_DIGEST_LENGTH], length - SHA_DIGEST_LENGTH, &computed_signature[0], &sig_len); - EXPECT_EQ(0, memcmp(&computed_signature[0], pst_report()->signature, + EXPECT_EQ(0, memcmp(&computed_signature[0], pst_report().signature(), SHA_DIGEST_LENGTH)); - EXPECT_GE(kInactive, pst_report()->status); - EXPECT_GE(kHardwareSecureClock, pst_report()->clock_security_level); - EXPECT_EQ(pst.length(), pst_report()->pst_length); - EXPECT_EQ(0, memcmp(pst.c_str(), pst_report()->pst, pst.length())); -} - -OEMCrypto_PST_Report* Session::pst_report() { - return reinterpret_cast(&pst_report_buffer_[0]); + EXPECT_GE(kInactiveUnused, pst_report().status()); + EXPECT_GE(kHardwareSecureClock, pst_report().clock_security_level()); + EXPECT_EQ(pst.length(), pst_report().pst_length()); + EXPECT_EQ(0, memcmp(pst.c_str(), pst_report().pst(), pst.length())); } void Session::DeleteEntry(const std::string& pst) { diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index 2b5fc720..285bd64a 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -10,6 +10,7 @@ #include #include "oec_device_features.h" +#include "pst_report.h" #include "wv_cdm_constants.h" using namespace std; @@ -253,9 +254,11 @@ class Session { // order to verify signatures. void GenerateReport(const std::string& pst, bool expect_success = true, Session* other = 0); - // Returns a pointer to the usage report generated by the previous call to - // GenerateReport. - OEMCrypto_PST_Report* pst_report(); + // Returns a pointer-like thing to the usage report generated by the previous + // call to GenerateReport. + wvcdm::Unpacked_PST_Report pst_report() { + return wvcdm::Unpacked_PST_Report(&pst_report_buffer_[0]); + } // Creates a signed delete usage table entry message and calls // OEMCrypto_DeleteUsageEntry on it. void DeleteEntry(const std::string& pst); diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 73eb96a7..68c944c6 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -90,7 +90,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) { cout << " OEMCrypto does not support usage tables." << endl; } ASSERT_GE(version, 8u); - ASSERT_LE(version, 12u); + ASSERT_LE(version, 13u); } TEST_F(OEMCryptoClientTest, ProvisioningDeclaredAPI12) { @@ -592,7 +592,7 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest { virtual void SetUp() { OEMCryptoClientTest::SetUp(); EnsureTestKeys(); - if (global_features.usage_table) OEMCrypto_DeleteUsageTable(); + if (global_features.usage_table) OEMCrypto_DeleteOldUsageTable(); } void EnsureTestKeys() { @@ -938,7 +938,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) { s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, &mac_keys[0], // Not pointing into buffer. - s.num_keys(), s.key_array(), NULL, 0); + s.num_keys(), s.key_array(), NULL, 0, NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -956,7 +956,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) { s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), &mac_key_iv[0], // bad. - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -974,7 +975,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -993,7 +995,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1010,7 +1013,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1029,7 +1033,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange6) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1048,7 +1053,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1063,7 +1069,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1088,7 +1095,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1103,26 +1111,58 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } -TEST_F(OEMCryptoSessionTests, LoadKeyWithFutureVerification) { +// This tests each key control block verification string in the range kc09-kc1?. +class SessionTestAlternateVerification : public OEMCryptoSessionTests, + public WithParamInterface { + public: + virtual void SetUp() { + OEMCryptoSessionTests::SetUp(); + target_api_ = GetParam(); + } + protected: + int target_api_; +}; + +TEST_P(SessionTestAlternateVerification, LoadKeys) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); - // OEMCrypto should reject API13 until the spec has been defined. - memcpy(s.license().keys[1].control.verification, "kc13", 4); + char buffer[5] = "kctl"; // This is the default verification string, required + // for all API versions. + if (target_api_ > 8 && target_api_ < 100) { + snprintf(buffer, 5, "kc%02d", target_api_); + } + for(int i=0; i < s.num_keys(); i++) { + memcpy(s.license().keys[i].control.verification, buffer, 4); + } ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); + // If this is a future API, then LoadKeys should fail. + if (global_features.api_version < target_api_) { + ASSERT_NE(OEMCrypto_SUCCESS, sts); + } else { + // Otherwise, LoadKeys should succeed. + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + } } +// Range of API versions to test. This should start at 8, and go to +// the current API + 2. We use +2 because we want to test at least 1 +// future API, and the ::testing::Range is not inclusive. +INSTANTIATE_TEST_CASE_P(TestAll, SessionTestAlternateVerification, + Range(8, 12 + 2)); + TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -1133,7 +1173,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1146,7 +1187,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1163,7 +1205,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeys) { OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), NULL, NULL, - kNoKeys, s.key_array(), NULL, 0)); + kNoKeys, s.key_array(), NULL, 0, + NULL)); } TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) { @@ -1178,7 +1221,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) { OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), NULL, NULL, - kNoKeys, s.key_array(), NULL, 0)); + kNoKeys, s.key_array(), NULL, 0, + NULL)); } TEST_F(OEMCryptoSessionTests, QueryKeyControl) { @@ -1218,7 +1262,8 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); if (OEMCrypto_IsAntiRollbackHwPresent()) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } else { @@ -1241,7 +1286,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), NULL, 0)); + s.key_array(), NULL, 0, + NULL)); if (patch_level < 0x3F) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); @@ -1256,7 +1302,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), NULL, 0)); + s.key_array(), NULL, 0, + NULL)); } if (patch_level > 0) { Session s; @@ -1272,7 +1319,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), NULL, 0)); + s.key_array(), NULL, 0, + NULL)); } } @@ -4250,7 +4298,7 @@ class UsageTableTest : public GenericCryptoTest { void DeactivatePST(const std::string& pst) { ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_DeactivateUsageEntry( + OEMCrypto_DeactivateUsageEntry(0, reinterpret_cast(pst.c_str()), pst.length())); } @@ -4264,9 +4312,9 @@ class UsageTableTest : public GenericCryptoTest { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); s.GenerateReport(pst); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -4303,27 +4351,6 @@ class UsageTableTestWithMAC : public UsageTableTest, } }; -TEST_F(UsageTableTest, PSTReportSizes) { - OEMCrypto_PST_Report report; - uint8_t* location = reinterpret_cast(&report); - EXPECT_EQ(48u, sizeof(report)); - uint8_t* field; - field = reinterpret_cast(&report.status); - EXPECT_EQ(20, field - location); - field = reinterpret_cast(&report.clock_security_level); - EXPECT_EQ(21, field - location); - field = reinterpret_cast(&report.pst_length); - EXPECT_EQ(22, field - location); - field = reinterpret_cast(&report.seconds_since_license_received); - EXPECT_EQ(24, field - location); - field = reinterpret_cast(&report.seconds_since_first_decrypt); - EXPECT_EQ(32, field - location); - field = reinterpret_cast(&report.seconds_since_last_decrypt); - EXPECT_EQ(40, field - location); - field = reinterpret_cast(&report.pst); - EXPECT_EQ(48, field - location); -} - TEST_P(UsageTableTestWithMAC, OnlineLicense) { std::string pst = "my_pst"; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); @@ -4341,25 +4368,22 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) { s.GenerateReport(pst); // test repeated report generation s.GenerateReport(pst); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); - EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_EQ(kUnused, s.pst_report().status()); + EXPECT_NEAR(0, s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); s.GenerateReport(pst); - EXPECT_EQ(kActive, s.pst_report()->status); - EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_EQ(kActive, s.pst_report().status()); + EXPECT_NEAR(0, s.pst_report().seconds_since_license_received(), kTimeTolerance); - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); - EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_EQ(kInactiveUsed, s.pst_report().status()); + EXPECT_NEAR(0, s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); @@ -4388,17 +4412,17 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) { s.get_nonce(), OEMCrypto_SUCCESS)); s.GenerateReport(pst); time_t report_generated = time(NULL); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); // license received at LoadKeys, not at RefreshKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); // First decrypt was just after LoadKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); // Last decrypt just before report generated. - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); } @@ -4427,7 +4451,8 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), pst_ptr, pst.length())); + s.key_array(), pst_ptr, pst.length(), + NULL)); ASSERT_NO_FATAL_FAILURE(s2.close()); } @@ -4444,7 +4469,8 @@ TEST_F(UsageTableTest, OnlineEmptyPST) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -4462,7 +4488,7 @@ TEST_F(UsageTableTest, EmptyTable) { ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); s.GenerateReport(pst); ASSERT_NO_FATAL_FAILURE(s.close()); - OEMCrypto_DeleteUsageTable(); + OEMCrypto_DeleteOldUsageTable(); Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); s2.GenerateReport(pst, false); @@ -4505,7 +4531,7 @@ TEST_F(UsageTableTest, FiftyEntries) { char c = 'A' + i; pst = pst + c; s.GenerateReport(pst, true, &sessions[i]); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s.close()); } sleep(kShortSleep); @@ -4532,14 +4558,14 @@ TEST_F(UsageTableTest, FiftyEntries) { char c = 'A' + i; pst = pst + c; s.GenerateReport(pst, true, &sessions[i]); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s.close()); } ASSERT_NO_FATAL_FAILURE(s1.close()); ASSERT_NO_FATAL_FAILURE( s1.open()); // Make sure s1's entry is still in the table. s1.GenerateReport(pst1); - EXPECT_EQ(kUnused, s1.pst_report()->status); + EXPECT_EQ(kUnused, s1.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s1.close()); } @@ -4561,7 +4587,7 @@ TEST_P(UsageTableTestWithMAC, DeleteUnusedEntry) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); s2.GenerateReport(pst, true, &s); - EXPECT_EQ(kUnused, s2.pst_report()->status); + EXPECT_EQ(kUnused, s2.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s2.DeleteEntry(pst)); ASSERT_NO_FATAL_FAILURE(s2.close()); @@ -4591,7 +4617,7 @@ TEST_P(UsageTableTestWithMAC, DeleteActiveEntry) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); ASSERT_NO_FATAL_FAILURE(s2.GenerateReport(pst, true, &s)); - EXPECT_EQ(kActive, s2.pst_report()->status); + EXPECT_EQ(kActive, s2.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s2.DeleteEntry(pst)); ASSERT_NO_FATAL_FAILURE(s2.close()); @@ -4646,7 +4672,7 @@ TEST_P(UsageTableTestWithMAC, DeleteInactiveEntry) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); s2.GenerateReport(pst, true, &s); - EXPECT_EQ(kInactive, s2.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s2.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s2.DeleteEntry(pst)); ASSERT_NO_FATAL_FAILURE(s2.close()); @@ -4690,7 +4716,7 @@ TEST_P(UsageTableTestWithMAC, DeleteEntryBadSignature) { Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); s3.GenerateReport(pst, true, &s); - EXPECT_EQ(kUnused, s3.pst_report()->status); + EXPECT_EQ(kUnused, s3.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s3.close()); } @@ -4728,7 +4754,7 @@ TEST_P(UsageTableTestWithMAC, DeleteEntryWrongSession) { Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); s3.GenerateReport(pst, true, &s); - EXPECT_EQ(kUnused, s3.pst_report()->status); + EXPECT_EQ(kUnused, s3.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s3.close()); } @@ -4766,18 +4792,18 @@ TEST_P(UsageTableTestWithMAC, DeleteEntryBadRange) { Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); s3.GenerateReport(pst, true, &s); - EXPECT_EQ(kUnused, s3.pst_report()->status); + EXPECT_EQ(kUnused, s3.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s3.close()); } TEST_P(UsageTableTestWithMAC, DeactivateBadPST) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); std::string pst = "nonexistant pst"; - OEMCryptoResult sts = OEMCrypto_DeactivateUsageEntry( + OEMCryptoResult sts = OEMCrypto_DeactivateUsageEntry(0, reinterpret_cast(pst.c_str()), pst.length()); EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); std::string null_pst = ""; - sts = OEMCrypto_DeactivateUsageEntry( + sts = OEMCrypto_DeactivateUsageEntry(0, reinterpret_cast(null_pst.c_str()), null_pst.length()); EXPECT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts); } @@ -4806,22 +4832,18 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); EXPECT_EQ(expected_encrypted, encrypted); session_.GenerateReport(pst); - EXPECT_EQ(kActive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_first_decrypt), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_last_decrypt), - kTimeTolerance); + EXPECT_EQ(kActive, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_first_decrypt(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_last_decrypt(), + kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); + EXPECT_EQ(kInactiveUsed, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); encrypted.assign(clear_buffer_.size(), 0); sts = OEMCrypto_Generic_Encrypt( session_.session_id(), &clear_buffer_[0], clear_buffer_.size(), iv_, @@ -4854,22 +4876,18 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); EXPECT_EQ(clear_buffer_, resultant); session_.GenerateReport(pst); - EXPECT_EQ(kActive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_first_decrypt), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_last_decrypt), - kTimeTolerance); + EXPECT_EQ(kActive, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_first_decrypt(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_last_decrypt(), + kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); session_.GenerateReport(pst); - EXPECT_EQ(kInactive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); + EXPECT_EQ(kInactiveUsed, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); resultant.assign(encrypted.size(), 0); sts = OEMCrypto_Generic_Decrypt( session_.session_id(), &encrypted[0], encrypted.size(), iv_, @@ -4911,22 +4929,18 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) { ASSERT_EQ(expected_signature, signature); session_.GenerateReport(pst); - EXPECT_EQ(kActive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_first_decrypt), - kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_last_decrypt), - kTimeTolerance); + EXPECT_EQ(kActive, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_first_decrypt(), + kTimeTolerance); + EXPECT_NEAR(0, session_.pst_report().seconds_since_last_decrypt(), + kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), - kTimeTolerance); + EXPECT_EQ(kInactiveUsed, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), + kTimeTolerance); signature.assign(SHA256_DIGEST_LENGTH, 0); gen_signature_length = SHA256_DIGEST_LENGTH; @@ -4962,21 +4976,18 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); session_.GenerateReport(pst); - EXPECT_EQ(kActive, session_.pst_report()->status); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), + EXPECT_EQ(kActive, session_.pst_report().status()); + EXPECT_NEAR(0, session_.pst_report().seconds_since_license_received(), kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_first_decrypt), + EXPECT_NEAR(0, session_.pst_report().seconds_since_first_decrypt(), kTimeTolerance); - EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, session_.pst_report().seconds_since_last_decrypt(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(session_.GenerateReport(pst)); - EXPECT_EQ(kInactive, session_.pst_report()->status); + EXPECT_EQ(kInactiveUsed, session_.pst_report().status()); EXPECT_NEAR( - 0, wvcdm::htonll64(session_.pst_report()->seconds_since_license_received), + 0, session_.pst_report().seconds_since_license_received(), kTimeTolerance); sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0], @@ -5012,17 +5023,17 @@ TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) { kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS)); s.GenerateReport(pst); time_t report_generated = time(NULL); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); // license received at LoadKeys, not at RefreshKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); // First decrypt was just after LoadKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); // Last decrypt just before report generated. - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); } @@ -5039,19 +5050,19 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicense) { ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); s.GenerateReport(pst); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); s.GenerateReport(pst); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5070,42 +5081,42 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithRefresh) { ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); s.GenerateReport(pst); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); time_t decrypt_time = time(NULL); s.GenerateReport(pst); time_t report_generated = time(NULL); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); // license received at first LoadKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); // First decrypt was just after second LoadKeys. EXPECT_NEAR(report_generated - decrypt_time, - wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); EXPECT_NEAR(report_generated - decrypt_time, - wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); size_t kAllKeys = 1; ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys( kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS)); s.GenerateReport(pst); report_generated = time(NULL); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); // license received at LoadKeys, not at RefreshKeys. EXPECT_NEAR(report_generated - loaded, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); // First decrypt was just after LoadKeys. EXPECT_NEAR(report_generated - decrypt_time, - wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + s.pst_report().seconds_since_first_decrypt(), kTimeTolerance); // Last decrypt just before report generated. - EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(0, s.pst_report().seconds_since_last_decrypt(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5130,7 +5141,8 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { &s2.signature()[0], s2.signature().size(), s2.encrypted_license().mac_key_iv, s2.encrypted_license().mac_keys, s.num_keys(), - s2.key_array(), pst_ptr, pst.length())); + s2.key_array(), pst_ptr, pst.length(), + NULL)); ASSERT_NO_FATAL_FAILURE(s2.close()); // Offline license with same mac keys should still be OK. @@ -5138,7 +5150,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_EQ(kUnused, s.pst_report().status()); } // An offline license should not load on the first call if the nonce is bad. @@ -5156,7 +5168,8 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) { s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), pst_ptr, - pst.length()); + pst.length(), + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5173,7 +5186,8 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) { OEMCryptoResult sts = OEMCrypto_LoadKeys( s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0); + s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0, + NULL); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5194,9 +5208,9 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); s.GenerateReport(pst); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report().status()); EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.close()); @@ -5211,12 +5225,13 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), pst_ptr, pst.length())); + s.key_array(), pst_ptr, pst.length(), + NULL)); // But we can still generate a report. Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); s3.GenerateReport(pst, true, &s); - EXPECT_EQ(kInactive, s3.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s3.pst_report().status()); } TEST_P(UsageTableTestWithMAC, BadRange) { @@ -5235,7 +5250,8 @@ TEST_P(UsageTableTestWithMAC, BadRange) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), pst_ptr, pst.length())); + s.key_array(), pst_ptr, pst.length(), + NULL)); } TEST_F(UsageTableTest, TimingTest) { @@ -5307,31 +5323,31 @@ TEST_F(UsageTableTest, TimingTest) { time_t report_generated3 = time(NULL); s3.GenerateReport(pst3); - EXPECT_EQ(kInactive, s1.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s1.pst_report().status()); EXPECT_NEAR(report_generated1 - loaded1, - wvcdm::htonll64(s1.pst_report()->seconds_since_license_received), + s1.pst_report().seconds_since_license_received(), kTimeTolerance); EXPECT_NEAR(report_generated1 - first_decrypt1, - wvcdm::htonll64(s1.pst_report()->seconds_since_first_decrypt), + s1.pst_report().seconds_since_first_decrypt(), kTimeTolerance); EXPECT_NEAR(report_generated1 - second_decrypt, - wvcdm::htonll64(s1.pst_report()->seconds_since_last_decrypt), + s1.pst_report().seconds_since_last_decrypt(), kTimeTolerance); - EXPECT_EQ(kActive, s2.pst_report()->status); + EXPECT_EQ(kActive, s2.pst_report().status()); EXPECT_NEAR(report_generated2 - loaded2, - wvcdm::htonll64(s2.pst_report()->seconds_since_license_received), + s2.pst_report().seconds_since_license_received(), kTimeTolerance); EXPECT_NEAR(report_generated2 - first_decrypt2, - wvcdm::htonll64(s2.pst_report()->seconds_since_first_decrypt), + s2.pst_report().seconds_since_first_decrypt(), kTimeTolerance); EXPECT_NEAR(report_generated2 - third_decrypt, - wvcdm::htonll64(s2.pst_report()->seconds_since_last_decrypt), + s2.pst_report().seconds_since_last_decrypt(), kTimeTolerance); - EXPECT_EQ(kUnused, s3.pst_report()->status); + EXPECT_EQ(kUnused, s3.pst_report().status()); EXPECT_NEAR(report_generated3 - loaded3, - wvcdm::htonll64(s3.pst_report()->seconds_since_license_received), + s3.pst_report().seconds_since_license_received(), kTimeTolerance); // We don't expect first or last decrypt for unused report. } @@ -5351,9 +5367,9 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { const int kLicenseReceivedTimeTolerance = kSpeedMultiplier; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_license_received), - 0, kLicenseReceivedTimeTolerance); + EXPECT_EQ(kUnused, s.pst_report().status()); + EXPECT_NEAR(0, s.pst_report().seconds_since_license_received(), + kLicenseReceivedTimeTolerance); const time_t kDotIntervalInSeconds = 5; const time_t kIdleInSeconds = 20; @@ -5372,8 +5388,8 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); s.GenerateReport(pst); - EXPECT_EQ(kUnused, s.pst_report()->status); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_EQ(kUnused, s.pst_report().status()); + EXPECT_NEAR(s.pst_report().seconds_since_license_received(), kIdleInSeconds, kLicenseReceivedTimeTolerance); cout << "Start simulated playback..." << endl; @@ -5383,7 +5399,7 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { do { ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); s.GenerateReport(pst); - EXPECT_EQ(kActive, s.pst_report()->status); + EXPECT_EQ(kActive, s.pst_report().status()); playback_time = time(NULL) - start_time; ASSERT_LE(0, playback_time); if (playback_time >= dot_time) { @@ -5396,14 +5412,14 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); s.GenerateReport(pst); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_NEAR(s.pst_report().seconds_since_license_received(), playback_time + kIdleInSeconds, kLicenseReceivedTimeTolerance); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + EXPECT_NEAR(s.pst_report().seconds_since_first_decrypt(), playback_time, kUsageTableTimeTolerance); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), 0, + EXPECT_NEAR(s.pst_report().seconds_since_last_decrypt(), 0, kUsageTableTimeTolerance); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt) - - wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(s.pst_report().seconds_since_first_decrypt() - + s.pst_report().seconds_since_last_decrypt(), playback_time, kUsageTableTimeTolerance); cout << "Wait another " << kIdleInSeconds @@ -5420,17 +5436,17 @@ TEST_F(UsageTableTest, VerifyUsageTimes) { // |<------------------------------------| = seconds_since_license_received ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); s.GenerateReport(pst); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_NEAR(s.pst_report().seconds_since_license_received(), playback_time + 2 * kIdleInSeconds, kLicenseReceivedTimeTolerance); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + EXPECT_NEAR(s.pst_report().seconds_since_first_decrypt(), playback_time + kIdleInSeconds, kUsageTableTimeTolerance); - EXPECT_NEAR(wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + EXPECT_NEAR(s.pst_report().seconds_since_last_decrypt(), kIdleInSeconds, kUsageTableTimeTolerance); ASSERT_NO_FATAL_FAILURE(DeactivatePST(pst)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s.pst_report().status()); ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); } @@ -5483,9 +5499,8 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { ASSERT_NO_FATAL_FAILURE( s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); ASSERT_NO_FATAL_FAILURE(s.GenerateReport(pst)); - EXPECT_EQ(kInactive, s.pst_report()->status); - EXPECT_NEAR(0, - wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + EXPECT_EQ(kInactiveUsed, s.pst_report().status()); + EXPECT_NEAR(0, s.pst_report().seconds_since_license_received(), kTimeTolerance); ASSERT_NO_FATAL_FAILURE(s.close()); @@ -5500,12 +5515,13 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { &s.signature()[0], s.signature().size(), s.encrypted_license().mac_key_iv, s.encrypted_license().mac_keys, s.num_keys(), - s.key_array(), pst_ptr, pst.length())); + s.key_array(), pst_ptr, pst.length(), + NULL)); // But we can still generate a report. Session s3; ASSERT_NO_FATAL_FAILURE(s3.open()); ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, true, &s)); - EXPECT_EQ(kInactive, s3.pst_report()->status); + EXPECT_EQ(kInactiveUsed, s3.pst_report().status()); } TEST_F(UsageTableTest, DeleteEntryLargeBuffer) { @@ -5527,7 +5543,7 @@ TEST_F(UsageTableTest, DeleteEntryLargeBuffer) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); ASSERT_NO_FATAL_FAILURE(s2.GenerateReport(pst, true, &s)); - EXPECT_EQ(kActive, s2.pst_report()->status); + EXPECT_EQ(kActive, s2.pst_report().status()); ASSERT_NO_FATAL_FAILURE(s2.DeleteEntry(pst)); ASSERT_NO_FATAL_FAILURE(s2.close()); diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index 340217c6..3e932b3a 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -82,8 +82,6 @@ adb_shell_run initialization_data_unittest adb_shell_run device_files_unittest adb_shell_run timer_unittest adb_shell_run buffer_reader_test -adb_shell_run circular_buffer_test -adb_shell_run entry_writer_test library_path="/system/vendor/lib/mediadrm/ " adb_shell_run libwvdrmengine_test LD_LIBRARY_PATH=$library_path