Source release 18.1.0

This commit is contained in:
John "Juce" Bruce
2023-06-23 15:45:08 -07:00
parent 2baa7c6e2b
commit b2c35151ad
2074 changed files with 196004 additions and 427059 deletions

View File

@@ -7,6 +7,7 @@
#include <openssl/aes.h>
#include <openssl/bio.h>
#include <openssl/cmac.h>
#include <openssl/hmac.h>
#include <stdlib.h>
#include <chrono>
@@ -163,24 +164,22 @@ void WvCdmTestBase::StripeBuffer(std::vector<uint8_t>* buffer, size_t size,
std::string WvCdmTestBase::Aes128CbcEncrypt(std::vector<uint8_t> key,
const std::vector<uint8_t>& clear,
const std::vector<uint8_t> iv) {
std::vector<uint8_t> iv) {
std::vector<uint8_t> encrypted(clear.size());
std::vector<uint8_t> iv_mod(iv.begin(), iv.end());
AES_KEY aes_key;
AES_set_encrypt_key(&key[0], 128, &aes_key);
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0],
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0],
AES_ENCRYPT);
return std::string(encrypted.begin(), encrypted.end());
}
std::string WvCdmTestBase::Aes128CbcDecrypt(std::vector<uint8_t> key,
const std::vector<uint8_t>& clear,
const std::vector<uint8_t> iv) {
std::vector<uint8_t> iv) {
std::vector<uint8_t> encrypted(clear.size());
std::vector<uint8_t> iv_mod(iv.begin(), iv.end());
AES_KEY aes_key;
AES_set_decrypt_key(&key[0], 128, &aes_key);
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv_mod[0],
AES_cbc_encrypt(&clear[0], &encrypted[0], clear.size(), &aes_key, &iv[0],
AES_DECRYPT);
return std::string(encrypted.begin(), encrypted.end());
}
@@ -198,15 +197,33 @@ std::string WvCdmTestBase::SignHMAC(const std::string& message,
TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics)
: CryptoSession(crypto_metrics) {
// The first CryptoSession should have initialized OEMCrypto. This is right
// after that, so we should tell oemcrypto to use a test keybox.
if (session_count() == 1) {
MaybeInstallTestKeybox();
}
TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics,
const TestCryptoSessionConfig* config)
: CryptoSession(crypto_metrics), config_(config) {
MaybeInstallTestKeybox();
}
void TestCryptoSession::MaybeInstallTestKeybox() {
if (IsTestKeyboxNeeded()) {
CryptoSession::SetAllowTestKeybox(true);
ReinitializeForTest();
WvCdmTestBase::InstallTestRootOfTrust();
}
}
bool TestCryptoSession::IsTestKeyboxNeeded() {
// The first CryptoSession should have initialized OEMCrypto. This is right
// after that.
if (session_count() != 1) return false;
// If config is not available, assume keybox is required.
if (config_ == nullptr) return true;
// Unless disabled, test keybox is required.
return !config_->disable_test_keybox;
}
CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) {
CdmResponseType status = CryptoSession::GenerateNonce(nonce);
for (int i = 0; status != NO_ERROR; i++) {
@@ -215,10 +232,11 @@ CdmResponseType TestCryptoSession::GenerateNonce(uint32_t* nonce) {
wvutil::TestSleep::Sleep(1);
status = CryptoSession::GenerateNonce(nonce);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
class TestCryptoSessionFactory : public CryptoSessionFactory {
public:
CryptoSession* MakeCryptoSession(
metrics::CryptoMetrics* crypto_metrics) override {
// We need to add extra locking here because we need to make sure that there
@@ -228,9 +246,18 @@ class TestCryptoSessionFactory : public CryptoSessionFactory {
// InstallTestRootOfTrust is only called in the constructor of the
// TestCryptoSession, above.
std::unique_lock<std::mutex> auto_lock(init_lock_);
return new TestCryptoSession(crypto_metrics);
return new TestCryptoSession(crypto_metrics, &session_config_);
}
void SetDisableTestKeybox(bool disable) {
std::unique_lock<std::mutex> auto_lock(init_lock_);
session_config_.disable_test_keybox = disable;
}
private:
std::mutex init_lock_;
// Shared with all TestCryptoSession instances created by this factory.
TestCryptoSessionConfig session_config_;
};
void WvCdmTestBase::SetUp() {
@@ -250,7 +277,13 @@ void WvCdmTestBase::SetUp() {
std::string(test_info->test_case_name()) + "." + test_info->name();
int overwrite = 1; // Set value even if already set.
setenv("MODEL_NAME", model_name.c_str(), overwrite);
CryptoSession::SetCryptoSessionFactory(new TestCryptoSessionFactory());
TestCryptoSessionFactory* factory = new TestCryptoSessionFactory();
CryptoSession::SetCryptoSessionFactory(factory);
const char* const disable_test_keybox_flag = getenv("DISABLE_TEST_KEYBOX");
if (disable_test_keybox_flag != nullptr &&
strcmp(disable_test_keybox_flag, "yes") == 0) {
factory->SetDisableTestKeybox(true);
}
// TODO(fredgc): Add a test version of DeviceFiles.
}
@@ -291,15 +324,11 @@ void WvCdmTestBase::Provision() {
const CdmCertificateType cert_type = kCertificateWidevine;
std::unique_ptr<wvutil::FileSystem> file_system(CreateTestFileSystem());
TestCdmEngine cdm_engine(file_system.get(),
std::shared_ptr<EngineMetrics>(new EngineMetrics));
std::make_shared<EngineMetrics>());
ProvisioningHolder provisioner(&cdm_engine, config_);
provisioner.Provision(cert_type, binary_provisioning_);
}
// TODO(fredgc): Replace this with a pre-defined DRM certificate. We could do
// that because either the device is using a known test keybox with a known
// device key, or the device is using an OEM certificate, and we can extract
// that certificate from the provisioning request.
void WvCdmTestBase::EnsureProvisioned() {
CdmSessionId session_id;
std::unique_ptr<wvutil::FileSystem> file_system(CreateTestFileSystem());
@@ -307,7 +336,7 @@ void WvCdmTestBase::EnsureProvisioned() {
// GenerateKeyRequest will actually load the wrapped private key.
// Either may return a NEED_PROVISIONING error, so both have to be checked.
TestCdmEngine cdm_engine(file_system.get(),
std::shared_ptr<EngineMetrics>(new EngineMetrics));
std::make_shared<EngineMetrics>());
CdmResponseType status = cdm_engine.OpenSession(config_.key_system(), nullptr,
nullptr, &session_id);
CdmAppParameterMap app_parameters;
@@ -339,6 +368,36 @@ void WvCdmTestBase::EnsureProvisioned() {
ASSERT_EQ(NO_ERROR, cdm_engine.CloseSession(session_id));
}
bool WvCdmTestBase::ExtractSignedMessage(const std::string& response,
std::string* result) {
static const std::string kMessageStart = "\"signedResponse\": \"";
static const std::string kMessageEnd = "\"";
std::string response_string;
size_t start = response.find(kMessageStart);
if (start == response.npos) {
// Assume serialized protobuf message.
result->assign(response);
} else {
// Assume JSON-wrapped protobuf.
size_t end = response.find(kMessageEnd, start + kMessageStart.length());
if (end == response.npos) {
LOGE("ExtractSignedMessage cannot locate end substring");
result->clear();
return false;
}
size_t result_string_size = end - start - kMessageStart.length();
result->assign(response, start + kMessageStart.length(),
result_string_size);
}
if (result->empty()) {
LOGE("ExtractSignedMessage: Response message is empty");
return false;
}
return true;
}
bool WvCdmTestBase::Initialize(int argc, const char* const argv[],
const std::string& extra_help_text) {
Properties::Init();
@@ -457,7 +516,13 @@ bool WvCdmTestBase::Initialize(int argc, const char* const argv[],
// Figure out which tests are appropriate for OEMCrypto, based on features
// supported.
wvoec::global_features.Initialize();
wvoec::global_features.set_cast_receiver(is_cast_receiver);
if (is_cast_receiver) {
// Turn it on if passed in on the command line. Do not turn these tests off
// automtically -- instead, we'll let the caller filter them out if they
// need to. These tests will normally only run if the device claims to
// support being a cast receiver.
wvoec::global_features.set_cast_receiver(is_cast_receiver);
}
// If the user requests --no_filter, we don't change the filter, otherwise, we
// filter out features that are not supported.
if (filter_tests) {