diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 4de39aa4..1e87036a 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -34,6 +34,7 @@ OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, SecurityLevel level); uint32_t OEMCrypto_APIVersion(SecurityLevel level); const char* OEMCrypto_SecurityLevel(SecurityLevel level); +bool OEMCrypto_SupportsUsageTable(SecurityLevel level); } // namespace wvcdm #endif // OEMCRYPTO_ADAPTER_H_ diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 59a841c2..b4982425 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -50,6 +50,11 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)( 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); +typedef OEMCryptoResult (*L1_LoadKeys_V8_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); typedef OEMCryptoResult (*L1_RefreshKeys_t)( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, size_t num_keys, @@ -91,6 +96,11 @@ typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(OEMCrypto_SESSION session, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme); +typedef OEMCryptoResult (*L1_GenerateRSASignature_V8_t)(OEMCrypto_SESSION session, + const uint8_t* message, + size_t message_length, + uint8_t* signature, + size_t* signature_length); typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)( OEMCrypto_SESSION session, const uint8_t* enc_session_key, size_t enc_session_key_length, const uint8_t* mac_key_context, @@ -118,8 +128,28 @@ typedef OEMCryptoResult (*L1_Generic_Verify_t)(OEMCrypto_SESSION session, size_t signature_length); typedef uint32_t (*L1_APIVersion_t)(); typedef const char* (*L1_SecurityLevel_t)(); +typedef OEMCryptoResult (*L1_GetHDCPCapability_t)(OEMCrypto_HDCP_Capability *current, + OEMCrypto_HDCP_Capability *maximum); +typedef bool (*L1_SupportsUsageTable_t)(); +typedef OEMCryptoResult (*L1_UpdateUsageTable_t)(); +typedef OEMCryptoResult (*L1_DeactivateUsageEntry_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, + size_t *buffer_length); +typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)(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); +typedef OEMCryptoResult (*L1_DeleteUsageTable_t)(); struct FunctionPointers { + uint32_t version; L1_Initialize_t Initialize; L1_Terminate_t Terminate; L1_OpenSession_t OpenSession; @@ -147,6 +177,16 @@ struct FunctionPointers { L1_Generic_Decrypt_t Generic_Decrypt; L1_Generic_Sign_t Generic_Sign; L1_Generic_Verify_t Generic_Verify; + L1_GetHDCPCapability_t GetHDCPCapability; + L1_SupportsUsageTable_t SupportsUsageTable; + L1_UpdateUsageTable_t UpdateUsageTable; + L1_DeactivateUsageEntry_t DeactivateUsageEntry; + L1_ReportUsage_t ReportUsage; + L1_DeleteUsageEntry_t DeleteUsageEntry; + L1_DeleteUsageTable_t DeleteUsageTable; + + L1_LoadKeys_V8_t LoadKeys_V8; + L1_GenerateRSASignature_V8_t GenerateRSASignature_V8; }; struct LevelSession { @@ -240,13 +280,25 @@ class Adapter { LOGW("Could not initialize L1. Falling Back to L3."); return false; } - uint32_t level1_version = level1_.APIVersion(); - uint32_t minimum_version = 8; // TODO(fredgc): allow version 8 and 9? - if (level1_version < minimum_version) { + level1_.version = level1_.APIVersion(); + uint32_t minimum_version = 8; + if (level1_.version < minimum_version) { LOGW("liboemcrypto.so is version %d, not %d. Falling Back to L3.", - level1_version, minimum_version); + level1_.version, minimum_version); return false; } + if( level1_.version == 8 ) { + LOOKUP(LoadKeys_V8, OEMCrypto_LoadKeys); + LOOKUP(GenerateRSASignature_V8, OEMCrypto_GenerateRSASignature); + } else { + LOOKUP(GetHDCPCapability, OEMCrypto_GetHDCPCapability); + LOOKUP(SupportsUsageTable, OEMCrypto_SupportsUsageTable); + LOOKUP(UpdateUsageTable, OEMCrypto_UpdateUsageTable); + LOOKUP(DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry); + LOOKUP(ReportUsage, OEMCrypto_ReportUsage); + LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry); + LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable); + } if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) { return true; } @@ -300,6 +352,14 @@ class Adapter { level3_.Generic_Encrypt = Level3_Generic_Encrypt; level3_.Generic_Sign = Level3_Generic_Sign; level3_.Generic_Verify = Level3_Generic_Verify; + level3_.GetHDCPCapability = Level3_GetHDCPCapability; + level3_.SupportsUsageTable = Level3_SupportsUsageTable; + level3_.UpdateUsageTable = Level3_UpdateUsageTable; + level3_.DeactivateUsageEntry = Level3_DeactivateUsageEntry; + level3_.ReportUsage = Level3_ReportUsage; + level3_.DeleteUsageEntry = Level3_DeleteUsageEntry; + level3_.DeleteUsageTable = Level3_DeleteUsageTable; + level3_.version = Level3_APIVersion(); } OEMCryptoResult Terminate() { @@ -447,9 +507,15 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = kAdapter->get(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; - 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 == 8) { + return pair.fcn->LoadKeys_V8(pair.session, message, message_length, signature, + signature_length, enc_mac_key_iv, enc_mac_key, + num_keys, key_array); + } 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); + } } extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( @@ -587,9 +653,14 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature( if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = kAdapter->get(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; - return pair.fcn->GenerateRSASignature(pair.session, message, message_length, - signature, signature_length, - padding_scheme); + if (pair.fcn->version == 8) { + return pair.fcn->GenerateRSASignature_V8(pair.session, message, message_length, + signature, signature_length); + } else { + return pair.fcn->GenerateRSASignature(pair.session, message, message_length, + signature, signature_length, + padding_scheme); + } } extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( @@ -672,4 +743,96 @@ extern "C" OEMCryptoResult OEMCrypto_Generic_Verify( algorithm, signature, signature_length); } +extern "C" +OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, + OEMCrypto_HDCP_Capability *maximum) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(kLevelDefault); + if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if( fcn->version == 8 ) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return fcn->GetHDCPCapability(current, maximum); +} + +extern "C" bool OEMCrypto_SupportsUsageTable() { + return OEMCrypto_SupportsUsageTable(kLevelDefault); +} + +bool OEMCrypto_SupportsUsageTable(SecurityLevel level) { + if (!kAdapter) return false; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return false; + if( fcn->version == 8 ) return false; + return fcn->SupportsUsageTable(); +} + +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(); + return sts; +} + +extern "C" OEMCryptoResult OEMCrypto_DeactivateUsageEntry(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 (fcn3 && fcn3->version > 8) { + sts = fcn3->DeactivateUsageEntry(pst, pst_length); + } + if (fcn1 && fcn1 != fcn3 && fcn1->version > 8) { + sts = fcn1->DeactivateUsageEntry(pst, pst_length); + } + return sts; +} + +extern "C" OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session, + const uint8_t *pst, + size_t pst_length, + OEMCrypto_PST_Report *buffer, + size_t *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 > 8 ) { + return pair.fcn->ReportUsage(pair.session, pst, pst_length,buffer, + buffer_length); + } else { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } +} + +extern "C" OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, + const uint8_t* pst, + size_t pst_length, + const uint8_t *message, + size_t message_length, + const uint8_t *signature, + size_t signature_length) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + LevelSession pair = kAdapter->get(session); + if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if( pair.fcn->version > 8 ) { + return pair.fcn->DeleteUsageEntry(session, pst, pst_length, message, + message_length, signature, + signature_length); + } else { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } +} + +extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() { + 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(); + return sts; +} + }; // namespace wvcdm diff --git a/libwvdrmengine/level3/arm/libwvlevel3.a b/libwvdrmengine/level3/arm/libwvlevel3.a index 6916ec2b..76d69056 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 cb9ac8c9..e74600c9 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 4a26ee70..c37269cd 100644 Binary files a/libwvdrmengine/level3/x86/libwvlevel3.a and b/libwvdrmengine/level3/x86/libwvlevel3.a differ diff --git a/libwvdrmengine/oemcrypto/include/level3.h b/libwvdrmengine/oemcrypto/include/level3.h index 19a5d367..5ae8403c 100644 --- a/libwvdrmengine/oemcrypto/include/level3.h +++ b/libwvdrmengine/oemcrypto/include/level3.h @@ -43,6 +43,13 @@ namespace wvoec3 { #define Level3_Generic_Decrypt _lcc25 #define Level3_Generic_Sign _lcc26 #define Level3_Generic_Verify _lcc27 +#define Level3_GetHDCPCapability _lcc28 +#define Level3_SupportsUsageTable _lcc29 +#define Level3_UpdateUsageTable _lcc30 +#define Level3_DeactivateUsageEntry _lcc31 +#define Level3_ReportUsage _lcc32 +#define Level3_DeleteUsageEntry _lcc33 +#define Level3_DeleteUsageTable _lcc34 extern "C" { @@ -159,7 +166,25 @@ OEMCryptoResult Level3_Generic_Verify(OEMCrypto_SESSION session, OEMCrypto_Algorithm algorithm, const uint8_t* signature, size_t signature_length); +OEMCryptoResult Level3_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, + OEMCrypto_HDCP_Capability *maximum); +bool Level3_SupportsUsageTable(); +OEMCryptoResult Level3_UpdateUsageTable(); +OEMCryptoResult Level3_DeactivateUsageEntry(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, + size_t *buffer_length); +OEMCryptoResult Level3_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); +OEMCryptoResult Level3_DeleteUsageTable(); }; - } #endif // LEVEL3_OEMCRYPTO_H_