Add Entitlement License to OEMCrypto

This CL adds entitlement license features and moves cipher mode from
LoadKeys to SelectKeys.

Merge from Widevine repo of http://go/wvgerrit/41660

bug: 70334840 Entitlement License - cdm layer
bug: 70334345 Entitlement License - reference code and unit tests

test: Entitlement license unit tests pass.
Change-Id: Ic7d7f42c15e6d83ef7fcfd8a866c778adc4c8095
This commit is contained in:
Fred Gylys-Colwell
2018-01-23 15:55:43 -08:00
parent 95fa4ffca9
commit 979ed70c7b
11 changed files with 1136 additions and 595 deletions

View File

@@ -227,7 +227,8 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
&signature_[0], signature_.size(),
encrypted_license().mac_key_iv,
encrypted_license().mac_keys, num_keys_,
key_array_, pst_ptr, pst.length(), NULL));
key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
@@ -237,11 +238,113 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), NULL, NULL,
num_keys_, key_array_, pst_ptr, pst.length(), NULL));
num_keys_, key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
}
VerifyTestKeys();
}
void Session::LoadEnitlementTestKeys(const std::string& pst,
bool new_mac_keys,
OEMCryptoResult expected_sts) {
uint8_t* pst_ptr = NULL;
if (pst.length() > 0) {
pst_ptr = encrypted_license().pst;
}
if (new_mac_keys) {
ASSERT_EQ(expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(),
encrypted_license().mac_key_iv,
encrypted_license().mac_keys, num_keys_,
key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_EntitlementLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
wvcdm::MAC_KEY_SIZE);
} else {
ASSERT_EQ(
expected_sts,
OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
&signature_[0], signature_.size(), NULL, NULL,
num_keys_, key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_EntitlementLicense));
}
}
void Session::FillEntitledKeyArray() {
for (size_t i = 0; i < num_keys_; ++i) {
EntitledContentKeyData* key_data = &entitled_key_data_[i];
entitled_key_array_[i].entitlement_key_id = key_array_[i].key_id;
entitled_key_array_[i].entitlement_key_id_length =
key_array_[i].key_id_length;
EXPECT_EQ(
1, GetRandBytes(key_data->content_key_id,
sizeof(key_data->content_key_id)));
entitled_key_array_[i].content_key_id = key_data->content_key_id;
entitled_key_array_[i].content_key_id_length =
sizeof(key_data->content_key_id);
EXPECT_EQ(
1, GetRandBytes(key_data->content_key_data,
sizeof(key_data->content_key_data)));
entitled_key_array_[i].content_key_data = key_data->content_key_data;
entitled_key_array_[i].content_key_data_length =
sizeof(key_data->content_key_data);
EXPECT_EQ(
1, GetRandBytes(entitled_key_data_[i].content_key_data_iv,
sizeof(entitled_key_data_[i].content_key_data_iv)));
entitled_key_array_[i].content_key_data_iv = key_data->content_key_data_iv;
}
}
void Session::LoadEntitledContentKeys(OEMCryptoResult expected_sts) {
// Create a copy of the stored |entitled_key_array_|.
std::vector<OEMCrypto_EntitledContentKeyObject> encrypted_entitled_key_array;
encrypted_entitled_key_array.resize(num_keys_);
memcpy(&encrypted_entitled_key_array[0], &entitled_key_array_[0],
sizeof(OEMCrypto_EntitledContentKeyObject) * num_keys_);
// Create a 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) {
// Load the entitlement key from |key_array_|.
AES_KEY aes_key;
AES_set_encrypt_key(&key_array_[i].key_data[0], 256, &aes_key);
encrypted_content_keys[i].resize(
encrypted_entitled_key_array[i].content_key_data_length);
// Encrypt the content key with the entitlement key.
uint8_t iv[16];
memcpy(&iv[0], &encrypted_entitled_key_array[i].content_key_data[0], 16);
AES_cbc_encrypt(
&entitled_key_array_[i].content_key_data[0],
const_cast<uint8_t*>(
&encrypted_entitled_key_array[i].content_key_data[0]),
encrypted_entitled_key_array[i].content_key_data_length,
&aes_key, iv, AES_ENCRYPT);
// Set the |encrypted_entitled_key_array| to point to the encrypted copy
// of the content key.
encrypted_entitled_key_array[i].content_key_data =
encrypted_content_keys[i].data();
}
ASSERT_EQ(expected_sts,
OEMCrypto_LoadEntitledContentKeys(
session_id(), num_keys_, &encrypted_entitled_key_array[0]));
if (expected_sts != OEMCrypto_SUCCESS) {
return;
}
VerifyEntitlementTestKeys();
}
void Session::VerifyTestKeys() {
for (unsigned int i = 0; i < num_keys_; i++) {
KeyControlBlock block;
@@ -264,6 +367,29 @@ void Session::VerifyTestKeys() {
}
}
void Session::VerifyEntitlementTestKeys() {
for (unsigned int i = 0; i < num_keys_; i++) {
KeyControlBlock block;
size_t size = sizeof(block);
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
session_id(), entitled_key_array_[i].content_key_id,
entitled_key_array_[i].content_key_id_length,
reinterpret_cast<uint8_t*>(&block), &size);
if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(sizeof(block), size);
// control duration and bits stored in network byte order. For printing
// we change to host byte order.
ASSERT_EQ((htonl_fnc(license_.keys[i].control.duration)),
(htonl_fnc(block.duration)))
<< "For key " << i;
ASSERT_EQ(htonl_fnc(license_.keys[i].control.control_bits),
htonl_fnc(block.control_bits))
<< "For key " << i;
}
}
}
void Session::RefreshTestKeys(const size_t key_count, uint32_t control_bits,
uint32_t nonce, OEMCryptoResult expected_result) {
// Note: we store the message in encrypted_license_, but the refresh key
@@ -319,7 +445,57 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
sizeof(license_.keys[i].key_iv)));
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
sizeof(license_.keys[i].control_iv)));
if (global_features.api_version == 13) {
if (global_features.api_version == 14) {
// For version 14, we require OEMCrypto to handle kc14 for all licenses.
memcpy(license_.keys[i].control.verification, "kc14", 4);
} else if (global_features.api_version == 13) {
// For version 13, we require OEMCrypto to handle kc13 for all licenses.
memcpy(license_.keys[i].control.verification, "kc13", 4);
} else if (global_features.api_version == 12) {
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
memcpy(license_.keys[i].control.verification, "kc12", 4);
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
// For versions before 12, we require the special key control block only
// when there are newer features present.
memcpy(license_.keys[i].control.verification, "kc11", 4);
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
memcpy(license_.keys[i].control.verification, "kc10", 4);
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
wvoec_mock::kControlReplayMask)) {
memcpy(license_.keys[i].control.verification, "kc09", 4);
} else {
memcpy(license_.keys[i].control.verification, "kctl", 4);
}
license_.keys[i].control.duration = htonl(duration);
license_.keys[i].control.nonce = htonl(nonce);
license_.keys[i].control.control_bits = htonl(control);
license_.keys[i].cipher_mode = OEMCrypto_CipherMode_CTR;
}
memcpy(license_.pst, pst.c_str(), min(sizeof(license_.pst), pst.length()));
pst_ = pst;
}
void Session::FillSimpleEntitlementMessage(
uint32_t duration, uint32_t control, uint32_t nonce,
const std::string& pst) {
EXPECT_EQ(
1, GetRandBytes(license_.mac_key_iv, sizeof(license_.mac_key_iv)));
EXPECT_EQ(1, GetRandBytes(license_.mac_keys, sizeof(license_.mac_keys)));
for (unsigned int i = 0; i < num_keys_; i++) {
memset(license_.keys[i].key_id, 0, kTestKeyIdMaxLength);
license_.keys[i].key_id_length = kDefaultKeyIdLength;
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_data,
sizeof(license_.keys[i].key_data)));
license_.keys[i].key_data_length = wvcdm::KEY_SIZE * 2; // AES-256 keys
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
sizeof(license_.keys[i].key_iv)));
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
sizeof(license_.keys[i].control_iv)));
if (global_features.api_version == 14) {
// For version 13, we require OEMCrypto to handle kc14 for all licenses.
memcpy(license_.keys[i].control.verification, "kc14", 4);
} else if (global_features.api_version == 13) {
// For version 13, we require OEMCrypto to handle kc13 for all licenses.
memcpy(license_.keys[i].control.verification, "kc13", 4);
} else if (global_features.api_version == 12) {
@@ -464,7 +640,6 @@ void Session::FillKeyArray(const MessageData& data,
key_array[i].key_control_iv = data.keys[i].control_iv;
key_array[i].key_control =
reinterpret_cast<const uint8_t*>(&data.keys[i].control);
key_array[i].cipher_mode = data.keys[i].cipher_mode;
}
}
@@ -514,7 +689,8 @@ void Session::TestDecryptCTR(bool select_key_first,
if (select_key_first) {
// Select the key (from FillSimpleMessage)
sts = OEMCrypto_SelectKey(session_id(), license_.keys[key_index].key_id,
license_.keys[key_index].key_id_length);
license_.keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
@@ -578,7 +754,8 @@ void Session::TestSelectExpired(unsigned int key_index) {
if (global_features.api_version >= 13) {
OEMCryptoResult status =
OEMCrypto_SelectKey(session_id(), license().keys[key_index].key_id,
license().keys[key_index].key_id_length);
license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
// It is OK for SelectKey to succeed with an expired key, but if there is
// an error, it must be OEMCrypto_ERROR_KEY_EXIRED.
if (status != OEMCrypto_SUCCESS) {

View File

@@ -103,6 +103,13 @@ struct Test_PST_Report {
std::string pst;
};
struct EntitledContentKeyData {
uint8_t entitlement_key_id[wvcdm::KEY_SIZE];
uint8_t content_key_id[wvcdm::KEY_SIZE];
uint8_t content_key_data_iv[wvcdm::KEY_SIZE];
uint8_t content_key_data[wvcdm::KEY_SIZE];
};
// Increment counter for AES-CTR. The CENC spec specifies we increment only
// the low 64 bits of the IV counter, and leave the high 64 bits alone. This
// is different from the OpenSSL implementation, so we implement the CTR loop
@@ -151,9 +158,27 @@ class Session {
// by FillSimpleMessage, modified if needed, and then encrypted and signed by
// the server's mac key in EncryptAndSign.
void LoadTestKeys(const std::string& pst = "", bool new_mac_keys = true);
// Loads the entitlement keys in the message pointed to by message_ptr()
// using OEMCrypto_LoadKeys. This message should have already been created
// by FillSimpleEntitlementMessage, modified if needed, and then encrypted
// and signed by the server's mac key in EncryptAndSign.
void LoadEnitlementTestKeys(const std::string& pst = "",
bool new_mac_keys = true,
OEMCryptoResult expected_sts = OEMCrypto_SUCCESS);
// Fills an OEMCrypto_EntitledContentKeyObject using the information from
// the license_ and randomly generated content keys. This method should be
// called after LoadEnitlementTestKeys.
void FillEntitledKeyArray();
// Encrypts and loads the entitled content keys via
// OEMCrypto_LoadEntitledContentKeys.
void LoadEntitledContentKeys(
OEMCryptoResult expected_sts = OEMCrypto_SUCCESS);
// This uses OEMCrypto_QueryKeyControl to check that the keys in OEMCrypto
// have the correct key control data.
void VerifyTestKeys();
// This uses OEMCrypto_QueryKeyControl to check that the keys in OEMCrypto
// have the correct key control data.
void VerifyEntitlementTestKeys();
// This creates a refresh key or license renewal message, signs it with the
// server's mac key, and calls OEMCrypto_RefreshKeys.
void RefreshTestKeys(const size_t key_count, uint32_t control_bits,
@@ -166,6 +191,12 @@ class Session {
// before being loaded in LoadTestKeys.
void FillSimpleMessage(uint32_t duration, uint32_t control, uint32_t nonce,
const std::string& pst = "");
// This fills the data structure license_ with entitlement key information.
// This data can be modified, and then should be encrypted and signed in
// EncryptAndSign before being loaded in LoadEnitlementTestKeys.
void FillSimpleEntitlementMessage(
uint32_t duration, uint32_t control,
uint32_t nonce, const std::string& pst = "");
// Like FillSimpleMessage, this fills encrypted_license_ with data. The name
// is a little misleading: the license renewal message is not encrypted, it
// is just signed. The signature is computed in RefreshTestKeys, above.
@@ -360,6 +391,12 @@ class Session {
vector<uint8_t> encrypted_usage_entry_;
uint32_t usage_entry_number_;
string pst_;
// Clear Entitlement key data. This is the backing data for
// |entitled_key_array_|.
EntitledContentKeyData entitled_key_data_[kMaxNumKeys];
// Entitled key object. Pointers are backed by |entitled_key_data_|.
OEMCrypto_EntitledContentKeyObject entitled_key_array_[kMaxNumKeys];
};
} // namespace wvoec

View File

@@ -835,6 +835,29 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNoMAC) {
ASSERT_EQ(expected_signature, signature);
}
TEST_F(OEMCryptoSessionTests, LoadEntitlementKeys) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleEntitlementMessage(0, 0, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadEnitlementTestKeys());
s.FillEntitledKeyArray();
ASSERT_NO_FATAL_FAILURE(s.LoadEntitledContentKeys());
s.FillEntitledKeyArray();
ASSERT_NO_FATAL_FAILURE(s.LoadEntitledContentKeys());
}
TEST_F(OEMCryptoSessionTests, LoadEntitlementKeysNoEntitlementKeys) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleEntitlementMessage(0, 0, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
s.FillEntitledKeyArray();
s.LoadEntitledContentKeys(OEMCrypto_ERROR_INVALID_CONTEXT);
}
// This tests GenerateSignature with an 8k licnese request.
TEST_F(OEMCryptoSessionTests, ClientSignatureLargeBuffer) {
Session s;
@@ -894,7 +917,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange1) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
&mac_keys[0], // Not pointing into buffer.
s.num_keys(), s.key_array(), NULL, 0, NULL);
s.num_keys(), s.key_array(), NULL, 0, NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -913,7 +936,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange2) {
&s.signature()[0], s.signature().size(),
&mac_key_iv[0], // bad.
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), NULL, 0, NULL);
s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -932,7 +956,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -952,7 +976,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -970,7 +994,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange5) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -990,7 +1014,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange6) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1010,7 +1034,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1026,7 +1050,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1052,7 +1076,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1068,7 +1092,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1104,7 +1128,7 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
// If this is a future API, then LoadKeys should fail.
if (global_features.api_version < target_api_) {
ASSERT_NE(OEMCrypto_SUCCESS, sts);
@@ -1132,7 +1156,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1146,7 +1170,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeysWithNoDerivedKeys) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
@@ -1163,7 +1187,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeys) {
OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
&s.signature()[0], s.signature().size(), NULL, NULL,
kNoKeys, s.key_array(), NULL, 0, NULL));
kNoKeys, s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense));
}
TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) {
@@ -1178,7 +1203,8 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) {
OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
&s.signature()[0], s.signature().size(), NULL, NULL,
kNoKeys, s.key_array(), NULL, 0, NULL));
kNoKeys, s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense));
}
TEST_F(OEMCryptoSessionTests, QueryKeyControl) {
@@ -1219,7 +1245,7 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
if (OEMCrypto_IsAntiRollbackHwPresent()) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
} else {
@@ -1243,7 +1269,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), NULL, 0, NULL));
s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense));
}
if (patch_level < 0x3F) {
Session s;
@@ -1259,7 +1286,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), NULL, 0, NULL));
s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense));
}
if (patch_level > 0) {
Session s;
@@ -1275,7 +1303,8 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), NULL, 0, NULL));
s.key_array(), NULL, 0, NULL,
OEMCrypto_ContentLicense));
}
}
@@ -1687,7 +1716,8 @@ class OEMCryptoSessionTestsDecryptTests
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[0].key_id,
s.license().keys[0].key_id_length);
s.license().keys[0].key_id_length,
cipher_mode_);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// We decrypt each subsample.
@@ -2016,7 +2046,7 @@ INSTANTIATE_TEST_CASE_P(CTRTests, OEMCryptoSessionTestsPartialBlockTests,
// Decrypt in place for CBC tests was only required in v13.
INSTANTIATE_TEST_CASE_P(
CBCTestsAPI13, OEMCryptoSessionTestsPartialBlockTests,
CBCTestsAPI14, OEMCryptoSessionTestsPartialBlockTests,
Combine(
Values(MakePattern(0, 0),
MakePattern(3, 7),
@@ -2039,7 +2069,7 @@ INSTANTIATE_TEST_CASE_P(
// Decrypt in place for CBC tests was only required in v13.
INSTANTIATE_TEST_CASE_P(
CBCTestsAPI13, OEMCryptoSessionTestsDecryptTests,
CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests,
Combine(
Values(MakePattern(0, 0),
MakePattern(3, 7),
@@ -3783,7 +3813,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
EncryptBuffer(key_index, clear_buffer_, &expected_encrypted);
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> encrypted(buffer_length);
sts =
@@ -3801,7 +3832,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
EncryptBuffer(key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts =
@@ -3818,7 +3850,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
size_t signature_length = (size_t)SHA256_DIGEST_LENGTH;
vector<uint8_t> signature(SHA256_DIGEST_LENGTH);
@@ -3840,7 +3873,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0],
clear_buffer_.size(), algorithm,
@@ -3867,7 +3901,8 @@ TEST_F(GenericCryptoTest, GenericKeyEncrypt) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> encrypted(clear_buffer_.size());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Encrypt(
@@ -3895,7 +3930,8 @@ TEST_F(GenericCryptoTest, GenericKeyEncryptSameBufferAPI12) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
// Input and output are same buffer:
vector<uint8_t> buffer = clear_buffer_;
ASSERT_EQ(OEMCrypto_SUCCESS,
@@ -3914,7 +3950,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecrypt) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> resultant(encrypted.size());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Decrypt(
@@ -3932,7 +3969,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptSameBufferAPI12) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> buffer = encrypted;
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Decrypt(
@@ -3952,7 +3990,8 @@ TEST_F(GenericCryptoTest, GenericSecureToClear) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> resultant(encrypted.size());
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Decrypt(
@@ -3981,7 +4020,8 @@ TEST_F(GenericCryptoTest, GenericKeySign) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
size_t gen_signature_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0],
@@ -4014,7 +4054,8 @@ TEST_F(GenericCryptoTest, GenericKeyVerify) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Verify(
session_.session_id(), &clear_buffer_[0], clear_buffer_.size(),
@@ -4042,7 +4083,8 @@ TEST_F(GenericCryptoTest, GenericKeyEncryptLargeBuffer) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> encrypted(clear_buffer_.size());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Encrypt(
@@ -4062,7 +4104,8 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptLargeBuffer) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> resultant(encrypted.size());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Decrypt(
@@ -4082,7 +4125,8 @@ TEST_F(GenericCryptoTest, GenericKeySignLargeBuffer) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
size_t gen_signature_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0],
@@ -4108,7 +4152,8 @@ TEST_F(GenericCryptoTest, GenericKeyVerifyLargeBuffer) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Verify(
session_.session_id(), &clear_buffer_[0], clear_buffer_.size(),
@@ -4128,7 +4173,8 @@ TEST_F(GenericCryptoTest, KeyDurationEncrypt) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Encrypt(
session_.session_id(), &clear_buffer_[0], clear_buffer_.size(),
@@ -4157,7 +4203,8 @@ TEST_F(GenericCryptoTest, KeyDurationDecrypt) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
sleep(kShortSleep); // Should still be valid key.
@@ -4193,7 +4240,8 @@ TEST_F(GenericCryptoTest, KeyDurationSign) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
sleep(kShortSleep); // Should still be valid key.
@@ -4226,7 +4274,8 @@ TEST_F(GenericCryptoTest, KeyDurationVerify) {
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
sleep(kShortSleep); // Should still be valid key.
@@ -4292,7 +4341,8 @@ class GenericCryptoKeyIdLengthTest : public GenericCryptoTest {
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(session_.session_id(), key_id_buffer.data(),
session_.license().keys[key_index].key_id_length));
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR));
vector<uint8_t> resultant(encrypted.size());
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_Generic_Decrypt(
@@ -4500,7 +4550,8 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), pst_ptr, pst.length(), NULL));
s.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
ASSERT_NO_FATAL_FAILURE(s2.close());
}
@@ -4518,7 +4569,7 @@ TEST_F(UsageTableTest, OnlineEmptyPST) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
ASSERT_NO_FATAL_FAILURE(s.close());
}
@@ -4538,7 +4589,7 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(),
s.encrypted_license().pst, pst.length(), NULL);
s.encrypted_license().pst, pst.length(), NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
ASSERT_NO_FATAL_FAILURE(s.close());
}
@@ -4617,7 +4668,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
EncryptBuffer(key_index, clear_buffer_, &expected_encrypted);
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> encrypted(clear_buffer_.size());
sts = OEMCrypto_Generic_Encrypt(
@@ -4653,7 +4705,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) {
EncryptBuffer(key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(
@@ -4692,7 +4745,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) {
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
size_t gen_signature_length = 0;
sts = OEMCrypto_Generic_Sign(session_.session_id(), &clear_buffer_[0],
@@ -4738,7 +4792,8 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) {
sts = OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[key_index].key_id,
session_.license().keys[key_index].key_id_length);
session_.license().keys[key_index].key_id_length,
OEMCrypto_CipherMode_CTR);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_Generic_Verify(session_.session_id(), &clear_buffer_[0],
clear_buffer_.size(), OEMCrypto_HMAC_SHA256,
@@ -4885,7 +4940,8 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
&s2.signature()[0], s2.signature().size(),
s2.encrypted_license().mac_key_iv,
s2.encrypted_license().mac_keys, s.num_keys(),
s2.key_array(), pst_ptr, pst.length(), NULL));
s2.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
ASSERT_NO_FATAL_FAILURE(s2.close());
// Offline license with same mac keys should still be OK.
@@ -4912,7 +4968,7 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), pst_ptr,
pst.length(), NULL);
pst.length(), NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
ASSERT_NO_FATAL_FAILURE(s.close());
}
@@ -4930,7 +4986,7 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) {
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL);
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
ASSERT_NO_FATAL_FAILURE(s.close());
}
@@ -4952,7 +5008,8 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineWrongPST) {
OEMCrypto_LoadKeys(s.session_id(), s.message_ptr(), s.message_size(),
&s.signature()[0], s.signature().size(), NULL, NULL,
s.num_keys(), s.key_array(),
pst_ptr, bad_pst.length(), NULL));
pst_ptr, bad_pst.length(), NULL,
OEMCrypto_ContentLicense));
}
TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
@@ -4986,7 +5043,8 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), pst_ptr, pst.length(), NULL));
s.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
s2.close();
// But we can still generate a report.
Session s3;
@@ -5013,7 +5071,8 @@ TEST_P(UsageTableTestWithMAC, BadRange) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), pst_ptr, pst.length(), NULL));
s.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
}
TEST_F(UsageTableTest, UpdateFailsWithNullPtr) {
@@ -5090,7 +5149,8 @@ class UsageTableDefragTest : public UsageTableTest {
&s->signature()[0], s->signature().size(),
s->encrypted_license().mac_key_iv,
s->encrypted_license().mac_keys, s->num_keys(),
s->key_array(), pst_ptr, s->pst().length(), NULL));
s->key_array(), pst_ptr, s->pst().length(), NULL,
OEMCrypto_ContentLicense));
ASSERT_NO_FATAL_FAILURE(s->close());
}
@@ -5212,6 +5272,7 @@ TEST_F(UsageTableDefragTest, ReloadUsageEntryBadData) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
vector<uint8_t> data = s.encrypted_usage_entry();
ASSERT_LT(0, data.size());
data[0] ^= 42;
// Error could be signature or verification error.
ASSERT_NE(OEMCrypto_SUCCESS,
@@ -5607,7 +5668,8 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys,
s.num_keys(), s.key_array(), pst_ptr, pst.length(), NULL));
s.num_keys(), s.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
ASSERT_NO_FATAL_FAILURE(s.close());
}
@@ -5642,7 +5704,8 @@ TEST_F(UsageTableTest, PSTLargeBuffer) {
&s.signature()[0], s.signature().size(),
s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(),
s.key_array(), pst_ptr, pst.length(), NULL));
s.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
s2.close();
// But we can still generate a report.
Session s3;