diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 19d78542..e2ff9064 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -53,7 +53,7 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(SecurityLevel level, 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); - +uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level); } // namespace wvcdm /* The following functions are deprecated in OEMCrypto v13. They are defined @@ -62,12 +62,25 @@ OEMCryptoResult OEMCrypto_CreateOldUsageEntry(SecurityLevel level, */ extern "C" { -OEMCryptoResult OEMCrypto_LoadKeys_V11_or_V12( +struct OEMCrypto_KeyObject_V13 { // Used for backwards compatibility. + const uint8_t* key_id; + size_t key_id_length; + const uint8_t* key_data_iv; + const uint8_t* key_data; + size_t key_data_length; + const uint8_t* key_control_iv; + const uint8_t* key_control; + OEMCryptoCipherMode cipher_mode; +}; + +// Backwards compitiblity between v14 and v13. +OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat( 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 num_keys, const OEMCrypto_KeyObject_V13* key_array, + const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement, + OEMCrypto_LicenseType license_type); OEMCryptoResult OEMCrypto_UpdateUsageTable(); diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index d15c29e6..e1f0f89c 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -203,10 +203,10 @@ class DefaultKeySession : public KeySession { } else { LOGV("DefaultKeySession::LoadKeys: enc_mac_key not set"); } - std::vector load_keys(keys.size()); + std::vector load_keys(keys.size()); for (size_t i = 0; i < keys.size(); ++i) { const CryptoKey* ki = &keys[i]; - OEMCrypto_KeyObject* ko = &load_keys[i]; + OEMCrypto_KeyObject_V13* ko = &load_keys[i]; ko->key_id = msg + GetOffset(message, ki->key_id()); ko->key_id_length = ki->key_id().length(); ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv()); diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index b0aef465..171a1b96 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -68,12 +68,19 @@ typedef OEMCryptoResult (*L1_LoadKeys_t)( 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, + OEMCrypto_LicenseType license_type); +typedef OEMCryptoResult (*L1_LoadKeys_V13_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_V13* key_array, const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement); typedef OEMCryptoResult (*L1_LoadKeys_V11_or_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, - const OEMCrypto_KeyObject* key_array, const uint8_t* pst, + const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst, size_t pst_length); typedef OEMCryptoResult (*L1_LoadKeys_V9_or_V10_t)( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, @@ -86,6 +93,9 @@ typedef OEMCryptoResult (*L1_LoadKeys_V8_t)( 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_V10* key_array); +typedef OEMCryptoResult(*L1_LoadEntitledContentKeys_t)( + OEMCrypto_SESSION session, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject* 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, @@ -94,8 +104,12 @@ typedef OEMCryptoResult (*L1_QueryKeyControl_t)( OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length, uint8_t* key_control_block, size_t* key_control_block_length); typedef OEMCryptoResult (*L1_SelectKey_t)(const OEMCrypto_SESSION session, - const uint8_t* key_id, - size_t key_id_length); + const uint8_t* content_key_id, + size_t content_key_id_length, + OEMCryptoCipherMode cipher_mode); +typedef OEMCryptoResult (*L1_SelectKey_V13_t)(const OEMCrypto_SESSION session, + const uint8_t* key_id, + size_t key_id_length); typedef OEMCryptoResult (*L1_DecryptCTR_V10_t)( OEMCrypto_SESSION session, const uint8_t* data_addr, size_t data_length, bool is_encrypted, const uint8_t* iv, size_t offset, @@ -117,7 +131,9 @@ typedef OEMCryptoResult (*L1_WrapKeybox_t)(const uint8_t* keybox, size_t transportKeyLength); typedef OEMCryptoResult (*L1_InstallKeybox_t)(const uint8_t* keybox, size_t keyBoxLength); -typedef OEMCryptoResult (*L1_LoadTestKeybox_t)(); +typedef OEMCryptoResult (*L1_LoadTestKeybox_t)(const uint8_t *buffer, + size_t length); +typedef OEMCryptoResult (*L1_LoadTestKeybox_V13_t)(); typedef OEMCryptoResult (*L1_IsKeyboxValid_t)(); typedef OEMCryptoResult (*L1_GetDeviceID_t)(uint8_t* deviceID, size_t* idLength); @@ -244,6 +260,7 @@ typedef OEMCryptoResult (*L1_CreateOldUsageEntry_t)( 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); +typedef uint32_t (*L1_GetAnalogOutputFlags_t)(void); struct FunctionPointers { uint32_t version; @@ -255,6 +272,7 @@ struct FunctionPointers { L1_GenerateNonce_t GenerateNonce; L1_GenerateSignature_t GenerateSignature; L1_LoadKeys_t LoadKeys; + L1_LoadEntitledContentKeys_t LoadEntitledContentKeys; L1_RefreshKeys_t RefreshKeys; L1_QueryKeyControl_t QueryKeyControl; L1_SelectKey_t SelectKey; @@ -308,6 +326,7 @@ struct FunctionPointers { L1_MoveEntry_t MoveEntry; L1_CopyOldUsageEntry_t CopyOldUsageEntry; L1_CreateOldUsageEntry_t CreateOldUsageEntry; + L1_GetAnalogOutputFlags_t GetAnalogOutputFlags; L1_LoadKeys_V8_t LoadKeys_V8; L1_GenerateRSASignature_V8_t GenerateRSASignature_V8; @@ -315,6 +334,9 @@ struct FunctionPointers { L1_LoadKeys_V9_or_V10_t LoadKeys_V9_or_V10; L1_LoadKeys_V11_or_V12_t LoadKeys_V11_or_V12; L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12; + L1_LoadKeys_V13_t LoadKeys_V13; + L1_SelectKey_V13_t SelectKey_V13; + L1_LoadTestKeybox_V13_t LoadTestKeybox_V13; }; // The WatchDog looks after a worker thread that is trying to initialize L3. @@ -493,6 +515,7 @@ struct LevelSession { if (!level1_.Name) { \ LOGW("Could not load L1 %s. Falling Back to L3.", \ QUOTE(Function)); \ + if (level1_.Terminate) level1_.Terminate(); \ return false; \ } \ } @@ -580,7 +603,7 @@ class Adapter { } level1_valid_ = true; const uint32_t kMinimumVersion = 8; - const uint32_t kMaximumVersion = 13; + const uint32_t kMaximumVersion = 14; level1_.version = kMinimumVersion; LOOKUP_ALL(8, Initialize, OEMCrypto_Initialize); LOOKUP_ALL(8, APIVersion, OEMCrypto_APIVersion); @@ -639,6 +662,7 @@ class Adapter { LOOKUP_ALL( 8, GetDeviceID, OEMCrypto_GetDeviceID); LOOKUP( 9, 9, GetHDCPCapability_V9, OEMCrypto_GetHDCPCapability_V9); LOOKUP_ALL(10, GetHDCPCapability, OEMCrypto_GetHDCPCapability); + LOOKUP_ALL(14, GetAnalogOutputFlags, OEMCrypto_GetAnalogOutputFlags); LOOKUP_ALL( 8, GetKeyData, OEMCrypto_GetKeyData); LOOKUP_ALL(10, GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions); LOOKUP_ALL(10, GetNumberOfOpenSessions, OEMCrypto_GetNumberOfOpenSessions); @@ -653,9 +677,12 @@ class Adapter { LOOKUP( 8, 8, LoadKeys_V8, OEMCrypto_LoadKeys_V8); LOOKUP( 9, 10, LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10); LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12); - LOOKUP_ALL(13, LoadKeys, OEMCrypto_LoadKeys); + LOOKUP(13, 13, LoadKeys_V13, OEMCrypto_LoadKeys_V13); + LOOKUP_ALL(14, LoadKeys, OEMCrypto_LoadKeys); + LOOKUP_ALL(14, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys); LOOKUP_ALL(13, LoadSRM, OEMCrypto_LoadSRM); - LOOKUP_ALL(10, LoadTestKeybox, OEMCrypto_LoadTestKeybox); + LOOKUP(10, 13, LoadTestKeybox_V13, OEMCrypto_LoadTestKeybox_V13); + LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox); LOOKUP_ALL(10, LoadTestRSAKey, OEMCrypto_LoadTestRSAKey); LOOKUP_ALL(13, LoadUsageEntry, OEMCrypto_LoadUsageEntry); LOOKUP_ALL(13, LoadUsageTableHeader, OEMCrypto_LoadUsageTableHeader); @@ -669,7 +696,8 @@ class Adapter { LOOKUP_ALL(12, RewrapDeviceRSAKey30, OEMCrypto_RewrapDeviceRSAKey30); LOOKUP_ALL( 8, SecurityLevel, OEMCrypto_SecurityLevel); LOOKUP_ALL(11, SecurityPatchLevel, OEMCrypto_Security_Patch_Level); - LOOKUP_ALL( 8, SelectKey, OEMCrypto_SelectKey); + LOOKUP( 8, 13, SelectKey_V13, OEMCrypto_SelectKey_V13); + LOOKUP_ALL(14, SelectKey, OEMCrypto_SelectKey); LOOKUP_ALL(13, ShrinkUsageTableHeader, OEMCrypto_ShrinkUsageTableHeader); LOOKUP_ALL(13, SupportedCertificates, OEMCrypto_SupportedCertificates); LOOKUP_ALL( 9, SupportsUsageTable, OEMCrypto_SupportsUsageTable); @@ -757,15 +785,18 @@ class Adapter { level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys; level3_.GenerateNonce = Level3_GenerateNonce; level3_.GenerateSignature = Level3_GenerateSignature; - level3_.LoadKeys = Level3_LoadKeys; + // TODO(srujzs): commenting out the following allows code to compile, but + // all unit tests will fail. + // TODO(srujzs): add level3_.LoadKeys = Level3_LoadKeys; + // TODO(srujzs): add level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys; level3_.RefreshKeys = Level3_RefreshKeys; level3_.QueryKeyControl = Level3_QueryKeyControl; - level3_.SelectKey = Level3_SelectKey; + level3_.SelectKey_V13 = Level3_SelectKey; // TODO(srujzs): update. level3_.DecryptCENC = Level3_DecryptCENC; level3_.CopyBuffer = Level3_CopyBuffer; level3_.WrapKeybox = Level3_WrapKeybox; level3_.InstallKeybox = Level3_InstallKeybox; - level3_.LoadTestKeybox = Level3_LoadTestKeybox; + level3_.LoadTestKeybox_V13 = Level3_LoadTestKeybox; // TODO(srujzs): update. level3_.IsKeyboxValid = Level3_IsKeyboxValid; level3_.GetDeviceID = Level3_GetDeviceID; level3_.GetKeyData = Level3_GetKeyData; @@ -779,6 +810,7 @@ class Adapter { level3_.SecurityPatchLevel = Level3_SecurityPatchLevel; level3_.SecurityLevel = Level3_SecurityLevel; level3_.GetHDCPCapability = Level3_GetHDCPCapability; + // TODO(srujzs): add level3_.GetAnalogOutputFlags = Level3_GetAnalogOutputFlags; level3_.SupportsUsageTable = Level3_SupportsUsageTable; level3_.IsAntiRollbackHwPresent = Level3_IsAntiRollbackHwPresent; level3_.GetNumberOfOpenSessions = Level3_GetNumberOfOpenSessions; @@ -1017,6 +1049,15 @@ OEMCryptoResult OEMCrypto_GetHDCPCapability( } } +uint32_t OEMCrypto_GetAnalogOutputFlags(SecurityLevel level) { + if (!kAdapter) return OEMCrypto_Unknown_Analog_Output; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return OEMCrypto_Unknown_Analog_Output; + if (fcn->version < 14) return OEMCrypto_Unknown_Analog_Output; + if (fcn->GetAnalogOutputFlags == NULL) return OEMCrypto_Unknown_Analog_Output; + return fcn->GetAnalogOutputFlags(); +} + bool OEMCrypto_SupportsUsageTable(SecurityLevel level) { if (!kAdapter) return false; const FunctionPointers* fcn = kAdapter->get(level); @@ -1183,16 +1224,19 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateSignature( signature, signature_length); } -extern "C" OEMCryptoResult OEMCrypto_LoadKeys( +extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat( 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) { + const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst, + size_t pst_length, const uint8_t* srm_requirement, + OEMCrypto_LicenseType license_type) { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = kAdapter->get(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (pair.fcn->version < 11) { + if (license_type != OEMCrypto_ContentLicense) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; std::vector key_array_v10(num_keys); for (size_t i = 0; i < num_keys; i++) { key_array_v10[i].key_id = key_array[i].key_id; @@ -1207,44 +1251,169 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( return OEMCrypto_ERROR_NOT_IMPLEMENTED; } } + OEMCrypto_KeyObject_V10* key_array_v10_ptr = NULL; + if (num_keys > 0) key_array_v10_ptr = &key_array_v10[0]; if (pair.fcn->version == 8) { if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; return pair.fcn->LoadKeys_V8(pair.session, message, message_length, signature, signature_length, enc_mac_key_iv, - enc_mac_key, num_keys, &key_array_v10[0]); + enc_mac_key, num_keys, key_array_v10_ptr); } else { if (pair.fcn->LoadKeys_V9_or_V10 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10( pair.session, message, message_length, signature, signature_length, - enc_mac_key_iv, enc_mac_key, num_keys, &key_array_v10[0], pst, + enc_mac_key_iv, enc_mac_key, num_keys, key_array_v10_ptr, pst, pst_length); // Convert a vendor specific error, to make it actionable if (result == kOemCryptoResultVendorSpecificError1) result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; return result; } + } else if (pair.fcn->version < 13) { + if (license_type != OEMCrypto_ContentLicense) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + if (pair.fcn->LoadKeys_V11_or_V12 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12( + pair.session, message, message_length, signature, signature_length, + enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length); + // Convert a vendor specific error, to make it actionable + if (result == kOemCryptoResultVendorSpecificError1) + result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; + return result; + } else if (pair.fcn->version < 14) { + if (license_type != OEMCrypto_ContentLicense) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + if (pair.fcn->LoadKeys_V13 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadKeys_V13(pair.session, message, message_length, + signature, signature_length, enc_mac_key_iv, + enc_mac_key, num_keys, key_array, pst, + pst_length, srm_requirement); } else { + if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + std::vector key_array_v14(num_keys); + for (size_t i = 0; i < num_keys; i++) { + key_array_v14[i].key_id = key_array[i].key_id; + key_array_v14[i].key_id_length = key_array[i].key_id_length; + key_array_v14[i].key_data_iv = key_array[i].key_data_iv; + key_array_v14[i].key_data = key_array[i].key_data; + key_array_v14[i].key_data_length = key_array[i].key_data_length; + key_array_v14[i].key_control_iv = key_array[i].key_control_iv; + key_array_v14[i].key_control = key_array[i].key_control; + } + OEMCrypto_KeyObject* key_array_v14_ptr = NULL; + if (num_keys > 0) key_array_v14_ptr = &key_array_v14[0]; + return pair.fcn->LoadKeys(pair.session, message, message_length, signature, + signature_length, enc_mac_key_iv, enc_mac_key, + num_keys, key_array_v14_ptr, pst, pst_length, + srm_requirement, license_type); + } +} + +/* The CDM layer should use OEMCrypto_LoadKeys_Back_Compat instead. This is + * used by unit tests, and forces cipher mode to CTR when used with an older + * oemcrypto. + */ +extern "C" 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_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, OEMCrypto_LicenseType license_type) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + LevelSession pair = kAdapter->get(session); + if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if (pair.fcn->version < 11) { + if (license_type != OEMCrypto_ContentLicense) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + std::vector key_array_v10(num_keys); + for (size_t i = 0; i < num_keys; i++) { + key_array_v10[i].key_id = key_array[i].key_id; + key_array_v10[i].key_id_length = key_array[i].key_id_length; + key_array_v10[i].key_data_iv = key_array[i].key_data_iv; + key_array_v10[i].key_data = key_array[i].key_data; + key_array_v10[i].key_data_length = key_array[i].key_data_length; + key_array_v10[i].key_control_iv = key_array[i].key_control_iv; + key_array_v10[i].key_control = key_array[i].key_control; + } + OEMCrypto_KeyObject_V10* key_array_v10_ptr = NULL; + if (num_keys > 0) key_array_v10_ptr = &key_array_v10[0]; + if (pair.fcn->version == 8) { + if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadKeys_V8(pair.session, message, message_length, + signature, signature_length, enc_mac_key_iv, + enc_mac_key, num_keys, key_array_v10_ptr); + } else { + if (pair.fcn->LoadKeys_V9_or_V10 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10( + pair.session, message, message_length, signature, signature_length, + enc_mac_key_iv, enc_mac_key, num_keys, key_array_v10_ptr, pst, + pst_length); + // Convert a vendor specific error, to make it actionable + if (result == kOemCryptoResultVendorSpecificError1) + result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; + return result; + } + } else if (pair.fcn->version < 14) { + if (license_type != OEMCrypto_ContentLicense) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + std::vector key_array_v13(num_keys); + for (size_t i = 0; i < num_keys; i++) { + key_array_v13[i].key_id = key_array[i].key_id; + key_array_v13[i].key_id_length = key_array[i].key_id_length; + key_array_v13[i].key_data_iv = key_array[i].key_data_iv; + key_array_v13[i].key_data = key_array[i].key_data; + key_array_v13[i].key_data_length = key_array[i].key_data_length; + key_array_v13[i].key_control_iv = key_array[i].key_control_iv; + key_array_v13[i].key_control = key_array[i].key_control; + key_array_v13[i].cipher_mode == OEMCrypto_CipherMode_CTR; + } + OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL; + if (num_keys > 0) key_array_v13_ptr = &key_array_v13[0]; if (pair.fcn->version < 13) { if (pair.fcn->LoadKeys_V11_or_V12 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12( pair.session, message, message_length, signature, signature_length, - enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length); + enc_mac_key_iv, enc_mac_key, num_keys, key_array_v13_ptr, pst, + pst_length); // Convert a vendor specific error, to make it actionable if (result == kOemCryptoResultVendorSpecificError1) result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; return result; } else { - if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - 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); + if (pair.fcn->LoadKeys_V13 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadKeys_V13(pair.session, message, message_length, + signature, signature_length, enc_mac_key_iv, + enc_mac_key, num_keys, key_array_v13_ptr, + pst, pst_length, srm_requirement); } + } else { + if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + 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, license_type); } } +extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( + OEMCrypto_SESSION session, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject* key_array) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + LevelSession pair = kAdapter->get(session); + if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if (pair.fcn->version < 14) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + if (pair.fcn->LoadEntitledContentKeys == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadEntitledContentKeys(pair.session, num_keys, key_array); +} + extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, size_t num_keys, @@ -1271,12 +1440,19 @@ extern "C" OEMCryptoResult OEMCrypto_QueryKeyControl( extern "C" OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session, const uint8_t* key_id, - size_t key_id_length) { + size_t key_id_length, + OEMCryptoCipherMode cipher_mode) { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = kAdapter->get(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; - if (pair.fcn->SelectKey == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - return pair.fcn->SelectKey(pair.session, key_id, key_id_length); + if (pair.fcn->version < 14) { + if (pair.fcn->SelectKey_V13 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->SelectKey_V13(pair.session, key_id, key_id_length); + } else { + if (pair.fcn->SelectKey == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->SelectKey(pair.session, key_id, key_id_length, + cipher_mode); + } } extern "C" OEMCryptoResult OEMCrypto_DecryptCENC( @@ -1327,13 +1503,18 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault); } -extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox() { +extern "C" OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer, + size_t length) { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; const FunctionPointers* fcn = kAdapter->get(kLevelDefault); if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (fcn->version < 10) return OEMCrypto_ERROR_NOT_IMPLEMENTED; + if (fcn->LoadTestKeybox_V13 != NULL) { + // Old versions might use wrong keybox, but this is the best we can do. + return fcn->LoadTestKeybox_V13(); + } if (fcn->LoadTestKeybox == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; - return fcn->LoadTestKeybox(); + return fcn->LoadTestKeybox(buffer, length); } extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() { diff --git a/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h b/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h index 614b04b1..9ae2c1fa 100644 --- a/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h +++ b/libwvdrmengine/mediadrm/include/WVGenericCryptoInterface.h @@ -21,7 +21,8 @@ class WVGenericCryptoInterface { virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length) { - return OEMCrypto_SelectKey(session, key_id, key_id_length); + return OEMCrypto_SelectKey(session, key_id, key_id_length, + OEMCrypto_CipherMode_CBC); } virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session, diff --git a/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h b/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h index c28a3601..00ef034b 100644 --- a/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h +++ b/libwvdrmengine/mediadrm/include_hidl/WVGenericCryptoInterface.h @@ -21,7 +21,8 @@ class WVGenericCryptoInterface { virtual OEMCryptoResult selectKey(const OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length) { - return OEMCrypto_SelectKey(session, key_id, key_id_length); + return OEMCrypto_SelectKey(session, key_id, key_id_length, + OEMCrypto_CipherMode_CBC); } virtual OEMCryptoResult encrypt(OEMCrypto_SESSION session,