Provisioning Unit Tests

This commit is contained in:
Fred Gylys-Colwell
2019-12-13 11:14:12 -08:00
parent 5b9580a351
commit ff7cc16e4a
8 changed files with 219 additions and 152 deletions

View File

@@ -4902,7 +4902,7 @@ OEMCryptoResult OEMCrypto_AllocateSecureBuffer(
* [in] secure_fd: The integer returned by OEMCrypto_AllocateSecureBuffer
*
* Returns:
* OEMCrypto_SUCCESS - if the buffer was created
* OEMCrypto_SUCCESS - if the buffer was freed
* OEMCrypto_ERROR_NOT_IMPLEMENTED
* OEMCrypto_ERROR_UNKNOWN_FAILURE
*

View File

@@ -216,7 +216,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest(
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("ERROR_INVALID_SESSION");
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->PrepAndSignLicenseRequest(message, message_length,
@@ -233,7 +233,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest(
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("ERROR_INVALID_SESSION");
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->PrepAndSignRenewalRequest(message, message_length,
@@ -250,7 +250,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignProvisioningRequest(
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("ERROR_INVALID_SESSION");
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return session_ctx->PrepAndSignProvisioningRequest(
@@ -698,7 +698,7 @@ OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session) {
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("ERROR_INVALID_SESSION");
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
return OEMCrypto_ERROR_INVALID_SESSION;
}
return crypto_engine->load_oem_private_key(session_ctx);
@@ -787,7 +787,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
}
// This function is no longer exported -- it is only used by LoadProvisioning.
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
OEMCrypto_SESSION session, const uint32_t* unaligned_nonce,
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length,
const uint8_t* enc_rsa_key, size_t enc_rsa_key_length,
@@ -901,7 +901,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
}
// This function is no longer exported -- it is only used by LoadProvisioning.
OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
const uint8_t* signature, size_t signature_length,
const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key,
@@ -1023,22 +1023,18 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadProvisioning(
LOGE("OEMCrypto Not Initialized");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (wrapped_private_key_length == nullptr) {
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (message == nullptr || message_length == 0 || signature == nullptr ||
signature_length == 0) {
if (wrapped_private_key_length == nullptr || message == nullptr ||
message_length == 0 || signature == nullptr || signature_length == 0) {
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (!crypto_engine->ValidRootOfTrust()) {
LOGE("ERROR_KEYBOX_INVALID");
LOGE("OEMCrypto_ERROR_KEYBOX_INVALID");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("ERROR_INVALID_SESSION");
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
return OEMCrypto_ERROR_INVALID_SESSION;
}
std::vector<uint8_t> device_id = crypto_engine->DeviceRootId();
@@ -1705,4 +1701,16 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetHashErrorCode(
return session_ctx->GetHashErrorCode(failed_frame_number);
}
OEMCRYPTO_API OEMCryptoResult OEMCrypto_AllocateSecureBuffer(
OEMCrypto_SESSION session, size_t buffer_size,
OEMCrypto_DestBufferDesc* output_descriptor, int* secure_fd) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
OEMCRYPTO_API OEMCryptoResult OEMCrypto_FreeSecureBuffer(
OEMCrypto_SESSION session, OEMCrypto_DestBufferDesc* output_descriptor,
int secure_fd) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
} // namespace wvoec_ref

View File

@@ -60,9 +60,8 @@ bool CanChangeTime() {
#endif
}
void DeviceFeatures::Initialize(bool is_cast_receiver,
bool force_load_test_keybox) {
cast_receiver = is_cast_receiver;
void DeviceFeatures::Initialize() {
if (initialized_) return;
uses_keybox = false;
uses_certificate = false;
loads_certificate = false;
@@ -117,11 +116,7 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
// usage tables.
if (api_version > 12) usage_table = OEMCrypto_SupportsUsageTable();
printf("usage_table = %s.\n", usage_table ? "true" : "false");
if (force_load_test_keybox) {
derive_key_method = FORCE_TEST_KEYBOX;
} else {
PickDerivedKey();
}
if (api_version >= 13) {
uint32_t supported_cert = OEMCrypto_SupportedCertificates();
if (supported_cert & OEMCrypto_Supports_RSA_CAST) {
@@ -161,9 +156,6 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
case LOAD_TEST_RSA_KEY:
printf("LOAD_TEST_RSA_KEY: Call LoadTestRSAKey before deriving keys.\n");
break;
case FORCE_TEST_KEYBOX:
printf("FORCE_TEST_KEYBOX: User requested calling InstallKeybox.\n");
break;
case TEST_PROVISION_30:
printf("TEST_PROVISION_30: Device provisioed with OEM Cert.\n");
break;
@@ -173,15 +165,15 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
printf("SecurityLevel is %s (%s)\n",
supports_level_1 ? "Level 1" : "Not Level 1",
security_level.c_str());
CheckSecureBuffers();
OEMCrypto_Terminate();
initialized_ = true;
}
std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
std::string filter = initial_filter;
// clang-format off
if (!uses_keybox) FilterOut(&filter, "*KeyboxTest*");
if (derive_key_method
!= FORCE_TEST_KEYBOX) FilterOut(&filter, "*ForceKeybox*");
if (!uses_certificate) FilterOut(&filter, "OEMCrypto*Cert*");
if (!loads_certificate) FilterOut(&filter, "OEMCryptoLoadsCert*");
if (!generic_crypto) FilterOut(&filter, "*GenericCrypto*");
@@ -246,6 +238,39 @@ void DeviceFeatures::PickDerivedKey() {
}
}
void DeviceFeatures::CheckSecureBuffers() {
output_types_.push_back({false, OEMCrypto_BufferType_Clear});
output_types_.push_back({true, OEMCrypto_BufferType_Clear});
test_secure_buffers = false;
OEMCrypto_SESSION session;
OEMCryptoResult result = OEMCrypto_OpenSession(&session);
if (result != OEMCrypto_SUCCESS) {
printf("--- ERROR: Could not open session: %d ----\n", result);
return;
}
OEMCrypto_DestBufferDesc output_descriptor;
output_descriptor.type = OEMCrypto_BufferType_Secure;
int secure_fd;
result = OEMCrypto_AllocateSecureBuffer(session, 42, &output_descriptor,
&secure_fd);
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
printf("Secure buffers will not be tested\n");
return;
}
if (result != OEMCrypto_SUCCESS) {
printf("--- ERROR: Could not create secure buffer: %d ----\n", result);
return;
}
result = OEMCrypto_FreeSecureBuffer(session, &output_descriptor, secure_fd);
if (result != OEMCrypto_SUCCESS) {
printf("--- ERROR: Could not free secure buffer: %d ----\n", result);
return;
}
printf("Secure buffers will be tested\n");
output_types_.push_back({false, OEMCrypto_BufferType_Secure});
test_secure_buffers = true;
}
void DeviceFeatures::FilterOut(std::string* current_filter,
const std::string& new_filter) {
if (current_filter->find('-') == std::string::npos) {
@@ -255,6 +280,14 @@ void DeviceFeatures::FilterOut(std::string* current_filter,
}
}
// Return the list of output types for the decrypt tests.
const std::vector<OutputType>& DeviceFeatures::GetOutputTypes() {
if (!initialized_) {
Initialize();
}
return output_types_;
}
const char* ProvisioningMethodName(OEMCrypto_ProvisioningMethod method) {
switch (method) {
case OEMCrypto_ProvisioningError:

View File

@@ -2,12 +2,21 @@
#define CDM_OEC_DEVICE_FEATURES_H_
#include <string>
#include <vector>
#include "OEMCryptoCENC.h"
#include "oemcrypto_types.h"
namespace wvoec {
// An output type for testing. The type field is secure, clear, or direct. If
// the type is clear, then decrypt_inplace could be true. Otherwise,
// decrypt_inplace is false.
struct OutputType {
bool decrypt_inplace;
OEMCryptoBufferType type;
};
// Keeps track of which features are supported by the version of OEMCrypto being
// tested. See the integration guide for a list of optional features.
class DeviceFeatures {
@@ -19,7 +28,6 @@ class DeviceFeatures {
NO_METHOD, // Cannot derive known session keys.
LOAD_TEST_KEYBOX, // Call LoadTestKeybox before deriving keys.
LOAD_TEST_RSA_KEY, // Call LoadTestRSAKey before deriving keys.
FORCE_TEST_KEYBOX, // User requested calling InstallKeybox.
TEST_PROVISION_30, // Device has OEM Certificate installed.
};
@@ -34,23 +42,36 @@ class DeviceFeatures {
bool supports_level_1; // Device supports Level 1 security.
uint32_t resource_rating; // Device's resource rating tier.
bool supports_crc; // Supported decrypt hash type CRC.
bool test_secure_buffers; // If we can create a secure buffer for testing.
uint32_t api_version;
OEMCrypto_ProvisioningMethod provisioning_method;
// This should be called from the test program's main procedure.
void Initialize(bool is_cast_receiver, bool force_load_test_keybox);
void Initialize();
void set_cast_receiver(bool is_cast_receiver) {
cast_receiver = is_cast_receiver;
}
// Generate a GTest filter of tests that should not be run. This should be
// called after Initialize. Tests are filtered out based on which features
// are not supported. For example, a device that uses Provisioning 3.0 will
// have all keybox tests filtered out.
std::string RestrictFilter(const std::string& initial_filter);
// Get a list of output types that should be tested.
const std::vector<OutputType>& GetOutputTypes();
private:
// Decide which method should be used to derive session keys, based on
// supported featuers.
void PickDerivedKey();
// Decide if secure buffers can be created, and initialize output_types_.
void CheckSecureBuffers();
// Add a GTest filter restriction to the current filter.
void FilterOut(std::string* current_filter, const std::string& new_filter);
// A list of possible output types.
std::vector<OutputType> output_types_;
bool initialized_ = false;
};
// There is one global set of features for the version of OEMCrypto being

View File

@@ -222,6 +222,7 @@ class ProvisioningRoundTrip
const std::vector<uint8_t>& encoded_rsa_key)
: RoundTrip(session),
allowed_schemes_(kSign_RSASSA_PSS),
encryptor_(),
encoded_rsa_key_(encoded_rsa_key) {}
// Prepare the session for signing the request.
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);

View File

@@ -60,10 +60,6 @@ void SessionUtil::EnsureTestKeys() {
case DeviceFeatures::LOAD_TEST_RSA_KEY:
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestRSAKey());
break;
case DeviceFeatures::FORCE_TEST_KEYBOX:
keybox_ = kTestKeybox;
InstallKeybox(keybox_, true);
break;
case DeviceFeatures::TEST_PROVISION_30:
// Can use oem certificate to install test rsa key.
break;

View File

@@ -52,14 +52,31 @@ using namespace std;
namespace std { // GTest wants PrintTo to be in the std namespace.
void PrintTo(const tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode,
bool>& param,
wvoec::OutputType>& param,
ostream* os) {
OEMCrypto_CENCEncryptPatternDesc pattern = ::testing::get<0>(param);
OEMCryptoCipherMode mode = ::testing::get<1>(param);
bool decrypt_inplace = ::testing::get<2>(param);
wvoec::OutputType output = ::testing::get<2>(param);
bool decrypt_inplace = output.decrypt_inplace;
OEMCryptoBufferType type = output.type;
*os << ((mode == OEMCrypto_CipherMode_CTR) ? "CTR mode" : "CBC mode")
<< ", encrypt=" << pattern.encrypt << ", skip=" << pattern.skip
<< ", decrypt in place = " << (decrypt_inplace ? "true" : "false");
<< ", pattern=(encrypt:" << pattern.encrypt << ", skip:" << pattern.skip
<< ")";
switch (type) {
case OEMCrypto_BufferType_Clear:
*os << ", BufferType = Clear";
break;
case OEMCrypto_BufferType_Secure:
*os << ", BufferType = Secure";
break;
case OEMCrypto_BufferType_Direct:
*os << ", BufferType = Direct";
break;
default:
*os << ", type = <bad type " << type << ">";
break;
}
if (decrypt_inplace) *os << " (in place)";
}
} // namespace std
@@ -743,13 +760,6 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
}
}
void TearDown() override {
// If we installed a bad keybox, end with a good one installed.
if (global_features.derive_key_method == DeviceFeatures::FORCE_TEST_KEYBOX)
InstallKeybox(kTestKeybox, true);
OEMCryptoClientTest::TearDown();
}
vector<uint8_t> encrypted_usage_header_;
};
@@ -759,53 +769,6 @@ TEST_F(OEMCryptoSessionTestKeyboxTest, TestKeyboxIsValid) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
}
TEST_F(OEMCryptoSessionTestKeyboxTest, GoodForceKeybox) {
ASSERT_EQ(DeviceFeatures::FORCE_TEST_KEYBOX,
global_features.derive_key_method)
<< "ForceKeybox tests will modify the installed keybox.";
wvoec::WidevineKeybox keybox = kTestKeybox;
OEMCryptoResult sts;
InstallKeybox(keybox, true);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
TEST_F(OEMCryptoSessionTestKeyboxTest, BadCRCForceKeybox) {
ASSERT_EQ(DeviceFeatures::FORCE_TEST_KEYBOX,
global_features.derive_key_method)
<< "ForceKeybox tests will modify the installed keybox.";
wvoec::WidevineKeybox keybox = kTestKeybox;
keybox.crc_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
}
TEST_F(OEMCryptoSessionTestKeyboxTest, BadMagicForceKeybox) {
ASSERT_EQ(DeviceFeatures::FORCE_TEST_KEYBOX,
global_features.derive_key_method)
<< "ForceKeybox tests will modify the installed keybox.";
wvoec::WidevineKeybox keybox = kTestKeybox;
keybox.magic_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_MAGIC, sts);
}
TEST_F(OEMCryptoSessionTestKeyboxTest, BadDataForceKeybox) {
ASSERT_EQ(DeviceFeatures::FORCE_TEST_KEYBOX,
global_features.derive_key_method)
<< "ForceKeybox tests will modify the installed keybox.";
wvoec::WidevineKeybox keybox = kTestKeybox;
keybox.data_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
}
// Verify that a license may be signed.
TEST_F(OEMCryptoSessionTests, SignLicenseRequest) {
Session s;
@@ -1894,14 +1857,15 @@ struct SampleInitData {
// buffers to be the same.
class OEMCryptoSessionTestsDecryptTests
: public OEMCryptoSessionTests,
public WithParamInterface<
tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode, bool> > {
public WithParamInterface<tuple<OEMCrypto_CENCEncryptPatternDesc,
OEMCryptoCipherMode, OutputType> > {
protected:
void SetUp() override {
OEMCryptoSessionTests::SetUp();
pattern_ = ::testing::get<0>(GetParam());
cipher_mode_ = ::testing::get<1>(GetParam());
decrypt_inplace_ = ::testing::get<2>(GetParam());
decrypt_inplace_ = ::testing::get<2>(GetParam()).decrypt_inplace;
output_buffer_type_ = ::testing::get<2>(GetParam()).type;
verify_crc_ = global_features.supports_crc;
// Pick a random key.
EXPECT_EQ(1, GetRandBytes(key_, AES_BLOCK_SIZE));
@@ -1912,6 +1876,7 @@ class OEMCryptoSessionTestsDecryptTests
}
void TearDown() override {
FreeBuffers();
ASSERT_NO_FATAL_FAILURE(session_.close());
OEMCryptoSessionTests::TearDown();
}
@@ -1924,14 +1889,16 @@ class OEMCryptoSessionTestsDecryptTests
}
}
// Set up the input buffer and output buffer.
// Set up the input buffer and either a clear or secure output buffer.
// This should be called after FindTotalSize().
void MakeBuffers() {
ASSERT_GT(total_size_, 0u);
encrypted_buffer_.resize(total_size_);
truth_buffer_.resize(total_size_);
for (size_t i = 0; i < total_size_; i++) truth_buffer_[i] = i % 256;
output_descriptor_.type = OEMCrypto_BufferType_Clear;
output_descriptor_.type = output_buffer_type_;
switch (output_descriptor_.type) {
case OEMCrypto_BufferType_Clear:
if (decrypt_inplace_) {
output_descriptor_.buffer.clear.address = encrypted_buffer_.data();
} else {
@@ -1940,16 +1907,58 @@ class OEMCryptoSessionTestsDecryptTests
output_descriptor_.buffer.clear.address = clear_buffer_.data();
}
output_descriptor_.buffer.clear.address_length = total_size_;
break;
case OEMCrypto_BufferType_Secure:
output_descriptor_.buffer.secure.handle_length = total_size_;
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_AllocateSecureBuffer(
session_.session_id(), total_size_, &output_descriptor_,
&secure_buffer_fid_));
ASSERT_NE(nullptr, output_descriptor_.buffer.secure.handle);
// It is OK if OEMCrypto changes the maximum size, but there must still
// be enough room for our data.
ASSERT_GE(output_descriptor_.buffer.secure.handle_length, total_size_);
output_descriptor_.buffer.secure.offset = 0;
break;
case OEMCrypto_BufferType_Direct:
output_descriptor_.buffer.direct.is_video = false;
break;
default:
ASSERT_TRUE(false) << "Invalid buffer type.";
}
}
void UpdateOutputOffset(size_t offset) {
switch (output_descriptor_.type) {
case OEMCrypto_BufferType_Clear:
if (decrypt_inplace_) {
output_descriptor_.buffer.clear.address =
encrypted_buffer_.data() + offset;
} else {
output_descriptor_.buffer.clear.address = clear_buffer_.data() + offset;
output_descriptor_.buffer.clear.address =
clear_buffer_.data() + offset;
}
output_descriptor_.buffer.clear.address_length = total_size_ - offset;
break;
case OEMCrypto_BufferType_Secure:
ASSERT_NE(nullptr, output_descriptor_.buffer.secure.handle);
ASSERT_GE(output_descriptor_.buffer.secure.handle_length, total_size_);
output_descriptor_.buffer.secure.offset = offset;
break;
case OEMCrypto_BufferType_Direct:
break;
default:
ASSERT_TRUE(false) << "Invalid buffer type.";
}
}
void FreeBuffers() {
if (output_descriptor_.type == OEMCrypto_BufferType_Secure) {
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_FreeSecureBuffer(session_.session_id(), &output_descriptor_,
secure_buffer_fid_));
}
}
void EncryptData() {
@@ -2035,6 +2044,8 @@ class OEMCryptoSessionTestsDecryptTests
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_));
uint32_t control = 0;
if (verify_crc_) control |= kControlAllowHashVerification;
if (output_buffer_type_ == OEMCrypto_BufferType_Secure)
control |= kControlObserveDataPath | kControlDataPathSecure;
ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage(kDuration, control, 0));
memcpy(session_.license().keys[0].key_data, key_, sizeof(key_));
session_.license().keys[0].cipher_mode = cipher_mode_;
@@ -2130,6 +2141,7 @@ class OEMCryptoSessionTestsDecryptTests
OEMCrypto_CENCEncryptPatternDesc pattern_;
OEMCryptoCipherMode cipher_mode_;
bool decrypt_inplace_; // If true, input and output buffers are the same.
OEMCryptoBufferType output_buffer_type_;
vector<SampleSize> subsample_size_;
size_t total_size_;
bool verify_crc_;
@@ -2137,9 +2149,9 @@ class OEMCryptoSessionTestsDecryptTests
// Encrypted data -- this is input to OEMCrypto, and output from EncryptData.
std::vector<uint8_t> encrypted_buffer_;
std::vector<uint8_t> clear_buffer_; // OEMCrypto store clear output here.
void* secure_handle_; // OEMCrypto stores secure output here.
std::vector<uint8_t> truth_buffer_; // Truth data for clear text.
OEMCrypto_DestBufferDesc output_descriptor_;
int secure_buffer_fid_;
uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key.
std::vector<uint8_t> starting_iv_; // Starting IV.
Session session_;
@@ -2156,8 +2168,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) {
// full patterns if we have more than 320 -- round up to 400.
subsample_size_.push_back(SampleSize(0, 400));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2169,8 +2181,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) {
TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
subsample_size_.push_back(SampleSize(0, 160 + 16));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2179,8 +2191,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) {
subsample_size_.push_back(SampleSize(0, 16));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2193,8 +2205,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, NoOffset) {
subsample_size_.push_back(SampleSize(50, 256));
subsample_size_.push_back(SampleSize(25, 160));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2209,8 +2221,8 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, EvenOffset) {
subsample_size_.push_back(SampleSize(25, 32));
subsample_size_.push_back(SampleSize(25, 50));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
// CTR Mode is self-inverse -- i.e. We can pick the encrypted data and
// compute the unencrypted data. By picking the encrypted data to be all 0,
// it is easier to re-encrypt the data and debug problems. Similarly, we
@@ -2237,8 +2249,8 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, OddOffset) {
subsample_size_.push_back(SampleSize(10, 75));
subsample_size_.push_back(SampleSize(10, 25));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2257,8 +2269,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) {
starting_iv_ = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE");
subsample_size_.push_back(SampleSize(0, 256));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2272,8 +2284,8 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, PartialBlock) {
// other tests, e.g. (7, 3). 3*16 < 50 and 7*16 > 50.
subsample_size_.push_back(SampleSize(0, 50));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2292,8 +2304,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSample) {
subsample_size_.push_back(SampleSize(0, max_subsample_size));
}
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2304,8 +2316,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) {
subsample_size_.push_back(SampleSize(max_subsample_size, 0));
subsample_size_.push_back(SampleSize(0, max_subsample_size));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2314,8 +2326,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) {
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
subsample_size_.push_back(SampleSize(5, 5));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2325,8 +2337,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) {
subsample_size_.push_back(SampleSize(256, 0));
FindTotalSize();
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(LoadLicense());
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
ASSERT_NO_FATAL_FAILURE(EncryptData());
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
@@ -2354,47 +2366,41 @@ OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt, size_t skip) {
return pattern;
}
INSTANTIATE_TEST_CASE_P(CTRTests, OEMCryptoSessionTestsPartialBlockTests,
Combine(Values(MakePattern(0,0)),
Values(OEMCrypto_CipherMode_CTR),
Bool()));
INSTANTIATE_TEST_CASE_P(
CTRTests, OEMCryptoSessionTestsPartialBlockTests,
Combine(Values(MakePattern(0, 0)), Values(OEMCrypto_CipherMode_CTR),
::testing::ValuesIn(global_features.GetOutputTypes())));
// Decrypt in place for CBC tests was only required in v13.
INSTANTIATE_TEST_CASE_P(
CBCTestsAPI14, OEMCryptoSessionTestsPartialBlockTests,
Combine(
Values(MakePattern(0, 0),
MakePattern(3, 7),
Values(MakePattern(0, 0), MakePattern(3, 7),
// HLS Edge case. We should follow the CENC spec, not HLS spec.
MakePattern(9, 1),
MakePattern(1, 9),
MakePattern(1, 3),
MakePattern(9, 1), MakePattern(1, 9), MakePattern(1, 3),
MakePattern(2, 1)),
Values(OEMCrypto_CipherMode_CBC), Bool()));
Values(OEMCrypto_CipherMode_CBC),
::testing::ValuesIn(global_features.GetOutputTypes())));
INSTANTIATE_TEST_CASE_P(
CTRTestsAPI11, OEMCryptoSessionTestsDecryptTests,
Combine(
Values(MakePattern(0, 0),
MakePattern(3, 7),
Combine(Values(MakePattern(0, 0), MakePattern(3, 7),
// Pattern length should be 10, but that is not guaranteed.
MakePattern(1, 3),
MakePattern(2, 1)),
Values(OEMCrypto_CipherMode_CTR), Bool()));
MakePattern(1, 3), MakePattern(2, 1)),
Values(OEMCrypto_CipherMode_CTR),
::testing::ValuesIn(global_features.GetOutputTypes())));
// Decrypt in place for CBC tests was only required in v13.
INSTANTIATE_TEST_CASE_P(
CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests,
Combine(
Values(MakePattern(0, 0),
MakePattern(3, 7),
Values(MakePattern(0, 0), MakePattern(3, 7),
// HLS Edge case. We should follow the CENC spec, not HLS spec.
MakePattern(9, 1),
MakePattern(1, 9),
MakePattern(9, 1), MakePattern(1, 9),
// Pattern length should be 10, but that is not guaranteed.
MakePattern(1, 3),
MakePattern(2, 1)),
Values(OEMCrypto_CipherMode_CBC), Bool()));
MakePattern(1, 3), MakePattern(2, 1)),
Values(OEMCrypto_CipherMode_CBC),
::testing::ValuesIn(global_features.GetOutputTypes())));
// A request to decrypt data to a clear buffer when the key control block
// requires a secure data path.
@@ -5171,7 +5177,7 @@ TEST_P(OEMCryptoUsageTableTestWithMAC, OfflineLicenseRefresh) {
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(
s.GenerateVerifyReport(pst, kActive,
loaded, // license recieved.
loaded, // license received.
loaded, // First decrypt when loaded, not refresh.
0)); // last decrypt now.
}

View File

@@ -17,9 +17,7 @@ static void acknowledge_cast() {
// because we need to initialize the list of features supported by the device.
// Also, the test filter is updated based on the feature list.
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
bool is_cast_receiver = false;
bool force_load_test_keybox = false;
bool filter_tests = true;
int verbosity = 0;
// Skip the first element, which is the program name.
@@ -32,7 +30,8 @@ int main(int argc, char** argv) {
is_cast_receiver = true;
}
if (arg == "--force_load_test_keybox") {
force_load_test_keybox = true;
std::cerr << "The argument --force_load_test_keybox is obsolete.\n";
return 1;
}
if (arg == "--no_filter") {
filter_tests = false;
@@ -42,7 +41,10 @@ int main(int argc, char** argv) {
}
}
wvcdm::g_cutoff = static_cast<wvcdm::LogPriority>(verbosity);
wvoec::global_features.Initialize(is_cast_receiver, force_load_test_keybox);
wvoec::global_features.Initialize();
wvoec::global_features.set_cast_receiver(is_cast_receiver);
// Init GTest after device properties has been initialized.
::testing::InitGoogleTest(&argc, argv);
// If the user requests --no_filter, we don't change the filter, otherwise, we
// filter out features that are not supported.
if (filter_tests) {