Update OEMCrypto calls to use substrings
Merge from master branch of Widevine repo of http://go/wvgerrit/66073 Merge from oemcrypto-v15 branch of Widevine repo of http://go/wvgerrit/64083 As part of the update to v15, LoadKeys, RefreshKeys, and LoadEntitledContentKeys should all use offsets and lengths into the message rather than a pointer for its parameters. The CDM, tests, adapters, and OEMCrypto implementations are changed to reflect this. Test: tested as part of http://go/ag/5501993 Bug: 115874964 Change-Id: I981fa322dec7c565066fd163ca5775dbff71fccf
This commit is contained in:
committed by
Fred Gylys-Colwell
parent
4550979f22
commit
e6439255ba
@@ -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<const uint8_t*>(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<OEMCrypto_KeyObject_V13> 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<OEMCrypto_KeyObject> load_keys(keys.size());
|
||||
std::vector<OEMCryptoCipherMode> 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<uint8_t*>(msg) + GetOffset(message, provider_session_token);
|
||||
}
|
||||
|
||||
uint8_t* srm_req = NULL;
|
||||
if (!srm_requirement.empty()) {
|
||||
srm_req = const_cast<uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<const uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(key_data_iv.data());
|
||||
|
||||
const std::string& key_data = input_key.key_data();
|
||||
output_key.content_key_data =
|
||||
reinterpret_cast<const uint8_t*>(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;
|
||||
}
|
||||
|
||||
@@ -41,16 +41,6 @@ static const size_t kMaxGenericEncryptChunkSize = 100*1024;
|
||||
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
|
||||
static_cast<OEMCryptoResult>(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<OEMCrypto_KeyObject_V10> 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<OEMCrypto_KeyObject> 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<OEMCrypto_KeyObject_V10> 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<OEMCrypto_KeyObject_V13> 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<OEMCrypto_KeyObject_V14> 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<OEMCrypto_KeyObject_V10> 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<OEMCrypto_KeyObject_V13> 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<OEMCrypto_KeyObject_V14> 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<OEMCrypto_EntitledContentKeyObject_V14> 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<OEMCrypto_KeyRefreshObject_V14> 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);
|
||||
|
||||
@@ -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<const uint8_t*>(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<uint8_t*>(msg) + GetOffset(message, provider_session_token);
|
||||
}
|
||||
|
||||
uint8_t* srm_req = NULL;
|
||||
if (!srm_requirement.empty()) {
|
||||
srm_req = const_cast<uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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<uint8_t*>(msg) + GetOffset(message, provider_session_token);
|
||||
}
|
||||
|
||||
uint8_t* srm_req = NULL;
|
||||
if (!srm_requirement.empty()) {
|
||||
srm_req = const_cast<uint8_t*>(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<const uint8_t*>(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<const uint8_t*>(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;
|
||||
|
||||
Reference in New Issue
Block a user