Source release 14.1.0
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
# Copyright 2017 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.
|
||||
#
|
||||
# Builds under the CDM ./build.py (target platform) build system
|
||||
# Refer to the distribution package's README for details.
|
||||
{
|
||||
'variables': {
|
||||
'oemcrypto_lib%': '',
|
||||
'oemcrypto_stubs%': '',
|
||||
'openssl_config%': 'system',
|
||||
'openssl_target%': '',
|
||||
},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Copyright 2017 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.
|
||||
#
|
||||
# Include this in any custom unit test targets.
|
||||
# Does not include the test runner main.
|
||||
@@ -14,7 +16,7 @@
|
||||
'include_dirs': [
|
||||
'../../../core/include', # log.h
|
||||
'../../include',
|
||||
'../../mock/src', # oemcrypto_key_mock.h
|
||||
'../../ref/src', # oemcrypto_key_ref.h
|
||||
'../',
|
||||
'../../../cdm/test',
|
||||
],
|
||||
@@ -32,23 +34,15 @@
|
||||
'../../../third_party/gmock.gyp:gtest',
|
||||
],
|
||||
'conditions': [
|
||||
['oemcrypto_stubs!=""', {
|
||||
'dependencies': [
|
||||
'../../stubs/stubs.gyp:oec_stubs_v<(oemcrypto_version)',
|
||||
],
|
||||
}, {
|
||||
'conditions': [
|
||||
['oemcrypto_lib==""', {
|
||||
'dependencies': [
|
||||
'../../mock/oec_mock.gyp:oec_mock',
|
||||
],
|
||||
}, {
|
||||
'libraries': [
|
||||
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
|
||||
'<(oemcrypto_lib)',
|
||||
],
|
||||
}],
|
||||
],
|
||||
['oemcrypto_lib==""', {
|
||||
'includes': [
|
||||
'../../ref/oec_ref.gypi',
|
||||
],
|
||||
}, {
|
||||
'libraries': [
|
||||
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
|
||||
'<(oemcrypto_lib)',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Copyright 2017 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.
|
||||
{
|
||||
# Here you can set platform-specific compiler settings.
|
||||
'target_defaults': {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
// 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 device features for unit tests
|
||||
//
|
||||
#include "oec_device_features.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@@ -141,6 +145,11 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
|
||||
if (api_version < 12) FilterOut(&filter, "*API12*");
|
||||
if (api_version < 13) FilterOut(&filter, "*API13*");
|
||||
if (api_version < 14) FilterOut(&filter, "*API14*");
|
||||
// Some tests may require root access. If user is not root, filter these tests
|
||||
// out.
|
||||
if (getuid()) {
|
||||
FilterOut(&filter, "UsageTableTest.TimeRollbackPrevention");
|
||||
}
|
||||
// Performance tests take a long time. Filter them out if they are not
|
||||
// specifically requested.
|
||||
if (filter.find("Performance") == std::string::npos) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wv_keybox.h"
|
||||
#include "oemcrypto_types.h"
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef CDM_OEC_SESSION_UTIL_H_
|
||||
#define CDM_OEC_SESSION_UTIL_H_
|
||||
|
||||
// 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
|
||||
//
|
||||
@@ -10,9 +12,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "oec_device_features.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "pst_report.h"
|
||||
#include "test_keybox.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -65,10 +67,10 @@ const size_t kMaxDecryptSize = 100 * 1024; // In specification.
|
||||
typedef struct {
|
||||
uint8_t key_id[kTestKeyIdMaxLength];
|
||||
size_t key_id_length;
|
||||
uint8_t key_data[wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t key_data[MAC_KEY_SIZE];
|
||||
size_t key_data_length;
|
||||
uint8_t key_iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t control_iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t key_iv[KEY_IV_SIZE];
|
||||
uint8_t control_iv[KEY_IV_SIZE];
|
||||
KeyControlBlock control;
|
||||
// Note: cipher_mode may not be part of a real signed message. For these
|
||||
// tests, it is convenient to keep it in this structure anyway.
|
||||
@@ -78,8 +80,8 @@ typedef struct {
|
||||
// This structure will be signed to simulate a message from the server.
|
||||
struct MessageData {
|
||||
MessageKeyData keys[kMaxNumKeys];
|
||||
uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE];
|
||||
uint8_t mac_key_iv[KEY_IV_SIZE];
|
||||
uint8_t mac_keys[2 * MAC_KEY_SIZE];
|
||||
uint8_t pst[kMaxPSTLength];
|
||||
};
|
||||
|
||||
@@ -87,7 +89,7 @@ struct MessageData {
|
||||
// server.
|
||||
struct RSAPrivateKeyMessage {
|
||||
uint8_t rsa_key[kMaxTestRSAKeyLength];
|
||||
uint8_t rsa_key_iv[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t rsa_key_iv[KEY_IV_SIZE];
|
||||
size_t rsa_key_length;
|
||||
uint32_t nonce;
|
||||
};
|
||||
@@ -106,10 +108,10 @@ struct Test_PST_Report {
|
||||
};
|
||||
|
||||
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];
|
||||
uint8_t entitlement_key_id[KEY_SIZE];
|
||||
uint8_t content_key_id[KEY_SIZE];
|
||||
uint8_t content_key_data_iv[KEY_SIZE];
|
||||
uint8_t content_key_data[KEY_SIZE];
|
||||
};
|
||||
|
||||
// Increment counter for AES-CTR. The CENC spec specifies we increment only
|
||||
@@ -332,9 +334,14 @@ class Session {
|
||||
// Verify the values in the PST report. The signature should have been
|
||||
// verified in GenerateReport, above.
|
||||
void VerifyPST(const Test_PST_Report& report);
|
||||
// Generate and Verify the Usage Report. If any time is greater than 10
|
||||
// minutes, it is assumed to be an absolute time, and time_since will be
|
||||
// computed relative to now.
|
||||
// Verify the Usage Report. If any time is greater than 10 minutes, it is
|
||||
// assumed to be an absolute time, and time_since will be computed relative to
|
||||
// now.
|
||||
void VerifyReport(Test_PST_Report report,
|
||||
int64_t time_license_received = 0,
|
||||
int64_t time_first_decrypt = 0,
|
||||
int64_t time_last_decrypt = 0);
|
||||
// Same as above, but generates the report with the given status.
|
||||
void GenerateVerifyReport(const std::string& pst,
|
||||
OEMCrypto_Usage_Entry_Status status,
|
||||
int64_t time_license_received = 0,
|
||||
@@ -373,9 +380,6 @@ class Session {
|
||||
// The size of the encrypted message.
|
||||
size_t message_size() { return message_size_; }
|
||||
|
||||
// If this session has an entitlement license.
|
||||
bool has_entitlement_license() const { return has_entitlement_license_; }
|
||||
|
||||
private:
|
||||
// Generate mac and enc keys give the master key.
|
||||
void DeriveKeys(const uint8_t* master_key,
|
||||
@@ -405,7 +409,6 @@ class Session {
|
||||
vector<uint8_t> encrypted_usage_entry_;
|
||||
uint32_t usage_entry_number_;
|
||||
string pst_;
|
||||
bool has_entitlement_license_;
|
||||
|
||||
// Clear Entitlement key data. This is the backing data for
|
||||
// |entitled_key_array_|.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "oec_session_util.h"
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "test_keybox.h"
|
||||
#include "test_rsa_key.h"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2013 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
|
||||
//
|
||||
@@ -29,14 +31,15 @@
|
||||
#include "log.h"
|
||||
#include "oec_device_features.h"
|
||||
#include "oec_session_util.h"
|
||||
#include "oemcrypto_key_mock.h"
|
||||
#include "oemcrypto_session_tests_helper.h"
|
||||
#include "properties.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "string_conversions.h"
|
||||
#include "test_keybox.h"
|
||||
#include "test_rsa_key.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_keybox.h"
|
||||
|
||||
#ifdef CDM_TESTS
|
||||
#include "properties.h"
|
||||
#endif
|
||||
|
||||
using ::testing::Bool;
|
||||
using ::testing::Combine;
|
||||
@@ -74,7 +77,9 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
||||
|
||||
virtual void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
#ifdef CDM_TESTS
|
||||
wvcdm::Properties::Init();
|
||||
#endif
|
||||
wvcdm::g_cutoff = wvcdm::LOG_INFO;
|
||||
const ::testing::TestInfo* const test_info =
|
||||
::testing::UnitTest::GetInstance()->current_test_info();
|
||||
@@ -769,7 +774,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
}
|
||||
@@ -786,7 +791,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeySeveralNonce) {
|
||||
s.GenerateNonce(); // three.
|
||||
s.GenerateNonce(); // four.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, first_nonce));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, first_nonce));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
}
|
||||
@@ -959,7 +964,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) {
|
||||
|
||||
vector<uint8_t> bad_buffer(
|
||||
s.encrypted_license().keys[1].key_data,
|
||||
s.encrypted_license().keys[1].key_data + wvcdm::KEY_SIZE);
|
||||
s.encrypted_license().keys[1].key_data + wvoec::KEY_SIZE);
|
||||
s.key_array()[1].key_data = &bad_buffer[0];
|
||||
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
@@ -1033,7 +1038,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
|
||||
wvoec_mock::kControlNonceEnabled,
|
||||
wvoec::kControlNonceEnabled,
|
||||
42)); // bad nonce.
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
@@ -1051,7 +1056,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
uint32_t nonce = s.get_nonce();
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, nonce));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, nonce));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||
@@ -1059,7 +1064,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
|
||||
wvoec_mock::kControlNonceEnabled,
|
||||
wvoec::kControlNonceEnabled,
|
||||
nonce)); // same old nonce.
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
@@ -1071,6 +1076,57 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
}
|
||||
|
||||
// This tests that a nonce cannot be used in new session.
|
||||
TEST_F(OEMCryptoSessionTests, LoadKeyNonceReopenSession) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
uint32_t nonce = s.get_nonce();
|
||||
// Do not use the nonce now. Close session and use it after re-opening.
|
||||
ASSERT_NO_FATAL_FAILURE(s.close());
|
||||
|
||||
// Actually, this isn't the same session. OEMCrypto opens a new session, but
|
||||
// we are guarding against the possiblity that it re-uses the session data
|
||||
// and might not clear out the nonce table correctly.
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
|
||||
nonce)); // same old nonce
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_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, OEMCrypto_ContentLicense);
|
||||
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
}
|
||||
|
||||
// This tests that a nonce cannot be used in wrong session.
|
||||
TEST_F(OEMCryptoSessionTests, LoadKeyNonceWrongSession) {
|
||||
Session s1;
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
uint32_t nonce = s1.get_nonce();
|
||||
// Do not use the nonce. Also, leave the session open. We want to make sure
|
||||
// that s and s1 do NOT share a nonce table. This is different from the
|
||||
// LoadKeyNonceReopenSession in that we do not close s1.
|
||||
|
||||
Session s2;
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
|
||||
nonce)); // nonce from session s1
|
||||
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0],
|
||||
s2.signature().size(), s2.encrypted_license().mac_key_iv,
|
||||
s2.encrypted_license().mac_keys, s2.num_keys(), s2.key_array(), NULL, 0,
|
||||
NULL, OEMCrypto_ContentLicense);
|
||||
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
@@ -1186,7 +1242,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
int kNoKeys = 0;
|
||||
ASSERT_NE(
|
||||
@@ -1202,7 +1258,7 @@ TEST_F(OEMCryptoSessionTests, QueryKeyControl) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
// Note: successful cases are tested in VerifyTestKeys.
|
||||
@@ -1229,7 +1285,7 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlRequireAntiRollbackHardware, 0));
|
||||
0, wvoec::kControlRequireAntiRollbackHardware, 0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||
@@ -1251,7 +1307,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, patch_level << wvoec_mock::kControlSecurityPatchLevelShift, 0));
|
||||
0, patch_level << wvoec::kControlSecurityPatchLevelShift, 0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
@@ -1267,7 +1323,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, (patch_level + 1) << wvoec_mock::kControlSecurityPatchLevelShift,
|
||||
0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift,
|
||||
0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_EQ(
|
||||
@@ -1284,7 +1340,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, (patch_level - 1) << wvoec_mock::kControlSecurityPatchLevelShift,
|
||||
0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift,
|
||||
0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_EQ(
|
||||
@@ -1326,8 +1382,8 @@ class SessionTestDecryptWithHDCP : public OEMCryptoSessionTests,
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0,
|
||||
(version << wvoec_mock::kControlHDCPVersionShift) |
|
||||
wvoec_mock::kControlObserveHDCP | wvoec_mock::kControlHDCPRequired,
|
||||
(version << wvoec::kControlHDCPVersionShift) |
|
||||
wvoec::kControlObserveHDCP | wvoec::kControlHDCPRequired,
|
||||
0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
@@ -1371,14 +1427,14 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
s.GenerateNonce();
|
||||
// License renewal message is signed by client and verified by the server.
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
|
||||
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(num_keys_,
|
||||
wvoec_mock::kControlNonceEnabled,
|
||||
wvoec::kControlNonceEnabled,
|
||||
s.get_nonce(), OEMCrypto_SUCCESS));
|
||||
}
|
||||
|
||||
@@ -1401,14 +1457,14 @@ TEST_P(SessionTestRefreshKeyTest, RefreshOldNonceAPI11) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
uint32_t nonce = s.get_nonce();
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, nonce));
|
||||
s.FillSimpleMessage(kDuration, wvoec::kControlNonceEnabled, nonce));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
// License renewal message is signed by client and verified by the server.
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
|
||||
// Tryinng to reuse the same nonce.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce,
|
||||
s.RefreshTestKeys(num_keys_, wvoec::kControlNonceEnabled, nonce,
|
||||
OEMCrypto_ERROR_INVALID_NONCE));
|
||||
}
|
||||
|
||||
@@ -1417,7 +1473,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshBadNonceAPI11) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
s.GenerateNonce();
|
||||
@@ -1425,7 +1481,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshBadNonceAPI11) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
|
||||
uint32_t nonce = s.get_nonce() ^ 42;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce,
|
||||
s.RefreshTestKeys(num_keys_, wvoec::kControlNonceEnabled, nonce,
|
||||
OEMCrypto_ERROR_INVALID_NONCE));
|
||||
}
|
||||
|
||||
@@ -1435,7 +1491,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshLargeBuffer) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
s.GenerateNonce();
|
||||
@@ -1443,7 +1499,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshLargeBuffer) {
|
||||
// This uses a large buffer for the renewal message.
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature(kMaxMessageSize));
|
||||
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(num_keys_,
|
||||
wvoec_mock::kControlNonceEnabled,
|
||||
wvoec::kControlNonceEnabled,
|
||||
s.get_nonce(), OEMCrypto_SUCCESS));
|
||||
}
|
||||
|
||||
@@ -1455,7 +1511,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
// Call select key before the refresh. No calls below to TestDecryptCTR with
|
||||
@@ -1469,7 +1525,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) {
|
||||
// message is not actually encrypted. It is, however, signed.
|
||||
// FillRefreshMessage fills the message with a duration of kLongDuration.
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillRefreshMessage(
|
||||
num_keys_, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
num_keys_, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
s.ServerSignBuffer(reinterpret_cast<const uint8_t*>(&s.encrypted_license()),
|
||||
s.message_size(), &s.signature());
|
||||
OEMCrypto_KeyRefreshObject key_array[num_keys_];
|
||||
@@ -2077,7 +2133,7 @@ TEST_F(OEMCryptoSessionTests, DecryptSecureToClear) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration,
|
||||
wvoec_mock::kControlObserveDataPath | wvoec_mock::kControlDataPathSecure,
|
||||
wvoec::kControlObserveDataPath | wvoec::kControlDataPathSecure,
|
||||
0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
@@ -2090,7 +2146,7 @@ TEST_F(OEMCryptoSessionTests, DecryptNoAnalogToClearAPI13) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlDisableAnalogOutput, 0));
|
||||
kDuration, wvoec::kControlDisableAnalogOutput, 0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
@@ -2102,7 +2158,7 @@ TEST_F(OEMCryptoSessionTests, KeyDuration) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(true, OEMCrypto_SUCCESS));
|
||||
@@ -3766,22 +3822,22 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
session_.FillSimpleMessage(duration, control, nonce, pst));
|
||||
session_.license().keys[0].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowEncrypt);
|
||||
htonl(wvoec::kControlAllowEncrypt);
|
||||
session_.license().keys[1].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowDecrypt);
|
||||
htonl(wvoec::kControlAllowDecrypt);
|
||||
session_.license().keys[2].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowSign);
|
||||
htonl(wvoec::kControlAllowSign);
|
||||
session_.license().keys[3].control.control_bits |=
|
||||
htonl(wvoec_mock::kControlAllowVerify);
|
||||
htonl(wvoec::kControlAllowVerify);
|
||||
|
||||
session_.license().keys[2].key_data_length = wvcdm::MAC_KEY_SIZE;
|
||||
session_.license().keys[3].key_data_length = wvcdm::MAC_KEY_SIZE;
|
||||
session_.license().keys[2].key_data_length = wvoec::MAC_KEY_SIZE;
|
||||
session_.license().keys[3].key_data_length = wvoec::MAC_KEY_SIZE;
|
||||
|
||||
clear_buffer_.assign(buffer_size_, 0);
|
||||
for (size_t i = 0; i < clear_buffer_.size(); i++) {
|
||||
clear_buffer_[i] = 1 + i % 250;
|
||||
}
|
||||
for (size_t i = 0; i < wvcdm::KEY_IV_SIZE; i++) {
|
||||
for (size_t i = 0; i < wvoec::KEY_IV_SIZE; i++) {
|
||||
iv_[i] = i;
|
||||
}
|
||||
}
|
||||
@@ -3797,8 +3853,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
|
||||
ASSERT_EQ(0,
|
||||
AES_set_encrypt_key(session_.license().keys[key_index].key_data,
|
||||
AES_BLOCK_SIZE * 8, &aes_key));
|
||||
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv_, wvcdm::KEY_IV_SIZE);
|
||||
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
|
||||
memcpy(iv_buffer, iv_, wvoec::KEY_IV_SIZE);
|
||||
out_buffer->resize(in_buffer.size());
|
||||
ASSERT_GT(in_buffer.size(), 0u);
|
||||
ASSERT_EQ(0u, in_buffer.size() % AES_BLOCK_SIZE);
|
||||
@@ -3812,7 +3868,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
|
||||
unsigned int md_len = SHA256_DIGEST_LENGTH;
|
||||
signature->resize(SHA256_DIGEST_LENGTH);
|
||||
HMAC(EVP_sha256(), session_.license().keys[key_index].key_data,
|
||||
wvcdm::MAC_KEY_SIZE, &in_buffer[0], in_buffer.size(),
|
||||
wvoec::MAC_KEY_SIZE, &in_buffer[0], in_buffer.size(),
|
||||
signature->data(), &md_len);
|
||||
}
|
||||
|
||||
@@ -3896,7 +3952,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
|
||||
size_t buffer_size_;
|
||||
vector<uint8_t> clear_buffer_;
|
||||
vector<uint8_t> encrypted_buffer_;
|
||||
uint8_t iv_[wvcdm::KEY_IV_SIZE];
|
||||
uint8_t iv_[wvoec::KEY_IV_SIZE];
|
||||
Session session_;
|
||||
};
|
||||
|
||||
@@ -3991,7 +4047,7 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptSameBufferAPI12) {
|
||||
|
||||
TEST_F(GenericCryptoTest, GenericSecureToClear) {
|
||||
session_.license().keys[1].control.control_bits |= htonl(
|
||||
wvoec_mock::kControlObserveDataPath | wvoec_mock::kControlDataPathSecure);
|
||||
wvoec::kControlObserveDataPath | wvoec::kControlDataPathSecure);
|
||||
EncryptAndLoadKeys();
|
||||
unsigned int key_index = 1;
|
||||
vector<uint8_t> encrypted;
|
||||
@@ -4313,7 +4369,7 @@ class GenericCryptoKeyIdLengthTest : public GenericCryptoTest {
|
||||
const uint32_t kNoNonce = 0;
|
||||
session_.set_num_keys(5);
|
||||
ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlAllowDecrypt, kNoNonce));
|
||||
kDuration, wvoec::kControlAllowDecrypt, kNoNonce));
|
||||
SetUniformKeyIdLength(16); // Start with all key ids being 16 bytes.
|
||||
// But, we are testing that the key ids do not have to have the same length.
|
||||
session_.SetKeyId(0, "123456789012"); // 12 bytes (common key id length).
|
||||
@@ -4404,7 +4460,7 @@ class UsageTableTest : public GenericCryptoTest {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
@@ -4451,7 +4507,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4475,13 +4531,37 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) {
|
||||
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, OnlineLicenseUnused) {
|
||||
std::string pst = "my_pst";
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
// No decrypt. We do not use this license.
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused));
|
||||
// Flag the entry as inactive.
|
||||
ASSERT_NO_FATAL_FAILURE(s.DeactivateUsageEntry(pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
// It should report as inactive.
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kInactiveUnused));
|
||||
// Decrypt should fail.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, ForbidReportWithNoUpdate) {
|
||||
std::string pst = "my_pst";
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4511,7 +4591,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4524,7 +4604,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) {
|
||||
size_t kAllKeys = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
|
||||
kAllKeys,
|
||||
wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), OEMCrypto_SUCCESS));
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
@@ -4540,7 +4620,7 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4571,7 +4651,7 @@ TEST_F(UsageTableTest, OnlineEmptyPST) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4591,7 +4671,7 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
// ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -4610,7 +4690,7 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
std::string pst1 = "pst saved";
|
||||
ASSERT_NO_FATAL_FAILURE(s1.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s1.get_nonce(), pst1));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.CreateNewUsageEntry());
|
||||
@@ -4620,7 +4700,8 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
|
||||
const size_t ENTRY_COUNT = 200; // API says should hold at least 200 entries.
|
||||
// API says should hold at least 200 entries. Subtract one for s1's entry.
|
||||
const size_t ENTRY_COUNT = 200 - 1;
|
||||
vector<Session> sessions(ENTRY_COUNT);
|
||||
for (size_t i = 0; i < ENTRY_COUNT; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
|
||||
@@ -4630,7 +4711,7 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
|
||||
char c2 = 'A' + (i%26);
|
||||
pst = pst + c1 + c2;
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i].CreateNewUsageEntry());
|
||||
ASSERT_EQ(sessions[i].usage_entry_number(), i + 1);
|
||||
@@ -4667,7 +4748,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
|
||||
std::string pst = "A PST";
|
||||
uint32_t nonce = session_.get_nonce();
|
||||
MakeFourKeys(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
nonce, pst);
|
||||
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||
@@ -4704,7 +4785,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) {
|
||||
std::string pst = "my_pst";
|
||||
uint32_t nonce = session_.get_nonce();
|
||||
MakeFourKeys(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
nonce, pst);
|
||||
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||
@@ -4741,7 +4822,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) {
|
||||
std::string pst = "my_pst";
|
||||
uint32_t nonce = session_.get_nonce();
|
||||
MakeFourKeys(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
nonce, pst);
|
||||
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||
@@ -4789,7 +4870,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) {
|
||||
std::string pst = "my_pst";
|
||||
uint32_t nonce = session_.get_nonce();
|
||||
MakeFourKeys(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
nonce, pst);
|
||||
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||
@@ -4832,7 +4913,7 @@ TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
@@ -4843,7 +4924,7 @@ TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
|
||||
size_t kAllKeys = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
|
||||
kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
|
||||
kAllKeys, wvoec::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
@@ -4896,7 +4977,7 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithRefresh) {
|
||||
decrypt_time)); // last decrypt
|
||||
size_t kAllKeys = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
|
||||
kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
|
||||
kAllKeys, wvoec::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kActive,
|
||||
@@ -4941,7 +5022,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s2.get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s2.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
|
||||
uint8_t* pst_ptr = s2.encrypted_license().pst;
|
||||
@@ -4975,7 +5056,7 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry, 42, pst));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
@@ -4994,7 +5075,7 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry, s.get_nonce()));
|
||||
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
|
||||
@@ -5069,6 +5150,49 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
|
||||
EXPECT_EQ(kInactiveUsed, s3.pst_report().status());
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) {
|
||||
std::string pst = "my_pst";
|
||||
Session s1;
|
||||
ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s1, pst));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s1.LoadTestKeys(pst, new_mac_keys_)); // Reload the license
|
||||
// No Decrypt. This license is unused.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.DeactivateUsageEntry(pst)); // Then deactivate.
|
||||
// After deactivate, should not be able to decrypt.
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s1.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.GenerateVerifyReport(pst, kInactiveUnused));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
|
||||
Session s2;
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s1));
|
||||
// Offline license can not be reused if it has been deactivated.
|
||||
uint8_t* pst_ptr = s1.encrypted_license().pst;
|
||||
EXPECT_NE(
|
||||
OEMCrypto_SUCCESS,
|
||||
OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(),
|
||||
&s1.signature()[0], s1.signature().size(),
|
||||
s1.encrypted_license().mac_key_iv,
|
||||
s1.encrypted_license().mac_keys, s1.num_keys(),
|
||||
s1.key_array(), pst_ptr, pst.length(), NULL,
|
||||
OEMCrypto_ContentLicense));
|
||||
s2.close();
|
||||
// But we can still generate a report.
|
||||
Session s3;
|
||||
ASSERT_NO_FATAL_FAILURE(s3.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s3.LoadUsageEntry(s1));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s1));
|
||||
EXPECT_EQ(kInactiveUnused, s3.pst_report().status());
|
||||
}
|
||||
|
||||
TEST_P(UsageTableTestWithMAC, BadRange) {
|
||||
std::string pst = "my_pst";
|
||||
Session s;
|
||||
@@ -5076,7 +5200,7 @@ TEST_P(UsageTableTestWithMAC, BadRange) {
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
uint8_t* pst_ptr = s.license().pst; // Bad: not in encrypted_license.
|
||||
ASSERT_NE(
|
||||
@@ -5095,7 +5219,7 @@ TEST_F(UsageTableTest, UpdateFailsWithNullPtr) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -5125,7 +5249,7 @@ class UsageTableDefragTest : public UsageTableTest {
|
||||
char c2 = 'A' + (index % 26);
|
||||
pst = pst + c1 + c2;
|
||||
ASSERT_NO_FATAL_FAILURE(s->FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s->get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s->get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s->EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s->CreateNewUsageEntry());
|
||||
ASSERT_EQ(s->usage_entry_number(), index);
|
||||
@@ -5433,7 +5557,7 @@ TEST_F(UsageTableTest, GenerateReportWrongPST) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
|
||||
@@ -5530,7 +5654,7 @@ TEST_F(UsageTableTest, VerifyUsageTimes) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
|
||||
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
|
||||
s.get_nonce(), pst));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
|
||||
@@ -5614,6 +5738,86 @@ TEST_F(UsageTableTest, VerifyUsageTimes) {
|
||||
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
// NOTE: This test needs root access since clock_settime messes with the system
|
||||
// time in order to verify that OEMCrypto protects against rollbacks in usage
|
||||
// entries. Therefore, this test is filtered if not run as root.
|
||||
// We don't test roll-forward protection or instances where the user rolls back
|
||||
// the time to the last decrypt call since this requires hardware-secure clocks
|
||||
// to guarantee.
|
||||
TEST_F(UsageTableTest, TimeRollbackPrevention) {
|
||||
std::string pst = "my_pst";
|
||||
Session s1;
|
||||
cout << "This test temporarily rolls back the system time in order to verify "
|
||||
<< "that the usage report accounts for the change. It then rolls "
|
||||
<< "the time back forward to the absolute time." << endl;
|
||||
// We use clock_gettime(CLOCK_REALTIME, ...) over time(...) so we can easily
|
||||
// set the time using clock_settime.
|
||||
timespec current_time;
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, ¤t_time));
|
||||
time_t loaded = current_time.tv_sec;
|
||||
ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s1, pst));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, ¤t_time));
|
||||
time_t first_decrypt = current_time.tv_sec;
|
||||
// Monotonic clock can't be changed. We use this since system clock will be
|
||||
// unreliable.
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, ¤t_time));
|
||||
time_t first_decrypt_monotonic = current_time.tv_sec;
|
||||
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
|
||||
// Imitate playback.
|
||||
sleep(kLongDuration * 2);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, ¤t_time));
|
||||
// Rollback the wall clock time.
|
||||
cout << "Rolling the system time back..." << endl;
|
||||
timeval current_time_of_day = {};
|
||||
current_time_of_day.tv_sec = current_time.tv_sec - kLongDuration * 10;
|
||||
ASSERT_EQ(0, settimeofday(¤t_time_of_day, NULL));
|
||||
|
||||
// Try to playback again.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, ¤t_time));
|
||||
time_t third_decrypt = current_time.tv_sec;
|
||||
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.GenerateReport(pst));
|
||||
Test_PST_Report expected(pst, kActive);
|
||||
|
||||
// Restore wall clock to its original position to verify that OEMCrypto does
|
||||
// not report negative times.
|
||||
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, ¤t_time));
|
||||
current_time_of_day.tv_sec =
|
||||
first_decrypt + current_time.tv_sec - first_decrypt_monotonic;
|
||||
cout << "Rolling the system time forward to the absolute time..." << endl;
|
||||
ASSERT_EQ(0, settimeofday(¤t_time_of_day, NULL));
|
||||
// Need to update time created since the verification checks the time of PST
|
||||
// report creation.
|
||||
expected.time_created = current_time_of_day.tv_sec;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s1.VerifyReport(expected, loaded, first_decrypt,
|
||||
first_decrypt + third_decrypt - first_decrypt_monotonic));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.close());
|
||||
}
|
||||
|
||||
// This is a special case where a group of assets can be licensed with a master
|
||||
// key. In order for this to work, a single session must first load a device
|
||||
// specific license, and then a shared content license. This shared license is
|
||||
@@ -5640,7 +5844,7 @@ TEST_F(UsageTableTest, LoadSharedLicense) {
|
||||
s.license().keys[i].key_id_length);
|
||||
s.license().keys[i].control.nonce = 0;
|
||||
s.license().keys[i].control.control_bits =
|
||||
htonl(wvoec_mock::kSharedLicense);
|
||||
htonl(wvoec::kSharedLicense);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, false));
|
||||
@@ -5669,7 +5873,7 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) {
|
||||
s.license().keys[i].key_id_length);
|
||||
s.license().keys[i].control.nonce = 0;
|
||||
s.license().keys[i].control.control_bits =
|
||||
htonl(wvoec_mock::kSharedLicense);
|
||||
htonl(wvoec::kSharedLicense);
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
uint8_t* pst_ptr = s.encrypted_license().pst;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Copyright 2013 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 - extra tests required for Android platform.
|
||||
//
|
||||
@@ -109,7 +111,7 @@ TEST_F(OEMCryptoAndroidMNCTest, LoadTestKeybox) {
|
||||
if (OEMCrypto_Keybox == OEMCrypto_GetProvisioningMethod()) {
|
||||
OEMCryptoResult status = OEMCrypto_LoadTestKeybox(
|
||||
reinterpret_cast<const uint8_t*>(&kTestKeybox),
|
||||
sizeof(kTestKeybox)));
|
||||
sizeof(kTestKeybox));
|
||||
// OEMCrypto may return success or not implemented.
|
||||
if (status == OEMCrypto_SUCCESS) {
|
||||
LOGV("OEMCrypto_LoadTestKeybox is implemented.");
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "log.h"
|
||||
#include "oec_device_features.h"
|
||||
#ifdef CDM_TESTS
|
||||
#include "properties.h"
|
||||
#endif
|
||||
|
||||
static void acknowledge_cast() {
|
||||
std::cout
|
||||
@@ -15,7 +17,9 @@ static void acknowledge_cast() {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
#ifdef CDM_TESTS
|
||||
wvcdm::Properties::Init();
|
||||
#endif
|
||||
wvcdm::g_cutoff = wvcdm::LOG_INFO;
|
||||
bool is_cast_receiver = false;
|
||||
bool force_load_test_keybox = false;
|
||||
|
||||
40
oemcrypto/test/oemcrypto_unittests.gyp
Normal file
40
oemcrypto/test/oemcrypto_unittests.gyp
Normal file
@@ -0,0 +1,40 @@
|
||||
# This is a gyp file for building the OEMCrypto unit tests with the reference
|
||||
# code from the stand-alone source code.
|
||||
{
|
||||
'variables': {
|
||||
# Override the variables below for the location of various gyp files.
|
||||
# Alternatively, set the environment variable CDM_DIR to point to a recent
|
||||
# version of the source CDM.
|
||||
'boringssl_dependency%': '<!(echo $CDM_DIR)/third_party/boringssl/boringssl.gyp:legacy_ssl',
|
||||
'gtest_dependency%': '<!(echo $CDM_DIR)/third_party/gmock.gyp:gtest',
|
||||
'gmock_dependency%': '<!(echo $CDM_DIR)/third_party/gmock.gyp:gmock',
|
||||
'oemcrypto_dir%': '..',
|
||||
'util_dir%': '../../util',
|
||||
'platform_specific_dir%': '<!(echo $CDM_DIR)/linux/src',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'oemcrypto_unittests',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'oemcrypto_test_main.cpp',
|
||||
'<(platform_specific_dir)/file_store.cpp',
|
||||
'<(platform_specific_dir)/lock.cpp',
|
||||
'<(platform_specific_dir)/log.cpp',
|
||||
'<(util_dir)/src/string_conversions.cpp',
|
||||
],
|
||||
'includes': [
|
||||
'oemcrypto_unittests.gypi',
|
||||
'../ref/oec_ref.gypi',
|
||||
],
|
||||
'libraries': [
|
||||
'-lpthread', # gtest
|
||||
],
|
||||
'dependencies': [
|
||||
'<(boringssl_dependency)',
|
||||
'<(gtest_dependency)',
|
||||
'<(gmock_dependency)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
30
oemcrypto/test/oemcrypto_unittests.gypi
Normal file
30
oemcrypto/test/oemcrypto_unittests.gypi
Normal file
@@ -0,0 +1,30 @@
|
||||
# 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.
|
||||
#
|
||||
# Include this in any custom unit test targets.
|
||||
# Does not include the test runner main.
|
||||
{
|
||||
'sources': [
|
||||
'oec_device_features.cpp',
|
||||
'oec_session_util.cpp',
|
||||
'oemcrypto_session_tests_helper.cpp',
|
||||
'oemcrypto_test.cpp',
|
||||
'../../test/auth/test_keybox.cpp',
|
||||
'../../test/auth/test_rsa_key.cpp',
|
||||
'../../test/auth/test_oem_cert.cpp',
|
||||
'../../test/auth/test_service_cert.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(util_dir)/include',
|
||||
'<(oemcrypto_dir)/include',
|
||||
'<(oemcrypto_dir)/test',
|
||||
'../../test/auth',
|
||||
],
|
||||
'defines': [
|
||||
'OEMCRYPTO_TESTS',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(boringssl_dependency)',
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user