Provisioning Unit Tests
This commit is contained in:
@@ -4902,7 +4902,7 @@ OEMCryptoResult OEMCrypto_AllocateSecureBuffer(
|
|||||||
* [in] secure_fd: The integer returned by OEMCrypto_AllocateSecureBuffer
|
* [in] secure_fd: The integer returned by OEMCrypto_AllocateSecureBuffer
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* OEMCrypto_SUCCESS - if the buffer was created
|
* OEMCrypto_SUCCESS - if the buffer was freed
|
||||||
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
* OEMCrypto_ERROR_NOT_IMPLEMENTED
|
||||||
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
* OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignLicenseRequest(
|
|||||||
}
|
}
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("ERROR_INVALID_SESSION");
|
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
return session_ctx->PrepAndSignLicenseRequest(message, message_length,
|
return session_ctx->PrepAndSignLicenseRequest(message, message_length,
|
||||||
@@ -233,7 +233,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignRenewalRequest(
|
|||||||
}
|
}
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("ERROR_INVALID_SESSION");
|
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
return session_ctx->PrepAndSignRenewalRequest(message, message_length,
|
return session_ctx->PrepAndSignRenewalRequest(message, message_length,
|
||||||
@@ -250,7 +250,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_PrepAndSignProvisioningRequest(
|
|||||||
}
|
}
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("ERROR_INVALID_SESSION");
|
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
return session_ctx->PrepAndSignProvisioningRequest(
|
return session_ctx->PrepAndSignProvisioningRequest(
|
||||||
@@ -698,7 +698,7 @@ OEMCrypto_LoadOEMPrivateKey(OEMCrypto_SESSION session) {
|
|||||||
}
|
}
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("ERROR_INVALID_SESSION");
|
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
return crypto_engine->load_oem_private_key(session_ctx);
|
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.
|
// 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,
|
OEMCrypto_SESSION session, const uint32_t* unaligned_nonce,
|
||||||
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length,
|
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length,
|
||||||
const uint8_t* enc_rsa_key, size_t enc_rsa_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.
|
// 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,
|
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||||
const uint8_t* signature, size_t signature_length,
|
const uint8_t* signature, size_t signature_length,
|
||||||
const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key,
|
const uint32_t* unaligned_nonce, const uint8_t* enc_rsa_key,
|
||||||
@@ -1023,22 +1023,18 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadProvisioning(
|
|||||||
LOGE("OEMCrypto Not Initialized");
|
LOGE("OEMCrypto Not Initialized");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
if (wrapped_private_key_length == nullptr) {
|
if (wrapped_private_key_length == nullptr || message == nullptr ||
|
||||||
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
message_length == 0 || signature == nullptr || signature_length == 0) {
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
||||||
}
|
|
||||||
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
|
||||||
signature_length == 0) {
|
|
||||||
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
if (!crypto_engine->ValidRootOfTrust()) {
|
if (!crypto_engine->ValidRootOfTrust()) {
|
||||||
LOGE("ERROR_KEYBOX_INVALID");
|
LOGE("OEMCrypto_ERROR_KEYBOX_INVALID");
|
||||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
||||||
}
|
}
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("ERROR_INVALID_SESSION");
|
LOGE("OEMCrypto_ERROR_INVALID_SESSION");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
std::vector<uint8_t> device_id = crypto_engine->DeviceRootId();
|
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);
|
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
|
} // namespace wvoec_ref
|
||||||
|
|||||||
@@ -60,9 +60,8 @@ bool CanChangeTime() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceFeatures::Initialize(bool is_cast_receiver,
|
void DeviceFeatures::Initialize() {
|
||||||
bool force_load_test_keybox) {
|
if (initialized_) return;
|
||||||
cast_receiver = is_cast_receiver;
|
|
||||||
uses_keybox = false;
|
uses_keybox = false;
|
||||||
uses_certificate = false;
|
uses_certificate = false;
|
||||||
loads_certificate = false;
|
loads_certificate = false;
|
||||||
@@ -117,11 +116,7 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
|
|||||||
// usage tables.
|
// usage tables.
|
||||||
if (api_version > 12) usage_table = OEMCrypto_SupportsUsageTable();
|
if (api_version > 12) usage_table = OEMCrypto_SupportsUsageTable();
|
||||||
printf("usage_table = %s.\n", usage_table ? "true" : "false");
|
printf("usage_table = %s.\n", usage_table ? "true" : "false");
|
||||||
if (force_load_test_keybox) {
|
PickDerivedKey();
|
||||||
derive_key_method = FORCE_TEST_KEYBOX;
|
|
||||||
} else {
|
|
||||||
PickDerivedKey();
|
|
||||||
}
|
|
||||||
if (api_version >= 13) {
|
if (api_version >= 13) {
|
||||||
uint32_t supported_cert = OEMCrypto_SupportedCertificates();
|
uint32_t supported_cert = OEMCrypto_SupportedCertificates();
|
||||||
if (supported_cert & OEMCrypto_Supports_RSA_CAST) {
|
if (supported_cert & OEMCrypto_Supports_RSA_CAST) {
|
||||||
@@ -161,9 +156,6 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
|
|||||||
case LOAD_TEST_RSA_KEY:
|
case LOAD_TEST_RSA_KEY:
|
||||||
printf("LOAD_TEST_RSA_KEY: Call LoadTestRSAKey before deriving keys.\n");
|
printf("LOAD_TEST_RSA_KEY: Call LoadTestRSAKey before deriving keys.\n");
|
||||||
break;
|
break;
|
||||||
case FORCE_TEST_KEYBOX:
|
|
||||||
printf("FORCE_TEST_KEYBOX: User requested calling InstallKeybox.\n");
|
|
||||||
break;
|
|
||||||
case TEST_PROVISION_30:
|
case TEST_PROVISION_30:
|
||||||
printf("TEST_PROVISION_30: Device provisioed with OEM Cert.\n");
|
printf("TEST_PROVISION_30: Device provisioed with OEM Cert.\n");
|
||||||
break;
|
break;
|
||||||
@@ -173,15 +165,15 @@ void DeviceFeatures::Initialize(bool is_cast_receiver,
|
|||||||
printf("SecurityLevel is %s (%s)\n",
|
printf("SecurityLevel is %s (%s)\n",
|
||||||
supports_level_1 ? "Level 1" : "Not Level 1",
|
supports_level_1 ? "Level 1" : "Not Level 1",
|
||||||
security_level.c_str());
|
security_level.c_str());
|
||||||
|
CheckSecureBuffers();
|
||||||
OEMCrypto_Terminate();
|
OEMCrypto_Terminate();
|
||||||
|
initialized_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
|
std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
|
||||||
std::string filter = initial_filter;
|
std::string filter = initial_filter;
|
||||||
// clang-format off
|
// clang-format off
|
||||||
if (!uses_keybox) FilterOut(&filter, "*KeyboxTest*");
|
if (!uses_keybox) FilterOut(&filter, "*KeyboxTest*");
|
||||||
if (derive_key_method
|
|
||||||
!= FORCE_TEST_KEYBOX) FilterOut(&filter, "*ForceKeybox*");
|
|
||||||
if (!uses_certificate) FilterOut(&filter, "OEMCrypto*Cert*");
|
if (!uses_certificate) FilterOut(&filter, "OEMCrypto*Cert*");
|
||||||
if (!loads_certificate) FilterOut(&filter, "OEMCryptoLoadsCert*");
|
if (!loads_certificate) FilterOut(&filter, "OEMCryptoLoadsCert*");
|
||||||
if (!generic_crypto) FilterOut(&filter, "*GenericCrypto*");
|
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,
|
void DeviceFeatures::FilterOut(std::string* current_filter,
|
||||||
const std::string& new_filter) {
|
const std::string& new_filter) {
|
||||||
if (current_filter->find('-') == std::string::npos) {
|
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) {
|
const char* ProvisioningMethodName(OEMCrypto_ProvisioningMethod method) {
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case OEMCrypto_ProvisioningError:
|
case OEMCrypto_ProvisioningError:
|
||||||
|
|||||||
@@ -2,12 +2,21 @@
|
|||||||
#define CDM_OEC_DEVICE_FEATURES_H_
|
#define CDM_OEC_DEVICE_FEATURES_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "OEMCryptoCENC.h"
|
#include "OEMCryptoCENC.h"
|
||||||
#include "oemcrypto_types.h"
|
#include "oemcrypto_types.h"
|
||||||
|
|
||||||
namespace wvoec {
|
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
|
// Keeps track of which features are supported by the version of OEMCrypto being
|
||||||
// tested. See the integration guide for a list of optional features.
|
// tested. See the integration guide for a list of optional features.
|
||||||
class DeviceFeatures {
|
class DeviceFeatures {
|
||||||
@@ -19,7 +28,6 @@ class DeviceFeatures {
|
|||||||
NO_METHOD, // Cannot derive known session keys.
|
NO_METHOD, // Cannot derive known session keys.
|
||||||
LOAD_TEST_KEYBOX, // Call LoadTestKeybox before deriving keys.
|
LOAD_TEST_KEYBOX, // Call LoadTestKeybox before deriving keys.
|
||||||
LOAD_TEST_RSA_KEY, // Call LoadTestRSAKey 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.
|
TEST_PROVISION_30, // Device has OEM Certificate installed.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,23 +42,36 @@ class DeviceFeatures {
|
|||||||
bool supports_level_1; // Device supports Level 1 security.
|
bool supports_level_1; // Device supports Level 1 security.
|
||||||
uint32_t resource_rating; // Device's resource rating tier.
|
uint32_t resource_rating; // Device's resource rating tier.
|
||||||
bool supports_crc; // Supported decrypt hash type CRC.
|
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;
|
uint32_t api_version;
|
||||||
OEMCrypto_ProvisioningMethod provisioning_method;
|
OEMCrypto_ProvisioningMethod provisioning_method;
|
||||||
|
|
||||||
// This should be called from the test program's main procedure.
|
// 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
|
// 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
|
// called after Initialize. Tests are filtered out based on which features
|
||||||
// are not supported. For example, a device that uses Provisioning 3.0 will
|
// are not supported. For example, a device that uses Provisioning 3.0 will
|
||||||
// have all keybox tests filtered out.
|
// have all keybox tests filtered out.
|
||||||
std::string RestrictFilter(const std::string& initial_filter);
|
std::string RestrictFilter(const std::string& initial_filter);
|
||||||
|
|
||||||
|
// Get a list of output types that should be tested.
|
||||||
|
const std::vector<OutputType>& GetOutputTypes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Decide which method should be used to derive session keys, based on
|
// Decide which method should be used to derive session keys, based on
|
||||||
// supported featuers.
|
// supported featuers.
|
||||||
void PickDerivedKey();
|
void PickDerivedKey();
|
||||||
|
// Decide if secure buffers can be created, and initialize output_types_.
|
||||||
|
void CheckSecureBuffers();
|
||||||
// Add a GTest filter restriction to the current filter.
|
// Add a GTest filter restriction to the current filter.
|
||||||
void FilterOut(std::string* current_filter, const std::string& new_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
|
// There is one global set of features for the version of OEMCrypto being
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ class ProvisioningRoundTrip
|
|||||||
const std::vector<uint8_t>& encoded_rsa_key)
|
const std::vector<uint8_t>& encoded_rsa_key)
|
||||||
: RoundTrip(session),
|
: RoundTrip(session),
|
||||||
allowed_schemes_(kSign_RSASSA_PSS),
|
allowed_schemes_(kSign_RSASSA_PSS),
|
||||||
|
encryptor_(),
|
||||||
encoded_rsa_key_(encoded_rsa_key) {}
|
encoded_rsa_key_(encoded_rsa_key) {}
|
||||||
// Prepare the session for signing the request.
|
// Prepare the session for signing the request.
|
||||||
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);
|
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);
|
||||||
|
|||||||
@@ -60,10 +60,6 @@ void SessionUtil::EnsureTestKeys() {
|
|||||||
case DeviceFeatures::LOAD_TEST_RSA_KEY:
|
case DeviceFeatures::LOAD_TEST_RSA_KEY:
|
||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestRSAKey());
|
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestRSAKey());
|
||||||
break;
|
break;
|
||||||
case DeviceFeatures::FORCE_TEST_KEYBOX:
|
|
||||||
keybox_ = kTestKeybox;
|
|
||||||
InstallKeybox(keybox_, true);
|
|
||||||
break;
|
|
||||||
case DeviceFeatures::TEST_PROVISION_30:
|
case DeviceFeatures::TEST_PROVISION_30:
|
||||||
// Can use oem certificate to install test rsa key.
|
// Can use oem certificate to install test rsa key.
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -52,14 +52,31 @@ using namespace std;
|
|||||||
|
|
||||||
namespace std { // GTest wants PrintTo to be in the std namespace.
|
namespace std { // GTest wants PrintTo to be in the std namespace.
|
||||||
void PrintTo(const tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode,
|
void PrintTo(const tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode,
|
||||||
bool>& param,
|
wvoec::OutputType>& param,
|
||||||
ostream* os) {
|
ostream* os) {
|
||||||
OEMCrypto_CENCEncryptPatternDesc pattern = ::testing::get<0>(param);
|
OEMCrypto_CENCEncryptPatternDesc pattern = ::testing::get<0>(param);
|
||||||
OEMCryptoCipherMode mode = ::testing::get<1>(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")
|
*os << ((mode == OEMCrypto_CipherMode_CTR) ? "CTR mode" : "CBC mode")
|
||||||
<< ", encrypt=" << pattern.encrypt << ", skip=" << pattern.skip
|
<< ", pattern=(encrypt:" << pattern.encrypt << ", skip:" << pattern.skip
|
||||||
<< ", decrypt in place = " << (decrypt_inplace ? "true" : "false");
|
<< ")";
|
||||||
|
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
|
} // 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_;
|
vector<uint8_t> encrypted_usage_header_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -759,53 +769,6 @@ TEST_F(OEMCryptoSessionTestKeyboxTest, TestKeyboxIsValid) {
|
|||||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid());
|
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.
|
// Verify that a license may be signed.
|
||||||
TEST_F(OEMCryptoSessionTests, SignLicenseRequest) {
|
TEST_F(OEMCryptoSessionTests, SignLicenseRequest) {
|
||||||
Session s;
|
Session s;
|
||||||
@@ -1894,14 +1857,15 @@ struct SampleInitData {
|
|||||||
// buffers to be the same.
|
// buffers to be the same.
|
||||||
class OEMCryptoSessionTestsDecryptTests
|
class OEMCryptoSessionTestsDecryptTests
|
||||||
: public OEMCryptoSessionTests,
|
: public OEMCryptoSessionTests,
|
||||||
public WithParamInterface<
|
public WithParamInterface<tuple<OEMCrypto_CENCEncryptPatternDesc,
|
||||||
tuple<OEMCrypto_CENCEncryptPatternDesc, OEMCryptoCipherMode, bool> > {
|
OEMCryptoCipherMode, OutputType> > {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
OEMCryptoSessionTests::SetUp();
|
OEMCryptoSessionTests::SetUp();
|
||||||
pattern_ = ::testing::get<0>(GetParam());
|
pattern_ = ::testing::get<0>(GetParam());
|
||||||
cipher_mode_ = ::testing::get<1>(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;
|
verify_crc_ = global_features.supports_crc;
|
||||||
// Pick a random key.
|
// Pick a random key.
|
||||||
EXPECT_EQ(1, GetRandBytes(key_, AES_BLOCK_SIZE));
|
EXPECT_EQ(1, GetRandBytes(key_, AES_BLOCK_SIZE));
|
||||||
@@ -1912,6 +1876,7 @@ class OEMCryptoSessionTestsDecryptTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TearDown() override {
|
void TearDown() override {
|
||||||
|
FreeBuffers();
|
||||||
ASSERT_NO_FATAL_FAILURE(session_.close());
|
ASSERT_NO_FATAL_FAILURE(session_.close());
|
||||||
OEMCryptoSessionTests::TearDown();
|
OEMCryptoSessionTests::TearDown();
|
||||||
}
|
}
|
||||||
@@ -1924,32 +1889,76 @@ 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().
|
// This should be called after FindTotalSize().
|
||||||
void MakeBuffers() {
|
void MakeBuffers() {
|
||||||
ASSERT_GT(total_size_, 0u);
|
ASSERT_GT(total_size_, 0u);
|
||||||
encrypted_buffer_.resize(total_size_);
|
encrypted_buffer_.resize(total_size_);
|
||||||
truth_buffer_.resize(total_size_);
|
truth_buffer_.resize(total_size_);
|
||||||
for (size_t i = 0; i < total_size_; i++) truth_buffer_[i] = i % 256;
|
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_;
|
||||||
if (decrypt_inplace_) {
|
switch (output_descriptor_.type) {
|
||||||
output_descriptor_.buffer.clear.address = encrypted_buffer_.data();
|
case OEMCrypto_BufferType_Clear:
|
||||||
} else {
|
if (decrypt_inplace_) {
|
||||||
// Add some padding to verify there is no overrun.
|
output_descriptor_.buffer.clear.address = encrypted_buffer_.data();
|
||||||
clear_buffer_.resize(total_size_ + 16, 0xaa);
|
} else {
|
||||||
output_descriptor_.buffer.clear.address = clear_buffer_.data();
|
// Add some padding to verify there is no overrun.
|
||||||
|
clear_buffer_.resize(total_size_ + 16, 0xaa);
|
||||||
|
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.";
|
||||||
}
|
}
|
||||||
output_descriptor_.buffer.clear.address_length = total_size_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateOutputOffset(size_t offset) {
|
void UpdateOutputOffset(size_t offset) {
|
||||||
if (decrypt_inplace_) {
|
switch (output_descriptor_.type) {
|
||||||
output_descriptor_.buffer.clear.address =
|
case OEMCrypto_BufferType_Clear:
|
||||||
encrypted_buffer_.data() + offset;
|
if (decrypt_inplace_) {
|
||||||
} else {
|
output_descriptor_.buffer.clear.address =
|
||||||
output_descriptor_.buffer.clear.address = clear_buffer_.data() + offset;
|
encrypted_buffer_.data() + offset;
|
||||||
|
} else {
|
||||||
|
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_));
|
||||||
}
|
}
|
||||||
output_descriptor_.buffer.clear.address_length = total_size_ - offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncryptData() {
|
void EncryptData() {
|
||||||
@@ -2035,6 +2044,8 @@ class OEMCryptoSessionTestsDecryptTests
|
|||||||
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_));
|
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session_));
|
||||||
uint32_t control = 0;
|
uint32_t control = 0;
|
||||||
if (verify_crc_) control |= kControlAllowHashVerification;
|
if (verify_crc_) control |= kControlAllowHashVerification;
|
||||||
|
if (output_buffer_type_ == OEMCrypto_BufferType_Secure)
|
||||||
|
control |= kControlObserveDataPath | kControlDataPathSecure;
|
||||||
ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage(kDuration, control, 0));
|
ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage(kDuration, control, 0));
|
||||||
memcpy(session_.license().keys[0].key_data, key_, sizeof(key_));
|
memcpy(session_.license().keys[0].key_data, key_, sizeof(key_));
|
||||||
session_.license().keys[0].cipher_mode = cipher_mode_;
|
session_.license().keys[0].cipher_mode = cipher_mode_;
|
||||||
@@ -2130,6 +2141,7 @@ class OEMCryptoSessionTestsDecryptTests
|
|||||||
OEMCrypto_CENCEncryptPatternDesc pattern_;
|
OEMCrypto_CENCEncryptPatternDesc pattern_;
|
||||||
OEMCryptoCipherMode cipher_mode_;
|
OEMCryptoCipherMode cipher_mode_;
|
||||||
bool decrypt_inplace_; // If true, input and output buffers are the same.
|
bool decrypt_inplace_; // If true, input and output buffers are the same.
|
||||||
|
OEMCryptoBufferType output_buffer_type_;
|
||||||
vector<SampleSize> subsample_size_;
|
vector<SampleSize> subsample_size_;
|
||||||
size_t total_size_;
|
size_t total_size_;
|
||||||
bool verify_crc_;
|
bool verify_crc_;
|
||||||
@@ -2137,9 +2149,9 @@ class OEMCryptoSessionTestsDecryptTests
|
|||||||
// Encrypted data -- this is input to OEMCrypto, and output from EncryptData.
|
// Encrypted data -- this is input to OEMCrypto, and output from EncryptData.
|
||||||
std::vector<uint8_t> encrypted_buffer_;
|
std::vector<uint8_t> encrypted_buffer_;
|
||||||
std::vector<uint8_t> clear_buffer_; // OEMCrypto store clear output here.
|
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.
|
std::vector<uint8_t> truth_buffer_; // Truth data for clear text.
|
||||||
OEMCrypto_DestBufferDesc output_descriptor_;
|
OEMCrypto_DestBufferDesc output_descriptor_;
|
||||||
|
int secure_buffer_fid_;
|
||||||
uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key.
|
uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key.
|
||||||
std::vector<uint8_t> starting_iv_; // Starting IV.
|
std::vector<uint8_t> starting_iv_; // Starting IV.
|
||||||
Session session_;
|
Session session_;
|
||||||
@@ -2156,8 +2168,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) {
|
|||||||
// full patterns if we have more than 320 -- round up to 400.
|
// full patterns if we have more than 320 -- round up to 400.
|
||||||
subsample_size_.push_back(SampleSize(0, 400));
|
subsample_size_.push_back(SampleSize(0, 400));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2169,8 +2181,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) {
|
|||||||
TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
|
TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
|
||||||
subsample_size_.push_back(SampleSize(0, 160 + 16));
|
subsample_size_.push_back(SampleSize(0, 160 + 16));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2179,8 +2191,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
|
|||||||
TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) {
|
TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) {
|
||||||
subsample_size_.push_back(SampleSize(0, 16));
|
subsample_size_.push_back(SampleSize(0, 16));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
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(50, 256));
|
||||||
subsample_size_.push_back(SampleSize(25, 160));
|
subsample_size_.push_back(SampleSize(25, 160));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
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, 32));
|
||||||
subsample_size_.push_back(SampleSize(25, 50));
|
subsample_size_.push_back(SampleSize(25, 50));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
// CTR Mode is self-inverse -- i.e. We can pick the encrypted data and
|
// 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,
|
// 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
|
// 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, 75));
|
||||||
subsample_size_.push_back(SampleSize(10, 25));
|
subsample_size_.push_back(SampleSize(10, 25));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2257,8 +2269,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) {
|
|||||||
starting_iv_ = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE");
|
starting_iv_ = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE");
|
||||||
subsample_size_.push_back(SampleSize(0, 256));
|
subsample_size_.push_back(SampleSize(0, 256));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
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.
|
// other tests, e.g. (7, 3). 3*16 < 50 and 7*16 > 50.
|
||||||
subsample_size_.push_back(SampleSize(0, 50));
|
subsample_size_.push_back(SampleSize(0, 50));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2292,8 +2304,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSample) {
|
|||||||
subsample_size_.push_back(SampleSize(0, max_subsample_size));
|
subsample_size_.push_back(SampleSize(0, max_subsample_size));
|
||||||
}
|
}
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
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(max_subsample_size, 0));
|
||||||
subsample_size_.push_back(SampleSize(0, max_subsample_size));
|
subsample_size_.push_back(SampleSize(0, max_subsample_size));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2314,8 +2326,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) {
|
|||||||
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
|
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
|
||||||
subsample_size_.push_back(SampleSize(5, 5));
|
subsample_size_.push_back(SampleSize(5, 5));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2325,8 +2337,8 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) {
|
|||||||
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) {
|
TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) {
|
||||||
subsample_size_.push_back(SampleSize(256, 0));
|
subsample_size_.push_back(SampleSize(256, 0));
|
||||||
FindTotalSize();
|
FindTotalSize();
|
||||||
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
|
||||||
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
ASSERT_NO_FATAL_FAILURE(LoadLicense());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(MakeBuffers());
|
||||||
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
ASSERT_NO_FATAL_FAILURE(EncryptData());
|
||||||
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
|
||||||
}
|
}
|
||||||
@@ -2354,47 +2366,41 @@ OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt, size_t skip) {
|
|||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(CTRTests, OEMCryptoSessionTestsPartialBlockTests,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
Combine(Values(MakePattern(0,0)),
|
CTRTests, OEMCryptoSessionTestsPartialBlockTests,
|
||||||
Values(OEMCrypto_CipherMode_CTR),
|
Combine(Values(MakePattern(0, 0)), Values(OEMCrypto_CipherMode_CTR),
|
||||||
Bool()));
|
::testing::ValuesIn(global_features.GetOutputTypes())));
|
||||||
|
|
||||||
// Decrypt in place for CBC tests was only required in v13.
|
// Decrypt in place for CBC tests was only required in v13.
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
CBCTestsAPI14, OEMCryptoSessionTestsPartialBlockTests,
|
CBCTestsAPI14, OEMCryptoSessionTestsPartialBlockTests,
|
||||||
Combine(
|
Combine(
|
||||||
Values(MakePattern(0, 0),
|
Values(MakePattern(0, 0), MakePattern(3, 7),
|
||||||
MakePattern(3, 7),
|
|
||||||
// HLS Edge case. We should follow the CENC spec, not HLS spec.
|
// HLS Edge case. We should follow the CENC spec, not HLS spec.
|
||||||
MakePattern(9, 1),
|
MakePattern(9, 1), MakePattern(1, 9), MakePattern(1, 3),
|
||||||
MakePattern(1, 9),
|
|
||||||
MakePattern(1, 3),
|
|
||||||
MakePattern(2, 1)),
|
MakePattern(2, 1)),
|
||||||
Values(OEMCrypto_CipherMode_CBC), Bool()));
|
Values(OEMCrypto_CipherMode_CBC),
|
||||||
|
::testing::ValuesIn(global_features.GetOutputTypes())));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
CTRTestsAPI11, OEMCryptoSessionTestsDecryptTests,
|
CTRTestsAPI11, OEMCryptoSessionTestsDecryptTests,
|
||||||
Combine(
|
Combine(Values(MakePattern(0, 0), MakePattern(3, 7),
|
||||||
Values(MakePattern(0, 0),
|
// Pattern length should be 10, but that is not guaranteed.
|
||||||
MakePattern(3, 7),
|
MakePattern(1, 3), MakePattern(2, 1)),
|
||||||
// Pattern length should be 10, but that is not guaranteed.
|
Values(OEMCrypto_CipherMode_CTR),
|
||||||
MakePattern(1, 3),
|
::testing::ValuesIn(global_features.GetOutputTypes())));
|
||||||
MakePattern(2, 1)),
|
|
||||||
Values(OEMCrypto_CipherMode_CTR), Bool()));
|
|
||||||
|
|
||||||
// Decrypt in place for CBC tests was only required in v13.
|
// Decrypt in place for CBC tests was only required in v13.
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests,
|
CBCTestsAPI14, OEMCryptoSessionTestsDecryptTests,
|
||||||
Combine(
|
Combine(
|
||||||
Values(MakePattern(0, 0),
|
Values(MakePattern(0, 0), MakePattern(3, 7),
|
||||||
MakePattern(3, 7),
|
|
||||||
// HLS Edge case. We should follow the CENC spec, not HLS spec.
|
// HLS Edge case. We should follow the CENC spec, not HLS spec.
|
||||||
MakePattern(9, 1),
|
MakePattern(9, 1), MakePattern(1, 9),
|
||||||
MakePattern(1, 9),
|
|
||||||
// Pattern length should be 10, but that is not guaranteed.
|
// Pattern length should be 10, but that is not guaranteed.
|
||||||
MakePattern(1, 3),
|
MakePattern(1, 3), MakePattern(2, 1)),
|
||||||
MakePattern(2, 1)),
|
Values(OEMCrypto_CipherMode_CBC),
|
||||||
Values(OEMCrypto_CipherMode_CBC), Bool()));
|
::testing::ValuesIn(global_features.GetOutputTypes())));
|
||||||
|
|
||||||
// A request to decrypt data to a clear buffer when the key control block
|
// A request to decrypt data to a clear buffer when the key control block
|
||||||
// requires a secure data path.
|
// 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.UpdateUsageEntry(&encrypted_usage_header_));
|
||||||
ASSERT_NO_FATAL_FAILURE(
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
s.GenerateVerifyReport(pst, kActive,
|
s.GenerateVerifyReport(pst, kActive,
|
||||||
loaded, // license recieved.
|
loaded, // license received.
|
||||||
loaded, // First decrypt when loaded, not refresh.
|
loaded, // First decrypt when loaded, not refresh.
|
||||||
0)); // last decrypt now.
|
0)); // last decrypt now.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ static void acknowledge_cast() {
|
|||||||
// because we need to initialize the list of features supported by the device.
|
// because we need to initialize the list of features supported by the device.
|
||||||
// Also, the test filter is updated based on the feature list.
|
// Also, the test filter is updated based on the feature list.
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
bool is_cast_receiver = false;
|
bool is_cast_receiver = false;
|
||||||
bool force_load_test_keybox = false;
|
|
||||||
bool filter_tests = true;
|
bool filter_tests = true;
|
||||||
int verbosity = 0;
|
int verbosity = 0;
|
||||||
// Skip the first element, which is the program name.
|
// Skip the first element, which is the program name.
|
||||||
@@ -32,7 +30,8 @@ int main(int argc, char** argv) {
|
|||||||
is_cast_receiver = true;
|
is_cast_receiver = true;
|
||||||
}
|
}
|
||||||
if (arg == "--force_load_test_keybox") {
|
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") {
|
if (arg == "--no_filter") {
|
||||||
filter_tests = false;
|
filter_tests = false;
|
||||||
@@ -42,7 +41,10 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
wvcdm::g_cutoff = static_cast<wvcdm::LogPriority>(verbosity);
|
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
|
// If the user requests --no_filter, we don't change the filter, otherwise, we
|
||||||
// filter out features that are not supported.
|
// filter out features that are not supported.
|
||||||
if (filter_tests) {
|
if (filter_tests) {
|
||||||
|
|||||||
Reference in New Issue
Block a user