diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index d421ba18..a79f7cd6 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -32,6 +32,9 @@ void GenerateMacContext(const std::string& input_context, void GenerateEncryptContext(const std::string& input_context, std::string* deriv_context); size_t GetOffset(std::string message, std::string field); +OEMCrypto_Substring GetSubstring(const std::string& message = "", + const std::string& field = "", + bool set_zero = false); OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode); class CryptoSessionFactory; diff --git a/libwvdrmengine/cdm/core/include/entitlement_key_session.h b/libwvdrmengine/cdm/core/include/entitlement_key_session.h index a052432d..22c51a0d 100644 --- a/libwvdrmengine/cdm/core/include/entitlement_key_session.h +++ b/libwvdrmengine/cdm/core/include/entitlement_key_session.h @@ -38,11 +38,11 @@ class EntitlementKeySession : public ContentKeySession { CdmCipherMode cipher_mode) override; private: - // The object returned by this function contains raw pointers to the passed-in - // CryptoKey object. Care should be taken that it does not outlive the - // CryptoKey. + // The message is populated with the fields of the provided CryptoKey and the + // returned object reflects the offsets and lengths into that message for each + // field. OEMCrypto_EntitledContentKeyObject MakeOecEntitledKey( - const CryptoKey& input_key); + const CryptoKey& input_key, std::string& message); std::map entitled_keys_; }; diff --git a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h index 80231d3c..074d7b9a 100644 --- a/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h +++ b/libwvdrmengine/cdm/core/include/oemcrypto_adapter.h @@ -63,7 +63,17 @@ uint32_t OEMCrypto_ResourceRatingTier(SecurityLevel level); */ extern "C" { -struct OEMCrypto_KeyObject_V13 { // Used for backwards compatibility. +typedef struct { // 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; +} OEMCrypto_KeyObject_V10; + +typedef struct { // Used for backwards compatibility. const uint8_t* key_id; size_t key_id_length; const uint8_t* key_data_iv; @@ -72,16 +82,26 @@ struct OEMCrypto_KeyObject_V13 { // Used for backwards compatibility. const uint8_t* key_control_iv; const uint8_t* key_control; OEMCryptoCipherMode cipher_mode; -}; +} OEMCrypto_KeyObject_V13; + +typedef struct { + 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; +} OEMCrypto_KeyObject_V14; // 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_V13* key_array, - const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement, - OEMCrypto_LicenseType license_type); + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes); OEMCryptoResult OEMCrypto_UpdateUsageTable(); @@ -94,6 +114,46 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry( OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst, size_t pst_length); + +typedef struct { + const uint8_t* entitlement_key_id; + size_t entitlement_key_id_length; + const uint8_t* content_key_id; + size_t content_key_id_length; + const uint8_t* content_key_data_iv; + const uint8_t* content_key_data; + size_t content_key_data_length; +} OEMCrypto_EntitledContentKeyObject_V14; + +typedef struct { + const uint8_t* key_id; + size_t key_id_length; + const uint8_t* key_control_iv; + const uint8_t* key_control; +} OEMCrypto_KeyRefreshObject_V14; + +OEMCryptoResult OEMCrypto_LoadKeys_V14( + 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_V14* key_array, + const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement, + OEMCrypto_LicenseType license_type); + +OEMCryptoResult OEMCrypto_LoadEntitledContentKeys_V14( + OEMCrypto_SESSION session, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject_V14* key_array); + +OEMCryptoResult OEMCrypto_RefreshKeys_V14( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, size_t num_keys, + const OEMCrypto_KeyRefreshObject_V14* key_array); + +OEMCryptoResult OEMCrypto_CopyBuffer_V14(const uint8_t* data_addr, + size_t data_length, + OEMCrypto_DestBufferDesc* out_buffer, + uint8_t subsample_flags); + } // extern "C" #endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_ diff --git a/libwvdrmengine/cdm/core/src/content_key_session.cpp b/libwvdrmengine/cdm/core/src/content_key_session.cpp index 7efc34ff..3c7c8413 100644 --- a/libwvdrmengine/cdm/core/src/content_key_session.cpp +++ b/libwvdrmengine/cdm/core/src/content_key_session.cpp @@ -124,59 +124,52 @@ OEMCryptoResult ContentKeySession::LoadKeysAsLicenseType( const std::string& provider_session_token, CdmCipherMode* cipher_mode, const std::string& srm_requirement, OEMCrypto_LicenseType license_type) { const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* enc_mac_key = NULL; - const uint8_t* enc_mac_key_iv = NULL; cached_key_id_.clear(); - if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { - enc_mac_key = msg + GetOffset(message, mac_key); - enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); - } else { - LOGV("enc_mac_key not set"); - } - std::vector load_keys(keys.size()); + bool valid_mac_keys = + mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE; + OEMCrypto_Substring enc_mac_key = + GetSubstring(message, mac_key, !valid_mac_keys); + OEMCrypto_Substring enc_mac_key_iv = + GetSubstring(message, mac_key_iv, !valid_mac_keys); + if (!valid_mac_keys) LOGV("enc_mac_key not set"); + std::vector load_keys(keys.size()); + std::vector cipher_modes(keys.size()); for (size_t i = 0; i < keys.size(); ++i) { const CryptoKey* ki = &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()); - ko->key_data = msg + GetOffset(message, ki->key_data()); - ko->key_data_length = ki->key_data().length(); - if (ki->HasKeyControl()) { - ko->key_control_iv = msg + GetOffset(message, ki->key_control_iv()); - ko->key_control = msg + GetOffset(message, ki->key_control()); - } else { + OEMCrypto_KeyObject* ko = &load_keys[i]; + ko->key_id = GetSubstring(message, ki->key_id()); + ko->key_data_iv = GetSubstring(message, ki->key_data_iv()); + ko->key_data = GetSubstring(message, ki->key_data()); + bool has_key_control = ki->HasKeyControl(); + ko->key_control_iv = + GetSubstring(message, ki->key_control_iv(), !has_key_control); + ko->key_control = + GetSubstring(message, ki->key_control(), !has_key_control); + if (!has_key_control) { LOGE("For key %d: XXX key has no control block. size=%d", i, - ki->key_control().size()); - ko->key_control_iv = NULL; - ko->key_control = NULL; + ki->key_control().length()); } - ko->cipher_mode = ToOEMCryptoCipherMode(ki->cipher_mode()); + cipher_modes[i] = ToOEMCryptoCipherMode(ki->cipher_mode()); // TODO(jfore): Is returning the cipher needed. If not drop this. *cipher_mode = ki->cipher_mode(); } - uint8_t* pst = NULL; - if (!provider_session_token.empty()) { - pst = - const_cast(msg) + GetOffset(message, provider_session_token); - } - - uint8_t* srm_req = NULL; - if (!srm_requirement.empty()) { - srm_req = const_cast(msg) + GetOffset(message, srm_requirement); - } + OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement); LOGV("id=%ld", (uint32_t)oec_session_id_); OEMCryptoResult sts; - M_TIME( - sts = ::OEMCrypto_LoadKeys_Back_Compat( - 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(), srm_req, license_type), - metrics_, oemcrypto_load_keys_, sts); + OEMCrypto_KeyObject* key_array_ptr = NULL; + if (keys.size() > 0) key_array_ptr = &load_keys[0]; + OEMCryptoCipherMode* cipher_mode_ptr = NULL; + if (keys.size() > 0) cipher_mode_ptr = &cipher_modes[0]; + M_TIME(sts = ::OEMCrypto_LoadKeys_Back_Compat( + oec_session_id_, msg, message.length(), + reinterpret_cast(signature.data()), + signature.length(), enc_mac_key_iv, enc_mac_key, keys.size(), + key_array_ptr, pst, srm_req, license_type, cipher_mode_ptr), + metrics_, oemcrypto_load_keys_, sts); return sts; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index c288e5a4..976a2cc0 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -92,6 +92,26 @@ size_t GetOffset(std::string message, std::string field) { return pos; } +OEMCrypto_Substring GetSubstring(const std::string& message, + const std::string& field, bool set_zero) { + OEMCrypto_Substring substring; + if (set_zero || field.empty() || message.empty()) { + substring.offset = 0; + substring.length = 0; + } else { + size_t pos = message.find(field); + if (pos == std::string::npos) { + LOGW("GetSubstring : Cannot find offset for %s", field.c_str()); + substring.offset = 0; + substring.length = 0; + } else { + substring.offset = pos; + substring.length = field.length(); + } + } + return substring; +} + void GenerateMacContext(const std::string& input_context, std::string* deriv_context) { if (!deriv_context) { @@ -933,22 +953,12 @@ bool CryptoSession::RefreshKeys(const std::string& message, for (int i = 0; i < num_keys; ++i) { const CryptoKey* ki = &key_array[i]; OEMCrypto_KeyRefreshObject* ko = &load_key_array[i]; - if (ki->key_id().empty()) { - ko->key_id = NULL; - } else { - ko->key_id = msg + GetOffset(message, ki->key_id()); - } - if (ki->HasKeyControl()) { - if (ki->key_control_iv().empty()) { - ko->key_control_iv = NULL; - } else { - ko->key_control_iv = msg + GetOffset(message, ki->key_control_iv()); - } - ko->key_control = msg + GetOffset(message, ki->key_control()); - } else { - ko->key_control_iv = NULL; - ko->key_control = NULL; - } + ko->key_id = GetSubstring(message, ki->key_id()); + bool has_key_control = ki->HasKeyControl(); + ko->key_control_iv = + GetSubstring(message, ki->key_control_iv(), !has_key_control); + ko->key_control = + GetSubstring(message, ki->key_control(), !has_key_control); } LOGV("RefreshKeys: id=%lu", oec_session_id_); OEMCryptoResult refresh_sts; diff --git a/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp b/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp index 52c1607b..6d52dad6 100644 --- a/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp +++ b/libwvdrmengine/cdm/core/src/entitlement_key_session.cpp @@ -52,12 +52,14 @@ OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id, return OEMCrypto_ERROR_NO_CONTENT_KEY; } + std::string message; OEMCrypto_EntitledContentKeyObject entitled_key = - MakeOecEntitledKey(entitled_keys_[key_id]); + MakeOecEntitledKey(entitled_keys_[key_id], message); OEMCryptoResult result = OEMCrypto_SUCCESS; - M_TIME(result = OEMCrypto_LoadEntitledContentKeys(oec_session_id_, 1, - &entitled_key), + M_TIME(result = OEMCrypto_LoadEntitledContentKeys( + oec_session_id_, reinterpret_cast(message.data()), + message.size(), 1, &entitled_key), metrics_, oemcrypto_load_entitled_keys_, result); if (result != OEMCrypto_SUCCESS) { return result; @@ -67,26 +69,30 @@ OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id, } OEMCrypto_EntitledContentKeyObject EntitlementKeySession::MakeOecEntitledKey( - const CryptoKey& input_key) { + const CryptoKey& input_key, std::string& message) { OEMCrypto_EntitledContentKeyObject output_key; + message.clear(); const std::string& entitlement_key_id = input_key.entitlement_key_id(); - output_key.entitlement_key_id = - reinterpret_cast(entitlement_key_id.data()); - output_key.entitlement_key_id_length = entitlement_key_id.size(); - const std::string& key_id = input_key.key_id(); - output_key.content_key_id = reinterpret_cast(key_id.data()); - output_key.content_key_id_length = key_id.size(); - const std::string& key_data_iv = input_key.key_data_iv(); - output_key.content_key_data_iv = - reinterpret_cast(key_data_iv.data()); - const std::string& key_data = input_key.key_data(); - output_key.content_key_data = - reinterpret_cast(key_data.data()); - output_key.content_key_data_length = key_data.size(); + + output_key.entitlement_key_id.offset = message.size(); + message += entitlement_key_id; + output_key.entitlement_key_id.length = entitlement_key_id.size(); + + output_key.content_key_id.offset = message.size(); + message += key_id; + output_key.content_key_id.length = key_id.size(); + + output_key.content_key_data_iv.offset = message.size(); + message += key_data_iv; + output_key.content_key_data_iv.length = key_data_iv.size(); + + output_key.content_key_data.offset = message.size(); + message += key_data; + output_key.content_key_data.length = key_data.size(); return output_key; } diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 16540364..4c01a5ad 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -41,16 +41,6 @@ static const size_t kMaxGenericEncryptChunkSize = 100*1024; const OEMCryptoResult kOemCryptoResultVendorSpecificError1 = static_cast(10008); -typedef struct { - 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; -} OEMCrypto_KeyObject_V10; - typedef OEMCryptoResult (*L1_Initialize_t)(void); typedef OEMCryptoResult (*L1_Terminate_t)(void); typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session); @@ -67,10 +57,17 @@ 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, + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type); +typedef OEMCryptoResult (*L1_LoadKeys_V14_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_V14* 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)( @@ -96,13 +93,20 @@ 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)( +typedef OEMCryptoResult (*L1_LoadEntitledContentKeys_t)( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array); +typedef OEMCryptoResult (*L1_LoadEntitledContentKeys_V14_t)( OEMCrypto_SESSION session, size_t num_keys, - const OEMCrypto_EntitledContentKeyObject* key_array); + const OEMCrypto_EntitledContentKeyObject_V14* 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, const OEMCrypto_KeyRefreshObject* key_array); +typedef OEMCryptoResult (*L1_RefreshKeys_V14_t)( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, size_t num_keys, + const OEMCrypto_KeyRefreshObject_V14* key_array); 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); @@ -348,8 +352,11 @@ struct FunctionPointers { L1_LoadKeys_V11_or_V12_t LoadKeys_V11_or_V12; L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12; L1_LoadKeys_V13_t LoadKeys_V13; + L1_LoadKeys_V14_t LoadKeys_V14; L1_SelectKey_V13_t SelectKey_V13; L1_LoadTestKeybox_V13_t LoadTestKeybox_V13; + L1_LoadEntitledContentKeys_V14_t LoadEntitledContentKeys_V14; + L1_RefreshKeys_V14_t RefreshKeys_V14; }; // The WatchDog looks after a worker thread that is trying to initialize L3. @@ -713,8 +720,10 @@ class Adapter { 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(13, 13, LoadKeys_V13, OEMCrypto_LoadKeys_V13); - LOOKUP_ALL(14, LoadKeys, OEMCrypto_LoadKeys); - LOOKUP_ALL(14, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys); + LOOKUP(14, 14, LoadKeys_V14, OEMCrypto_LoadKeys_V14); + LOOKUP_ALL(15, LoadKeys, OEMCrypto_LoadKeys); + LOOKUP(14, 14, LoadEntitledContentKeys_V14,OEMCrypto_LoadEntitledContentKeys_V14); + LOOKUP_ALL(15, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys); LOOKUP_ALL(13, LoadSRM, OEMCrypto_LoadSRM); LOOKUP(10, 13, LoadTestKeybox_V13, OEMCrypto_LoadTestKeybox_V13); LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox); @@ -724,7 +733,8 @@ class Adapter { LOOKUP_ALL(13, MoveEntry, OEMCrypto_MoveEntry); LOOKUP_ALL( 8, OpenSession, OEMCrypto_OpenSession); LOOKUP_ALL(10, QueryKeyControl, OEMCrypto_QueryKeyControl); - LOOKUP_ALL( 8, RefreshKeys, OEMCrypto_RefreshKeys); + LOOKUP( 8, 14, RefreshKeys_V14, OEMCrypto_RefreshKeys_V14); + LOOKUP_ALL(15, RefreshKeys, OEMCrypto_RefreshKeys); LOOKUP_ALL(13, RemoveSRM, OEMCrypto_RemoveSRM); LOOKUP_ALL( 9, ReportUsage, OEMCrypto_ReportUsage); LOOKUP_ALL( 8, RewrapDeviceRSAKey, OEMCrypto_RewrapDeviceRSAKey); @@ -817,9 +827,12 @@ class Adapter { level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys; level3_.GenerateNonce = Level3_GenerateNonce; level3_.GenerateSignature = Level3_GenerateSignature; - level3_.LoadKeys = Level3_LoadKeys; - level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys; - level3_.RefreshKeys = Level3_RefreshKeys; + // TODO(srujzs) level3_.LoadKeys = Level3_LoadKeys; + level3_.LoadKeys_V14 = Level3_LoadKeys; + // TODO(srujzs) level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys; + level3_.LoadEntitledContentKeys_V14 = Level3_LoadEntitledContentKeys; + // TODO(srujzs) level3_.RefreshKeys = Level3_RefreshKeys; + level3_.RefreshKeys_V14 = Level3_RefreshKeys; level3_.QueryKeyControl = Level3_QueryKeyControl; level3_.SelectKey = Level3_SelectKey; level3_.DecryptCENC = Level3_DecryptCENC; @@ -1270,13 +1283,19 @@ extern "C" uint32_t OEMCrypto_ResourceRatingTier() { return OEMCrypto_ResourceRatingTier(kLevelDefault); } +// Used for backwards compatibility. If the length is 0, this denotes a NULL +// pointer for OEMCrypto v15. +const uint8_t* PointerOrNull(const uint8_t* pointer, size_t length) { + return length ? pointer : NULL; +} + 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_V13* key_array, const uint8_t* pst, - size_t pst_length, const uint8_t* srm_requirement, - OEMCrypto_LicenseType license_type) { + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes) { if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = gAdapter->GetSession(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; @@ -1285,118 +1304,46 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat( 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; - if (key_array[i].cipher_mode == OEMCrypto_CipherMode_CBC) { + key_array_v10[i].key_id = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v10[i].key_id_length = key_array[i].key_id.length; + key_array_v10[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v10[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v10[i].key_data_length = key_array[i].key_data.length; + key_array_v10[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v10[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + if (cipher_modes[i] == OEMCrypto_CipherMode_CBC) { LOGE("CBC Mode not supported."); 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 (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); + return pair.fcn->LoadKeys_V8( + pair.session, message, message_length, signature, signature_length, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + 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 < 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 (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - LevelSession pair = gAdapter->GetSession(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); + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v10_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length); // Convert a vendor specific error, to make it actionable if (result == kOemCryptoResultVendorSpecificError1) result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; @@ -1407,13 +1354,172 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( 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].key_id = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v13[i].key_id_length = key_array[i].key_id.length; + key_array_v13[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v13[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v13[i].key_data_length = key_array[i].key_data.length; + key_array_v13[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v13[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + key_array_v13[i].cipher_mode = cipher_modes[i]; + } + 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, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v13_ptr, + PointerOrNull(message + pst.offset, pst.length), 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_V13 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadKeys_V13( + pair.session, message, message_length, signature, signature_length, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v13_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length, + PointerOrNull(message + srm_restriction_data.offset, + srm_restriction_data.length)); + } + } else if (pair.fcn->version < 15) { + if (pair.fcn->LoadKeys_V14 == 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 = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v14[i].key_id_length = key_array[i].key_id.length; + key_array_v14[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v14[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v14[i].key_data_length = key_array[i].key_data.length; + key_array_v14[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v14[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + } + OEMCrypto_KeyObject_V14* key_array_v14_ptr = NULL; + if (num_keys > 0) key_array_v14_ptr = &key_array_v14[0]; + return pair.fcn->LoadKeys_V14( + pair.session, message, message_length, signature, signature_length, + PointerOrNull(message + enc_mac_keys_iv.offset, enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v14_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length, + PointerOrNull(message + srm_restriction_data.offset, + srm_restriction_data.length), + license_type); + } 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_keys_iv, enc_mac_keys, + num_keys, key_array, pst, srm_restriction_data, + 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, + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type) { + if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + LevelSession pair = gAdapter->GetSession(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 = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v10[i].key_id_length = key_array[i].key_id.length; + key_array_v10[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v10[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v10[i].key_data_length = key_array[i].key_data.length; + key_array_v10[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v10[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + } + 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, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + 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, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v10_ptr, + PointerOrNull(message + pst.offset, pst.length), 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 = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v13[i].key_id_length = key_array[i].key_id.length; + key_array_v13[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v13[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v13[i].key_data_length = key_array[i].key_data.length; + key_array_v13[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v13[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); key_array_v13[i].cipher_mode = OEMCrypto_CipherMode_CTR; } OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL; @@ -1423,8 +1529,11 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( 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_v13_ptr, pst, - pst_length); + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v13_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length); // Convert a vendor specific error, to make it actionable if (result == kOemCryptoResultVendorSpecificError1) result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE; @@ -1432,32 +1541,99 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( } else { 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); + return pair.fcn->LoadKeys_V13( + pair.session, message, message_length, signature, signature_length, + PointerOrNull(message + enc_mac_keys_iv.offset, + enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v13_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length, + PointerOrNull(message + srm_restriction_data.offset, + srm_restriction_data.length)); } + } else if (pair.fcn->version < 15) { + if (pair.fcn->LoadKeys_V14 == 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 = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + key_array_v14[i].key_id_length = key_array[i].key_id.length; + key_array_v14[i].key_data_iv = + PointerOrNull(message + key_array[i].key_data_iv.offset, + key_array[i].key_data_iv.length); + key_array_v14[i].key_data = PointerOrNull( + message + key_array[i].key_data.offset, key_array[i].key_data.length); + key_array_v14[i].key_data_length = key_array[i].key_data.length; + key_array_v14[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + key_array_v14[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + } + OEMCrypto_KeyObject_V14* key_array_v14_ptr = NULL; + if (num_keys > 0) key_array_v14_ptr = &key_array_v14[0]; + return pair.fcn->LoadKeys_V14( + pair.session, message, message_length, signature, signature_length, + PointerOrNull(message + enc_mac_keys_iv.offset, enc_mac_keys_iv.length), + PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length), + num_keys, key_array_v14_ptr, + PointerOrNull(message + pst.offset, pst.length), pst.length, + PointerOrNull(message + srm_restriction_data.offset, + srm_restriction_data.length), + license_type); } 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); + signature_length, enc_mac_keys_iv, enc_mac_keys, + num_keys, key_array, pst, srm_restriction_data, + license_type); } } extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( - OEMCrypto_SESSION session, size_t num_keys, - const OEMCrypto_EntitledContentKeyObject* key_array) { + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) { if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = gAdapter->GetSession(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; if (pair.fcn->version < 14) { return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } else if (pair.fcn->version < 15) { + if (pair.fcn->LoadEntitledContentKeys_V14 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + std::vector ecko_array_v14( + num_keys); + for (size_t i = 0; i < num_keys; i++) { + ecko_array_v14[i].entitlement_key_id = + PointerOrNull(message + key_array[i].entitlement_key_id.offset, + key_array[i].entitlement_key_id.length); + ecko_array_v14[i].entitlement_key_id_length = + key_array[i].entitlement_key_id.length; + ecko_array_v14[i].content_key_id = + PointerOrNull(message + key_array[i].content_key_id.offset, + key_array[i].content_key_id.length); + ecko_array_v14[i].content_key_id_length = + key_array[i].content_key_id.length; + ecko_array_v14[i].content_key_data_iv = + PointerOrNull(message + key_array[i].content_key_data_iv.offset, + key_array[i].content_key_data_iv.length); + ecko_array_v14[i].content_key_data = + PointerOrNull(message + key_array[i].content_key_data.offset, + key_array[i].content_key_data.length); + ecko_array_v14[i].content_key_data_length = + key_array[i].content_key_data.length; + } + OEMCrypto_EntitledContentKeyObject_V14* ecko_array_v14_ptr = NULL; + if (num_keys > 0) ecko_array_v14_ptr = &ecko_array_v14[0]; + return pair.fcn->LoadEntitledContentKeys_V14(pair.session, num_keys, + ecko_array_v14_ptr); + } else { + if (pair.fcn->LoadEntitledContentKeys == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + return pair.fcn->LoadEntitledContentKeys( + pair.session, message, message_length, num_keys, key_array); } - 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( @@ -1467,6 +1643,27 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE; LevelSession pair = gAdapter->GetSession(session); if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION; + if (pair.fcn->version < 15) { + if (pair.fcn->RefreshKeys_V14 == NULL) + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + std::vector kro_array_v14(num_keys); + for (size_t i = 0; i < num_keys; i++) { + kro_array_v14[i].key_id = PointerOrNull( + message + key_array[i].key_id.offset, key_array[i].key_id.length); + kro_array_v14[i].key_id_length = key_array[i].key_id.length; + kro_array_v14[i].key_control_iv = + PointerOrNull(message + key_array[i].key_control_iv.offset, + key_array[i].key_control_iv.length); + kro_array_v14[i].key_control = + PointerOrNull(message + key_array[i].key_control.offset, + key_array[i].key_control.length); + } + OEMCrypto_KeyRefreshObject_V14* kro_array_v14_ptr = NULL; + if (num_keys > 0) kro_array_v14_ptr = &kro_array_v14[0]; + return pair.fcn->RefreshKeys_V14(pair.session, message, message_length, + signature, signature_length, num_keys, + kro_array_v14_ptr); + } if (pair.fcn->RefreshKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED; return pair.fcn->RefreshKeys(pair.session, message, message_length, signature, signature_length, num_keys, key_array); diff --git a/libwvdrmengine/cdm/core/src/sublicense_key_session.cpp b/libwvdrmengine/cdm/core/src/sublicense_key_session.cpp index f839f6d2..f8d4d0ff 100644 --- a/libwvdrmengine/cdm/core/src/sublicense_key_session.cpp +++ b/libwvdrmengine/cdm/core/src/sublicense_key_session.cpp @@ -163,45 +163,34 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys( const std::string& provider_session_token, CdmCipherMode* cipher_mode, const std::string& srm_requirement) { const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* enc_mac_key = NULL; - const uint8_t* enc_mac_key_iv = NULL; - if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { - enc_mac_key = msg + GetOffset(message, mac_key); - enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); - } else { - LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); - } + bool valid_mac_keys = + mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE; + OEMCrypto_Substring enc_mac_key = + GetSubstring(message, mac_key, !valid_mac_keys); + OEMCrypto_Substring enc_mac_key_iv = + GetSubstring(message, mac_key_iv, !valid_mac_keys); + if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); - uint8_t* pst = NULL; - if (!provider_session_token.empty()) { - pst = - const_cast(msg) + GetOffset(message, provider_session_token); - } - - uint8_t* srm_req = NULL; - if (!srm_requirement.empty()) { - srm_req = const_cast(msg) + GetOffset(message, srm_requirement); - } + OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement); for (size_t i = 0; i < keys.size(); i++) { - OEMCrypto_KeyObject_V13 key_object; + OEMCrypto_KeyObject key_object; const CryptoKey& key_data = keys[i]; - key_object.key_id = msg + GetOffset(message, key_data.key_id()); - key_object.key_id_length = key_data.key_id().length(); - key_object.key_data_iv = msg + GetOffset(message, key_data.key_data_iv()); - key_object.key_data = msg + GetOffset(message, key_data.key_data()); - key_object.key_data_length = key_data.key_data().length(); - if (key_data.HasKeyControl()) { - key_object.key_control_iv = - msg + GetOffset(message, key_data.key_control_iv()); - key_object.key_control = msg + GetOffset(message, key_data.key_control()); - } else { + key_object.key_id = GetSubstring(message, key_data.key_id()); + key_object.key_data_iv = GetSubstring(message, key_data.key_data_iv()); + key_object.key_data = GetSubstring(message, key_data.key_data()); + bool has_key_control = key_data.HasKeyControl(); + key_object.key_control_iv = + GetSubstring(message, key_data.key_control_iv(), !has_key_control); + key_object.key_control = + GetSubstring(message, key_data.key_control(), !has_key_control); + if (!has_key_control) { LOGE("For key %s: XXX key has no control block. size=%d", key_data.key_id().c_str(), key_data.key_control().size()); - key_object.key_control_iv = NULL; - key_object.key_control = NULL; } - key_object.cipher_mode = ToOEMCryptoCipherMode(key_data.cipher_mode()); + OEMCryptoCipherMode oem_cipher_mode = + ToOEMCryptoCipherMode(key_data.cipher_mode()); // TODO(jfore): Does returning the cipher mode serve any purpose? // If not drop. @@ -216,13 +205,12 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys( } OEMCryptoResult sts; - M_TIME( - sts = OEMCrypto_LoadKeys_Back_Compat( - oec_session_id->second, msg, message.size(), - reinterpret_cast(signature.data()), - signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst, - provider_session_token.length(), srm_req, OEMCrypto_ContentLicense), - metrics_, oemcrypto_load_keys_, sts); + M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat( + oec_session_id->second, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, + pst, srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode), + metrics_, oemcrypto_load_keys_, sts); if (sts != OEMCrypto_SUCCESS) { return sts; @@ -269,31 +257,20 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys( std::string mac_deriv_message; std::string enc_deriv_message; - GenerateMacContext(group_id_ + message.c_str(), - &mac_deriv_message); - GenerateEncryptContext(group_id_ + message.c_str(), - &enc_deriv_message); + GenerateMacContext(group_id_ + message.c_str(), &mac_deriv_message); + GenerateEncryptContext(group_id_ + message.c_str(), &enc_deriv_message); const uint8_t* msg = reinterpret_cast(message.data()); - const uint8_t* enc_mac_key = NULL; - const uint8_t* enc_mac_key_iv = NULL; - if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) { - enc_mac_key = msg + GetOffset(message, mac_key); - enc_mac_key_iv = msg + GetOffset(message, mac_key_iv); - } else { - LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); - } + bool valid_mac_keys = + mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE; + OEMCrypto_Substring enc_mac_key = + GetSubstring(message, mac_key, !valid_mac_keys); + OEMCrypto_Substring enc_mac_key_iv = + GetSubstring(message, mac_key_iv, !valid_mac_keys); + if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set"); - uint8_t* pst = NULL; - if (!provider_session_token.empty()) { - pst = - const_cast(msg) + GetOffset(message, provider_session_token); - } - - uint8_t* srm_req = NULL; - if (!srm_requirement.empty()) { - srm_req = const_cast(msg) + GetOffset(message, srm_requirement); - } + OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement); OEMCryptoResult sts; const std::string& sub_session_key = keys_[key_index].sub_session_key(); @@ -314,29 +291,25 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys( return sts; } - OEMCrypto_KeyObject_V13 key_object; - key_object.key_id = msg + GetOffset(message, keys_[key_index].key_id()); - key_object.key_id_length = keys_[key_index].key_id().length(); + OEMCrypto_KeyObject key_object; + key_object.key_id = GetSubstring(message, keys_[key_index].key_id()); key_object.key_data_iv = - msg + GetOffset(message, keys_[key_index].key_data_iv()); - key_object.key_data = msg + GetOffset(message, keys_[key_index].key_data()); - key_object.key_data_length = keys_[key_index].key_data().length(); - if (key.HasKeyControl()) { - key_object.key_control_iv = - msg + GetOffset(message, keys_[key_index].key_control_iv()); - key_object.key_control = - msg + GetOffset(message, keys_[key_index].key_control()); - } - key_object.cipher_mode = + GetSubstring(message, keys_[key_index].key_data_iv()); + key_object.key_data = GetSubstring(message, keys_[key_index].key_data()); + bool has_key_control = key.HasKeyControl(); + key_object.key_control_iv = GetSubstring( + message, keys_[key_index].key_control_iv(), !has_key_control); + key_object.key_control = + GetSubstring(message, keys_[key_index].key_control(), !has_key_control); + OEMCryptoCipherMode oem_cipher_mode = ToOEMCryptoCipherMode(keys_[key_index].cipher_mode()); - M_TIME( - sts = OEMCrypto_LoadKeys_Back_Compat( - it->second, msg, message.size(), - reinterpret_cast(signature.data()), signature.size(), - enc_mac_key_iv, enc_mac_key, 1, &key_object, pst, - provider_session_token.length(), srm_req, OEMCrypto_ContentLicense), - metrics_, oemcrypto_load_keys_, sts); + M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat( + it->second, msg, message.size(), + reinterpret_cast(signature.data()), + signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst, + srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode), + metrics_, oemcrypto_load_keys_, sts); if (sts != OEMCrypto_SUCCESS) { return sts; diff --git a/libwvdrmengine/cdm/core/test/test_base.cpp b/libwvdrmengine/cdm/core/test/test_base.cpp index 95618ffa..f0341bb0 100644 --- a/libwvdrmengine/cdm/core/test/test_base.cpp +++ b/libwvdrmengine/cdm/core/test/test_base.cpp @@ -600,7 +600,6 @@ void TestLicenseHolder::SignAndLoadLicense() { std::string session_key_s(session_key_.begin(), session_key_.end()); std::string encrypted_session_key; EXPECT_TRUE(rsa_key_.Encrypt(session_key_s, &encrypted_session_key)); - video_widevine::SignedMessage signed_response; signed_response.set_msg(license_data); signed_response.set_type(video_widevine::SignedMessage_MessageType_LICENSE); diff --git a/libwvdrmengine/cdm/util/include/string_conversions.h b/libwvdrmengine/cdm/util/include/string_conversions.h index 6e6d781a..3a6a3543 100644 --- a/libwvdrmengine/cdm/util/include/string_conversions.h +++ b/libwvdrmengine/cdm/util/include/string_conversions.h @@ -26,6 +26,7 @@ std::string HexEncode(const uint8_t* bytes, unsigned size); std::string IntToString(int value); int64_t htonll64(int64_t x); inline int64_t ntohll64(int64_t x) { return htonll64(x); } +std::string BytesToString(const uint8_t* bytes, unsigned size); } // namespace wvcdm diff --git a/libwvdrmengine/cdm/util/src/string_conversions.cpp b/libwvdrmengine/cdm/util/src/string_conversions.cpp index 1f5661e3..d3a561d6 100644 --- a/libwvdrmengine/cdm/util/src/string_conversions.cpp +++ b/libwvdrmengine/cdm/util/src/string_conversions.cpp @@ -292,4 +292,10 @@ int64_t htonll64(int64_t x) { // Convert to big endian (network-byte-order) } } +std::string BytesToString(const uint8_t* bytes, unsigned size) { + if (!bytes || !size) return ""; + const char* char_bytes = reinterpret_cast(bytes); + return std::string(char_bytes, char_bytes + size); +} + } // namespace wvcdm diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index fcc5a3c7..2440beae 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -202,20 +202,6 @@ typedef struct { * The memory for the OEMCrypto_KeyObject fields is allocated and freed * by the caller of OEMCrypto_LoadKeys(). */ -#if 1 -// TODO(b/115874964, srujzs): For this and the ones below struct and function -// using Substring, rename the the old structure to *_V14 and move to the -// dynamic adapter for backwards compatiblity. -typedef struct { - 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; -} OEMCrypto_KeyObject; -#else typedef struct { OEMCrypto_Substring key_id; OEMCrypto_Substring key_data_iv; @@ -223,7 +209,6 @@ typedef struct { OEMCrypto_Substring key_control_iv; OEMCrypto_Substring key_control; } OEMCrypto_KeyObject; -#endif /* * SRM_Restriction_Data @@ -248,24 +233,12 @@ typedef struct { * key_data - encrypted content key data. * key_data_length - length of key_data - 16 or 32 depending on intended use. */ -#if 1 // TODO(b/115874964, srujzs): rename and move. -typedef struct { - const uint8_t* entitlement_key_id; - size_t entitlement_key_id_length; - const uint8_t* content_key_id; - size_t content_key_id_length; - const uint8_t* content_key_data_iv; - const uint8_t* content_key_data; - size_t content_key_data_length; -} OEMCrypto_EntitledContentKeyObject; -#else typedef struct { OEMCrypto_Substring entitlement_key_id; OEMCrypto_Substring content_key_id; OEMCrypto_Substring content_key_data_iv; OEMCrypto_Substring content_key_data; } OEMCrypto_EntitledContentKeyObject; -#endif /* * OEMCrypto_KeyRefreshObject @@ -286,21 +259,11 @@ typedef struct { * The memory for the OEMCrypto_KeyRefreshObject fields is allocated and freed * by the caller of OEMCrypto_RefreshKeys(). */ -#if 1 // TODO(b/115874964, srujzs): rename and move. -typedef struct { - const uint8_t* key_id; - size_t key_id_length; - const uint8_t* key_control_iv; - const uint8_t* key_control; -} OEMCrypto_KeyRefreshObject; -#else typedef struct { OEMCrypto_Substring key_id; OEMCrypto_Substring key_control_iv; OEMCrypto_Substring key_control; } OEMCrypto_KeyRefreshObject; -#endif - /* * OEMCrypto_Algorithm @@ -478,7 +441,7 @@ const uint32_t OEMCrypto_Partner_Defined_Hash = 2; #define OEMCrypto_GetMaxNumberOfSessions _oecc37 #define OEMCrypto_GetNumberOfOpenSessions _oecc38 #define OEMCrypto_IsAntiRollbackHwPresent _oecc39 -#define OEMCrypto_CopyBuffer_v14 _oecc40 +#define OEMCrypto_CopyBuffer_V14 _oecc40 #define OEMCrypto_QueryKeyControl _oecc41 #define OEMCrypto_LoadTestKeybox_V13 _oecc42 #define OEMCrypto_ForceDeleteUsageEntry _oecc43 @@ -1208,15 +1171,6 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length); * Version: * This method changed in API version 14. */ -#if 1 // TODO(b/115874964, srujzs): rename and move. -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, const uint8_t* srm_requirement, - OEMCrypto_LicenseType license_type); -#else OEMCryptoResult OEMCrypto_LoadKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, @@ -1224,7 +1178,6 @@ OEMCryptoResult OEMCrypto_LoadKeys( size_t num_keys, const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, OEMCrypto_LicenseType license_type); -#endif /* * OEMCrypto_LoadEntitledContentKeys @@ -1285,17 +1238,9 @@ OEMCryptoResult OEMCrypto_LoadKeys( * Version: * This method is new in API version 14. */ -#if 1 // TODO(b/115874964, srujzs): rename and move. -OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( - OEMCrypto_SESSION session, - size_t num_keys, - const OEMCrypto_EntitledContentKeyObject* key_array); -#else -// DOUBLE TODO(jfore,srujzs,fredgc): Do we really have a message for this? OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array); -#endif /* * OEMCrypto_RefreshKeys @@ -1409,17 +1354,10 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( * Version: * This method changed in API version 12. */ -#if 1 // TODO(b/115874964, srujzs): rename and move. 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, const OEMCrypto_KeyRefreshObject* key_array); -#else -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, - const OEMCrypto_KeyRefreshObject* key_array); -#endif /* * OEMCrypto_QueryKeyControl diff --git a/libwvdrmengine/oemcrypto/include/level3.h b/libwvdrmengine/oemcrypto/include/level3.h index d2f2d1a7..499d2ca4 100644 --- a/libwvdrmengine/oemcrypto/include/level3.h +++ b/libwvdrmengine/oemcrypto/include/level3.h @@ -170,13 +170,10 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session, size_t message_length, uint8_t* signature, size_t* signature_length); -OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session, - const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, - size_t num_keys, - const OEMCrypto_KeyRefreshObject* key_array); +OEMCryptoResult Level3_RefreshKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, size_t num_keys, + const OEMCrypto_KeyRefreshObject_V14* key_array); OEMCryptoResult Level3_QueryKeyControl(OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length, @@ -347,27 +344,20 @@ OEMCryptoResult Level3_CreateOldUsageEntry(uint64_t time_since_license_received, const uint8_t* pst, size_t pst_length); uint32_t Level3_GetAnalogOutputFlags(); -OEMCryptoResult Level3_LoadTestKeybox(const uint8_t *buffer, size_t length); -OEMCryptoResult Level3_LoadEntitledContentKeys(OEMCrypto_SESSION session, - size_t num_keys, - const OEMCrypto_EntitledContentKeyObject* key_array); +OEMCryptoResult Level3_LoadTestKeybox(const uint8_t* buffer, size_t length); +OEMCryptoResult Level3_LoadEntitledContentKeys( + OEMCrypto_SESSION session, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject_V14* key_array); OEMCryptoResult Level3_SelectKey(const OEMCrypto_SESSION session, - const uint8_t* key_id, - size_t key_id_length, + const uint8_t* key_id, size_t key_id_length, OEMCryptoCipherMode cipher_mode); -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, - const uint8_t* srm_requirement, - OEMCrypto_LicenseType license_type); +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_V14* key_array, const uint8_t* pst, + size_t pst_length, const uint8_t* srm_requirement, + OEMCrypto_LicenseType license_type); /* * Level3_GetInitializationState * diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index cff1c742..bbe064dc 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -239,12 +239,21 @@ bool RangeCheck(const uint8_t* message, uint32_t message_length, return true; } +bool RangeCheck(uint32_t message_length, const OEMCrypto_Substring& substring, + bool allow_null) { + if (!substring.length) return allow_null; + if (substring.offset > message_length) return false; + if (substring.offset + substring.length > message_length) return false; + return true; +} + 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_keys, 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) { + OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys, + size_t num_keys, const OEMCrypto_KeyObject* key_array, + OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type) { if (!crypto_engine) { LOGE("OEMCrypto_LoadKeys: OEMCrypto Not Initialized."); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -263,20 +272,12 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - // Later on, we use pst_length to verify the the pst is valid. This makes - // sure that we aren't given a null string but told it has postiive length. - if (pst == NULL && pst_length > 0) { - LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_ONCTEXT - null pst.]"); - return OEMCrypto_ERROR_INVALID_CONTEXT; - } // Range check - if (!RangeCheck(message, message_length, enc_mac_keys, 2 * wvoec::MAC_KEY_SIZE, - true) || - !RangeCheck(message, message_length, enc_mac_key_iv, wvoec::KEY_IV_SIZE, true) || - !RangeCheck(message, message_length, pst, pst_length, true) || - !RangeCheck(message, message_length, srm_requirement, - wvoec::SRM_REQUIREMENT_SIZE, true)) { + if (!RangeCheck(message_length, enc_mac_keys_iv, true) || + !RangeCheck(message_length, enc_mac_keys, true) || + !RangeCheck(message_length, pst, true) || + !RangeCheck(message_length, srm_restriction_data, true)) { LOGE( "[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range " "check.]"); @@ -284,16 +285,11 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( } for (unsigned int i = 0; i < num_keys; i++) { - if (!RangeCheck(message, message_length, key_array[i].key_id, - key_array[i].key_id_length, false) || - !RangeCheck(message, message_length, key_array[i].key_data, - key_array[i].key_data_length, false) || - !RangeCheck(message, message_length, key_array[i].key_data_iv, - wvoec::KEY_IV_SIZE, false) || - !RangeCheck(message, message_length, key_array[i].key_control, - wvoec::KEY_CONTROL_SIZE, false) || - !RangeCheck(message, message_length, key_array[i].key_control_iv, - wvoec::KEY_IV_SIZE, false)) { + if (!RangeCheck(message_length, key_array[i].key_id, false) || + !RangeCheck(message_length, key_array[i].key_data, false) || + !RangeCheck(message_length, key_array[i].key_data_iv, false) || + !RangeCheck(message_length, key_array[i].key_control, false) || + !RangeCheck(message_length, key_array[i].key_control_iv, false)) { LOGE( "[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range " "check %d]", @@ -302,14 +298,14 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys( } } return session_ctx->LoadKeys(message, message_length, signature, - signature_length, enc_mac_key_iv, enc_mac_keys, - num_keys, key_array, pst, pst_length, - srm_requirement, license_type); + signature_length, enc_mac_keys_iv, enc_mac_keys, + num_keys, key_array, pst, srm_restriction_data, + license_type); } extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( - OEMCrypto_SESSION session, size_t num_keys, - const OEMCrypto_EntitledContentKeyObject* key_array) { + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) { if (num_keys == 0) { LOGE("[OEMCrypto_LoadEntitledContentKeys(): key_array is empty."); return OEMCrypto_SUCCESS; @@ -327,8 +323,22 @@ extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys( LOGE("[OEMCrypto_LoadEntitledContentKeys(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } + for (unsigned int i = 0; i < num_keys; i++) { + if (!RangeCheck(message_length, key_array[i].entitlement_key_id, false) || + !RangeCheck(message_length, key_array[i].content_key_id, false) || + !RangeCheck(message_length, key_array[i].content_key_data_iv, false) || + !RangeCheck(message_length, key_array[i].content_key_data, false)) { + LOGE( + "[OEMCrypto_LoadEntitledContentKeys(): " + "OEMCrypto_ERROR_INVALID_CONTEXT -range " + "check %d]", + i); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + } - return session_ctx->LoadEntitledContentKeys(num_keys, key_array); + return session_ctx->LoadEntitledContentKeys(message, message_length, num_keys, + key_array); } extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( @@ -359,12 +369,9 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( // Range check for (unsigned int i = 0; i < num_keys; i++) { - if (!RangeCheck(message, message_length, key_array[i].key_id, - key_array[i].key_id_length, true) || - !RangeCheck(message, message_length, key_array[i].key_control, - wvoec::KEY_CONTROL_SIZE, false) || - !RangeCheck(message, message_length, key_array[i].key_control_iv, - wvoec::KEY_IV_SIZE, true)) { + if (!RangeCheck(message_length, key_array[i].key_id, true) || + !RangeCheck(message_length, key_array[i].key_control, false) || + !RangeCheck(message_length, key_array[i].key_control_iv, true)) { LOGE("[OEMCrypto_RefreshKeys(): Range Check %d]", i); return OEMCrypto_ERROR_INVALID_CONTEXT; } @@ -383,24 +390,28 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys( std::vector key_control; std::vector key_control_iv; for (unsigned int i = 0; i < num_keys; i++) { - if (key_array[i].key_id != NULL) { - key_id.assign(key_array[i].key_id, - key_array[i].key_id + key_array[i].key_id_length); - key_control.assign(key_array[i].key_control, - key_array[i].key_control + wvoec::KEY_CONTROL_SIZE); - if (key_array[i].key_control_iv == NULL) { + if (key_array[i].key_id.length != 0) { + key_id.assign( + message + key_array[i].key_id.offset, + message + key_array[i].key_id.offset + key_array[i].key_id.length); + key_control.assign( + message + key_array[i].key_control.offset, + message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE); + if (key_array[i].key_control_iv.length == 0) { key_control_iv.clear(); } else { - key_control_iv.assign(key_array[i].key_control_iv, - key_array[i].key_control_iv + wvoec::KEY_IV_SIZE); + key_control_iv.assign( + message + key_array[i].key_control_iv.offset, + message + key_array[i].key_control_iv.offset + wvoec::KEY_IV_SIZE); } } else { // key_id could be null if special control key type // key_control is not encrypted in this case key_id.clear(); key_control_iv.clear(); - key_control.assign(key_array[i].key_control, - key_array[i].key_control + wvoec::KEY_CONTROL_SIZE); + key_control.assign( + message + key_array[i].key_control.offset, + message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE); } status = session_ctx->RefreshKey(key_id, key_control, key_control_iv); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index eadc640b..ba5ef9e6 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -492,10 +492,11 @@ uint32_t SessionContext::CurrentTimer() { OEMCryptoResult SessionContext::LoadKeys( 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_keys, 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) { + size_t signature_length, OEMCrypto_Substring enc_mac_keys_iv, + OEMCrypto_Substring enc_mac_keys, size_t num_keys, + const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst, + OEMCrypto_Substring srm_restriction_data, + OEMCrypto_LicenseType license_type) { // Validate message signature if (!ValidateMessage(message, message_length, signature, signature_length)) { return OEMCrypto_ERROR_SIGNATURE_FAILURE; @@ -522,16 +523,16 @@ OEMCryptoResult SessionContext::LoadKeys( StartTimer(); - if (srm_requirement) { + if (srm_restriction_data.length != 0) { const std::string kSRMVerificationString = "HDCPDATA"; - if (memcmp(srm_requirement, kSRMVerificationString.c_str(), - kSRMVerificationString.size())) { + if (memcmp(message + srm_restriction_data.offset, + kSRMVerificationString.c_str(), kSRMVerificationString.size())) { LOGE("SRM Requirement Data has bad verification string: %8s", - srm_requirement); + message + srm_restriction_data.offset); return OEMCrypto_ERROR_INVALID_CONTEXT; } - uint32_t minimum_version = - htonl(*reinterpret_cast(srm_requirement + 8)); + uint32_t minimum_version = htonl(*reinterpret_cast( + message + srm_restriction_data.offset + 8)); uint16_t current_version = 0; if (OEMCrypto_SUCCESS != ce_->current_srm_version(¤t_version)) { LOGW("[LoadKeys: SRM Version not available."); @@ -563,20 +564,25 @@ OEMCryptoResult SessionContext::LoadKeys( std::vector key_control; std::vector key_control_iv; for (unsigned int i = 0; i < num_keys; i++) { - key_id.assign(key_array[i].key_id, - key_array[i].key_id + key_array[i].key_id_length); - enc_key_data.assign(key_array[i].key_data, - key_array[i].key_data + key_array[i].key_data_length); - key_data_iv.assign(key_array[i].key_data_iv, - key_array[i].key_data_iv + wvoec::KEY_IV_SIZE); - if (key_array[i].key_control == NULL) { + key_id.assign( + message + key_array[i].key_id.offset, + message + key_array[i].key_id.offset + key_array[i].key_id.length); + enc_key_data.assign( + message + key_array[i].key_data.offset, + message + key_array[i].key_data.offset + key_array[i].key_data.length); + key_data_iv.assign( + message + key_array[i].key_data_iv.offset, + message + key_array[i].key_data_iv.offset + wvoec::KEY_IV_SIZE); + if (key_array[i].key_control.length == 0) { status = OEMCrypto_ERROR_UNKNOWN_FAILURE; break; } - key_control.assign(key_array[i].key_control, - key_array[i].key_control + wvoec::KEY_CONTROL_SIZE); - key_control_iv.assign(key_array[i].key_control_iv, - key_array[i].key_control_iv + wvoec::KEY_IV_SIZE); + key_control.assign( + message + key_array[i].key_control.offset, + message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE); + key_control_iv.assign( + message + key_array[i].key_control_iv.offset, + message + key_array[i].key_control_iv.offset + wvoec::KEY_IV_SIZE); OEMCryptoResult result = InstallKey(key_id, enc_key_data, key_data_iv, key_control, @@ -590,12 +596,14 @@ OEMCryptoResult SessionContext::LoadKeys( if (status != OEMCrypto_SUCCESS) return status; // enc_mac_key can be NULL if license renewal is not supported - if (enc_mac_keys != NULL) { + if (enc_mac_keys.length != 0) { // V2.1 license protocol: update mac keys after processing license response const std::vector enc_mac_keys_str = std::vector( - enc_mac_keys, enc_mac_keys + 2 * wvoec::MAC_KEY_SIZE); + message + enc_mac_keys.offset, + message + enc_mac_keys.offset + 2 * wvoec::MAC_KEY_SIZE); const std::vector enc_mac_key_iv_str = std::vector( - enc_mac_key_iv, enc_mac_key_iv + wvoec::KEY_IV_SIZE); + message + enc_mac_keys_iv.offset, + message + enc_mac_keys_iv.offset + wvoec::KEY_IV_SIZE); if (!UpdateMacKeys(enc_mac_keys_str, enc_mac_key_iv_str)) { LOGE("Failed to update mac keys.\n"); @@ -606,13 +614,13 @@ OEMCryptoResult SessionContext::LoadKeys( OEMCryptoResult result = OEMCrypto_SUCCESS; switch (usage_entry_status_) { case kNoUsageEntry: - if (pst_length > 0) { + if (pst.length > 0) { LOGE("LoadKeys: PST specified but no usage entry loaded."); return OEMCrypto_ERROR_INVALID_CONTEXT; } break; // no extra check. case kUsageEntryNew: - result = usage_entry_->SetPST(pst, pst_length); + result = usage_entry_->SetPST(message + pst.offset, pst.length); if (result != OEMCrypto_SUCCESS) { return result; } @@ -622,7 +630,7 @@ OEMCryptoResult SessionContext::LoadKeys( } break; case kUsageEntryLoaded: - if (!usage_entry_->VerifyPST(pst, pst_length)) { + if (!usage_entry_->VerifyPST(message + pst.offset, pst.length)) { return OEMCrypto_ERROR_WRONG_PST; } if (!usage_entry_->VerifyMacKeys(mac_key_server_, mac_key_client_)) { @@ -637,7 +645,8 @@ OEMCryptoResult SessionContext::LoadKeys( } OEMCryptoResult SessionContext::LoadEntitledContentKeys( - size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) { + const uint8_t* message, size_t message_length, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject* key_array) { if (!key_array) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -647,9 +656,9 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys( for (size_t i = 0; i < num_keys; ++i) { const OEMCrypto_EntitledContentKeyObject* key_data = &key_array[i]; std::vector entitlement_key_id; - entitlement_key_id.assign( - key_data->entitlement_key_id, - key_data->entitlement_key_id + key_data->entitlement_key_id_length); + entitlement_key_id.assign(message + key_data->entitlement_key_id.offset, + message + key_data->entitlement_key_id.offset + + key_data->entitlement_key_id.length); const std::vector* entitlement_key = NULL; if (!session_keys_->GetEntitlementKey(entitlement_key_id, @@ -661,14 +670,14 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys( std::vector encrypted_content_key; std::vector content_key_id; - iv.assign(key_data->content_key_data_iv, - key_data->content_key_data_iv + 16); - encrypted_content_key.assign( - key_data->content_key_data, - key_data->content_key_data + key_data->content_key_data_length); - content_key_id.assign( - key_data->content_key_id, - key_data->content_key_id + key_data->content_key_id_length); + iv.assign(message + key_data->content_key_data_iv.offset, + message + key_data->content_key_data_iv.offset + 16); + encrypted_content_key.assign(message + key_data->content_key_data.offset, + message + key_data->content_key_data.offset + + key_data->content_key_data.length); + content_key_id.assign(message + key_data->content_key_id.offset, + message + key_data->content_key_id.offset + + key_data->content_key_id.length); if (!DecryptMessage(*entitlement_key, iv, encrypted_content_key, &content_key, 256 /* key size */)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index 0ddf74e6..5471ac7e 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h @@ -119,13 +119,14 @@ class SessionContext { uint32_t CurrentTimer(); // (seconds). virtual OEMCryptoResult LoadKeys( 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_keys, size_t num_keys, - const OEMCrypto_KeyObject* key_array, const uint8_t* pst, - size_t pst_length, const uint8_t* srm_requirement, + size_t signature_length, OEMCrypto_Substring enc_mac_keys_iv, + OEMCrypto_Substring enc_mac_keys, size_t num_keys, + const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst, + OEMCrypto_Substring srm_restriction_data, OEMCrypto_LicenseType license_type); OEMCryptoResult LoadEntitledContentKeys( - size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array); + const uint8_t* message, size_t message_length, size_t num_keys, + const OEMCrypto_EntitledContentKeyObject* key_array); virtual OEMCryptoResult InstallKey(const KeyId& key_id, const std::vector& key_data, const std::vector& key_data_iv, diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp index a68c1973..d87fcd6c 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_usage_table_ref.cpp @@ -69,7 +69,7 @@ UsageTableEntry::~UsageTableEntry() { usage_table_->ReleaseEntry(data_.index); } OEMCryptoResult UsageTableEntry::SetPST(const uint8_t* pst, size_t pst_length) { if (pst_length > kMaxPSTLength) return OEMCrypto_ERROR_BUFFER_TOO_LARGE; data_.pst_length = pst_length; - if (!pst) return OEMCrypto_ERROR_INVALID_CONTEXT; + if (!pst || !pst_length) return OEMCrypto_ERROR_INVALID_CONTEXT; memcpy(data_.pst, pst, pst_length); data_.time_of_license_received = time(NULL); return OEMCrypto_SUCCESS; @@ -78,7 +78,7 @@ OEMCryptoResult UsageTableEntry::SetPST(const uint8_t* pst, size_t pst_length) { bool UsageTableEntry::VerifyPST(const uint8_t* pst, size_t pst_length) { if (pst_length > kMaxPSTLength) return false; if (data_.pst_length != pst_length) return false; - if (!pst) return false; + if (!pst || !pst_length) return false; return 0 == memcmp(pst, data_.pst, pst_length); } diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index e1ff80d7..f155c05e 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -97,6 +97,26 @@ class boringssl_ptr { CORE_DISALLOW_COPY_AND_ASSIGN(boringssl_ptr); }; +OEMCrypto_Substring GetSubstring(const std::string& message, + const std::string& field, bool set_zero) { + OEMCrypto_Substring substring; + if (set_zero || field.empty() || message.empty()) { + substring.offset = 0; + substring.length = 0; + } else { + size_t pos = message.find(field); + if (pos == std::string::npos) { + LOGW("GetSubstring : Cannot find offset for %s", field.c_str()); + substring.offset = 0; + substring.length = 0; + } else { + substring.offset = pos; + substring.length = field.length(); + } + } + return substring; +} + Session::Session() : open_(false), forced_session_id_(false), @@ -254,129 +274,146 @@ void Session::GenerateDerivedKeysFromSessionKey() { DeriveKeys(&session_key[0], mac_context, enc_context); } -void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) { - uint8_t* pst_ptr = NULL; - if (pst.length() > 0) { - pst_ptr = encrypted_license().pst; - } +void Session::LoadTestKeys(const std::string& provider_session_token, + bool new_mac_keys) { + std::string message = + wvcdm::BytesToString(message_ptr(), sizeof(MessageData)); + OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + OEMCrypto_Substring enc_mac_keys_iv = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_key_iv, + sizeof(encrypted_license().mac_key_iv))); + OEMCrypto_Substring enc_mac_keys = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_keys, + sizeof(encrypted_license().mac_keys))); if (new_mac_keys) { ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_, - &signature_[0], signature_.size(), - encrypted_license().mac_key_iv, - encrypted_license().mac_keys, num_keys_, - key_array_, pst_ptr, pst.length(), NULL, - OEMCrypto_ContentLicense)); + OEMCrypto_LoadKeys( + session_id(), message_ptr(), message_size_, &signature_[0], + signature_.size(), enc_mac_keys_iv, enc_mac_keys, num_keys_, + key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense)); // Update new generated keys. memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE); - memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, - MAC_KEY_SIZE); + memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE); } else { - 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(), NULL, - OEMCrypto_ContentLicense)); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys( + session_id(), message_ptr(), message_size_, &signature_[0], + signature_.size(), GetSubstring(), GetSubstring(), num_keys_, + key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense)); } VerifyTestKeys(); } -void Session::LoadEntitlementTestKeys(const std::string& pst, - bool new_mac_keys, - OEMCryptoResult expected_sts) { - uint8_t* pst_ptr = NULL; - if (pst.length() > 0) { - pst_ptr = encrypted_license().pst; - } +void Session::LoadEntitlementTestKeys(const std::string& provider_session_token, + bool new_mac_keys, + OEMCryptoResult expected_sts) { + std::string message = + wvcdm::BytesToString(message_ptr(), sizeof(MessageData)); + OEMCrypto_Substring pst = GetSubstring(message, provider_session_token); + OEMCrypto_Substring enc_mac_keys_iv = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_key_iv, + sizeof(encrypted_license().mac_key_iv))); + OEMCrypto_Substring enc_mac_keys = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_keys, + sizeof(encrypted_license().mac_keys))); if (new_mac_keys) { - ASSERT_EQ(expected_sts, - OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_, - &signature_[0], signature_.size(), - encrypted_license().mac_key_iv, - encrypted_license().mac_keys, num_keys_, - key_array_, pst_ptr, pst.length(), NULL, - OEMCrypto_EntitlementLicense)); + ASSERT_EQ( + expected_sts, + OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_, + &signature_[0], signature_.size(), enc_mac_keys_iv, + enc_mac_keys, num_keys_, key_array_, pst, + GetSubstring(), OEMCrypto_EntitlementLicense)); // Update new generated keys. memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE); - memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, - MAC_KEY_SIZE); + memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE); } else { ASSERT_EQ( expected_sts, OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_, - &signature_[0], signature_.size(), NULL, NULL, - num_keys_, key_array_, pst_ptr, pst.length(), NULL, - OEMCrypto_EntitlementLicense)); + &signature_[0], signature_.size(), GetSubstring(), + GetSubstring(), num_keys_, key_array_, pst, + GetSubstring(), OEMCrypto_EntitlementLicense)); } } void Session::FillEntitledKeyArray() { + int offset = 0; + entitled_message_.clear(); for (size_t i = 0; i < num_keys_; ++i) { EntitledContentKeyData* key_data = &entitled_key_data_[i]; - entitled_key_array_[i].entitlement_key_id = key_array_[i].key_id; - entitled_key_array_[i].entitlement_key_id_length = - key_array_[i].key_id_length; + entitled_key_array_[i].entitlement_key_id.offset = offset; + entitled_key_array_[i].entitlement_key_id.length = + key_array_[i].key_id.length; + offset += key_array_[i].key_id.length; + entitled_message_ += + wvcdm::BytesToString(message_ptr() + key_array_[i].key_id.offset, + key_array_[i].key_id.length); - EXPECT_EQ( - 1, GetRandBytes(key_data->content_key_id, - sizeof(key_data->content_key_id))); - entitled_key_array_[i].content_key_id = key_data->content_key_id; - entitled_key_array_[i].content_key_id_length = + EXPECT_EQ(1, GetRandBytes(key_data->content_key_id, + sizeof(key_data->content_key_id))); + entitled_key_array_[i].content_key_id.offset = offset; + entitled_key_array_[i].content_key_id.length = sizeof(key_data->content_key_id); + offset += sizeof(key_data->content_key_id); + entitled_message_ += wvcdm::BytesToString(key_data->content_key_id, + sizeof(key_data->content_key_id)); - EXPECT_EQ( - 1, GetRandBytes(key_data->content_key_data, - sizeof(key_data->content_key_data))); - entitled_key_array_[i].content_key_data = key_data->content_key_data; - entitled_key_array_[i].content_key_data_length = + EXPECT_EQ(1, GetRandBytes(key_data->content_key_data, + sizeof(key_data->content_key_data))); + entitled_key_array_[i].content_key_data.offset = offset; + entitled_key_array_[i].content_key_data.length = sizeof(key_data->content_key_data); + offset += sizeof(key_data->content_key_data); + entitled_message_ += wvcdm::BytesToString( + key_data->content_key_data, sizeof(key_data->content_key_data)); - EXPECT_EQ( - 1, GetRandBytes(entitled_key_data_[i].content_key_data_iv, - sizeof(entitled_key_data_[i].content_key_data_iv))); - entitled_key_array_[i].content_key_data_iv = key_data->content_key_data_iv; + EXPECT_EQ(1, GetRandBytes(key_data[i].content_key_data_iv, + sizeof(key_data[i].content_key_data_iv))); + entitled_key_array_[i].content_key_data_iv.offset = offset; + entitled_key_array_[i].content_key_data_iv.length = + sizeof(key_data->content_key_data_iv); + offset += sizeof(key_data->content_key_data_iv); + entitled_message_ += wvcdm::BytesToString( + key_data->content_key_data_iv, sizeof(key_data->content_key_data_iv)); } } void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) { - // Create a copy of the stored |entitled_key_array_|. + encrypted_entitled_message_ = entitled_message_; std::vector encrypted_entitled_key_array; encrypted_entitled_key_array.resize(num_keys_); memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0], sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_); - // Create an encrypted version of all of the content keys stored in - // |entitled_key_array_|. - std::vector > encrypted_content_keys; - encrypted_content_keys.resize(num_keys_); - for (size_t i = 0; i < num_keys_; ++i) { // Load the entitlement key from |key_array_|. AES_KEY aes_key; - AES_set_encrypt_key(&key_array_[i].key_data[0], 256, &aes_key); - encrypted_content_keys[i].resize( - encrypted_entitled_key_array[i].content_key_data_length); + AES_set_encrypt_key(message_ptr() + key_array_[i].key_data.offset, 256, + &aes_key); // Encrypt the content key with the entitlement key. uint8_t iv[16]; - memcpy(&iv[0], &encrypted_entitled_key_array[i].content_key_data[0], 16); - AES_cbc_encrypt( - &entitled_key_array_[i].content_key_data[0], - const_cast( - &encrypted_entitled_key_array[i].content_key_data[0]), - encrypted_entitled_key_array[i].content_key_data_length, - &aes_key, iv, AES_ENCRYPT); - - // Set the |encrypted_entitled_key_array| to point to the encrypted copy - // of the content key. - encrypted_entitled_key_array[i].content_key_data = - encrypted_content_keys[i].data(); + const uint8_t* content_key_data = reinterpret_cast( + entitled_message_.data() + + entitled_key_array_[i].content_key_data.offset); + const uint8_t* encrypted_content_key_data = + reinterpret_cast( + encrypted_entitled_message_.data() + + encrypted_entitled_key_array[i].content_key_data.offset); + memcpy(&iv[0], encrypted_content_key_data, 16); + AES_cbc_encrypt(content_key_data, + const_cast(encrypted_content_key_data), + encrypted_entitled_key_array[i].content_key_data.length, + &aes_key, iv, AES_ENCRYPT); } - ASSERT_EQ(expected_sts, - OEMCrypto_LoadEntitledContentKeys( - session_id(), num_keys_, &encrypted_entitled_key_array[0])); + ASSERT_EQ( + expected_sts, + OEMCrypto_LoadEntitledContentKeys( + session_id(), + reinterpret_cast(encrypted_entitled_message_.data()), + encrypted_entitled_message_.size(), num_keys_, + &encrypted_entitled_key_array[0])); if (expected_sts != OEMCrypto_SUCCESS) { return; } @@ -409,9 +446,12 @@ void Session::VerifyEntitlementTestKeys() { for (unsigned int i = 0; i < num_keys_; i++) { KeyControlBlock block; size_t size = sizeof(block); + const uint8_t* content_key_id = + reinterpret_cast(entitled_message_.data()); OEMCryptoResult sts = OEMCrypto_QueryKeyControl( - session_id(), entitled_key_array_[i].content_key_id, - entitled_key_array_[i].content_key_id_length, + session_id(), + content_key_id + entitled_key_array_[i].content_key_id.offset, + entitled_key_array_[i].content_key_id.length, reinterpret_cast(&block), &size); if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -578,6 +618,27 @@ void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits, } } +void Session::SetLoadKeysSubstringParams() { + load_keys_params_.resize(4); + std::string message = + wvcdm::BytesToString(message_ptr(), sizeof(MessageData)); + OEMCrypto_Substring* enc_mac_keys_iv = &load_keys_params_[0]; + *enc_mac_keys_iv = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_key_iv, + sizeof(encrypted_license().mac_key_iv))); + OEMCrypto_Substring* enc_mac_keys = &load_keys_params_[1]; + *enc_mac_keys = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().mac_keys, + sizeof(encrypted_license().mac_keys))); + OEMCrypto_Substring* pst = &load_keys_params_[2]; + size_t pst_length = + strlen(reinterpret_cast(encrypted_license().pst)); + *pst = GetSubstring( + message, wvcdm::BytesToString(encrypted_license().pst, pst_length)); + OEMCrypto_Substring* srm_req = &load_keys_params_[3]; + *srm_req = GetSubstring(); +} + void Session::EncryptAndSign() { encrypted_license() = license_; @@ -606,6 +667,7 @@ void Session::EncryptAndSign() { ServerSignBuffer(reinterpret_cast(&padded_message_), message_size_, &signature_); FillKeyArray(encrypted_license(), key_array_); + SetLoadKeysSubstringParams(); } void Session::EncryptProvisioningMessage( @@ -664,31 +726,45 @@ void Session::VerifyClientSignature(size_t data_length) { void Session::FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array) { + const uint8_t* data_ptr = reinterpret_cast(&data); + std::string message = wvcdm::BytesToString(data_ptr, sizeof(MessageData)); for (unsigned int i = 0; i < num_keys_; i++) { - key_array[i].key_id = data.keys[i].key_id; - key_array[i].key_id_length = data.keys[i].key_id_length; - key_array[i].key_data_iv = data.keys[i].key_iv; - key_array[i].key_data = data.keys[i].key_data; - key_array[i].key_data_length = data.keys[i].key_data_length; - key_array[i].key_control_iv = data.keys[i].control_iv; - key_array[i].key_control = + key_array[i].key_id = GetSubstring( + message, + wvcdm::BytesToString(data.keys[i].key_id, data.keys[i].key_id_length)); + key_array[i].key_data_iv = GetSubstring( + message, + wvcdm::BytesToString(data.keys[i].key_iv, sizeof(data.keys[i].key_iv))); + key_array[i].key_data = GetSubstring( + message, wvcdm::BytesToString(data.keys[i].key_data, + data.keys[i].key_data_length)); + key_array[i].key_control_iv = GetSubstring( + message, wvcdm::BytesToString(data.keys[i].control_iv, + sizeof(data.keys[i].control_iv))); + const uint8_t* key_control_ptr = reinterpret_cast(&data.keys[i].control); + key_array[i].key_control = GetSubstring( + message, + wvcdm::BytesToString(key_control_ptr, sizeof(data.keys[i].control))); } } void Session::FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array, size_t key_count) { + std::string message = + wvcdm::BytesToString(message_ptr(), sizeof(MessageData)); for (size_t i = 0; i < key_count; i++) { - if (key_count > 1) { - key_array[i].key_id = encrypted_license().keys[i].key_id; - key_array[i].key_id_length = encrypted_license().keys[i].key_id_length; - } else { - key_array[i].key_id = NULL; - key_array[i].key_id_length = 0; - } - key_array[i].key_control_iv = NULL; - key_array[i].key_control = - reinterpret_cast(&encrypted_license().keys[i].control); + key_array[i].key_id = GetSubstring( + message, + wvcdm::BytesToString(encrypted_license().keys[i].key_id, + sizeof(encrypted_license().keys[i].key_id)), + key_count <= 1); + key_array[i].key_control_iv = GetSubstring(); + key_array[i].key_control = GetSubstring( + message, + wvcdm::BytesToString(reinterpret_cast( + &encrypted_license().keys[i].control), + sizeof(encrypted_license().keys[i].control))); } } @@ -1290,4 +1366,8 @@ void Session::set_message_size(size_t size) { ASSERT_LE(message_size_, kMaxMessageSize); } +const uint8_t* Session::encrypted_entitled_message_ptr() { + return reinterpret_cast(encrypted_entitled_message_.data()); +} + } // namespace wvoec diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.h b/libwvdrmengine/oemcrypto/test/oec_session_util.h index 0de68ec8..885ce2ad 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.h +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.h @@ -125,6 +125,13 @@ uint32_t htonl_fnc(uint32_t x); // Prints error string from BoringSSL void dump_boringssl_error(); +// Given a message and field, returns an OEMCrypto_Substring with the field's +// offset into the message and its length. If |set_zero| is true, both the +// offset and length will be zero. +OEMCrypto_Substring GetSubstring(const std::string& message = "", + const std::string& field = "", + bool set_zero = false); + class Session { public: Session(); @@ -205,6 +212,11 @@ class Session { // is just signed. The signature is computed in RefreshTestKeys, above. void FillRefreshMessage(size_t key_count, uint32_t control_bits, uint32_t nonce); + // Sets the OEMCrypto_Substring parameters of the LoadKeys method. + // Specifically, it sets the |enc_mac_keys_iv|, |enc_mac_keys|, |pst|, and + // |srm_restriction_data| in that order. For testing purposes, + // |srm_restriction_data| will always be NULL. + void SetLoadKeysSubstringParams(); // This copies data from license_ to encrypted_license_, and then encrypts // each field in the key array appropriately. It then signes the buffer with // the server mac keys. It then fills out the key_array_ so that pointers in @@ -386,6 +398,19 @@ class Session { // The size of the encrypted message. size_t message_size() { return message_size_; } + // The OEMCrypto_Substrings associated with the encrypted license that are + // passed to LoadKeys. + vector load_keys_params() { return load_keys_params_; } + OEMCrypto_Substring enc_mac_keys_iv_substr() { return load_keys_params_[0]; } + OEMCrypto_Substring enc_mac_keys_substr() { return load_keys_params_[1]; } + OEMCrypto_Substring pst_substr() { return load_keys_params_[2]; } + OEMCrypto_Substring srm_restriction_data_substr() { + return load_keys_params_[3]; + } + + // Pointer to buffer holding |encrypted_entitled_message_| + const uint8_t* encrypted_entitled_message_ptr(); + private: // Generate mac and enc keys give the master key. void DeriveKeys(const uint8_t* master_key, @@ -410,6 +435,7 @@ class Session { } padded_message_; size_t message_size_; // How much of the padded message to use. OEMCrypto_KeyObject key_array_[kMaxNumKeys]; + vector load_keys_params_; std::vector signature_; unsigned int num_keys_; vector encrypted_usage_entry_; @@ -419,8 +445,11 @@ class Session { // Clear Entitlement key data. This is the backing data for // |entitled_key_array_|. EntitledContentKeyData entitled_key_data_[kMaxNumKeys]; + // Message containing data from |key_array| and |entitled_key_data_|. + std::string entitled_message_; // Entitled key object. Pointers are backed by |entitled_key_data_|. OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys]; + std::string encrypted_entitled_message_; }; } // namespace wvoec diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 7a6bd875..54cf8c72 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -913,9 +913,10 @@ TEST_F(OEMCryptoSessionTests, LoadEntitlementKeysWrongEntitlementKeysAPI14) { ASSERT_NO_FATAL_FAILURE(s.LoadEntitlementTestKeys()); s.FillEntitledKeyArray(); const std::string key_id = "no_key"; - s.entitled_key_array()[0].entitlement_key_id = - reinterpret_cast(key_id.c_str()); - s.entitled_key_array()[0].entitlement_key_id_length = key_id.length(); + memcpy(const_cast(s.encrypted_entitled_message_ptr()) + + s.entitled_key_array()[0].entitlement_key_id.offset, + reinterpret_cast(key_id.c_str()), key_id.length()); + s.entitled_key_array()[0].entitlement_key_id.length = key_id.length(); s.LoadEntitledContentKeys(OEMCrypto_KEY_NOT_ENTITLED); } @@ -961,6 +962,15 @@ TEST_F(OEMCryptoSessionTests, LoadKeyLargeBuffer) { ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys()); } +// Returns a string containing two times the original message in continuous +// memory. Used as part of the BadRange tests. +std::string DuplicateMessage(MessageData& message) { + std::string single_message = wvcdm::BytesToString( + reinterpret_cast(&message), sizeof(message)); + std::string double_message = single_message + single_message; + return double_message; +} + /* The Bad Range tests verify that OEMCrypto_LoadKeys checks the range of all the pointers. It should reject a message if the pointer does not point into the message buffer */ @@ -970,15 +980,17 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector mac_keys( - s.encrypted_license().mac_keys, - s.encrypted_license().mac_keys + sizeof(s.encrypted_license().mac_keys)); + std::string double_message = DuplicateMessage(s.encrypted_license()); + OEMCrypto_Substring wrong_mac_keys = s.enc_mac_keys_substr(); + wrong_mac_keys.offset += s.message_size(); 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, - &mac_keys[0], // Not pointing into buffer. - s.num_keys(), s.key_array(), NULL, 0, NULL, OEMCrypto_ContentLicense); + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), + wrong_mac_keys, // Not within range of one message. + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -988,17 +1000,16 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector mac_key_iv(s.encrypted_license().mac_key_iv, - s.encrypted_license().mac_key_iv + - sizeof(s.encrypted_license().mac_key_iv)); + std::string double_message = DuplicateMessage(s.encrypted_license()); + OEMCrypto_Substring wrong_mac_keys_iv = s.enc_mac_keys_iv_substr(); + wrong_mac_keys_iv.offset += s.message_size(); - OEMCryptoResult sts = - OEMCrypto_LoadKeys(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, NULL, - OEMCrypto_ContentLicense); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + wrong_mac_keys_iv, // bad. + s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(), + GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1008,16 +1019,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector bad_buffer(s.encrypted_license().keys[0].key_id, - s.encrypted_license().keys[0].key_id + - s.encrypted_license().keys[0].key_id_length); - s.key_array()[0].key_id = &bad_buffer[0]; + std::string double_message = DuplicateMessage(s.encrypted_license()); + s.key_array()[0].key_id.offset += s.message_size(); 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, - NULL, OEMCrypto_ContentLicense); + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), + s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1028,16 +1037,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) { ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector bad_buffer( - s.encrypted_license().keys[1].key_data, - s.encrypted_license().keys[1].key_data + wvoec::KEY_SIZE); - s.key_array()[1].key_data = &bad_buffer[0]; + std::string double_message = DuplicateMessage(s.encrypted_license()); + s.key_array()[1].key_data.offset += s.message_size(); 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, - NULL, OEMCrypto_ContentLicense); + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), + s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1047,15 +1054,13 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector bad_buffer(s.encrypted_license().keys[1].key_iv, - s.encrypted_license().keys[1].key_iv + - sizeof(s.encrypted_license().keys[1].key_iv)); - s.key_array()[1].key_data_iv = &bad_buffer[0]; + std::string double_message = DuplicateMessage(s.encrypted_license()); + s.key_array()[1].key_data_iv.offset += s.message_size(); 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, - NULL, OEMCrypto_ContentLicense); + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), + s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1066,16 +1071,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange6) { ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector bad_buffer(s.key_array()[2].key_control, - s.key_array()[2].key_control + - sizeof(s.encrypted_license().keys[1].control)); - s.key_array()[2].key_control = &bad_buffer[0]; + std::string double_message = DuplicateMessage(s.encrypted_license()); + s.key_array()[2].key_control.offset += s.message_size(); 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, - NULL, OEMCrypto_ContentLicense); + s.session_id(), reinterpret_cast(double_message.data()), + s.message_size(), &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(), + s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1085,17 +1088,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - vector bad_buffer( - s.key_array()[2].key_control_iv, - s.key_array()[2].key_control_iv + - sizeof(s.encrypted_license().keys[1].control_iv)); - s.key_array()[2].key_control_iv = &bad_buffer[0]; + std::string double_message = DuplicateMessage(s.encrypted_license()); + s.key_array()[2].key_control_iv.offset += s.message_size(); 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1103,15 +1103,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); - ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, - wvoec::kControlNonceEnabled, + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, 42)); // bad nonce. 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1129,15 +1128,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) { ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); - ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, - wvoec::kControlNonceEnabled, + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, nonce)); // same old nonce. 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1161,9 +1159,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceReopenSession) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1186,9 +1184,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceWrongSession) { ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign()); OEMCryptoResult sts = OEMCrypto_LoadKeys( s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0], - s2.signature().size(), s2.encrypted_license().mac_key_iv, - s2.encrypted_license().mac_keys, s2.num_keys(), s2.key_array(), NULL, 0, - NULL, OEMCrypto_ContentLicense); + s2.signature().size(), s2.enc_mac_keys_iv_substr(), + s2.enc_mac_keys_substr(), s2.num_keys(), s2.key_array(), GetSubstring(), + GetSubstring(), OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1202,9 +1200,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1238,9 +1236,9 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); // If this is a future API, then LoadKeys should fail. if (global_features.api_version < target_api_) { ASSERT_NE(OEMCrypto_SUCCESS, sts); @@ -1266,9 +1264,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) { s.signature()[0] ^= 42; // Bad signature. 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1280,9 +1278,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); } @@ -1298,8 +1296,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeys) { ASSERT_NE( 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, NULL, + &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + kNoKeys, s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); } @@ -1314,8 +1313,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) { ASSERT_NE( 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, NULL, + &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + kNoKeys, s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense)); } @@ -1370,9 +1370,9 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); if (OEMCrypto_IsAntiRollbackHwPresent()) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } else { @@ -1394,44 +1394,39 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) { OEMCrypto_SUCCESS, 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, NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), + GetSubstring(), OEMCrypto_ContentLicense)); } if (patch_level < 0x3F) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( - 0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift, - 0)); + 0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); ASSERT_EQ( OEMCrypto_ERROR_UNKNOWN_FAILURE, 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, NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), + GetSubstring(), OEMCrypto_ContentLicense)); } if (patch_level > 0) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( - 0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift, - 0)); + 0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift, 0)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); ASSERT_EQ( OEMCrypto_SUCCESS, 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, NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), + GetSubstring(), OEMCrypto_ContentLicense)); } } @@ -4781,7 +4776,6 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) { Session s2; ASSERT_NO_FATAL_FAILURE(s2.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2)); - uint8_t* pst_ptr = s.encrypted_license().pst; s2.LoadUsageEntry(s); // Use the same entry. // Trying to reuse a PST is bad. We use session ID for s2, everything else // reused from s. @@ -4789,10 +4783,9 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) { OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.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(), NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); ASSERT_NO_FATAL_FAILURE(s2.close()); } @@ -4808,9 +4801,9 @@ TEST_F(UsageTableTest, OnlineEmptyPST) { ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -4828,9 +4821,9 @@ TEST_F(UsageTableTest, OnlineMissingEntry) { // ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry()); 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(), - s.encrypted_license().pst, pst.length(), NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -4838,9 +4831,8 @@ TEST_F(UsageTableTest, OnlineMissingEntry) { TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) { std::string pst = "A PST"; uint32_t nonce = session_.get_nonce(); - MakeFourKeys( - 0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired, - nonce, pst); + MakeFourKeys(0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired, + nonce, pst); ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign()); ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry()); ASSERT_NO_FATAL_FAILURE(session_.LoadTestKeys(pst, new_mac_keys_)); @@ -5116,15 +5108,13 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { 0, wvoec::kControlNonceOrEntry, s2.get_nonce(), pst)); ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign()); ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); - uint8_t* pst_ptr = s2.encrypted_license().pst; ASSERT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s2.message_ptr(), s2.message_size(), &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(), NULL, - OEMCrypto_ContentLicense)); + s2.enc_mac_keys_iv_substr(), s2.enc_mac_keys_substr(), + s.num_keys(), s2.key_array(), s2.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); ASSERT_NO_FATAL_FAILURE(s2.close()); // Offline license with same mac keys should still be OK. @@ -5133,10 +5123,10 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); - ASSERT_NO_FATAL_FAILURE( - s.GenerateVerifyReport(pst, kUnused, - loaded, // license loaded. - 0, 0)); // first and last decrypt + ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused, + loaded, // license loaded. + 0, + 0)); // first and last decrypt } // An offline license should not load on the first call if the nonce is bad. @@ -5149,12 +5139,11 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) { ASSERT_NO_FATAL_FAILURE( s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - uint8_t* pst_ptr = s.encrypted_license().pst; 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(), pst_ptr, - pst.length(), NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5170,9 +5159,9 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) { 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, - NULL, OEMCrypto_ContentLicense); + s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(), + OEMCrypto_ContentLicense); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -5188,14 +5177,12 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineWrongPST) { ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); memcpy(s.license().pst, bad_pst.c_str(), bad_pst.length()); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - uint8_t* pst_ptr = s.encrypted_license().pst; - ASSERT_NE( - OEMCrypto_SUCCESS, - OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), - &s.signature()[0], s.signature().size(), NULL, NULL, - s.num_keys(), s.key_array(), - pst_ptr, bad_pst.length(), NULL, - OEMCrypto_ContentLicense)); + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), s.message_size(), + &s.signature()[0], s.signature().size(), GetSubstring(), + GetSubstring(), s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); } TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { @@ -5222,15 +5209,13 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2)); ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); // Offile license can not be reused if it has been deactivated. - uint8_t* pst_ptr = s.encrypted_license().pst; EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.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(), NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); s2.close(); // But we can still generate a report. Session s3; @@ -5265,15 +5250,13 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) { ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2)); ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s1)); // Offline license can not be reused if it has been deactivated. - uint8_t* pst_ptr = s1.encrypted_license().pst; EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(), &s1.signature()[0], s1.signature().size(), - s1.encrypted_license().mac_key_iv, - s1.encrypted_license().mac_keys, s1.num_keys(), - s1.key_array(), pst_ptr, pst.length(), NULL, - OEMCrypto_ContentLicense)); + s1.enc_mac_keys_iv_substr(), s1.enc_mac_keys_substr(), + s1.num_keys(), s1.key_array(), s1.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); s2.close(); // But we can still generate a report. Session s3; @@ -5293,15 +5276,13 @@ TEST_P(UsageTableTestWithMAC, BadRange) { ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( 0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst)); ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - uint8_t* pst_ptr = s.license().pst; // Bad: not in encrypted_license. ASSERT_NE( OEMCrypto_SUCCESS, 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(), pst_ptr, pst.length(), NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); } TEST_F(UsageTableTest, UpdateFailsWithNullPtr) { @@ -5371,15 +5352,13 @@ class UsageTableDefragTest : public UsageTableTest { &s->encrypted_usage_entry()[0], s->encrypted_usage_entry().size())); - uint8_t* pst_ptr = s->encrypted_license().pst; - ASSERT_NE( - OEMCrypto_SUCCESS, - 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(), pst_ptr, s->pst().length(), NULL, - OEMCrypto_ContentLicense)); + ASSERT_NE(OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys( + s->session_id(), s->message_ptr(), s->message_size(), + &s->signature()[0], s->signature().size(), + s->enc_mac_keys_iv_substr(), s->enc_mac_keys_substr(), + s->num_keys(), s->key_array(), s->pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); ASSERT_NO_FATAL_FAILURE(s->close()); } @@ -6056,15 +6035,13 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) { htonl(wvoec::kSharedLicense); } ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - uint8_t* pst_ptr = s.encrypted_license().pst; - ASSERT_EQ(OEMCrypto_ERROR_MISSING_MASTER, - 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(), pst_ptr, pst.length(), NULL, - OEMCrypto_ContentLicense)); + ASSERT_EQ( + OEMCrypto_ERROR_MISSING_MASTER, + OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(), + &s.signature()[0], s.signature().size(), + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); ASSERT_NO_FATAL_FAILURE(s.close()); } @@ -6091,16 +6068,14 @@ TEST_F(UsageTableTest, PSTLargeBuffer) { ASSERT_NO_FATAL_FAILURE(s2.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2)); // Offile license can not be reused if it has been deactivated. - uint8_t* pst_ptr = s.encrypted_license().pst; ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s)); EXPECT_NE( OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(s2.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(), NULL, - OEMCrypto_ContentLicense)); + s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), + s.num_keys(), s.key_array(), s.pst_substr(), + GetSubstring(), OEMCrypto_ContentLicense)); s2.close(); // But we can still generate a report. Session s3;