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
@@ -32,6 +32,9 @@ void GenerateMacContext(const std::string& input_context,
|
|||||||
void GenerateEncryptContext(const std::string& input_context,
|
void GenerateEncryptContext(const std::string& input_context,
|
||||||
std::string* deriv_context);
|
std::string* deriv_context);
|
||||||
size_t GetOffset(std::string message, std::string field);
|
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);
|
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode);
|
||||||
|
|
||||||
class CryptoSessionFactory;
|
class CryptoSessionFactory;
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ class EntitlementKeySession : public ContentKeySession {
|
|||||||
CdmCipherMode cipher_mode) override;
|
CdmCipherMode cipher_mode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The object returned by this function contains raw pointers to the passed-in
|
// The message is populated with the fields of the provided CryptoKey and the
|
||||||
// CryptoKey object. Care should be taken that it does not outlive the
|
// returned object reflects the offsets and lengths into that message for each
|
||||||
// CryptoKey.
|
// field.
|
||||||
OEMCrypto_EntitledContentKeyObject MakeOecEntitledKey(
|
OEMCrypto_EntitledContentKeyObject MakeOecEntitledKey(
|
||||||
const CryptoKey& input_key);
|
const CryptoKey& input_key, std::string& message);
|
||||||
|
|
||||||
std::map<std::string, CryptoKey> entitled_keys_;
|
std::map<std::string, CryptoKey> entitled_keys_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,7 +63,17 @@ uint32_t OEMCrypto_ResourceRatingTier(SecurityLevel level);
|
|||||||
*/
|
*/
|
||||||
extern "C" {
|
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;
|
const uint8_t* key_id;
|
||||||
size_t key_id_length;
|
size_t key_id_length;
|
||||||
const uint8_t* key_data_iv;
|
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_iv;
|
||||||
const uint8_t* key_control;
|
const uint8_t* key_control;
|
||||||
OEMCryptoCipherMode cipher_mode;
|
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.
|
// Backwards compitiblity between v14 and v13.
|
||||||
OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_length,
|
const uint8_t* signature, size_t signature_length,
|
||||||
const uint8_t* enc_mac_keys_iv, const uint8_t* enc_mac_keys,
|
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
|
||||||
size_t num_keys, const OEMCrypto_KeyObject_V13* key_array,
|
size_t num_keys, const OEMCrypto_KeyObject* key_array,
|
||||||
const uint8_t* pst, size_t pst_length, const uint8_t* srm_requirement,
|
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
|
||||||
OEMCrypto_LicenseType license_type);
|
OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes);
|
||||||
|
|
||||||
OEMCryptoResult OEMCrypto_UpdateUsageTable();
|
OEMCryptoResult OEMCrypto_UpdateUsageTable();
|
||||||
|
|
||||||
@@ -94,6 +114,46 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(
|
|||||||
|
|
||||||
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
|
OEMCryptoResult OEMCrypto_ForceDeleteUsageEntry(const uint8_t* pst,
|
||||||
size_t pst_length);
|
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"
|
} // extern "C"
|
||||||
|
|
||||||
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
#endif // WVCDM_CORE_OEMCRYPTO_ADAPTER_H_
|
||||||
|
|||||||
@@ -124,58 +124,51 @@ OEMCryptoResult ContentKeySession::LoadKeysAsLicenseType(
|
|||||||
const std::string& provider_session_token, CdmCipherMode* cipher_mode,
|
const std::string& provider_session_token, CdmCipherMode* cipher_mode,
|
||||||
const std::string& srm_requirement, OEMCrypto_LicenseType license_type) {
|
const std::string& srm_requirement, OEMCrypto_LicenseType license_type) {
|
||||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
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();
|
cached_key_id_.clear();
|
||||||
if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) {
|
bool valid_mac_keys =
|
||||||
enc_mac_key = msg + GetOffset(message, mac_key);
|
mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE;
|
||||||
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
|
OEMCrypto_Substring enc_mac_key =
|
||||||
} else {
|
GetSubstring(message, mac_key, !valid_mac_keys);
|
||||||
LOGV("enc_mac_key not set");
|
OEMCrypto_Substring enc_mac_key_iv =
|
||||||
}
|
GetSubstring(message, mac_key_iv, !valid_mac_keys);
|
||||||
std::vector<OEMCrypto_KeyObject_V13> load_keys(keys.size());
|
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) {
|
for (size_t i = 0; i < keys.size(); ++i) {
|
||||||
const CryptoKey* ki = &keys[i];
|
const CryptoKey* ki = &keys[i];
|
||||||
OEMCrypto_KeyObject_V13* ko = &load_keys[i];
|
OEMCrypto_KeyObject* ko = &load_keys[i];
|
||||||
ko->key_id = msg + GetOffset(message, ki->key_id());
|
ko->key_id = GetSubstring(message, ki->key_id());
|
||||||
ko->key_id_length = ki->key_id().length();
|
ko->key_data_iv = GetSubstring(message, ki->key_data_iv());
|
||||||
ko->key_data_iv = msg + GetOffset(message, ki->key_data_iv());
|
ko->key_data = GetSubstring(message, ki->key_data());
|
||||||
ko->key_data = msg + GetOffset(message, ki->key_data());
|
bool has_key_control = ki->HasKeyControl();
|
||||||
ko->key_data_length = ki->key_data().length();
|
ko->key_control_iv =
|
||||||
if (ki->HasKeyControl()) {
|
GetSubstring(message, ki->key_control_iv(), !has_key_control);
|
||||||
ko->key_control_iv = msg + GetOffset(message, ki->key_control_iv());
|
ko->key_control =
|
||||||
ko->key_control = msg + GetOffset(message, ki->key_control());
|
GetSubstring(message, ki->key_control(), !has_key_control);
|
||||||
} else {
|
if (!has_key_control) {
|
||||||
LOGE("For key %d: XXX key has no control block. size=%d", i,
|
LOGE("For key %d: XXX key has no control block. size=%d", i,
|
||||||
ki->key_control().size());
|
ki->key_control().length());
|
||||||
ko->key_control_iv = NULL;
|
|
||||||
ko->key_control = NULL;
|
|
||||||
}
|
}
|
||||||
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.
|
// TODO(jfore): Is returning the cipher needed. If not drop this.
|
||||||
*cipher_mode = ki->cipher_mode();
|
*cipher_mode = ki->cipher_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* pst = NULL;
|
OEMCrypto_Substring pst = GetSubstring(message, provider_session_token);
|
||||||
if (!provider_session_token.empty()) {
|
OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGV("id=%ld", (uint32_t)oec_session_id_);
|
LOGV("id=%ld", (uint32_t)oec_session_id_);
|
||||||
OEMCryptoResult sts;
|
OEMCryptoResult sts;
|
||||||
M_TIME(
|
OEMCrypto_KeyObject* key_array_ptr = NULL;
|
||||||
sts = ::OEMCrypto_LoadKeys_Back_Compat(
|
if (keys.size() > 0) key_array_ptr = &load_keys[0];
|
||||||
oec_session_id_, msg, message.size(),
|
OEMCryptoCipherMode* cipher_mode_ptr = NULL;
|
||||||
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
|
if (keys.size() > 0) cipher_mode_ptr = &cipher_modes[0];
|
||||||
enc_mac_key_iv, enc_mac_key, keys.size(), &load_keys[0], pst,
|
M_TIME(sts = ::OEMCrypto_LoadKeys_Back_Compat(
|
||||||
provider_session_token.length(), srm_req, license_type),
|
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);
|
metrics_, oemcrypto_load_keys_, sts);
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,26 @@ size_t GetOffset(std::string message, std::string field) {
|
|||||||
return pos;
|
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,
|
void GenerateMacContext(const std::string& input_context,
|
||||||
std::string* deriv_context) {
|
std::string* deriv_context) {
|
||||||
if (!deriv_context) {
|
if (!deriv_context) {
|
||||||
@@ -933,22 +953,12 @@ bool CryptoSession::RefreshKeys(const std::string& message,
|
|||||||
for (int i = 0; i < num_keys; ++i) {
|
for (int i = 0; i < num_keys; ++i) {
|
||||||
const CryptoKey* ki = &key_array[i];
|
const CryptoKey* ki = &key_array[i];
|
||||||
OEMCrypto_KeyRefreshObject* ko = &load_key_array[i];
|
OEMCrypto_KeyRefreshObject* ko = &load_key_array[i];
|
||||||
if (ki->key_id().empty()) {
|
ko->key_id = GetSubstring(message, ki->key_id());
|
||||||
ko->key_id = NULL;
|
bool has_key_control = ki->HasKeyControl();
|
||||||
} else {
|
ko->key_control_iv =
|
||||||
ko->key_id = msg + GetOffset(message, ki->key_id());
|
GetSubstring(message, ki->key_control_iv(), !has_key_control);
|
||||||
}
|
ko->key_control =
|
||||||
if (ki->HasKeyControl()) {
|
GetSubstring(message, ki->key_control(), !has_key_control);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LOGV("RefreshKeys: id=%lu", oec_session_id_);
|
LOGV("RefreshKeys: id=%lu", oec_session_id_);
|
||||||
OEMCryptoResult refresh_sts;
|
OEMCryptoResult refresh_sts;
|
||||||
|
|||||||
@@ -52,12 +52,14 @@ OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id,
|
|||||||
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string message;
|
||||||
OEMCrypto_EntitledContentKeyObject entitled_key =
|
OEMCrypto_EntitledContentKeyObject entitled_key =
|
||||||
MakeOecEntitledKey(entitled_keys_[key_id]);
|
MakeOecEntitledKey(entitled_keys_[key_id], message);
|
||||||
|
|
||||||
OEMCryptoResult result = OEMCrypto_SUCCESS;
|
OEMCryptoResult result = OEMCrypto_SUCCESS;
|
||||||
M_TIME(result = OEMCrypto_LoadEntitledContentKeys(oec_session_id_, 1,
|
M_TIME(result = OEMCrypto_LoadEntitledContentKeys(
|
||||||
&entitled_key),
|
oec_session_id_, reinterpret_cast<const uint8_t*>(message.data()),
|
||||||
|
message.size(), 1, &entitled_key),
|
||||||
metrics_, oemcrypto_load_entitled_keys_, result);
|
metrics_, oemcrypto_load_entitled_keys_, result);
|
||||||
if (result != OEMCrypto_SUCCESS) {
|
if (result != OEMCrypto_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
@@ -67,26 +69,30 @@ OEMCryptoResult EntitlementKeySession::SelectKey(const std::string& key_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCrypto_EntitledContentKeyObject EntitlementKeySession::MakeOecEntitledKey(
|
OEMCrypto_EntitledContentKeyObject EntitlementKeySession::MakeOecEntitledKey(
|
||||||
const CryptoKey& input_key) {
|
const CryptoKey& input_key, std::string& message) {
|
||||||
OEMCrypto_EntitledContentKeyObject output_key;
|
OEMCrypto_EntitledContentKeyObject output_key;
|
||||||
|
message.clear();
|
||||||
|
|
||||||
const std::string& entitlement_key_id = input_key.entitlement_key_id();
|
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();
|
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();
|
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();
|
const std::string& key_data = input_key.key_data();
|
||||||
output_key.content_key_data =
|
|
||||||
reinterpret_cast<const uint8_t*>(key_data.data());
|
output_key.entitlement_key_id.offset = message.size();
|
||||||
output_key.content_key_data_length = key_data.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;
|
return output_key;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,16 +41,6 @@ static const size_t kMaxGenericEncryptChunkSize = 100*1024;
|
|||||||
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
|
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
|
||||||
static_cast<OEMCryptoResult>(10008);
|
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_Initialize_t)(void);
|
||||||
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
||||||
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
|
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
|
||||||
@@ -67,10 +57,17 @@ typedef OEMCryptoResult (*L1_GenerateSignature_t)(OEMCrypto_SESSION session,
|
|||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
size_t* signature_length);
|
size_t* signature_length);
|
||||||
typedef OEMCryptoResult (*L1_LoadKeys_t)(
|
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,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_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 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,
|
size_t pst_length, const uint8_t* srm_requirement,
|
||||||
OEMCrypto_LicenseType license_type);
|
OEMCrypto_LicenseType license_type);
|
||||||
typedef OEMCryptoResult (*L1_LoadKeys_V13_t)(
|
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* signature, size_t signature_length,
|
||||||
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
|
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
|
||||||
const OEMCrypto_KeyObject_V10* key_array);
|
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,
|
OEMCrypto_SESSION session, size_t num_keys,
|
||||||
const OEMCrypto_EntitledContentKeyObject* key_array);
|
const OEMCrypto_EntitledContentKeyObject_V14* key_array);
|
||||||
typedef OEMCryptoResult (*L1_RefreshKeys_t)(
|
typedef OEMCryptoResult (*L1_RefreshKeys_t)(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_length, size_t num_keys,
|
const uint8_t* signature, size_t signature_length, size_t num_keys,
|
||||||
const OEMCrypto_KeyRefreshObject* key_array);
|
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)(
|
typedef OEMCryptoResult (*L1_QueryKeyControl_t)(
|
||||||
OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length,
|
OEMCrypto_SESSION session, const uint8_t* key_id, size_t key_id_length,
|
||||||
uint8_t* key_control_block, size_t* key_control_block_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_LoadKeys_V11_or_V12_t LoadKeys_V11_or_V12;
|
||||||
L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12;
|
L1_DeactivateUsageEntry_V12_t DeactivateUsageEntry_V12;
|
||||||
L1_LoadKeys_V13_t LoadKeys_V13;
|
L1_LoadKeys_V13_t LoadKeys_V13;
|
||||||
|
L1_LoadKeys_V14_t LoadKeys_V14;
|
||||||
L1_SelectKey_V13_t SelectKey_V13;
|
L1_SelectKey_V13_t SelectKey_V13;
|
||||||
L1_LoadTestKeybox_V13_t LoadTestKeybox_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.
|
// 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( 9, 10, LoadKeys_V9_or_V10, OEMCrypto_LoadKeys_V9_or_V10);
|
||||||
LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12);
|
LOOKUP(11, 12, LoadKeys_V11_or_V12, OEMCrypto_LoadKeys_V11_or_V12);
|
||||||
LOOKUP(13, 13, LoadKeys_V13, OEMCrypto_LoadKeys_V13);
|
LOOKUP(13, 13, LoadKeys_V13, OEMCrypto_LoadKeys_V13);
|
||||||
LOOKUP_ALL(14, LoadKeys, OEMCrypto_LoadKeys);
|
LOOKUP(14, 14, LoadKeys_V14, OEMCrypto_LoadKeys_V14);
|
||||||
LOOKUP_ALL(14, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys);
|
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_ALL(13, LoadSRM, OEMCrypto_LoadSRM);
|
||||||
LOOKUP(10, 13, LoadTestKeybox_V13, OEMCrypto_LoadTestKeybox_V13);
|
LOOKUP(10, 13, LoadTestKeybox_V13, OEMCrypto_LoadTestKeybox_V13);
|
||||||
LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox);
|
LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox);
|
||||||
@@ -724,7 +733,8 @@ class Adapter {
|
|||||||
LOOKUP_ALL(13, MoveEntry, OEMCrypto_MoveEntry);
|
LOOKUP_ALL(13, MoveEntry, OEMCrypto_MoveEntry);
|
||||||
LOOKUP_ALL( 8, OpenSession, OEMCrypto_OpenSession);
|
LOOKUP_ALL( 8, OpenSession, OEMCrypto_OpenSession);
|
||||||
LOOKUP_ALL(10, QueryKeyControl, OEMCrypto_QueryKeyControl);
|
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(13, RemoveSRM, OEMCrypto_RemoveSRM);
|
||||||
LOOKUP_ALL( 9, ReportUsage, OEMCrypto_ReportUsage);
|
LOOKUP_ALL( 9, ReportUsage, OEMCrypto_ReportUsage);
|
||||||
LOOKUP_ALL( 8, RewrapDeviceRSAKey, OEMCrypto_RewrapDeviceRSAKey);
|
LOOKUP_ALL( 8, RewrapDeviceRSAKey, OEMCrypto_RewrapDeviceRSAKey);
|
||||||
@@ -817,9 +827,12 @@ class Adapter {
|
|||||||
level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys;
|
level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys;
|
||||||
level3_.GenerateNonce = Level3_GenerateNonce;
|
level3_.GenerateNonce = Level3_GenerateNonce;
|
||||||
level3_.GenerateSignature = Level3_GenerateSignature;
|
level3_.GenerateSignature = Level3_GenerateSignature;
|
||||||
level3_.LoadKeys = Level3_LoadKeys;
|
// TODO(srujzs) level3_.LoadKeys = Level3_LoadKeys;
|
||||||
level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys;
|
level3_.LoadKeys_V14 = Level3_LoadKeys;
|
||||||
level3_.RefreshKeys = Level3_RefreshKeys;
|
// 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_.QueryKeyControl = Level3_QueryKeyControl;
|
||||||
level3_.SelectKey = Level3_SelectKey;
|
level3_.SelectKey = Level3_SelectKey;
|
||||||
level3_.DecryptCENC = Level3_DecryptCENC;
|
level3_.DecryptCENC = Level3_DecryptCENC;
|
||||||
@@ -1270,13 +1283,19 @@ extern "C" uint32_t OEMCrypto_ResourceRatingTier() {
|
|||||||
return OEMCrypto_ResourceRatingTier(kLevelDefault);
|
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(
|
extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_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,
|
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
|
||||||
const OEMCrypto_KeyObject_V13* key_array, const uint8_t* pst,
|
size_t num_keys, const OEMCrypto_KeyObject* key_array,
|
||||||
size_t pst_length, const uint8_t* srm_requirement,
|
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
|
||||||
OEMCrypto_LicenseType license_type) {
|
OEMCrypto_LicenseType license_type, OEMCryptoCipherMode* cipher_modes) {
|
||||||
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
LevelSession pair = gAdapter->GetSession(session);
|
LevelSession pair = gAdapter->GetSession(session);
|
||||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
@@ -1285,14 +1304,22 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
|||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys);
|
std::vector<OEMCrypto_KeyObject_V10> key_array_v10(num_keys);
|
||||||
for (size_t i = 0; i < num_keys; i++) {
|
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 = PointerOrNull(
|
||||||
key_array_v10[i].key_id_length = key_array[i].key_id_length;
|
message + key_array[i].key_id.offset, key_array[i].key_id.length);
|
||||||
key_array_v10[i].key_data_iv = key_array[i].key_data_iv;
|
key_array_v10[i].key_id_length = key_array[i].key_id.length;
|
||||||
key_array_v10[i].key_data = key_array[i].key_data;
|
key_array_v10[i].key_data_iv =
|
||||||
key_array_v10[i].key_data_length = key_array[i].key_data_length;
|
PointerOrNull(message + key_array[i].key_data_iv.offset,
|
||||||
key_array_v10[i].key_control_iv = key_array[i].key_control_iv;
|
key_array[i].key_data_iv.length);
|
||||||
key_array_v10[i].key_control = key_array[i].key_control;
|
key_array_v10[i].key_data = PointerOrNull(
|
||||||
if (key_array[i].cipher_mode == OEMCrypto_CipherMode_CBC) {
|
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.");
|
LOGE("CBC Mode not supported.");
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
@@ -1301,102 +1328,22 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys_Back_Compat(
|
|||||||
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->version == 8) {
|
||||||
if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
if (pair.fcn->LoadKeys_V8 == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
return pair.fcn->LoadKeys_V8(pair.session, message, message_length,
|
return pair.fcn->LoadKeys_V8(
|
||||||
signature, signature_length, enc_mac_key_iv,
|
pair.session, message, message_length, signature, signature_length,
|
||||||
enc_mac_key, num_keys, key_array_v10_ptr);
|
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 {
|
} else {
|
||||||
if (pair.fcn->LoadKeys_V9_or_V10 == NULL)
|
if (pair.fcn->LoadKeys_V9_or_V10 == NULL)
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10(
|
OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10(
|
||||||
pair.session, message, message_length, signature, signature_length,
|
pair.session, message, message_length, signature, signature_length,
|
||||||
enc_mac_key_iv, enc_mac_key, num_keys, key_array_v10_ptr, pst,
|
PointerOrNull(message + enc_mac_keys_iv.offset,
|
||||||
pst_length);
|
enc_mac_keys_iv.length),
|
||||||
// Convert a vendor specific error, to make it actionable
|
PointerOrNull(message + enc_mac_keys.offset, enc_mac_keys.length),
|
||||||
if (result == kOemCryptoResultVendorSpecificError1)
|
num_keys, key_array_v10_ptr,
|
||||||
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
|
PointerOrNull(message + pst.offset, pst.length), pst.length);
|
||||||
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);
|
|
||||||
// Convert a vendor specific error, to make it actionable
|
// Convert a vendor specific error, to make it actionable
|
||||||
if (result == kOemCryptoResultVendorSpecificError1)
|
if (result == kOemCryptoResultVendorSpecificError1)
|
||||||
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
|
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
|
||||||
@@ -1407,13 +1354,172 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
std::vector<OEMCrypto_KeyObject_V13> key_array_v13(num_keys);
|
std::vector<OEMCrypto_KeyObject_V13> key_array_v13(num_keys);
|
||||||
for (size_t i = 0; i < num_keys; i++) {
|
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 = PointerOrNull(
|
||||||
key_array_v13[i].key_id_length = key_array[i].key_id_length;
|
message + key_array[i].key_id.offset, key_array[i].key_id.length);
|
||||||
key_array_v13[i].key_data_iv = key_array[i].key_data_iv;
|
key_array_v13[i].key_id_length = key_array[i].key_id.length;
|
||||||
key_array_v13[i].key_data = key_array[i].key_data;
|
key_array_v13[i].key_data_iv =
|
||||||
key_array_v13[i].key_data_length = key_array[i].key_data_length;
|
PointerOrNull(message + key_array[i].key_data_iv.offset,
|
||||||
key_array_v13[i].key_control_iv = key_array[i].key_control_iv;
|
key_array[i].key_data_iv.length);
|
||||||
key_array_v13[i].key_control = key_array[i].key_control;
|
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;
|
key_array_v13[i].cipher_mode = OEMCrypto_CipherMode_CTR;
|
||||||
}
|
}
|
||||||
OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL;
|
OEMCrypto_KeyObject_V13* key_array_v13_ptr = NULL;
|
||||||
@@ -1423,8 +1529,11 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12(
|
OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12(
|
||||||
pair.session, message, message_length, signature, signature_length,
|
pair.session, message, message_length, signature, signature_length,
|
||||||
enc_mac_key_iv, enc_mac_key, num_keys, key_array_v13_ptr, pst,
|
PointerOrNull(message + enc_mac_keys_iv.offset,
|
||||||
pst_length);
|
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
|
// Convert a vendor specific error, to make it actionable
|
||||||
if (result == kOemCryptoResultVendorSpecificError1)
|
if (result == kOemCryptoResultVendorSpecificError1)
|
||||||
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
|
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
|
||||||
@@ -1432,32 +1541,99 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
} else {
|
} else {
|
||||||
if (pair.fcn->LoadKeys_V13 == NULL)
|
if (pair.fcn->LoadKeys_V13 == NULL)
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
return pair.fcn->LoadKeys_V13(pair.session, message, message_length,
|
return pair.fcn->LoadKeys_V13(
|
||||||
signature, signature_length, enc_mac_key_iv,
|
pair.session, message, message_length, signature, signature_length,
|
||||||
enc_mac_key, num_keys, key_array_v13_ptr,
|
PointerOrNull(message + enc_mac_keys_iv.offset,
|
||||||
pst, pst_length, srm_requirement);
|
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 {
|
} else {
|
||||||
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
|
return pair.fcn->LoadKeys(pair.session, message, message_length, signature,
|
||||||
signature_length, enc_mac_key_iv, enc_mac_key,
|
signature_length, enc_mac_keys_iv, enc_mac_keys,
|
||||||
num_keys, key_array, pst, pst_length,
|
num_keys, key_array, pst, srm_restriction_data,
|
||||||
srm_requirement, license_type);
|
license_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
||||||
OEMCrypto_SESSION session, size_t num_keys,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const OEMCrypto_EntitledContentKeyObject* key_array) {
|
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) {
|
||||||
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
LevelSession pair = gAdapter->GetSession(session);
|
LevelSession pair = gAdapter->GetSession(session);
|
||||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
if (pair.fcn->version < 14) {
|
if (pair.fcn->version < 14) {
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
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)
|
if (pair.fcn->LoadEntitledContentKeys == NULL)
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
return pair.fcn->LoadEntitledContentKeys(pair.session, num_keys, key_array);
|
return pair.fcn->LoadEntitledContentKeys(
|
||||||
|
pair.session, message, message_length, num_keys, key_array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||||
@@ -1467,6 +1643,27 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
|||||||
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
LevelSession pair = gAdapter->GetSession(session);
|
LevelSession pair = gAdapter->GetSession(session);
|
||||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_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;
|
if (pair.fcn->RefreshKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
return pair.fcn->RefreshKeys(pair.session, message, message_length, signature,
|
return pair.fcn->RefreshKeys(pair.session, message, message_length, signature,
|
||||||
signature_length, num_keys, key_array);
|
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& provider_session_token, CdmCipherMode* cipher_mode,
|
||||||
const std::string& srm_requirement) {
|
const std::string& srm_requirement) {
|
||||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||||
const uint8_t* enc_mac_key = NULL;
|
bool valid_mac_keys =
|
||||||
const uint8_t* enc_mac_key_iv = NULL;
|
mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE;
|
||||||
if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) {
|
OEMCrypto_Substring enc_mac_key =
|
||||||
enc_mac_key = msg + GetOffset(message, mac_key);
|
GetSubstring(message, mac_key, !valid_mac_keys);
|
||||||
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
|
OEMCrypto_Substring enc_mac_key_iv =
|
||||||
} else {
|
GetSubstring(message, mac_key_iv, !valid_mac_keys);
|
||||||
LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* pst = NULL;
|
OEMCrypto_Substring pst = GetSubstring(message, provider_session_token);
|
||||||
if (!provider_session_token.empty()) {
|
OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < keys.size(); i++) {
|
for (size_t i = 0; i < keys.size(); i++) {
|
||||||
OEMCrypto_KeyObject_V13 key_object;
|
OEMCrypto_KeyObject key_object;
|
||||||
const CryptoKey& key_data = keys[i];
|
const CryptoKey& key_data = keys[i];
|
||||||
key_object.key_id = msg + GetOffset(message, key_data.key_id());
|
key_object.key_id = GetSubstring(message, key_data.key_id());
|
||||||
key_object.key_id_length = key_data.key_id().length();
|
key_object.key_data_iv = GetSubstring(message, key_data.key_data_iv());
|
||||||
key_object.key_data_iv = msg + GetOffset(message, key_data.key_data_iv());
|
key_object.key_data = GetSubstring(message, key_data.key_data());
|
||||||
key_object.key_data = msg + GetOffset(message, key_data.key_data());
|
bool has_key_control = key_data.HasKeyControl();
|
||||||
key_object.key_data_length = key_data.key_data().length();
|
|
||||||
if (key_data.HasKeyControl()) {
|
|
||||||
key_object.key_control_iv =
|
key_object.key_control_iv =
|
||||||
msg + GetOffset(message, key_data.key_control_iv());
|
GetSubstring(message, key_data.key_control_iv(), !has_key_control);
|
||||||
key_object.key_control = msg + GetOffset(message, key_data.key_control());
|
key_object.key_control =
|
||||||
} else {
|
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",
|
LOGE("For key %s: XXX key has no control block. size=%d",
|
||||||
key_data.key_id().c_str(), key_data.key_control().size());
|
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?
|
// TODO(jfore): Does returning the cipher mode serve any purpose?
|
||||||
// If not drop.
|
// If not drop.
|
||||||
@@ -216,12 +205,11 @@ OEMCryptoResult SubLicenseKeySession::DoLoadKeys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult sts;
|
OEMCryptoResult sts;
|
||||||
M_TIME(
|
M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat(
|
||||||
sts = OEMCrypto_LoadKeys_Back_Compat(
|
|
||||||
oec_session_id->second, msg, message.size(),
|
oec_session_id->second, msg, message.size(),
|
||||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||||
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
|
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object,
|
||||||
provider_session_token.length(), srm_req, OEMCrypto_ContentLicense),
|
pst, srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode),
|
||||||
metrics_, oemcrypto_load_keys_, sts);
|
metrics_, oemcrypto_load_keys_, sts);
|
||||||
|
|
||||||
if (sts != OEMCrypto_SUCCESS) {
|
if (sts != OEMCrypto_SUCCESS) {
|
||||||
@@ -269,31 +257,20 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
|
|||||||
|
|
||||||
std::string mac_deriv_message;
|
std::string mac_deriv_message;
|
||||||
std::string enc_deriv_message;
|
std::string enc_deriv_message;
|
||||||
GenerateMacContext(group_id_ + message.c_str(),
|
GenerateMacContext(group_id_ + message.c_str(), &mac_deriv_message);
|
||||||
&mac_deriv_message);
|
GenerateEncryptContext(group_id_ + message.c_str(), &enc_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* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||||
const uint8_t* enc_mac_key = NULL;
|
bool valid_mac_keys =
|
||||||
const uint8_t* enc_mac_key_iv = NULL;
|
mac_key.length() >= MAC_KEY_SIZE && mac_key_iv.length() >= KEY_IV_SIZE;
|
||||||
if (mac_key.size() >= MAC_KEY_SIZE && mac_key_iv.size() >= KEY_IV_SIZE) {
|
OEMCrypto_Substring enc_mac_key =
|
||||||
enc_mac_key = msg + GetOffset(message, mac_key);
|
GetSubstring(message, mac_key, !valid_mac_keys);
|
||||||
enc_mac_key_iv = msg + GetOffset(message, mac_key_iv);
|
OEMCrypto_Substring enc_mac_key_iv =
|
||||||
} else {
|
GetSubstring(message, mac_key_iv, !valid_mac_keys);
|
||||||
LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
if (!valid_mac_keys) LOGV("CryptoSession::LoadKeys: enc_mac_key not set");
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* pst = NULL;
|
OEMCrypto_Substring pst = GetSubstring(message, provider_session_token);
|
||||||
if (!provider_session_token.empty()) {
|
OEMCrypto_Substring srm_req = GetSubstring(message, srm_requirement);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult sts;
|
OEMCryptoResult sts;
|
||||||
const std::string& sub_session_key = keys_[key_index].sub_session_key();
|
const std::string& sub_session_key = keys_[key_index].sub_session_key();
|
||||||
@@ -314,28 +291,24 @@ OEMCryptoResult SubLicenseKeySession::DoSubLicenseLoadKeys(
|
|||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCrypto_KeyObject_V13 key_object;
|
OEMCrypto_KeyObject key_object;
|
||||||
key_object.key_id = msg + GetOffset(message, keys_[key_index].key_id());
|
key_object.key_id = GetSubstring(message, keys_[key_index].key_id());
|
||||||
key_object.key_id_length = keys_[key_index].key_id().length();
|
|
||||||
key_object.key_data_iv =
|
key_object.key_data_iv =
|
||||||
msg + GetOffset(message, keys_[key_index].key_data_iv());
|
GetSubstring(message, keys_[key_index].key_data_iv());
|
||||||
key_object.key_data = msg + GetOffset(message, keys_[key_index].key_data());
|
key_object.key_data = GetSubstring(message, keys_[key_index].key_data());
|
||||||
key_object.key_data_length = keys_[key_index].key_data().length();
|
bool has_key_control = key.HasKeyControl();
|
||||||
if (key.HasKeyControl()) {
|
key_object.key_control_iv = GetSubstring(
|
||||||
key_object.key_control_iv =
|
message, keys_[key_index].key_control_iv(), !has_key_control);
|
||||||
msg + GetOffset(message, keys_[key_index].key_control_iv());
|
|
||||||
key_object.key_control =
|
key_object.key_control =
|
||||||
msg + GetOffset(message, keys_[key_index].key_control());
|
GetSubstring(message, keys_[key_index].key_control(), !has_key_control);
|
||||||
}
|
OEMCryptoCipherMode oem_cipher_mode =
|
||||||
key_object.cipher_mode =
|
|
||||||
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode());
|
ToOEMCryptoCipherMode(keys_[key_index].cipher_mode());
|
||||||
|
|
||||||
M_TIME(
|
M_TIME(sts = OEMCrypto_LoadKeys_Back_Compat(
|
||||||
sts = OEMCrypto_LoadKeys_Back_Compat(
|
|
||||||
it->second, msg, message.size(),
|
it->second, msg, message.size(),
|
||||||
reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
|
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||||
enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
|
signature.size(), enc_mac_key_iv, enc_mac_key, 1, &key_object, pst,
|
||||||
provider_session_token.length(), srm_req, OEMCrypto_ContentLicense),
|
srm_req, OEMCrypto_ContentLicense, &oem_cipher_mode),
|
||||||
metrics_, oemcrypto_load_keys_, sts);
|
metrics_, oemcrypto_load_keys_, sts);
|
||||||
|
|
||||||
if (sts != OEMCrypto_SUCCESS) {
|
if (sts != OEMCrypto_SUCCESS) {
|
||||||
|
|||||||
@@ -600,7 +600,6 @@ void TestLicenseHolder::SignAndLoadLicense() {
|
|||||||
std::string session_key_s(session_key_.begin(), session_key_.end());
|
std::string session_key_s(session_key_.begin(), session_key_.end());
|
||||||
std::string encrypted_session_key;
|
std::string encrypted_session_key;
|
||||||
EXPECT_TRUE(rsa_key_.Encrypt(session_key_s, &encrypted_session_key));
|
EXPECT_TRUE(rsa_key_.Encrypt(session_key_s, &encrypted_session_key));
|
||||||
|
|
||||||
video_widevine::SignedMessage signed_response;
|
video_widevine::SignedMessage signed_response;
|
||||||
signed_response.set_msg(license_data);
|
signed_response.set_msg(license_data);
|
||||||
signed_response.set_type(video_widevine::SignedMessage_MessageType_LICENSE);
|
signed_response.set_type(video_widevine::SignedMessage_MessageType_LICENSE);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ std::string HexEncode(const uint8_t* bytes, unsigned size);
|
|||||||
std::string IntToString(int value);
|
std::string IntToString(int value);
|
||||||
int64_t htonll64(int64_t x);
|
int64_t htonll64(int64_t x);
|
||||||
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
||||||
|
std::string BytesToString(const uint8_t* bytes, unsigned size);
|
||||||
|
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|
||||||
|
|||||||
@@ -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<const char*>(bytes);
|
||||||
|
return std::string(char_bytes, char_bytes + size);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|||||||
@@ -202,20 +202,6 @@ typedef struct {
|
|||||||
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
|
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
|
||||||
* by the caller of OEMCrypto_LoadKeys().
|
* 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 {
|
typedef struct {
|
||||||
OEMCrypto_Substring key_id;
|
OEMCrypto_Substring key_id;
|
||||||
OEMCrypto_Substring key_data_iv;
|
OEMCrypto_Substring key_data_iv;
|
||||||
@@ -223,7 +209,6 @@ typedef struct {
|
|||||||
OEMCrypto_Substring key_control_iv;
|
OEMCrypto_Substring key_control_iv;
|
||||||
OEMCrypto_Substring key_control;
|
OEMCrypto_Substring key_control;
|
||||||
} OEMCrypto_KeyObject;
|
} OEMCrypto_KeyObject;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SRM_Restriction_Data
|
* SRM_Restriction_Data
|
||||||
@@ -248,24 +233,12 @@ typedef struct {
|
|||||||
* key_data - encrypted content key data.
|
* key_data - encrypted content key data.
|
||||||
* key_data_length - length of key_data - 16 or 32 depending on intended use.
|
* 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 {
|
typedef struct {
|
||||||
OEMCrypto_Substring entitlement_key_id;
|
OEMCrypto_Substring entitlement_key_id;
|
||||||
OEMCrypto_Substring content_key_id;
|
OEMCrypto_Substring content_key_id;
|
||||||
OEMCrypto_Substring content_key_data_iv;
|
OEMCrypto_Substring content_key_data_iv;
|
||||||
OEMCrypto_Substring content_key_data;
|
OEMCrypto_Substring content_key_data;
|
||||||
} OEMCrypto_EntitledContentKeyObject;
|
} OEMCrypto_EntitledContentKeyObject;
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OEMCrypto_KeyRefreshObject
|
* OEMCrypto_KeyRefreshObject
|
||||||
@@ -286,21 +259,11 @@ typedef struct {
|
|||||||
* The memory for the OEMCrypto_KeyRefreshObject fields is allocated and freed
|
* The memory for the OEMCrypto_KeyRefreshObject fields is allocated and freed
|
||||||
* by the caller of OEMCrypto_RefreshKeys().
|
* 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 {
|
typedef struct {
|
||||||
OEMCrypto_Substring key_id;
|
OEMCrypto_Substring key_id;
|
||||||
OEMCrypto_Substring key_control_iv;
|
OEMCrypto_Substring key_control_iv;
|
||||||
OEMCrypto_Substring key_control;
|
OEMCrypto_Substring key_control;
|
||||||
} OEMCrypto_KeyRefreshObject;
|
} OEMCrypto_KeyRefreshObject;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OEMCrypto_Algorithm
|
* OEMCrypto_Algorithm
|
||||||
@@ -478,7 +441,7 @@ const uint32_t OEMCrypto_Partner_Defined_Hash = 2;
|
|||||||
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
|
#define OEMCrypto_GetMaxNumberOfSessions _oecc37
|
||||||
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
|
#define OEMCrypto_GetNumberOfOpenSessions _oecc38
|
||||||
#define OEMCrypto_IsAntiRollbackHwPresent _oecc39
|
#define OEMCrypto_IsAntiRollbackHwPresent _oecc39
|
||||||
#define OEMCrypto_CopyBuffer_v14 _oecc40
|
#define OEMCrypto_CopyBuffer_V14 _oecc40
|
||||||
#define OEMCrypto_QueryKeyControl _oecc41
|
#define OEMCrypto_QueryKeyControl _oecc41
|
||||||
#define OEMCrypto_LoadTestKeybox_V13 _oecc42
|
#define OEMCrypto_LoadTestKeybox_V13 _oecc42
|
||||||
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
|
#define OEMCrypto_ForceDeleteUsageEntry _oecc43
|
||||||
@@ -1208,15 +1171,6 @@ OEMCryptoResult OEMCrypto_LoadSRM(const uint8_t* buffer, size_t buffer_length);
|
|||||||
* Version:
|
* Version:
|
||||||
* This method changed in API version 14.
|
* 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(
|
OEMCryptoResult OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_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,
|
size_t num_keys, const OEMCrypto_KeyObject* key_array,
|
||||||
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
|
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
|
||||||
OEMCrypto_LicenseType license_type);
|
OEMCrypto_LicenseType license_type);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OEMCrypto_LoadEntitledContentKeys
|
* OEMCrypto_LoadEntitledContentKeys
|
||||||
@@ -1285,17 +1238,9 @@ OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
* Version:
|
* Version:
|
||||||
* This method is new in API version 14.
|
* 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(
|
OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array);
|
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OEMCrypto_RefreshKeys
|
* OEMCrypto_RefreshKeys
|
||||||
@@ -1409,17 +1354,10 @@ OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
|||||||
* Version:
|
* Version:
|
||||||
* This method changed in API version 12.
|
* This method changed in API version 12.
|
||||||
*/
|
*/
|
||||||
#if 1 // TODO(b/115874964, srujzs): rename and move.
|
|
||||||
OEMCryptoResult OEMCrypto_RefreshKeys(
|
OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_length, size_t num_keys,
|
const uint8_t* signature, size_t signature_length, size_t num_keys,
|
||||||
const OEMCrypto_KeyRefreshObject* key_array);
|
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
|
* OEMCrypto_QueryKeyControl
|
||||||
|
|||||||
@@ -170,13 +170,10 @@ OEMCryptoResult Level3_GenerateSignature(OEMCrypto_SESSION session,
|
|||||||
size_t message_length,
|
size_t message_length,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
size_t* signature_length);
|
size_t* signature_length);
|
||||||
OEMCryptoResult Level3_RefreshKeys(OEMCrypto_SESSION session,
|
OEMCryptoResult Level3_RefreshKeys(
|
||||||
const uint8_t* message,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
size_t message_length,
|
const uint8_t* signature, size_t signature_length, size_t num_keys,
|
||||||
const uint8_t* signature,
|
const OEMCrypto_KeyRefreshObject_V14* key_array);
|
||||||
size_t signature_length,
|
|
||||||
size_t num_keys,
|
|
||||||
const OEMCrypto_KeyRefreshObject* key_array);
|
|
||||||
OEMCryptoResult Level3_QueryKeyControl(OEMCrypto_SESSION session,
|
OEMCryptoResult Level3_QueryKeyControl(OEMCrypto_SESSION session,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id,
|
||||||
size_t key_id_length,
|
size_t key_id_length,
|
||||||
@@ -347,26 +344,19 @@ OEMCryptoResult Level3_CreateOldUsageEntry(uint64_t time_since_license_received,
|
|||||||
const uint8_t* pst,
|
const uint8_t* pst,
|
||||||
size_t pst_length);
|
size_t pst_length);
|
||||||
uint32_t Level3_GetAnalogOutputFlags();
|
uint32_t Level3_GetAnalogOutputFlags();
|
||||||
OEMCryptoResult Level3_LoadTestKeybox(const uint8_t *buffer, size_t length);
|
OEMCryptoResult Level3_LoadTestKeybox(const uint8_t* buffer, size_t length);
|
||||||
OEMCryptoResult Level3_LoadEntitledContentKeys(OEMCrypto_SESSION session,
|
OEMCryptoResult Level3_LoadEntitledContentKeys(
|
||||||
size_t num_keys,
|
OEMCrypto_SESSION session, size_t num_keys,
|
||||||
const OEMCrypto_EntitledContentKeyObject* key_array);
|
const OEMCrypto_EntitledContentKeyObject_V14* key_array);
|
||||||
OEMCryptoResult Level3_SelectKey(const OEMCrypto_SESSION session,
|
OEMCryptoResult Level3_SelectKey(const OEMCrypto_SESSION session,
|
||||||
const uint8_t* key_id,
|
const uint8_t* key_id, size_t key_id_length,
|
||||||
size_t key_id_length,
|
|
||||||
OEMCryptoCipherMode cipher_mode);
|
OEMCryptoCipherMode cipher_mode);
|
||||||
OEMCryptoResult Level3_LoadKeys(OEMCrypto_SESSION session,
|
OEMCryptoResult Level3_LoadKeys(
|
||||||
const uint8_t* message,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
size_t message_length,
|
const uint8_t* signature, size_t signature_length,
|
||||||
const uint8_t* signature,
|
const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys,
|
||||||
size_t signature_length,
|
const OEMCrypto_KeyObject_V14* key_array, const uint8_t* pst,
|
||||||
const uint8_t* enc_mac_key_iv,
|
size_t pst_length, const uint8_t* srm_requirement,
|
||||||
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);
|
OEMCrypto_LicenseType license_type);
|
||||||
/*
|
/*
|
||||||
* Level3_GetInitializationState
|
* Level3_GetInitializationState
|
||||||
|
|||||||
@@ -239,12 +239,21 @@ bool RangeCheck(const uint8_t* message, uint32_t message_length,
|
|||||||
return true;
|
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(
|
extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_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,
|
OEMCrypto_Substring enc_mac_keys_iv, OEMCrypto_Substring enc_mac_keys,
|
||||||
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, size_t pst_length,
|
size_t num_keys, const OEMCrypto_KeyObject* key_array,
|
||||||
const uint8_t* srm_requirement, OEMCrypto_LicenseType license_type) {
|
OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data,
|
||||||
|
OEMCrypto_LicenseType license_type) {
|
||||||
if (!crypto_engine) {
|
if (!crypto_engine) {
|
||||||
LOGE("OEMCrypto_LoadKeys: OEMCrypto Not Initialized.");
|
LOGE("OEMCrypto_LoadKeys: OEMCrypto Not Initialized.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
@@ -263,20 +272,12 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||||
return 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
|
// Range check
|
||||||
if (!RangeCheck(message, message_length, enc_mac_keys, 2 * wvoec::MAC_KEY_SIZE,
|
if (!RangeCheck(message_length, enc_mac_keys_iv, true) ||
|
||||||
true) ||
|
!RangeCheck(message_length, enc_mac_keys, true) ||
|
||||||
!RangeCheck(message, message_length, enc_mac_key_iv, wvoec::KEY_IV_SIZE, true) ||
|
!RangeCheck(message_length, pst, true) ||
|
||||||
!RangeCheck(message, message_length, pst, pst_length, true) ||
|
!RangeCheck(message_length, srm_restriction_data, true)) {
|
||||||
!RangeCheck(message, message_length, srm_requirement,
|
|
||||||
wvoec::SRM_REQUIREMENT_SIZE, true)) {
|
|
||||||
LOGE(
|
LOGE(
|
||||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
|
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
|
||||||
"check.]");
|
"check.]");
|
||||||
@@ -284,16 +285,11 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num_keys; i++) {
|
for (unsigned int i = 0; i < num_keys; i++) {
|
||||||
if (!RangeCheck(message, message_length, key_array[i].key_id,
|
if (!RangeCheck(message_length, key_array[i].key_id, false) ||
|
||||||
key_array[i].key_id_length, false) ||
|
!RangeCheck(message_length, key_array[i].key_data, false) ||
|
||||||
!RangeCheck(message, message_length, key_array[i].key_data,
|
!RangeCheck(message_length, key_array[i].key_data_iv, false) ||
|
||||||
key_array[i].key_data_length, false) ||
|
!RangeCheck(message_length, key_array[i].key_control, false) ||
|
||||||
!RangeCheck(message, message_length, key_array[i].key_data_iv,
|
!RangeCheck(message_length, key_array[i].key_control_iv, false)) {
|
||||||
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)) {
|
|
||||||
LOGE(
|
LOGE(
|
||||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
|
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
|
||||||
"check %d]",
|
"check %d]",
|
||||||
@@ -302,14 +298,14 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return session_ctx->LoadKeys(message, message_length, signature,
|
return session_ctx->LoadKeys(message, message_length, signature,
|
||||||
signature_length, enc_mac_key_iv, enc_mac_keys,
|
signature_length, enc_mac_keys_iv, enc_mac_keys,
|
||||||
num_keys, key_array, pst, pst_length,
|
num_keys, key_array, pst, srm_restriction_data,
|
||||||
srm_requirement, license_type);
|
license_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
||||||
OEMCrypto_SESSION session, size_t num_keys,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const OEMCrypto_EntitledContentKeyObject* key_array) {
|
size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array) {
|
||||||
if (num_keys == 0) {
|
if (num_keys == 0) {
|
||||||
LOGE("[OEMCrypto_LoadEntitledContentKeys(): key_array is empty.");
|
LOGE("[OEMCrypto_LoadEntitledContentKeys(): key_array is empty.");
|
||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
@@ -327,8 +323,22 @@ extern "C" OEMCryptoResult OEMCrypto_LoadEntitledContentKeys(
|
|||||||
LOGE("[OEMCrypto_LoadEntitledContentKeys(): ERROR_INVALID_SESSION]");
|
LOGE("[OEMCrypto_LoadEntitledContentKeys(): ERROR_INVALID_SESSION]");
|
||||||
return OEMCrypto_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(
|
extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
||||||
@@ -359,12 +369,9 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
|||||||
|
|
||||||
// Range check
|
// Range check
|
||||||
for (unsigned int i = 0; i < num_keys; i++) {
|
for (unsigned int i = 0; i < num_keys; i++) {
|
||||||
if (!RangeCheck(message, message_length, key_array[i].key_id,
|
if (!RangeCheck(message_length, key_array[i].key_id, true) ||
|
||||||
key_array[i].key_id_length, true) ||
|
!RangeCheck(message_length, key_array[i].key_control, false) ||
|
||||||
!RangeCheck(message, message_length, key_array[i].key_control,
|
!RangeCheck(message_length, key_array[i].key_control_iv, true)) {
|
||||||
wvoec::KEY_CONTROL_SIZE, false) ||
|
|
||||||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
|
|
||||||
wvoec::KEY_IV_SIZE, true)) {
|
|
||||||
LOGE("[OEMCrypto_RefreshKeys(): Range Check %d]", i);
|
LOGE("[OEMCrypto_RefreshKeys(): Range Check %d]", i);
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
@@ -383,24 +390,28 @@ extern "C" OEMCryptoResult OEMCrypto_RefreshKeys(
|
|||||||
std::vector<uint8_t> key_control;
|
std::vector<uint8_t> key_control;
|
||||||
std::vector<uint8_t> key_control_iv;
|
std::vector<uint8_t> key_control_iv;
|
||||||
for (unsigned int i = 0; i < num_keys; i++) {
|
for (unsigned int i = 0; i < num_keys; i++) {
|
||||||
if (key_array[i].key_id != NULL) {
|
if (key_array[i].key_id.length != 0) {
|
||||||
key_id.assign(key_array[i].key_id,
|
key_id.assign(
|
||||||
key_array[i].key_id + key_array[i].key_id_length);
|
message + key_array[i].key_id.offset,
|
||||||
key_control.assign(key_array[i].key_control,
|
message + key_array[i].key_id.offset + key_array[i].key_id.length);
|
||||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
key_control.assign(
|
||||||
if (key_array[i].key_control_iv == NULL) {
|
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();
|
key_control_iv.clear();
|
||||||
} else {
|
} else {
|
||||||
key_control_iv.assign(key_array[i].key_control_iv,
|
key_control_iv.assign(
|
||||||
key_array[i].key_control_iv + wvoec::KEY_IV_SIZE);
|
message + key_array[i].key_control_iv.offset,
|
||||||
|
message + key_array[i].key_control_iv.offset + wvoec::KEY_IV_SIZE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// key_id could be null if special control key type
|
// key_id could be null if special control key type
|
||||||
// key_control is not encrypted in this case
|
// key_control is not encrypted in this case
|
||||||
key_id.clear();
|
key_id.clear();
|
||||||
key_control_iv.clear();
|
key_control_iv.clear();
|
||||||
key_control.assign(key_array[i].key_control,
|
key_control.assign(
|
||||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
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);
|
status = session_ctx->RefreshKey(key_id, key_control, key_control_iv);
|
||||||
|
|||||||
@@ -492,10 +492,11 @@ uint32_t SessionContext::CurrentTimer() {
|
|||||||
|
|
||||||
OEMCryptoResult SessionContext::LoadKeys(
|
OEMCryptoResult SessionContext::LoadKeys(
|
||||||
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
||||||
size_t signature_length, const uint8_t* enc_mac_key_iv,
|
size_t signature_length, OEMCrypto_Substring enc_mac_keys_iv,
|
||||||
const uint8_t* enc_mac_keys, size_t num_keys,
|
OEMCrypto_Substring enc_mac_keys, size_t num_keys,
|
||||||
const OEMCrypto_KeyObject* key_array, const uint8_t* pst, size_t pst_length,
|
const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst,
|
||||||
const uint8_t* srm_requirement, OEMCrypto_LicenseType license_type) {
|
OEMCrypto_Substring srm_restriction_data,
|
||||||
|
OEMCrypto_LicenseType license_type) {
|
||||||
// Validate message signature
|
// Validate message signature
|
||||||
if (!ValidateMessage(message, message_length, signature, signature_length)) {
|
if (!ValidateMessage(message, message_length, signature, signature_length)) {
|
||||||
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||||
@@ -522,16 +523,16 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
|
|
||||||
StartTimer();
|
StartTimer();
|
||||||
|
|
||||||
if (srm_requirement) {
|
if (srm_restriction_data.length != 0) {
|
||||||
const std::string kSRMVerificationString = "HDCPDATA";
|
const std::string kSRMVerificationString = "HDCPDATA";
|
||||||
if (memcmp(srm_requirement, kSRMVerificationString.c_str(),
|
if (memcmp(message + srm_restriction_data.offset,
|
||||||
kSRMVerificationString.size())) {
|
kSRMVerificationString.c_str(), kSRMVerificationString.size())) {
|
||||||
LOGE("SRM Requirement Data has bad verification string: %8s",
|
LOGE("SRM Requirement Data has bad verification string: %8s",
|
||||||
srm_requirement);
|
message + srm_restriction_data.offset);
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
uint32_t minimum_version =
|
uint32_t minimum_version = htonl(*reinterpret_cast<const uint32_t*>(
|
||||||
htonl(*reinterpret_cast<const uint32_t*>(srm_requirement + 8));
|
message + srm_restriction_data.offset + 8));
|
||||||
uint16_t current_version = 0;
|
uint16_t current_version = 0;
|
||||||
if (OEMCrypto_SUCCESS != ce_->current_srm_version(¤t_version)) {
|
if (OEMCrypto_SUCCESS != ce_->current_srm_version(¤t_version)) {
|
||||||
LOGW("[LoadKeys: SRM Version not available.");
|
LOGW("[LoadKeys: SRM Version not available.");
|
||||||
@@ -563,20 +564,25 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
std::vector<uint8_t> key_control;
|
std::vector<uint8_t> key_control;
|
||||||
std::vector<uint8_t> key_control_iv;
|
std::vector<uint8_t> key_control_iv;
|
||||||
for (unsigned int i = 0; i < num_keys; i++) {
|
for (unsigned int i = 0; i < num_keys; i++) {
|
||||||
key_id.assign(key_array[i].key_id,
|
key_id.assign(
|
||||||
key_array[i].key_id + key_array[i].key_id_length);
|
message + key_array[i].key_id.offset,
|
||||||
enc_key_data.assign(key_array[i].key_data,
|
message + key_array[i].key_id.offset + key_array[i].key_id.length);
|
||||||
key_array[i].key_data + key_array[i].key_data_length);
|
enc_key_data.assign(
|
||||||
key_data_iv.assign(key_array[i].key_data_iv,
|
message + key_array[i].key_data.offset,
|
||||||
key_array[i].key_data_iv + wvoec::KEY_IV_SIZE);
|
message + key_array[i].key_data.offset + key_array[i].key_data.length);
|
||||||
if (key_array[i].key_control == NULL) {
|
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;
|
status = OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
key_control.assign(key_array[i].key_control,
|
key_control.assign(
|
||||||
key_array[i].key_control + wvoec::KEY_CONTROL_SIZE);
|
message + key_array[i].key_control.offset,
|
||||||
key_control_iv.assign(key_array[i].key_control_iv,
|
message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE);
|
||||||
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);
|
||||||
|
|
||||||
OEMCryptoResult result =
|
OEMCryptoResult result =
|
||||||
InstallKey(key_id, enc_key_data, key_data_iv, key_control,
|
InstallKey(key_id, enc_key_data, key_data_iv, key_control,
|
||||||
@@ -590,12 +596,14 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
if (status != OEMCrypto_SUCCESS) return status;
|
if (status != OEMCrypto_SUCCESS) return status;
|
||||||
|
|
||||||
// enc_mac_key can be NULL if license renewal is not supported
|
// 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
|
// V2.1 license protocol: update mac keys after processing license response
|
||||||
const std::vector<uint8_t> enc_mac_keys_str = std::vector<uint8_t>(
|
const std::vector<uint8_t> enc_mac_keys_str = std::vector<uint8_t>(
|
||||||
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<uint8_t> enc_mac_key_iv_str = std::vector<uint8_t>(
|
const std::vector<uint8_t> enc_mac_key_iv_str = std::vector<uint8_t>(
|
||||||
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)) {
|
if (!UpdateMacKeys(enc_mac_keys_str, enc_mac_key_iv_str)) {
|
||||||
LOGE("Failed to update mac keys.\n");
|
LOGE("Failed to update mac keys.\n");
|
||||||
@@ -606,13 +614,13 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
OEMCryptoResult result = OEMCrypto_SUCCESS;
|
OEMCryptoResult result = OEMCrypto_SUCCESS;
|
||||||
switch (usage_entry_status_) {
|
switch (usage_entry_status_) {
|
||||||
case kNoUsageEntry:
|
case kNoUsageEntry:
|
||||||
if (pst_length > 0) {
|
if (pst.length > 0) {
|
||||||
LOGE("LoadKeys: PST specified but no usage entry loaded.");
|
LOGE("LoadKeys: PST specified but no usage entry loaded.");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
break; // no extra check.
|
break; // no extra check.
|
||||||
case kUsageEntryNew:
|
case kUsageEntryNew:
|
||||||
result = usage_entry_->SetPST(pst, pst_length);
|
result = usage_entry_->SetPST(message + pst.offset, pst.length);
|
||||||
if (result != OEMCrypto_SUCCESS) {
|
if (result != OEMCrypto_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -622,7 +630,7 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kUsageEntryLoaded:
|
case kUsageEntryLoaded:
|
||||||
if (!usage_entry_->VerifyPST(pst, pst_length)) {
|
if (!usage_entry_->VerifyPST(message + pst.offset, pst.length)) {
|
||||||
return OEMCrypto_ERROR_WRONG_PST;
|
return OEMCrypto_ERROR_WRONG_PST;
|
||||||
}
|
}
|
||||||
if (!usage_entry_->VerifyMacKeys(mac_key_server_, mac_key_client_)) {
|
if (!usage_entry_->VerifyMacKeys(mac_key_server_, mac_key_client_)) {
|
||||||
@@ -637,7 +645,8 @@ OEMCryptoResult SessionContext::LoadKeys(
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
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) {
|
if (!key_array) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -647,9 +656,9 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
|||||||
for (size_t i = 0; i < num_keys; ++i) {
|
for (size_t i = 0; i < num_keys; ++i) {
|
||||||
const OEMCrypto_EntitledContentKeyObject* key_data = &key_array[i];
|
const OEMCrypto_EntitledContentKeyObject* key_data = &key_array[i];
|
||||||
std::vector<uint8_t> entitlement_key_id;
|
std::vector<uint8_t> entitlement_key_id;
|
||||||
entitlement_key_id.assign(
|
entitlement_key_id.assign(message + key_data->entitlement_key_id.offset,
|
||||||
key_data->entitlement_key_id,
|
message + key_data->entitlement_key_id.offset +
|
||||||
key_data->entitlement_key_id + key_data->entitlement_key_id_length);
|
key_data->entitlement_key_id.length);
|
||||||
|
|
||||||
const std::vector<uint8_t>* entitlement_key = NULL;
|
const std::vector<uint8_t>* entitlement_key = NULL;
|
||||||
if (!session_keys_->GetEntitlementKey(entitlement_key_id,
|
if (!session_keys_->GetEntitlementKey(entitlement_key_id,
|
||||||
@@ -661,14 +670,14 @@ OEMCryptoResult SessionContext::LoadEntitledContentKeys(
|
|||||||
std::vector<uint8_t> encrypted_content_key;
|
std::vector<uint8_t> encrypted_content_key;
|
||||||
std::vector<uint8_t> content_key_id;
|
std::vector<uint8_t> content_key_id;
|
||||||
|
|
||||||
iv.assign(key_data->content_key_data_iv,
|
iv.assign(message + key_data->content_key_data_iv.offset,
|
||||||
key_data->content_key_data_iv + 16);
|
message + key_data->content_key_data_iv.offset + 16);
|
||||||
encrypted_content_key.assign(
|
encrypted_content_key.assign(message + key_data->content_key_data.offset,
|
||||||
key_data->content_key_data,
|
message + key_data->content_key_data.offset +
|
||||||
key_data->content_key_data + key_data->content_key_data_length);
|
key_data->content_key_data.length);
|
||||||
content_key_id.assign(
|
content_key_id.assign(message + key_data->content_key_id.offset,
|
||||||
key_data->content_key_id,
|
message + key_data->content_key_id.offset +
|
||||||
key_data->content_key_id + key_data->content_key_id_length);
|
key_data->content_key_id.length);
|
||||||
if (!DecryptMessage(*entitlement_key, iv, encrypted_content_key,
|
if (!DecryptMessage(*entitlement_key, iv, encrypted_content_key,
|
||||||
&content_key, 256 /* key size */)) {
|
&content_key, 256 /* key size */)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
|||||||
@@ -119,13 +119,14 @@ class SessionContext {
|
|||||||
uint32_t CurrentTimer(); // (seconds).
|
uint32_t CurrentTimer(); // (seconds).
|
||||||
virtual OEMCryptoResult LoadKeys(
|
virtual OEMCryptoResult LoadKeys(
|
||||||
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
const uint8_t* message, size_t message_length, const uint8_t* signature,
|
||||||
size_t signature_length, const uint8_t* enc_mac_key_iv,
|
size_t signature_length, OEMCrypto_Substring enc_mac_keys_iv,
|
||||||
const uint8_t* enc_mac_keys, size_t num_keys,
|
OEMCrypto_Substring enc_mac_keys, size_t num_keys,
|
||||||
const OEMCrypto_KeyObject* key_array, const uint8_t* pst,
|
const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst,
|
||||||
size_t pst_length, const uint8_t* srm_requirement,
|
OEMCrypto_Substring srm_restriction_data,
|
||||||
OEMCrypto_LicenseType license_type);
|
OEMCrypto_LicenseType license_type);
|
||||||
OEMCryptoResult LoadEntitledContentKeys(
|
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,
|
virtual OEMCryptoResult InstallKey(const KeyId& key_id,
|
||||||
const std::vector<uint8_t>& key_data,
|
const std::vector<uint8_t>& key_data,
|
||||||
const std::vector<uint8_t>& key_data_iv,
|
const std::vector<uint8_t>& key_data_iv,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ UsageTableEntry::~UsageTableEntry() { usage_table_->ReleaseEntry(data_.index); }
|
|||||||
OEMCryptoResult UsageTableEntry::SetPST(const uint8_t* pst, size_t pst_length) {
|
OEMCryptoResult UsageTableEntry::SetPST(const uint8_t* pst, size_t pst_length) {
|
||||||
if (pst_length > kMaxPSTLength) return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
if (pst_length > kMaxPSTLength) return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
||||||
data_.pst_length = pst_length;
|
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);
|
memcpy(data_.pst, pst, pst_length);
|
||||||
data_.time_of_license_received = time(NULL);
|
data_.time_of_license_received = time(NULL);
|
||||||
return OEMCrypto_SUCCESS;
|
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) {
|
bool UsageTableEntry::VerifyPST(const uint8_t* pst, size_t pst_length) {
|
||||||
if (pst_length > kMaxPSTLength) return false;
|
if (pst_length > kMaxPSTLength) return false;
|
||||||
if (data_.pst_length != pst_length) 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);
|
return 0 == memcmp(pst, data_.pst, pst_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,26 @@ class boringssl_ptr {
|
|||||||
CORE_DISALLOW_COPY_AND_ASSIGN(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()
|
Session::Session()
|
||||||
: open_(false),
|
: open_(false),
|
||||||
forced_session_id_(false),
|
forced_session_id_(false),
|
||||||
@@ -254,129 +274,146 @@ void Session::GenerateDerivedKeysFromSessionKey() {
|
|||||||
DeriveKeys(&session_key[0], mac_context, enc_context);
|
DeriveKeys(&session_key[0], mac_context, enc_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
|
void Session::LoadTestKeys(const std::string& provider_session_token,
|
||||||
uint8_t* pst_ptr = NULL;
|
bool new_mac_keys) {
|
||||||
if (pst.length() > 0) {
|
std::string message =
|
||||||
pst_ptr = encrypted_license().pst;
|
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) {
|
if (new_mac_keys) {
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
OEMCrypto_LoadKeys(
|
||||||
&signature_[0], signature_.size(),
|
session_id(), message_ptr(), message_size_, &signature_[0],
|
||||||
encrypted_license().mac_key_iv,
|
signature_.size(), enc_mac_keys_iv, enc_mac_keys, num_keys_,
|
||||||
encrypted_license().mac_keys, num_keys_,
|
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
key_array_, pst_ptr, pst.length(), NULL,
|
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
// Update new generated keys.
|
// Update new generated keys.
|
||||||
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
||||||
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
|
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
|
||||||
MAC_KEY_SIZE);
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
session_id(), message_ptr(), message_size_, &signature_[0],
|
||||||
&signature_[0], signature_.size(), NULL, NULL,
|
signature_.size(), GetSubstring(), GetSubstring(), num_keys_,
|
||||||
num_keys_, key_array_, pst_ptr, pst.length(), NULL,
|
key_array_, pst, GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
VerifyTestKeys();
|
VerifyTestKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::LoadEntitlementTestKeys(const std::string& pst,
|
void Session::LoadEntitlementTestKeys(const std::string& provider_session_token,
|
||||||
bool new_mac_keys,
|
bool new_mac_keys,
|
||||||
OEMCryptoResult expected_sts) {
|
OEMCryptoResult expected_sts) {
|
||||||
uint8_t* pst_ptr = NULL;
|
std::string message =
|
||||||
if (pst.length() > 0) {
|
wvcdm::BytesToString(message_ptr(), sizeof(MessageData));
|
||||||
pst_ptr = encrypted_license().pst;
|
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) {
|
if (new_mac_keys) {
|
||||||
ASSERT_EQ(expected_sts,
|
ASSERT_EQ(
|
||||||
|
expected_sts,
|
||||||
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
||||||
&signature_[0], signature_.size(),
|
&signature_[0], signature_.size(), enc_mac_keys_iv,
|
||||||
encrypted_license().mac_key_iv,
|
enc_mac_keys, num_keys_, key_array_, pst,
|
||||||
encrypted_license().mac_keys, num_keys_,
|
GetSubstring(), OEMCrypto_EntitlementLicense));
|
||||||
key_array_, pst_ptr, pst.length(), NULL,
|
|
||||||
OEMCrypto_EntitlementLicense));
|
|
||||||
// Update new generated keys.
|
// Update new generated keys.
|
||||||
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
||||||
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
|
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE, MAC_KEY_SIZE);
|
||||||
MAC_KEY_SIZE);
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
expected_sts,
|
expected_sts,
|
||||||
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
|
||||||
&signature_[0], signature_.size(), NULL, NULL,
|
&signature_[0], signature_.size(), GetSubstring(),
|
||||||
num_keys_, key_array_, pst_ptr, pst.length(), NULL,
|
GetSubstring(), num_keys_, key_array_, pst,
|
||||||
OEMCrypto_EntitlementLicense));
|
GetSubstring(), OEMCrypto_EntitlementLicense));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::FillEntitledKeyArray() {
|
void Session::FillEntitledKeyArray() {
|
||||||
|
int offset = 0;
|
||||||
|
entitled_message_.clear();
|
||||||
for (size_t i = 0; i < num_keys_; ++i) {
|
for (size_t i = 0; i < num_keys_; ++i) {
|
||||||
EntitledContentKeyData* key_data = &entitled_key_data_[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.offset = offset;
|
||||||
entitled_key_array_[i].entitlement_key_id_length =
|
entitled_key_array_[i].entitlement_key_id.length =
|
||||||
key_array_[i].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(
|
EXPECT_EQ(1, GetRandBytes(key_data->content_key_id,
|
||||||
1, GetRandBytes(key_data->content_key_id,
|
|
||||||
sizeof(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.offset = offset;
|
||||||
entitled_key_array_[i].content_key_id_length =
|
entitled_key_array_[i].content_key_id.length =
|
||||||
sizeof(key_data->content_key_id);
|
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(
|
EXPECT_EQ(1, GetRandBytes(key_data->content_key_data,
|
||||||
1, GetRandBytes(key_data->content_key_data,
|
|
||||||
sizeof(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.offset = offset;
|
||||||
entitled_key_array_[i].content_key_data_length =
|
entitled_key_array_[i].content_key_data.length =
|
||||||
sizeof(key_data->content_key_data);
|
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(
|
EXPECT_EQ(1, GetRandBytes(key_data[i].content_key_data_iv,
|
||||||
1, GetRandBytes(entitled_key_data_[i].content_key_data_iv,
|
sizeof(key_data[i].content_key_data_iv)));
|
||||||
sizeof(entitled_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 = key_data->content_key_data_iv;
|
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) {
|
void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
|
||||||
// Create a copy of the stored |entitled_key_array_|.
|
encrypted_entitled_message_ = entitled_message_;
|
||||||
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array;
|
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array;
|
||||||
encrypted_entitled_key_array.resize(num_keys_);
|
encrypted_entitled_key_array.resize(num_keys_);
|
||||||
memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0],
|
memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0],
|
||||||
sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_);
|
sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_);
|
||||||
|
|
||||||
// Create an encrypted version of all of the content keys stored in
|
|
||||||
// |entitled_key_array_|.
|
|
||||||
std::vector<std::vector<uint8_t> > encrypted_content_keys;
|
|
||||||
encrypted_content_keys.resize(num_keys_);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_keys_; ++i) {
|
for (size_t i = 0; i < num_keys_; ++i) {
|
||||||
// Load the entitlement key from |key_array_|.
|
// Load the entitlement key from |key_array_|.
|
||||||
AES_KEY aes_key;
|
AES_KEY aes_key;
|
||||||
AES_set_encrypt_key(&key_array_[i].key_data[0], 256, &aes_key);
|
AES_set_encrypt_key(message_ptr() + key_array_[i].key_data.offset, 256,
|
||||||
encrypted_content_keys[i].resize(
|
&aes_key);
|
||||||
encrypted_entitled_key_array[i].content_key_data_length);
|
|
||||||
|
|
||||||
// Encrypt the content key with the entitlement key.
|
// Encrypt the content key with the entitlement key.
|
||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
memcpy(&iv[0], &encrypted_entitled_key_array[i].content_key_data[0], 16);
|
const uint8_t* content_key_data = reinterpret_cast<const uint8_t*>(
|
||||||
AES_cbc_encrypt(
|
entitled_message_.data() +
|
||||||
&entitled_key_array_[i].content_key_data[0],
|
entitled_key_array_[i].content_key_data.offset);
|
||||||
const_cast<uint8_t*>(
|
const uint8_t* encrypted_content_key_data =
|
||||||
&encrypted_entitled_key_array[i].content_key_data[0]),
|
reinterpret_cast<const uint8_t*>(
|
||||||
encrypted_entitled_key_array[i].content_key_data_length,
|
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<uint8_t*>(encrypted_content_key_data),
|
||||||
|
encrypted_entitled_key_array[i].content_key_data.length,
|
||||||
&aes_key, iv, AES_ENCRYPT);
|
&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();
|
|
||||||
}
|
}
|
||||||
ASSERT_EQ(expected_sts,
|
ASSERT_EQ(
|
||||||
|
expected_sts,
|
||||||
OEMCrypto_LoadEntitledContentKeys(
|
OEMCrypto_LoadEntitledContentKeys(
|
||||||
session_id(), num_keys_, &encrypted_entitled_key_array[0]));
|
session_id(),
|
||||||
|
reinterpret_cast<const uint8_t*>(encrypted_entitled_message_.data()),
|
||||||
|
encrypted_entitled_message_.size(), num_keys_,
|
||||||
|
&encrypted_entitled_key_array[0]));
|
||||||
if (expected_sts != OEMCrypto_SUCCESS) {
|
if (expected_sts != OEMCrypto_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -409,9 +446,12 @@ void Session::VerifyEntitlementTestKeys() {
|
|||||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||||
KeyControlBlock block;
|
KeyControlBlock block;
|
||||||
size_t size = sizeof(block);
|
size_t size = sizeof(block);
|
||||||
|
const uint8_t* content_key_id =
|
||||||
|
reinterpret_cast<const uint8_t*>(entitled_message_.data());
|
||||||
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
|
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
|
||||||
session_id(), entitled_key_array_[i].content_key_id,
|
session_id(),
|
||||||
entitled_key_array_[i].content_key_id_length,
|
content_key_id + entitled_key_array_[i].content_key_id.offset,
|
||||||
|
entitled_key_array_[i].content_key_id.length,
|
||||||
reinterpret_cast<uint8_t*>(&block), &size);
|
reinterpret_cast<uint8_t*>(&block), &size);
|
||||||
if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
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<const char*>(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() {
|
void Session::EncryptAndSign() {
|
||||||
encrypted_license() = license_;
|
encrypted_license() = license_;
|
||||||
|
|
||||||
@@ -606,6 +667,7 @@ void Session::EncryptAndSign() {
|
|||||||
ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
|
ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
|
||||||
message_size_, &signature_);
|
message_size_, &signature_);
|
||||||
FillKeyArray(encrypted_license(), key_array_);
|
FillKeyArray(encrypted_license(), key_array_);
|
||||||
|
SetLoadKeysSubstringParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::EncryptProvisioningMessage(
|
void Session::EncryptProvisioningMessage(
|
||||||
@@ -664,31 +726,45 @@ void Session::VerifyClientSignature(size_t data_length) {
|
|||||||
|
|
||||||
void Session::FillKeyArray(const MessageData& data,
|
void Session::FillKeyArray(const MessageData& data,
|
||||||
OEMCrypto_KeyObject* key_array) {
|
OEMCrypto_KeyObject* key_array) {
|
||||||
|
const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(&data);
|
||||||
|
std::string message = wvcdm::BytesToString(data_ptr, sizeof(MessageData));
|
||||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||||
key_array[i].key_id = data.keys[i].key_id;
|
key_array[i].key_id = GetSubstring(
|
||||||
key_array[i].key_id_length = data.keys[i].key_id_length;
|
message,
|
||||||
key_array[i].key_data_iv = data.keys[i].key_iv;
|
wvcdm::BytesToString(data.keys[i].key_id, data.keys[i].key_id_length));
|
||||||
key_array[i].key_data = data.keys[i].key_data;
|
key_array[i].key_data_iv = GetSubstring(
|
||||||
key_array[i].key_data_length = data.keys[i].key_data_length;
|
message,
|
||||||
key_array[i].key_control_iv = data.keys[i].control_iv;
|
wvcdm::BytesToString(data.keys[i].key_iv, sizeof(data.keys[i].key_iv)));
|
||||||
key_array[i].key_control =
|
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<const uint8_t*>(&data.keys[i].control);
|
reinterpret_cast<const uint8_t*>(&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,
|
void Session::FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array,
|
||||||
size_t key_count) {
|
size_t key_count) {
|
||||||
|
std::string message =
|
||||||
|
wvcdm::BytesToString(message_ptr(), sizeof(MessageData));
|
||||||
for (size_t i = 0; i < key_count; i++) {
|
for (size_t i = 0; i < key_count; i++) {
|
||||||
if (key_count > 1) {
|
key_array[i].key_id = GetSubstring(
|
||||||
key_array[i].key_id = encrypted_license().keys[i].key_id;
|
message,
|
||||||
key_array[i].key_id_length = encrypted_license().keys[i].key_id_length;
|
wvcdm::BytesToString(encrypted_license().keys[i].key_id,
|
||||||
} else {
|
sizeof(encrypted_license().keys[i].key_id)),
|
||||||
key_array[i].key_id = NULL;
|
key_count <= 1);
|
||||||
key_array[i].key_id_length = 0;
|
key_array[i].key_control_iv = GetSubstring();
|
||||||
}
|
key_array[i].key_control = GetSubstring(
|
||||||
key_array[i].key_control_iv = NULL;
|
message,
|
||||||
key_array[i].key_control =
|
wvcdm::BytesToString(reinterpret_cast<const uint8_t*>(
|
||||||
reinterpret_cast<const uint8_t*>(&encrypted_license().keys[i].control);
|
&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);
|
ASSERT_LE(message_size_, kMaxMessageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t* Session::encrypted_entitled_message_ptr() {
|
||||||
|
return reinterpret_cast<const uint8_t*>(encrypted_entitled_message_.data());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wvoec
|
} // namespace wvoec
|
||||||
|
|||||||
@@ -125,6 +125,13 @@ uint32_t htonl_fnc(uint32_t x);
|
|||||||
// Prints error string from BoringSSL
|
// Prints error string from BoringSSL
|
||||||
void dump_boringssl_error();
|
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 {
|
class Session {
|
||||||
public:
|
public:
|
||||||
Session();
|
Session();
|
||||||
@@ -205,6 +212,11 @@ class Session {
|
|||||||
// is just signed. The signature is computed in RefreshTestKeys, above.
|
// is just signed. The signature is computed in RefreshTestKeys, above.
|
||||||
void FillRefreshMessage(size_t key_count, uint32_t control_bits,
|
void FillRefreshMessage(size_t key_count, uint32_t control_bits,
|
||||||
uint32_t nonce);
|
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
|
// This copies data from license_ to encrypted_license_, and then encrypts
|
||||||
// each field in the key array appropriately. It then signes the buffer with
|
// 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
|
// 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.
|
// The size of the encrypted message.
|
||||||
size_t message_size() { return message_size_; }
|
size_t message_size() { return message_size_; }
|
||||||
|
|
||||||
|
// The OEMCrypto_Substrings associated with the encrypted license that are
|
||||||
|
// passed to LoadKeys.
|
||||||
|
vector<OEMCrypto_Substring> 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:
|
private:
|
||||||
// Generate mac and enc keys give the master key.
|
// Generate mac and enc keys give the master key.
|
||||||
void DeriveKeys(const uint8_t* master_key,
|
void DeriveKeys(const uint8_t* master_key,
|
||||||
@@ -410,6 +435,7 @@ class Session {
|
|||||||
} padded_message_;
|
} padded_message_;
|
||||||
size_t message_size_; // How much of the padded message to use.
|
size_t message_size_; // How much of the padded message to use.
|
||||||
OEMCrypto_KeyObject key_array_[kMaxNumKeys];
|
OEMCrypto_KeyObject key_array_[kMaxNumKeys];
|
||||||
|
vector<OEMCrypto_Substring> load_keys_params_;
|
||||||
std::vector<uint8_t> signature_;
|
std::vector<uint8_t> signature_;
|
||||||
unsigned int num_keys_;
|
unsigned int num_keys_;
|
||||||
vector<uint8_t> encrypted_usage_entry_;
|
vector<uint8_t> encrypted_usage_entry_;
|
||||||
@@ -419,8 +445,11 @@ class Session {
|
|||||||
// Clear Entitlement key data. This is the backing data for
|
// Clear Entitlement key data. This is the backing data for
|
||||||
// |entitled_key_array_|.
|
// |entitled_key_array_|.
|
||||||
EntitledContentKeyData entitled_key_data_[kMaxNumKeys];
|
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_|.
|
// Entitled key object. Pointers are backed by |entitled_key_data_|.
|
||||||
OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys];
|
OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys];
|
||||||
|
std::string encrypted_entitled_message_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wvoec
|
} // namespace wvoec
|
||||||
|
|||||||
@@ -913,9 +913,10 @@ TEST_F(OEMCryptoSessionTests, LoadEntitlementKeysWrongEntitlementKeysAPI14) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.LoadEntitlementTestKeys());
|
ASSERT_NO_FATAL_FAILURE(s.LoadEntitlementTestKeys());
|
||||||
s.FillEntitledKeyArray();
|
s.FillEntitledKeyArray();
|
||||||
const std::string key_id = "no_key";
|
const std::string key_id = "no_key";
|
||||||
s.entitled_key_array()[0].entitlement_key_id =
|
memcpy(const_cast<uint8_t*>(s.encrypted_entitled_message_ptr()) +
|
||||||
reinterpret_cast<const uint8_t*>(key_id.c_str());
|
s.entitled_key_array()[0].entitlement_key_id.offset,
|
||||||
s.entitled_key_array()[0].entitlement_key_id_length = key_id.length();
|
reinterpret_cast<const uint8_t*>(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);
|
s.LoadEntitledContentKeys(OEMCrypto_KEY_NOT_ENTITLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,6 +962,15 @@ TEST_F(OEMCryptoSessionTests, LoadKeyLargeBuffer) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
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<const uint8_t*>(&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
|
/* The Bad Range tests verify that OEMCrypto_LoadKeys checks the range
|
||||||
of all the pointers. It should reject a message if the pointer does
|
of all the pointers. It should reject a message if the pointer does
|
||||||
not point into the message buffer */
|
not point into the message buffer */
|
||||||
@@ -970,15 +980,17 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
vector<uint8_t> mac_keys(
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.encrypted_license().mac_keys,
|
OEMCrypto_Substring wrong_mac_keys = s.enc_mac_keys_substr();
|
||||||
s.encrypted_license().mac_keys + sizeof(s.encrypted_license().mac_keys));
|
wrong_mac_keys.offset += s.message_size();
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
&mac_keys[0], // Not pointing into buffer.
|
s.enc_mac_keys_iv_substr(),
|
||||||
s.num_keys(), s.key_array(), NULL, 0, NULL, OEMCrypto_ContentLicense);
|
wrong_mac_keys, // Not within range of one message.
|
||||||
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,17 +1000,16 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
vector<uint8_t> mac_key_iv(s.encrypted_license().mac_key_iv,
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.encrypted_license().mac_key_iv +
|
OEMCrypto_Substring wrong_mac_keys_iv = s.enc_mac_keys_iv_substr();
|
||||||
sizeof(s.encrypted_license().mac_key_iv));
|
wrong_mac_keys_iv.offset += s.message_size();
|
||||||
|
|
||||||
OEMCryptoResult sts =
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
&s.signature()[0], s.signature().size(),
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
&mac_key_iv[0], // bad.
|
wrong_mac_keys_iv, // bad.
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.enc_mac_keys_substr(), s.num_keys(), s.key_array(), GetSubstring(),
|
||||||
s.key_array(), NULL, 0, NULL,
|
GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
OEMCrypto_ContentLicense);
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1008,16 +1019,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
vector<uint8_t> bad_buffer(s.encrypted_license().keys[0].key_id,
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.encrypted_license().keys[0].key_id +
|
s.key_array()[0].key_id.offset += s.message_size();
|
||||||
s.encrypted_license().keys[0].key_id_length);
|
|
||||||
s.key_array()[0].key_id = &bad_buffer[0];
|
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
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.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
|
|
||||||
vector<uint8_t> bad_buffer(
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.encrypted_license().keys[1].key_data,
|
s.key_array()[1].key_data.offset += s.message_size();
|
||||||
s.encrypted_license().keys[1].key_data + wvoec::KEY_SIZE);
|
|
||||||
s.key_array()[1].key_data = &bad_buffer[0];
|
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1047,15 +1054,13 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
vector<uint8_t> bad_buffer(s.encrypted_license().keys[1].key_iv,
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.encrypted_license().keys[1].key_iv +
|
s.key_array()[1].key_data_iv.offset += s.message_size();
|
||||||
sizeof(s.encrypted_license().keys[1].key_iv));
|
|
||||||
s.key_array()[1].key_data_iv = &bad_buffer[0];
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
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.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
|
|
||||||
vector<uint8_t> bad_buffer(s.key_array()[2].key_control,
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.key_array()[2].key_control +
|
s.key_array()[2].key_control.offset += s.message_size();
|
||||||
sizeof(s.encrypted_license().keys[1].control));
|
|
||||||
s.key_array()[2].key_control = &bad_buffer[0];
|
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), reinterpret_cast<const uint8_t*>(double_message.data()),
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.message_size(), &s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(), s.num_keys(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
s.key_array(), GetSubstring(), GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1085,17 +1088,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
vector<uint8_t> bad_buffer(
|
std::string double_message = DuplicateMessage(s.encrypted_license());
|
||||||
s.key_array()[2].key_control_iv,
|
s.key_array()[2].key_control_iv.offset += s.message_size();
|
||||||
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];
|
|
||||||
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,15 +1103,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) {
|
|||||||
Session s;
|
Session s;
|
||||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
|
||||||
wvoec::kControlNonceEnabled,
|
|
||||||
42)); // bad nonce.
|
42)); // bad nonce.
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
@@ -1129,15 +1128,14 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
|
|||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
|
||||||
wvoec::kControlNonceEnabled,
|
|
||||||
nonce)); // same old nonce.
|
nonce)); // same old nonce.
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
@@ -1161,9 +1159,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceReopenSession) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
@@ -1186,9 +1184,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNonceWrongSession) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0],
|
s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0],
|
||||||
s2.signature().size(), s2.encrypted_license().mac_key_iv,
|
s2.signature().size(), s2.enc_mac_keys_iv_substr(),
|
||||||
s2.encrypted_license().mac_keys, s2.num_keys(), s2.key_array(), NULL, 0,
|
s2.enc_mac_keys_substr(), s2.num_keys(), s2.key_array(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
GetSubstring(), OEMCrypto_ContentLicense);
|
||||||
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
@@ -1202,9 +1200,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
|
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
@@ -1238,9 +1236,9 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
// If this is a future API, then LoadKeys should fail.
|
// If this is a future API, then LoadKeys should fail.
|
||||||
if (global_features.api_version < target_api_) {
|
if (global_features.api_version < target_api_) {
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
@@ -1266,9 +1264,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) {
|
|||||||
s.signature()[0] ^= 42; // Bad signature.
|
s.signature()[0] ^= 42; // Bad signature.
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1280,9 +1278,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1298,8 +1296,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeys) {
|
|||||||
ASSERT_NE(
|
ASSERT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(), NULL, NULL,
|
&s.signature()[0], s.signature().size(),
|
||||||
kNoKeys, s.key_array(), NULL, 0, NULL,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
|
kNoKeys, s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
OEMCrypto_ContentLicense));
|
OEMCrypto_ContentLicense));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1314,8 +1313,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) {
|
|||||||
ASSERT_NE(
|
ASSERT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(), NULL, NULL,
|
&s.signature()[0], s.signature().size(),
|
||||||
kNoKeys, s.key_array(), NULL, 0, NULL,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
|
kNoKeys, s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
OEMCrypto_ContentLicense));
|
OEMCrypto_ContentLicense));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1370,9 +1370,9 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
if (OEMCrypto_IsAntiRollbackHwPresent()) {
|
if (OEMCrypto_IsAntiRollbackHwPresent()) {
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||||
} else {
|
} else {
|
||||||
@@ -1394,44 +1394,39 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
|||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), GetSubstring(),
|
||||||
s.key_array(), NULL, 0, NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
if (patch_level < 0x3F) {
|
if (patch_level < 0x3F) {
|
||||||
Session s;
|
Session s;
|
||||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||||
0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift,
|
0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift, 0));
|
||||||
0));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
OEMCrypto_ERROR_UNKNOWN_FAILURE,
|
OEMCrypto_ERROR_UNKNOWN_FAILURE,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), GetSubstring(),
|
||||||
s.key_array(), NULL, 0, NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
if (patch_level > 0) {
|
if (patch_level > 0) {
|
||||||
Session s;
|
Session s;
|
||||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||||
0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift,
|
0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift, 0));
|
||||||
0));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
ASSERT_EQ(
|
ASSERT_EQ(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), GetSubstring(),
|
||||||
s.key_array(), NULL, 0, NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4781,7 +4776,6 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) {
|
|||||||
Session s2;
|
Session s2;
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
|
||||||
s2.LoadUsageEntry(s); // Use the same entry.
|
s2.LoadUsageEntry(s); // Use the same entry.
|
||||||
// Trying to reuse a PST is bad. We use session ID for s2, everything else
|
// Trying to reuse a PST is bad. We use session ID for s2, everything else
|
||||||
// reused from s.
|
// reused from s.
|
||||||
@@ -4789,10 +4783,9 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) {
|
|||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.close());
|
ASSERT_NO_FATAL_FAILURE(s2.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4808,9 +4801,9 @@ TEST_F(UsageTableTest, OnlineEmptyPST) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||||
}
|
}
|
||||||
@@ -4828,9 +4821,9 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
|
|||||||
// ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
// ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(),
|
s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(),
|
||||||
s.encrypted_license().pst, pst.length(), NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||||
}
|
}
|
||||||
@@ -4838,8 +4831,7 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
|
|||||||
TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
|
TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
|
||||||
std::string pst = "A PST";
|
std::string pst = "A PST";
|
||||||
uint32_t nonce = session_.get_nonce();
|
uint32_t nonce = session_.get_nonce();
|
||||||
MakeFourKeys(
|
MakeFourKeys(0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
|
||||||
nonce, pst);
|
nonce, pst);
|
||||||
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
||||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||||
@@ -5116,15 +5108,13 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
|
|||||||
0, wvoec::kControlNonceOrEntry, s2.get_nonce(), pst));
|
0, wvoec::kControlNonceOrEntry, s2.get_nonce(), pst));
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
||||||
uint8_t* pst_ptr = s2.encrypted_license().pst;
|
|
||||||
ASSERT_NE(
|
ASSERT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s2.session_id(), s2.message_ptr(), s2.message_size(),
|
OEMCrypto_LoadKeys(s2.session_id(), s2.message_ptr(), s2.message_size(),
|
||||||
&s2.signature()[0], s2.signature().size(),
|
&s2.signature()[0], s2.signature().size(),
|
||||||
s2.encrypted_license().mac_key_iv,
|
s2.enc_mac_keys_iv_substr(), s2.enc_mac_keys_substr(),
|
||||||
s2.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s2.key_array(), s2.pst_substr(),
|
||||||
s2.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.close());
|
ASSERT_NO_FATAL_FAILURE(s2.close());
|
||||||
|
|
||||||
// Offline license with same mac keys should still be OK.
|
// 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(InstallTestSessionKeys(&s));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||||
ASSERT_NO_FATAL_FAILURE(
|
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused,
|
||||||
s.GenerateVerifyReport(pst, kUnused,
|
|
||||||
loaded, // license loaded.
|
loaded, // license loaded.
|
||||||
0, 0)); // first and last decrypt
|
0,
|
||||||
|
0)); // first and last decrypt
|
||||||
}
|
}
|
||||||
|
|
||||||
// An offline license should not load on the first call if the nonce is bad.
|
// 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(
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst));
|
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), pst_ptr,
|
s.num_keys(), s.key_array(), s.pst_substr(), GetSubstring(),
|
||||||
pst.length(), NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||||
}
|
}
|
||||||
@@ -5170,9 +5159,9 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||||
s.signature().size(), s.encrypted_license().mac_key_iv,
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
NULL, OEMCrypto_ContentLicense);
|
OEMCrypto_ContentLicense);
|
||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||||
}
|
}
|
||||||
@@ -5188,14 +5177,12 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineWrongPST) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry());
|
ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry());
|
||||||
memcpy(s.license().pst, bad_pst.c_str(), bad_pst.length());
|
memcpy(s.license().pst, bad_pst.c_str(), bad_pst.length());
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
ASSERT_NE(OEMCrypto_SUCCESS,
|
||||||
ASSERT_NE(
|
OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_SUCCESS,
|
s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
&s.signature()[0], s.signature().size(), GetSubstring(),
|
||||||
&s.signature()[0], s.signature().size(), NULL, NULL,
|
GetSubstring(), s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.num_keys(), s.key_array(),
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
pst_ptr, bad_pst.length(), NULL,
|
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
|
TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
|
||||||
@@ -5222,15 +5209,13 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
||||||
// Offile license can not be reused if it has been deactivated.
|
// Offile license can not be reused if it has been deactivated.
|
||||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
|
||||||
EXPECT_NE(
|
EXPECT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
s2.close();
|
s2.close();
|
||||||
// But we can still generate a report.
|
// But we can still generate a report.
|
||||||
Session s3;
|
Session s3;
|
||||||
@@ -5265,15 +5250,13 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||||
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s1));
|
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s1));
|
||||||
// Offline license can not be reused if it has been deactivated.
|
// Offline license can not be reused if it has been deactivated.
|
||||||
uint8_t* pst_ptr = s1.encrypted_license().pst;
|
|
||||||
EXPECT_NE(
|
EXPECT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(),
|
OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(),
|
||||||
&s1.signature()[0], s1.signature().size(),
|
&s1.signature()[0], s1.signature().size(),
|
||||||
s1.encrypted_license().mac_key_iv,
|
s1.enc_mac_keys_iv_substr(), s1.enc_mac_keys_substr(),
|
||||||
s1.encrypted_license().mac_keys, s1.num_keys(),
|
s1.num_keys(), s1.key_array(), s1.pst_substr(),
|
||||||
s1.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
s2.close();
|
s2.close();
|
||||||
// But we can still generate a report.
|
// But we can still generate a report.
|
||||||
Session s3;
|
Session s3;
|
||||||
@@ -5293,15 +5276,13 @@ TEST_P(UsageTableTestWithMAC, BadRange) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||||
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
uint8_t* pst_ptr = s.license().pst; // Bad: not in encrypted_license.
|
|
||||||
ASSERT_NE(
|
ASSERT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UsageTableTest, UpdateFailsWithNullPtr) {
|
TEST_F(UsageTableTest, UpdateFailsWithNullPtr) {
|
||||||
@@ -5371,15 +5352,13 @@ class UsageTableDefragTest : public UsageTableTest {
|
|||||||
&s->encrypted_usage_entry()[0],
|
&s->encrypted_usage_entry()[0],
|
||||||
s->encrypted_usage_entry().size()));
|
s->encrypted_usage_entry().size()));
|
||||||
|
|
||||||
uint8_t* pst_ptr = s->encrypted_license().pst;
|
ASSERT_NE(OEMCrypto_SUCCESS,
|
||||||
ASSERT_NE(
|
OEMCrypto_LoadKeys(
|
||||||
OEMCrypto_SUCCESS,
|
s->session_id(), s->message_ptr(), s->message_size(),
|
||||||
OEMCrypto_LoadKeys(s->session_id(), s->message_ptr(), s->message_size(),
|
|
||||||
&s->signature()[0], s->signature().size(),
|
&s->signature()[0], s->signature().size(),
|
||||||
s->encrypted_license().mac_key_iv,
|
s->enc_mac_keys_iv_substr(), s->enc_mac_keys_substr(),
|
||||||
s->encrypted_license().mac_keys, s->num_keys(),
|
s->num_keys(), s->key_array(), s->pst_substr(),
|
||||||
s->key_array(), pst_ptr, s->pst().length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s->close());
|
ASSERT_NO_FATAL_FAILURE(s->close());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6056,15 +6035,13 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) {
|
|||||||
htonl(wvoec::kSharedLicense);
|
htonl(wvoec::kSharedLicense);
|
||||||
}
|
}
|
||||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
ASSERT_EQ(
|
||||||
ASSERT_EQ(OEMCrypto_ERROR_MISSING_MASTER,
|
OEMCrypto_ERROR_MISSING_MASTER,
|
||||||
OEMCrypto_LoadKeys(
|
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
|
||||||
s.session_id(), s.message_ptr(), s.message_size(),
|
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys,
|
s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.num_keys(), s.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6091,16 +6068,14 @@ TEST_F(UsageTableTest, PSTLargeBuffer) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||||
// Offile license can not be reused if it has been deactivated.
|
// 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));
|
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
||||||
EXPECT_NE(
|
EXPECT_NE(
|
||||||
OEMCrypto_SUCCESS,
|
OEMCrypto_SUCCESS,
|
||||||
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
OEMCrypto_LoadKeys(s2.session_id(), s.message_ptr(), s.message_size(),
|
||||||
&s.signature()[0], s.signature().size(),
|
&s.signature()[0], s.signature().size(),
|
||||||
s.encrypted_license().mac_key_iv,
|
s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
s.encrypted_license().mac_keys, s.num_keys(),
|
s.num_keys(), s.key_array(), s.pst_substr(),
|
||||||
s.key_array(), pst_ptr, pst.length(), NULL,
|
GetSubstring(), OEMCrypto_ContentLicense));
|
||||||
OEMCrypto_ContentLicense));
|
|
||||||
s2.close();
|
s2.close();
|
||||||
// But we can still generate a report.
|
// But we can still generate a report.
|
||||||
Session s3;
|
Session s3;
|
||||||
|
|||||||
Reference in New Issue
Block a user