Buffer Size Unit Tests

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

This CL adds some oemcrypto unit tests for various buffer sizes, as
described in b/28887904 and the OEMCrypto v12 specification.

Encryption and Decryption buffers can be 100k large.  License request
and response messages can be 8k. A provider session token (pst) can be
at most 255 bytes long.

I also passed the code through clang-format.

b/28887904

Change-Id: Ia3e317c0f6466e663461e66b610c9a98a90efb0a
This commit is contained in:
Fred Gylys-Colwell
2016-11-28 21:44:36 -08:00
parent 5228b538f0
commit 67b06a70e4
3 changed files with 546 additions and 259 deletions

View File

@@ -76,8 +76,14 @@ Session::Session()
mac_key_client_(wvcdm::MAC_KEY_SIZE), mac_key_client_(wvcdm::MAC_KEY_SIZE),
enc_key_(wvcdm::KEY_SIZE), enc_key_(wvcdm::KEY_SIZE),
public_rsa_(0), public_rsa_(0),
num_keys_(4) {} // Most tests only use 4 keys. message_size_(sizeof(MessageData)),
// Other tests will explicitly call set_num_keys. num_keys_(4) { // Most tests only use 4 keys.
// Other tests will explicitly call set_num_keys.
// Stripe the padded message.
for (int i = 0; i < sizeof(padded_message_.padding); i++) {
padded_message_.padding[i] = i % 0x100;
}
}
Session::~Session() { Session::~Session() {
if (!forced_session_id_ && open_) close(); if (!forced_session_id_ && open_) close();
@@ -194,25 +200,24 @@ void Session::GenerateTestSessionKeys() {
void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) { void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
uint8_t* pst_ptr = NULL; uint8_t* pst_ptr = NULL;
if (pst.length() > 0) { if (pst.length() > 0) {
pst_ptr = encrypted_license_.pst; pst_ptr = encrypted_license().pst;
} }
if (new_mac_keys) { if (new_mac_keys) {
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys( OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
session_id(), message_ptr(), sizeof(MessageData), &signature_[0], signature_.size(),
&signature_[0], signature_.size(), encrypted_license().mac_key_iv,
encrypted_license_.mac_key_iv, encrypted_license_.mac_keys, encrypted_license().mac_keys, num_keys_,
num_keys_, key_array_, pst_ptr, pst.length())); key_array_, pst_ptr, pst.length()));
// Update new generated keys. // Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE); memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE, memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
wvcdm::MAC_KEY_SIZE); wvcdm::MAC_KEY_SIZE);
} else { } else {
ASSERT_EQ( ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_SUCCESS, OEMCrypto_LoadKeys(session_id(), message_ptr(), message_size_,
OEMCrypto_LoadKeys(session_id(), message_ptr(), sizeof(MessageData), &signature_[0], signature_.size(), NULL, NULL,
&signature_[0], signature_.size(), NULL, NULL, num_keys_, key_array_, pst_ptr, pst.length()));
num_keys_, key_array_, pst_ptr, pst.length()));
} }
VerifyTestKeys(); VerifyTestKeys();
} }
@@ -222,8 +227,8 @@ void Session::VerifyTestKeys() {
KeyControlBlock block; KeyControlBlock block;
size_t size = sizeof(block); size_t size = sizeof(block);
OEMCryptoResult sts = OEMCrypto_QueryKeyControl( OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
session_id(), license_.keys[i].key_id, license_.keys[i].key_id_length, session_id(), license_.keys[i].key_id, license_.keys[i].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);
ASSERT_EQ(sizeof(block), size); ASSERT_EQ(sizeof(block), size);
@@ -237,17 +242,17 @@ void Session::VerifyTestKeys() {
} }
} }
void Session::RefreshTestKeys(const size_t key_count, void Session::RefreshTestKeys(const size_t key_count, uint32_t control_bits,
uint32_t control_bits, uint32_t nonce, uint32_t nonce, OEMCryptoResult expected_result) {
OEMCryptoResult expected_result) {
// Note: we store the message in encrypted_license_, but the refresh key // Note: we store the message in encrypted_license_, but the refresh key
// message is not actually encrypted. It is, however, signed. // message is not actually encrypted. It is, however, signed.
FillRefreshMessage(key_count, control_bits, nonce); FillRefreshMessage(key_count, control_bits, nonce);
ServerSignMessage(encrypted_license_, &signature_); ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
message_size_, &signature_);
OEMCrypto_KeyRefreshObject key_array[key_count]; OEMCrypto_KeyRefreshObject key_array[key_count];
FillRefreshArray(key_array, key_count); FillRefreshArray(key_array, key_count);
OEMCryptoResult sts = OEMCrypto_RefreshKeys( OEMCryptoResult sts = OEMCrypto_RefreshKeys(
session_id(), message_ptr(), sizeof(MessageData), &signature_[0], session_id(), message_ptr(), message_size_, &signature_[0],
signature_.size(), key_count, key_array); signature_.size(), key_count, key_array);
ASSERT_EQ(expected_result, sts); ASSERT_EQ(expected_result, sts);
@@ -272,9 +277,9 @@ void Session::SetKeyId(int index, const string& key_id) {
void Session::FillSimpleMessage(uint32_t duration, uint32_t control, void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
uint32_t nonce, const std::string& pst) { uint32_t nonce, const std::string& pst) {
EXPECT_EQ(OEMCrypto_SUCCESS, EXPECT_EQ(
OEMCrypto_GetRandom(license_.mac_key_iv, OEMCrypto_SUCCESS,
sizeof(license_.mac_key_iv))); OEMCrypto_GetRandom(license_.mac_key_iv, sizeof(license_.mac_key_iv)));
EXPECT_EQ(OEMCrypto_SUCCESS, EXPECT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetRandom(license_.mac_keys, sizeof(license_.mac_keys))); OEMCrypto_GetRandom(license_.mac_keys, sizeof(license_.mac_keys)));
for (unsigned int i = 0; i < num_keys_; i++) { for (unsigned int i = 0; i < num_keys_; i++) {
@@ -312,24 +317,24 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits, void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits,
uint32_t nonce) { uint32_t nonce) {
for (unsigned int i = 0; i < key_count; i++) { for (unsigned int i = 0; i < key_count; i++) {
encrypted_license_.keys[i].key_id_length = license_.keys[i].key_id_length; 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, memcpy(encrypted_license().keys[i].key_id, license_.keys[i].key_id,
encrypted_license_.keys[i].key_id_length); encrypted_license().keys[i].key_id_length);
memcpy(encrypted_license_.keys[i].control.verification, "kctl", 4); memcpy(encrypted_license().keys[i].control.verification, "kctl", 4);
encrypted_license_.keys[i].control.duration = htonl(kLongDuration); encrypted_license().keys[i].control.duration = htonl(kLongDuration);
encrypted_license_.keys[i].control.nonce = htonl(nonce); encrypted_license().keys[i].control.nonce = htonl(nonce);
encrypted_license_.keys[i].control.control_bits = htonl(control_bits); encrypted_license().keys[i].control.control_bits = htonl(control_bits);
} }
} }
void Session::EncryptAndSign() { void Session::EncryptAndSign() {
encrypted_license_ = license_; encrypted_license() = license_;
uint8_t iv_buffer[16]; uint8_t iv_buffer[16];
memcpy(iv_buffer, &license_.mac_key_iv[0], wvcdm::KEY_IV_SIZE); memcpy(iv_buffer, &license_.mac_key_iv[0], wvcdm::KEY_IV_SIZE);
AES_KEY aes_key; AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license_.mac_keys[0], AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); 2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
for (unsigned int i = 0; i < num_keys_; i++) { for (unsigned int i = 0; i < num_keys_; i++) {
@@ -337,19 +342,19 @@ void Session::EncryptAndSign() {
AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key); AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key);
AES_cbc_encrypt( AES_cbc_encrypt(
reinterpret_cast<const uint8_t*>(&license_.keys[i].control), reinterpret_cast<const uint8_t*>(&license_.keys[i].control),
reinterpret_cast<uint8_t*>(&encrypted_license_.keys[i].control), reinterpret_cast<uint8_t*>(&encrypted_license().keys[i].control),
wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
memcpy(iv_buffer, &license_.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE); memcpy(iv_buffer, &license_.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE);
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_cbc_encrypt(&license_.keys[i].key_data[0], AES_cbc_encrypt(
&encrypted_license_.keys[i].key_data[0], &license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
license_.keys[i].key_data_length, &aes_key, iv_buffer, license_.keys[i].key_data_length, &aes_key, iv_buffer, AES_ENCRYPT);
AES_ENCRYPT);
} }
memcpy(encrypted_license_.pst, license_.pst, sizeof(license_.pst)); memcpy(encrypted_license().pst, license_.pst, sizeof(license_.pst));
ServerSignMessage(encrypted_license_, &signature_); ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
FillKeyArray(encrypted_license_, key_array_); message_size_, &signature_);
FillKeyArray(encrypted_license(), key_array_);
} }
void Session::EncryptMessage(RSAPrivateKeyMessage* data, void Session::EncryptMessage(RSAPrivateKeyMessage* data,
@@ -364,30 +369,18 @@ void Session::EncryptMessage(RSAPrivateKeyMessage* data,
AES_KEY aes_key; AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0], AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0],
encrypted->rsa_key_length, &aes_key, iv_buffer, encrypted->rsa_key_length, &aes_key, iv_buffer, AES_ENCRYPT);
AES_ENCRYPT);
} }
template <typename T> void Session::ServerSignBuffer(const uint8_t* data, size_t data_length,
void Session::ServerSignMessage(const T& data, std::vector<uint8_t>* signature) {
std::vector<uint8_t>* signature) { ASSERT_LE(data_length, kMaxMessageSize);
signature->assign(SHA256_DIGEST_LENGTH, 0); signature->assign(SHA256_DIGEST_LENGTH, 0);
unsigned int md_len = SHA256_DIGEST_LENGTH; unsigned int md_len = SHA256_DIGEST_LENGTH;
HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), data,
reinterpret_cast<const uint8_t*>(&data), sizeof(data), data_length, &(signature->front()), &md_len);
&(signature->front()), &md_len);
} }
template
void Session::ServerSignMessage<MessageData>(
const MessageData& data,
std::vector<uint8_t>* signature);
template
void Session::ServerSignMessage<RSAPrivateKeyMessage>(
const RSAPrivateKeyMessage& data,
std::vector<uint8_t>* signature);
void Session::ClientSignMessage(const vector<uint8_t>& data, void Session::ClientSignMessage(const vector<uint8_t>& data,
std::vector<uint8_t>* signature) { std::vector<uint8_t>* signature) {
signature->assign(SHA256_DIGEST_LENGTH, 0); signature->assign(SHA256_DIGEST_LENGTH, 0);
@@ -415,21 +408,21 @@ void Session::FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array,
size_t key_count) { size_t key_count) {
for (size_t i = 0; i < key_count; i++) { for (size_t i = 0; i < key_count; i++) {
if (key_count > 1) { if (key_count > 1) {
key_array[i].key_id = encrypted_license_.keys[i].key_id; key_array[i].key_id = encrypted_license().keys[i].key_id;
key_array[i].key_id_length = encrypted_license_.keys[i].key_id_length; key_array[i].key_id_length = encrypted_license().keys[i].key_id_length;
} else { } else {
key_array[i].key_id = NULL; key_array[i].key_id = NULL;
key_array[i].key_id_length = 0; key_array[i].key_id_length = 0;
} }
key_array[i].key_control_iv = NULL; key_array[i].key_control_iv = NULL;
key_array[i].key_control = key_array[i].key_control =
reinterpret_cast<const uint8_t*>(&encrypted_license_.keys[i].control); reinterpret_cast<const uint8_t*>(&encrypted_license().keys[i].control);
} }
} }
void Session::EncryptCTR( void Session::EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const vector<uint8_t>& in_buffer, const uint8_t *key, const uint8_t* starting_iv,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer) { vector<uint8_t>* out_buffer) {
ASSERT_NE(static_cast<void*>(NULL), key); ASSERT_NE(static_cast<void*>(NULL), key);
ASSERT_NE(static_cast<void*>(NULL), starting_iv); ASSERT_NE(static_cast<void*>(NULL), starting_iv);
ASSERT_NE(static_cast<void*>(NULL), out_buffer); ASSERT_NE(static_cast<void*>(NULL), out_buffer);
@@ -452,8 +445,7 @@ void Session::EncryptCTR(
} }
void Session::TestDecryptCTR(bool select_key_first, void Session::TestDecryptCTR(bool select_key_first,
OEMCryptoResult expected_result, OEMCryptoResult expected_result, int key_index) {
int key_index) {
OEMCryptoResult sts; OEMCryptoResult sts;
if (select_key_first) { if (select_key_first) {
// Select the key (from FillSimpleMessage) // Select the key (from FillSimpleMessage)
@@ -463,15 +455,16 @@ void Session::TestDecryptCTR(bool select_key_first,
} }
vector<uint8_t> unencryptedData(256); vector<uint8_t> unencryptedData(256);
for(size_t i=0; i < unencryptedData.size(); i++) unencryptedData[i] = i % 256; for (size_t i = 0; i < unencryptedData.size(); i++)
unencryptedData[i] = i % 256;
EXPECT_EQ(OEMCrypto_SUCCESS, EXPECT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetRandom(&unencryptedData[0], unencryptedData.size())); OEMCrypto_GetRandom(&unencryptedData[0], unencryptedData.size()));
vector<uint8_t> encryptionIv(wvcdm::KEY_IV_SIZE); vector<uint8_t> encryptionIv(wvcdm::KEY_IV_SIZE);
EXPECT_EQ(OEMCrypto_SUCCESS, EXPECT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GetRandom(&encryptionIv[0], wvcdm::KEY_IV_SIZE)); OEMCrypto_GetRandom(&encryptionIv[0], wvcdm::KEY_IV_SIZE));
vector<uint8_t> encryptedData(unencryptedData.size()); vector<uint8_t> encryptedData(unencryptedData.size());
EncryptCTR(unencryptedData, license_.keys[key_index].key_data, &encryptionIv[0], EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
&encryptedData); &encryptionIv[0], &encryptedData);
// Describe the output // Describe the output
vector<uint8_t> outputBuffer(256); vector<uint8_t> outputBuffer(256);
@@ -507,9 +500,11 @@ void Session::TestDecryptCTR(bool select_key_first,
} }
} }
void Session::MakeRSACertificate( void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
struct RSAPrivateKeyMessage* encrypted, std::vector<uint8_t>* signature, size_t message_size,
uint32_t allowed_schemes, const vector<uint8_t>& rsa_key) { std::vector<uint8_t>* signature,
uint32_t allowed_schemes,
const vector<uint8_t>& rsa_key) {
// Dummy context for testing signature generation. // Dummy context for testing signature generation.
vector<uint8_t> context = wvcdm::a2b_hex( vector<uint8_t> context = wvcdm::a2b_hex(
"0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840" "0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840"
@@ -555,28 +550,28 @@ void Session::MakeRSACertificate(
message.nonce = nonce_; message.nonce = nonce_;
EncryptMessage(&message, encrypted); EncryptMessage(&message, encrypted);
ServerSignMessage(*encrypted, signature); ServerSignBuffer(reinterpret_cast<const uint8_t*>(encrypted), message_size,
signature);
} }
void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted, void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size,
const std::vector<uint8_t>& signature, const std::vector<uint8_t>& signature,
vector<uint8_t>* wrapped_key, bool force) { vector<uint8_t>* wrapped_key, bool force) {
size_t wrapped_key_length = 0; size_t wrapped_key_length = 0;
const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(&encrypted); const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(&encrypted);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey( OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, sizeof(encrypted), &signature[0], session_id(), message_ptr, message_size, &signature[0],
signature.size(), &encrypted.nonce, encrypted.rsa_key, signature.size(), &encrypted.nonce, encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length)); &wrapped_key_length));
wrapped_key->clear(); wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0); wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey( OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey(
session_id(), message_ptr, sizeof(encrypted), &signature[0], session_id(), message_ptr, message_size, &signature[0], signature.size(),
signature.size(), &encrypted.nonce, encrypted.rsa_key, &encrypted.nonce, encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_length, encrypted.rsa_key_iv, &(wrapped_key->front()), encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
&wrapped_key_length);
if (force) { if (force) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(OEMCrypto_SUCCESS, sts);
} }
@@ -585,8 +580,7 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
} }
} }
void Session::PreparePublicKey(const uint8_t* rsa_key, void Session::PreparePublicKey(const uint8_t* rsa_key, size_t rsa_key_length) {
size_t rsa_key_length) {
if (rsa_key == NULL) { if (rsa_key == NULL) {
rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048; rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048;
rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048); rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048);
@@ -610,23 +604,24 @@ void Session::PreparePublicKey(const uint8_t* rsa_key,
ASSERT_TRUE(false); ASSERT_TRUE(false);
} }
switch (RSA_check_key(public_rsa_)) { switch (RSA_check_key(public_rsa_)) {
case 1: // valid. case 1: // valid.
ASSERT_TRUE(true); ASSERT_TRUE(true);
return; return;
case 0: // not valid. case 0: // not valid.
cout << "[rsa key not valid] "; cout << "[rsa key not valid] ";
dump_openssl_error(); dump_openssl_error();
ASSERT_TRUE(false); ASSERT_TRUE(false);
default: // -1 == check failed. default: // -1 == check failed.
cout << "[error checking rsa key] "; cout << "[error checking rsa key] ";
dump_openssl_error(); dump_openssl_error();
ASSERT_TRUE(false); ASSERT_TRUE(false);
} }
} }
bool Session::VerifyPSSSignature( bool Session::VerifyPSSSignature(EVP_PKEY* pkey, const uint8_t* message,
EVP_PKEY* pkey, const uint8_t* message, size_t message_length, size_t message_length,
const uint8_t* signature, size_t signature_length) { const uint8_t* signature,
size_t signature_length) {
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&ctx);
EVP_PKEY_CTX* pctx = NULL; EVP_PKEY_CTX* pctx = NULL;
@@ -668,15 +663,16 @@ bool Session::VerifyPSSSignature(
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx);
return true; return true;
err: err:
dump_openssl_error(); dump_openssl_error();
EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&ctx);
return false; return false;
} }
void Session::VerifyRSASignature( void Session::VerifyRSASignature(const vector<uint8_t>& message,
const vector<uint8_t>& message, const uint8_t* signature, const uint8_t* signature,
size_t signature_length, RSA_Padding_Scheme padding_scheme) { size_t signature_length,
RSA_Padding_Scheme padding_scheme) {
EXPECT_TRUE(NULL != public_rsa_) EXPECT_TRUE(NULL != public_rsa_)
<< "No public RSA key loaded in test code.\n"; << "No public RSA key loaded in test code.\n";
EXPECT_EQ(static_cast<size_t>(RSA_size(public_rsa_)), signature_length) EXPECT_EQ(static_cast<size_t>(RSA_size(public_rsa_)), signature_length)
@@ -726,8 +722,7 @@ bool Session::GenerateRSASessionKey(vector<uint8_t>* enc_session_key) {
return true; return true;
} }
void Session::InstallRSASessionTestKey( void Session::InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key) {
const vector<uint8_t>& wrapped_rsa_key) {
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadDeviceRSAKey(session_id(), &wrapped_rsa_key[0], OEMCrypto_LoadDeviceRSAKey(session_id(), &wrapped_rsa_key[0],
wrapped_rsa_key.size())); wrapped_rsa_key.size()));
@@ -749,8 +744,8 @@ void Session::DisallowDeriveKeys() {
enc_context.size())); enc_context.size()));
} }
void Session::GenerateReport( void Session::GenerateReport(const std::string& pst, bool expect_success,
const std::string& pst, bool expect_success, Session* other) { Session* other) {
if (other) { // If other is specified, copy mac keys. if (other) { // If other is specified, copy mac keys.
mac_key_server_ = other->mac_key_server_; mac_key_server_ = other->mac_key_server_;
mac_key_client_ = other->mac_key_client_; mac_key_client_ = other->mac_key_client_;
@@ -792,12 +787,13 @@ OEMCrypto_PST_Report* Session::pst_report() {
} }
void Session::DeleteEntry(const std::string& pst) { void Session::DeleteEntry(const std::string& pst) {
uint8_t* pst_ptr = encrypted_license_.pst; uint8_t* pst_ptr = encrypted_license().pst;
memcpy(pst_ptr, pst.c_str(), min(sizeof(license_.pst), pst.length())); memcpy(pst_ptr, pst.c_str(), min(sizeof(license_.pst), pst.length()));
ServerSignMessage(encrypted_license_, &signature_); ServerSignBuffer(reinterpret_cast<const uint8_t*>(&padded_message_),
message_size_, &signature_);
ASSERT_EQ(OEMCrypto_SUCCESS, ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_DeleteUsageEntry(session_id(), pst_ptr, pst.length(), OEMCrypto_DeleteUsageEntry(session_id(), pst_ptr, pst.length(),
message_ptr(), sizeof(MessageData), message_ptr(), message_size_,
&signature_[0], signature_.size())); &signature_[0], signature_.size()));
} }
@@ -808,7 +804,13 @@ void Session::ForceDeleteEntry(const std::string& pst) {
} }
const uint8_t* Session::message_ptr() { const uint8_t* Session::message_ptr() {
return reinterpret_cast<const uint8_t*>(&encrypted_license_); return reinterpret_cast<const uint8_t*>(&encrypted_license());
}
void Session::set_message_size(size_t size) {
message_size_ = size;
ASSERT_GE(message_size_, sizeof(MessageData));
ASSERT_LE(message_size_, kMaxMessageSize);
} }
} // namespace wvoec } // namespace wvoec

View File

@@ -67,6 +67,9 @@ const size_t kTestKeyIdMaxLength = 16;
const int kDefaultKeyIdLength = 16; const int kDefaultKeyIdLength = 16;
const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate. const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate.
const size_t kMaxPSTLength = 255; // In specification.
const size_t kMaxMessageSize = 8 * 1024; // In specification.
const size_t kMaxDecryptSize = 100 * 1024; // In specification.
typedef struct { typedef struct {
uint8_t key_id[kTestKeyIdMaxLength]; uint8_t key_id[kTestKeyIdMaxLength];
@@ -86,7 +89,7 @@ struct MessageData {
MessageKeyData keys[kMaxNumKeys]; MessageKeyData keys[kMaxNumKeys];
uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE]; uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE];
uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE]; uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE];
uint8_t pst[kTestKeyIdMaxLength]; uint8_t pst[kMaxPSTLength];
}; };
struct RSAPrivateKeyMessage { struct RSAPrivateKeyMessage {
@@ -141,35 +144,34 @@ class Session {
void EncryptAndSign(); void EncryptAndSign();
void EncryptMessage(RSAPrivateKeyMessage* data, void EncryptMessage(RSAPrivateKeyMessage* data,
RSAPrivateKeyMessage* encrypted); RSAPrivateKeyMessage* encrypted);
void ServerSignBuffer(const uint8_t* data, size_t data_length,
template <typename T> std::vector<uint8_t>* signature);
void ServerSignMessage(const T& data, std::vector<uint8_t>* signature);
void ClientSignMessage(const vector<uint8_t>& data, void ClientSignMessage(const vector<uint8_t>& data,
std::vector<uint8_t>* signature); std::vector<uint8_t>* signature);
void FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array); void FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array);
void FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array, void FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array,
size_t key_count); size_t key_count);
void EncryptCTR( void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const vector<uint8_t>& in_buffer, const uint8_t *key, const uint8_t* starting_iv, vector<uint8_t>* out_buffer);
const uint8_t* starting_iv, vector<uint8_t>* out_buffer);
void TestDecryptCTR(bool select_key_first = true, void TestDecryptCTR(bool select_key_first = true,
OEMCryptoResult expected_result = OEMCrypto_SUCCESS, OEMCryptoResult expected_result = OEMCrypto_SUCCESS,
int key_index = 0); int key_index = 0);
void MakeRSACertificate( void MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
struct RSAPrivateKeyMessage* encrypted, std::vector<uint8_t>* signature, size_t message_size, std::vector<uint8_t>* signature,
uint32_t allowed_schemes, const vector<uint8_t>& rsa_key); uint32_t allowed_schemes,
const vector<uint8_t>& rsa_key);
void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted, void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
const std::vector<uint8_t>& signature, size_t message_size, const std::vector<uint8_t>& signature,
vector<uint8_t>* wrapped_key, bool force); vector<uint8_t>* wrapped_key, bool force);
void PreparePublicKey(const uint8_t* rsa_key = NULL, void PreparePublicKey(const uint8_t* rsa_key = NULL,
size_t rsa_key_length = 0); size_t rsa_key_length = 0);
static bool VerifyPSSSignature( static bool VerifyPSSSignature(EVP_PKEY* pkey, const uint8_t* message,
EVP_PKEY* pkey, const uint8_t* message, size_t message_length, size_t message_length,
const uint8_t* signature, size_t signature_length); const uint8_t* signature,
void VerifyRSASignature( size_t signature_length);
const vector<uint8_t>& message, const uint8_t* signature, void VerifyRSASignature(const vector<uint8_t>& message,
size_t signature_length, RSA_Padding_Scheme padding_scheme); const uint8_t* signature, size_t signature_length,
RSA_Padding_Scheme padding_scheme);
bool GenerateRSASessionKey(vector<uint8_t>* enc_session_key); bool GenerateRSASessionKey(vector<uint8_t>* enc_session_key);
void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key); void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key);
void DisallowDeriveKeys(); void DisallowDeriveKeys();
@@ -180,7 +182,7 @@ class Session {
void ForceDeleteEntry(const std::string& pst); void ForceDeleteEntry(const std::string& pst);
MessageData& license() { return license_; } MessageData& license() { return license_; }
MessageData& encrypted_license() { return encrypted_license_; } MessageData& encrypted_license() { return padded_message_; }
const uint8_t* message_ptr(); const uint8_t* message_ptr();
@@ -190,6 +192,9 @@ class Session {
void set_num_keys(int num_keys) { num_keys_ = num_keys; } void set_num_keys(int num_keys) { num_keys_ = num_keys; }
int num_keys() const { return num_keys_; } int num_keys() const { return num_keys_; }
void set_message_size(size_t size);
size_t message_size() { return message_size_; }
private: private:
bool open_; bool open_;
bool forced_session_id_; bool forced_session_id_;
@@ -201,7 +206,10 @@ class Session {
RSA* public_rsa_; RSA* public_rsa_;
vector<uint8_t> pst_report_buffer_; vector<uint8_t> pst_report_buffer_;
MessageData license_; MessageData license_;
MessageData encrypted_license_; struct PaddedMessageData : public MessageData {
uint8_t padding[kMaxMessageSize - sizeof(MessageData)];
} padded_message_;
size_t message_size_; // How much of the padded message to use.
OEMCrypto_KeyObject key_array_[kMaxNumKeys]; OEMCrypto_KeyObject key_array_[kMaxNumKeys];
std::vector<uint8_t> signature_; std::vector<uint8_t> signature_;
int num_keys_; int num_keys_;

File diff suppressed because it is too large Load Diff