Source release 14.1.0
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine Master
|
||||
// License Agreement.
|
||||
//
|
||||
// OEMCrypto unit tests
|
||||
//
|
||||
@@ -24,14 +26,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "log.h"
|
||||
#include "oec_device_features.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "test_rsa_key.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_types.h"
|
||||
#include "wv_keybox.h"
|
||||
#include "test_rsa_key.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -100,14 +100,14 @@ Session::Session()
|
||||
: open_(false),
|
||||
forced_session_id_(false),
|
||||
session_id_(0),
|
||||
mac_key_server_(wvcdm::MAC_KEY_SIZE),
|
||||
mac_key_client_(wvcdm::MAC_KEY_SIZE),
|
||||
enc_key_(wvcdm::KEY_SIZE),
|
||||
mac_key_server_(MAC_KEY_SIZE),
|
||||
mac_key_client_(MAC_KEY_SIZE),
|
||||
enc_key_(KEY_SIZE),
|
||||
public_rsa_(0),
|
||||
message_size_(sizeof(MessageData)),
|
||||
num_keys_(4), // Most tests only use 4 keys.
|
||||
// Other tests will explicitly call set_num_keys.
|
||||
has_entitlement_license_(false) {
|
||||
// Most tests only use 4 keys. Other tests will explicitly call
|
||||
// set_num_keys.
|
||||
num_keys_(4) {
|
||||
// Stripe the padded message.
|
||||
for (size_t i = 0; i < sizeof(padded_message_.padding); i++) {
|
||||
padded_message_.padding[i] = i % 0x100;
|
||||
@@ -185,7 +185,7 @@ void Session::DeriveKey(const uint8_t* key, const vector<uint8_t>& context,
|
||||
CMAC_CTX* cmac_ctx = CMAC_CTX_new();
|
||||
ASSERT_NE(static_cast<void*>(NULL), cmac_ctx);
|
||||
|
||||
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, wvcdm::KEY_SIZE, cipher, 0));
|
||||
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, KEY_SIZE, cipher, 0));
|
||||
|
||||
std::vector<uint8_t> message;
|
||||
message.push_back(counter);
|
||||
@@ -267,9 +267,9 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
|
||||
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,
|
||||
wvcdm::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,
|
||||
MAC_KEY_SIZE);
|
||||
} else {
|
||||
ASSERT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
@@ -297,9 +297,9 @@ void Session::LoadEnitlementTestKeys(const std::string& pst,
|
||||
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);
|
||||
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
|
||||
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
|
||||
MAC_KEY_SIZE);
|
||||
} else {
|
||||
ASSERT_EQ(
|
||||
expected_sts,
|
||||
@@ -311,7 +311,6 @@ void Session::LoadEnitlementTestKeys(const std::string& pst,
|
||||
}
|
||||
|
||||
void Session::FillEntitledKeyArray() {
|
||||
has_entitlement_license_ = true;
|
||||
for (size_t i = 0; i < num_keys_; ++i) {
|
||||
EntitledContentKeyData* key_data = &entitled_key_data_[i];
|
||||
|
||||
@@ -478,7 +477,7 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
||||
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;
|
||||
license_.keys[i].key_data_length = KEY_SIZE;
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
|
||||
sizeof(license_.keys[i].key_iv)));
|
||||
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
|
||||
@@ -492,14 +491,14 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
||||
} 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) {
|
||||
} else if (control & wvoec::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) {
|
||||
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
|
||||
memcpy(license_.keys[i].control.verification, "kc10", 4);
|
||||
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
|
||||
wvoec_mock::kControlReplayMask)) {
|
||||
} else if (control & (wvoec::kControlHDCPVersionMask |
|
||||
wvoec::kControlReplayMask)) {
|
||||
memcpy(license_.keys[i].control.verification, "kc09", 4);
|
||||
} else {
|
||||
memcpy(license_.keys[i].control.verification, "kctl", 4);
|
||||
@@ -525,7 +524,7 @@ void Session::FillSimpleEntitlementMessage(
|
||||
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
|
||||
license_.keys[i].key_data_length = 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,
|
||||
@@ -539,14 +538,14 @@ void Session::FillSimpleEntitlementMessage(
|
||||
} 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) {
|
||||
} else if (control & wvoec::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) {
|
||||
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
|
||||
memcpy(license_.keys[i].control.verification, "kc10", 4);
|
||||
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
|
||||
wvoec_mock::kControlReplayMask)) {
|
||||
} else if (control & (wvoec::kControlHDCPVersionMask |
|
||||
wvoec::kControlReplayMask)) {
|
||||
memcpy(license_.keys[i].control.verification, "kc09", 4);
|
||||
} else {
|
||||
memcpy(license_.keys[i].control.verification, "kctl", 4);
|
||||
@@ -590,22 +589,21 @@ void Session::EncryptAndSign() {
|
||||
encrypted_license() = license_;
|
||||
|
||||
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], KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
|
||||
2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
2 * MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
|
||||
int key_size = has_entitlement_license() ? 256 : 128;
|
||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||
memcpy(iv_buffer, &license_.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&license_.keys[i].key_data[0], key_size, &aes_key);
|
||||
memcpy(iv_buffer, &license_.keys[i].control_iv[0], KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
reinterpret_cast<const uint8_t*>(&license_.keys[i].control),
|
||||
reinterpret_cast<uint8_t*>(&encrypted_license().keys[i].control),
|
||||
wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
|
||||
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], KEY_IV_SIZE);
|
||||
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(
|
||||
&license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
|
||||
@@ -620,14 +618,14 @@ void Session::EncryptAndSign() {
|
||||
void Session::EncryptProvisioningMessage(
|
||||
RSAPrivateKeyMessage* data, RSAPrivateKeyMessage* encrypted,
|
||||
const vector<uint8_t>& encryption_key) {
|
||||
ASSERT_EQ(encryption_key.size(), wvcdm::KEY_SIZE);
|
||||
ASSERT_EQ(encryption_key.size(), KEY_SIZE);
|
||||
*encrypted = *data;
|
||||
size_t padding = wvcdm::KEY_SIZE - (data->rsa_key_length % wvcdm::KEY_SIZE);
|
||||
size_t padding = KEY_SIZE - (data->rsa_key_length % KEY_SIZE);
|
||||
memset(data->rsa_key + data->rsa_key_length, static_cast<uint8_t>(padding),
|
||||
padding);
|
||||
encrypted->rsa_key_length = data->rsa_key_length + padding;
|
||||
uint8_t iv_buffer[16];
|
||||
memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE);
|
||||
memcpy(iv_buffer, &data->rsa_key_iv[0], KEY_IV_SIZE);
|
||||
AES_KEY aes_key;
|
||||
AES_set_encrypt_key(&encryption_key[0], 128, &aes_key);
|
||||
AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0],
|
||||
@@ -740,8 +738,8 @@ void Session::TestDecryptCTR(bool select_key_first,
|
||||
for (size_t i = 0; i < unencryptedData.size(); i++)
|
||||
unencryptedData[i] = i % 256;
|
||||
EXPECT_EQ(1, GetRandBytes(&unencryptedData[0], unencryptedData.size()));
|
||||
vector<uint8_t> encryptionIv(wvcdm::KEY_IV_SIZE);
|
||||
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], wvcdm::KEY_IV_SIZE));
|
||||
vector<uint8_t> encryptionIv(KEY_IV_SIZE);
|
||||
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE));
|
||||
vector<uint8_t> encryptedData(unencryptedData.size());
|
||||
EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
|
||||
&encryptionIv[0], &encryptedData);
|
||||
@@ -893,7 +891,7 @@ void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
|
||||
memcpy(message.rsa_key, rsa_key.data(), rsa_key.size());
|
||||
message.rsa_key_length = rsa_key.size();
|
||||
}
|
||||
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, wvcdm::KEY_IV_SIZE));
|
||||
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, KEY_IV_SIZE));
|
||||
message.nonce = nonce_;
|
||||
|
||||
EncryptProvisioningMessage(&message, encrypted, *encryption_key);
|
||||
@@ -1196,7 +1194,7 @@ void Session::VerifyPST(const Test_PST_Report& expected) {
|
||||
char* pst_ptr = reinterpret_cast<char *>(computed.pst());
|
||||
std::string computed_pst(pst_ptr, pst_ptr + computed.pst_length());
|
||||
ASSERT_EQ(expected.pst, computed_pst);
|
||||
time_t now = time(NULL);
|
||||
time_t now = time(NULL);
|
||||
int64_t age = now - expected.time_created; // How old is this report.
|
||||
EXPECT_NEAR(expected.seconds_since_license_received + age,
|
||||
computed.seconds_since_license_received(),
|
||||
@@ -1232,13 +1230,10 @@ static int64_t MaybeAdjustTime(int64_t t, time_t now) {
|
||||
return t;
|
||||
}
|
||||
|
||||
void Session::GenerateVerifyReport(const std::string& pst,
|
||||
OEMCrypto_Usage_Entry_Status status,
|
||||
int64_t time_license_received,
|
||||
int64_t time_first_decrypt,
|
||||
int64_t time_last_decrypt) {
|
||||
ASSERT_NO_FATAL_FAILURE(GenerateReport(pst));
|
||||
Test_PST_Report expected(pst, status);
|
||||
void Session::VerifyReport(Test_PST_Report expected,
|
||||
int64_t time_license_received,
|
||||
int64_t time_first_decrypt,
|
||||
int64_t time_last_decrypt) {
|
||||
time_t now = time(NULL);
|
||||
expected.seconds_since_license_received =
|
||||
MaybeAdjustTime(time_license_received, now);
|
||||
@@ -1248,6 +1243,17 @@ void Session::GenerateVerifyReport(const std::string& pst,
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyPST(expected));
|
||||
}
|
||||
|
||||
void Session::GenerateVerifyReport(const std::string& pst,
|
||||
OEMCrypto_Usage_Entry_Status status,
|
||||
int64_t time_license_received,
|
||||
int64_t time_first_decrypt,
|
||||
int64_t time_last_decrypt) {
|
||||
ASSERT_NO_FATAL_FAILURE(GenerateReport(pst));
|
||||
Test_PST_Report expected(pst, status);
|
||||
ASSERT_NO_FATAL_FAILURE(VerifyReport(expected, time_license_received,
|
||||
time_first_decrypt, time_last_decrypt));
|
||||
}
|
||||
|
||||
void Session::CreateOldEntry(const Test_PST_Report& report) {
|
||||
OEMCryptoResult result = OEMCrypto_CreateOldUsageEntry(
|
||||
report.seconds_since_license_received,
|
||||
|
||||
Reference in New Issue
Block a user