Add Tests With Different Sized Key IDs

Merge from widevine repo of http://go/wvgerrit/14550

This CL adds several tests with different sized key ids to
oemcrypto_test.

bug: 21643096
Change-Id: I62a89c557f3f746f09ee5a2fe5bdd3ca821448e4
This commit is contained in:
Fred Gylys-Colwell
2015-06-04 15:57:56 -07:00
parent 4fce36e91f
commit 177c59033e

View File

@@ -69,9 +69,10 @@ typedef struct {
uint32_t control_bits;
} KeyControlBlock;
const size_t kTestKeyIdLength = 12; // pick a length. any length.
const size_t kTestKeyIdMaxLength = 48; // pick a length. any length.
typedef struct {
uint8_t key_id[kTestKeyIdLength];
uint8_t key_id[kTestKeyIdMaxLength];
size_t key_id_length;
uint8_t key_data[wvcdm::MAC_KEY_SIZE];
size_t key_data_length;
uint8_t key_iv[wvcdm::KEY_IV_SIZE];
@@ -79,11 +80,12 @@ typedef struct {
KeyControlBlock control;
} MessageKeyData;
// This structure will be signed to simulate a message from the server.
struct MessageData {
MessageKeyData keys[kNumKeys];
uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE];
uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE];
uint8_t pst[kTestKeyIdLength];
uint8_t pst[kTestKeyIdMaxLength];
};
const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate.
@@ -888,8 +890,7 @@ class Session {
KeyControlBlock block;
size_t size = sizeof(block);
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
session_id(), license_.keys[i].key_id,
sizeof(license_.keys[i].key_id),
session_id(), license_.keys[i].key_id, license_.keys[i].key_id_length,
reinterpret_cast<uint8_t*>(&block), &size);
if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
@@ -932,12 +933,21 @@ class Session {
}
}
void SetKeyId(int index, const string& key_id) {
MessageKeyData &key = license_.keys[index];
key.key_id_length = key_id.length();
ASSERT_LE(key.key_id_length, kTestKeyIdMaxLength);
memcpy(key.key_id, key_id.data(), key.key_id_length);
}
void FillSimpleMessage(uint32_t duration, uint32_t control, uint32_t nonce,
const std::string& pst = "") {
OEMCrypto_GetRandom(license_.mac_key_iv, sizeof(license_.mac_key_iv));
OEMCrypto_GetRandom(license_.mac_keys, sizeof(license_.mac_keys));
for (unsigned int i = 0; i < kNumKeys; i++) {
memset(license_.keys[i].key_id, i, kTestKeyIdLength);
memset(license_.keys[i].key_id, 0, kTestKeyIdMaxLength);
license_.keys[i].key_id_length = 12;
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
OEMCrypto_GetRandom(license_.keys[i].key_data,
sizeof(license_.keys[i].key_data));
license_.keys[i].key_data_length = wvcdm::KEY_SIZE;
@@ -967,7 +977,9 @@ class Session {
void FillRefreshMessage(size_t key_count, uint32_t control_bits,
uint32_t nonce) {
for (unsigned int i = 0; i < key_count; i++) {
memset(encrypted_license_.keys[i].key_id, i, kTestKeyIdLength);
encrypted_license_.keys[i].key_id_length = license_.keys[i].key_id_length;
memcpy(encrypted_license_.keys[i].key_id, license_.keys[i].key_id,
encrypted_license_.keys[i].key_id_length);
memcpy(encrypted_license_.keys[i].control.verification, "kctl", 4);
encrypted_license_.keys[i].control.duration = htonl(kLongDuration);
encrypted_license_.keys[i].control.nonce = htonl(nonce);
@@ -1041,7 +1053,7 @@ class Session {
void FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array) {
for (unsigned int i = 0; i < kNumKeys; i++) {
key_array[i].key_id = data.keys[i].key_id;
key_array[i].key_id_length = kTestKeyIdLength;
key_array[i].key_id_length = data.keys[i].key_id_length;
key_array[i].key_data_iv = data.keys[i].key_iv;
key_array[i].key_data = data.keys[i].key_data;
key_array[i].key_data_length = data.keys[i].key_data_length;
@@ -1056,7 +1068,7 @@ class Session {
for (size_t i = 0; i < key_count; i++) {
if (key_count > 1) {
key_array[i].key_id = encrypted_license_.keys[i].key_id;
key_array[i].key_id_length = kTestKeyIdLength;
key_array[i].key_id_length = encrypted_license_.keys[i].key_id_length;
} else {
key_array[i].key_id = NULL;
key_array[i].key_id_length = 0;
@@ -1072,8 +1084,8 @@ class Session {
OEMCryptoResult sts;
if (select_key_first) {
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
sts = OEMCrypto_SelectKey(session_id(), &keyId[0], keyId.size());
sts = OEMCrypto_SelectKey(session_id(), license_.keys[0].key_id,
license_.keys[0].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
@@ -2099,9 +2111,9 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange3) {
s.GenerateTestSessionKeys();
s.FillSimpleMessage(0, 0, 0);
s.EncryptAndSign();
vector<uint8_t> bad_buffer(
s.encrypted_license().keys[0].key_id,
s.encrypted_license().keys[0].key_id + kTestKeyIdLength);
vector<uint8_t> bad_buffer(s.encrypted_license().keys[0].key_id,
s.encrypted_license().keys[0].key_id +
s.encrypted_license().keys[0].key_id_length);
s.key_array()[0].key_id = &bad_buffer[0];
OEMCryptoResult sts = OEMCrypto_LoadKeys(
@@ -2630,8 +2642,8 @@ TEST_F(OEMCryptoSessionTests, DecryptUnencrypted) {
s.LoadTestKeys();
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size());
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[0].key_id,
s.license().keys[0].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// Set up our expected input and output
@@ -4177,7 +4189,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
vector<uint8_t> expected_encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &expected_encrypted);
sts = OEMCrypto_SelectKey(
s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength);
s.session_id(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> encrypted(buffer_length);
sts = OEMCrypto_Generic_Encrypt(s.session_id(), &clear_buffer_[0],
@@ -4199,7 +4212,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(
s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength);
s.session_id(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], buffer_length,
@@ -4220,7 +4234,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
SignBuffer(&s, key_index, clear_buffer_, &expected_signature);
sts = OEMCrypto_SelectKey(
s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength);
s.session_id(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
size_t signature_length = (size_t)SHA256_DIGEST_LENGTH;
vector<uint8_t> signature(SHA256_DIGEST_LENGTH);
@@ -4247,7 +4262,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
}
sts = OEMCrypto_SelectKey(
s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength);
s.session_id(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_Generic_Verify(s.session_id(), &clear_buffer_[0],
clear_buffer_.size(), algorithm,
@@ -4277,7 +4293,7 @@ TEST_F(GenericCryptoTest, GenericKeyEncrypt) {
vector<uint8_t> expected_encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &expected_encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> encrypted(clear_buffer_.size());
sts = OEMCrypto_Generic_Encrypt(s.session_id(), &clear_buffer_[0],
@@ -4307,7 +4323,7 @@ TEST_F(GenericCryptoTest, GenericKeyDecrypt) {
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], encrypted.size(),
@@ -4331,7 +4347,7 @@ TEST_F(GenericCryptoTest, GenericSecureToClear) {
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], encrypted.size(),
@@ -4362,7 +4378,7 @@ TEST_F(GenericCryptoTest, GenericKeySign) {
SignBuffer(&s, key_index, clear_buffer_, &expected_signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
size_t gen_signature_length = 0;
sts = OEMCrypto_Generic_Sign(s.session_id(), &clear_buffer_[0],
@@ -4398,7 +4414,7 @@ TEST_F(GenericCryptoTest, GenericKeyVerify) {
SignBuffer(&s, key_index, clear_buffer_, &signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_Generic_Verify(s.session_id(), &clear_buffer_[0],
clear_buffer_.size(), OEMCrypto_HMAC_SHA256,
@@ -4433,7 +4449,7 @@ TEST_F(GenericCryptoTest, KeyDurationEncrypt) {
sleep(kShortSleep); // Should still be valid key.
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts =
OEMCrypto_Generic_Encrypt(s.session_id(), &clear_buffer_[0],
@@ -4466,7 +4482,7 @@ TEST_F(GenericCryptoTest, KeyDurationDecrypt) {
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(kShortSleep); // Should still be valid key.
@@ -4506,7 +4522,7 @@ TEST_F(GenericCryptoTest, KeyDurationSign) {
SignBuffer(&s, key_index, clear_buffer_, &expected_signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(kShortSleep); // Should still be valid key.
@@ -4541,7 +4557,7 @@ TEST_F(GenericCryptoTest, KeyDurationVerify) {
SignBuffer(&s, key_index, clear_buffer_, &signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(kShortSleep); // Should still be valid key.
@@ -4559,6 +4575,109 @@ TEST_F(GenericCryptoTest, KeyDurationVerify) {
ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts);
}
TEST_F(GenericCryptoTest, ShortKeyId) {
OEMCryptoResult sts;
Session s;
s.open();
s.GenerateTestSessionKeys();
MakeFourKeys(&s);
// We are testing that the key ids do not have to have the same length.
s.SetKeyId(0, "123456789012"); // 12 bytes.
s.SetKeyId(1, "12345"); // short key id.
s.SetKeyId(2, "123456789012-very-long-key-id");
s.EncryptAndSign();
s.LoadTestKeys();
unsigned int key_index = 1;
vector<uint8_t> encrypted;
// To make sure OEMCrypto is not expecting the key_id to be zero padded, we
// will create a buffer that is padded with 'Z'.
vector<uint8_t> key_id_buffer(s.license().keys[key_index].key_id_length + 5,
'Z'); // Fill a bigger buffer with letter 'Z'.
memcpy(key_id_buffer.data(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), key_id_buffer.data(),
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], encrypted.size(),
iv_, OEMCrypto_AES_CBC_128_NO_PADDING,
&resultant[0]);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(clear_buffer_, resultant);
}
TEST_F(GenericCryptoTest, LongKeyId) {
OEMCryptoResult sts;
Session s;
s.open();
s.GenerateTestSessionKeys();
MakeFourKeys(&s);
// We are testing that the key ids do not have to have the same length.
s.SetKeyId(0, "123456789012"); // 12 bytes.
s.SetKeyId(1, "123456789012-very-long-key-id"); // long key id.
s.SetKeyId(2, "12345");
s.EncryptAndSign();
s.LoadTestKeys();
unsigned int key_index = 1;
vector<uint8_t> encrypted;
// To make sure OEMCrypto is not expecting the key_id to be zero padded, we
// will create a buffer that is padded with 'Z'.
vector<uint8_t> key_id_buffer(s.license().keys[key_index].key_id_length + 5,
'Z'); // Fill a bigger buffer with letter 'Z'.
memcpy(key_id_buffer.data(), s.license().keys[key_index].key_id,
s.license().keys[key_index].key_id_length);
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), key_id_buffer.data(),
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], encrypted.size(),
iv_, OEMCrypto_AES_CBC_128_NO_PADDING,
&resultant[0]);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(clear_buffer_, resultant);
}
TEST_F(GenericCryptoTest, CommonPrefixKeyId) {
OEMCryptoResult sts;
Session s;
s.open();
s.GenerateTestSessionKeys();
MakeFourKeys(&s);
// We are testing that the key ids do not have to have the same length.
// Worse, they may have a common prefix.
// This test is more diabolical. We put the long key id in the buffer, but
// the length is for the shorter key. If OEMCrypto is paying attention to the
// key id length, it should see key 1. If it looks beyond the whole buffer,
// it will see key 0.
s.SetKeyId(0, "123456789012"); // 12 bytes.
s.SetKeyId(1, "12345"); // short key id, with common prefix with key 0.
s.SetKeyId(2, "123456789012-very-long-key-id");
s.EncryptAndSign();
s.LoadTestKeys();
unsigned int key_index = 1;
unsigned int other_key_index = 0; // Key with shared prefix.
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
// Note: we pass in a buffer pointer to key id 0, because it starts off the
// same as key id 1. Since the length is for key id 1, oemcrypto should
// select key 1.
sts = OEMCrypto_SelectKey(s.session_id(),
s.license().keys[other_key_index].key_id,
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0], encrypted.size(),
iv_, OEMCrypto_AES_CBC_128_NO_PADDING,
&resultant[0]);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(clear_buffer_, resultant);
}
TEST_F(OEMCryptoClientTest, UpdateUsageTableTest) {
EXPECT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
}
@@ -5076,7 +5195,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
vector<uint8_t> expected_encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &expected_encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> encrypted(clear_buffer_.size());
sts = OEMCrypto_Generic_Encrypt(s.session_id(), &clear_buffer_[0],
@@ -5122,7 +5241,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) {
vector<uint8_t> encrypted;
EncryptBuffer(&s, key_index, clear_buffer_, &encrypted);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
vector<uint8_t> resultant(encrypted.size());
sts = OEMCrypto_Generic_Decrypt(s.session_id(), &encrypted[0],
@@ -5170,7 +5289,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) {
SignBuffer(&s, key_index, clear_buffer_, &expected_signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
size_t gen_signature_length = 0;
sts = OEMCrypto_Generic_Sign(s.session_id(), &clear_buffer_[0],
@@ -5227,7 +5346,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) {
SignBuffer(&s, key_index, clear_buffer_, &signature);
sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id,
kTestKeyIdLength);
s.license().keys[key_index].key_id_length);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_Generic_Verify(s.session_id(), &clear_buffer_[0],
clear_buffer_.size(), OEMCrypto_HMAC_SHA256,