Merge oemcrypto buffer overflow tests from cdm
Widevine CLs: http://go/wvgerrit/112243 http://go/wvgerrit/110563 http://go/wvgerrit/95483 http://go/wvgerrit/107047 http://go/wvgerrit/111123 http://go/wvgerrit/106224 http://go/wvgerrit/106263 http://go/wvgerrit/106223 http://go/wvgerrit/104223 http://go/wvgerrit/108583 http://go/wvgerrit/111403 http://go/wvgerrit/111623 http://go/wvgerrit/106264 http://go/wvgerrit/110483 http://go/wvgerrit/111944 http://go/wvgerrit/108684 http://go/wvgerrit/104183 http://go/wvgerrit/111443 http://go/wvgerrit/111869 http://go/wvgerrit/108843 http://go/wvgerrit/104363 http://go/wvgerrit/104423 http://go/wvgerrit/104263 http://go/wvgerrit/106584 http://go/wvgerrit/105924 http://go/wvgerrit/104524 http://go/wvgerrit/113023 Bug:175401639 Test: We would like to run these tests on pixel devices from master branch using go/wv-and-dash Change-Id: Ic4188504af64de9ce79941f75ac6feaf29189a4d
This commit is contained in:
@@ -104,17 +104,13 @@
|
|||||||
oemcrypto_fuzztests.gypi cflags_cc in order to generate additional debug
|
oemcrypto_fuzztests.gypi cflags_cc in order to generate additional debug
|
||||||
information locally.
|
information locally.
|
||||||
|
|
||||||
* Build and test fuzz scripts locally using:
|
* Build and test fuzz scripts locally using following commands. The build
|
||||||
|
script builds fuzz binaries for both oemcrypto reference implementation
|
||||||
|
as well as odkitee implementation.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ export CXX=clang++
|
$ cd PATH_TO_CDM_DIR
|
||||||
$ export CC=clang
|
$ ./oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests
|
||||||
$ export GYP_DEFINES="clang=1"
|
|
||||||
$ cd /path/to/cdm/repo
|
|
||||||
$ export PATH_TO_CDM_DIR=.
|
|
||||||
$ gyp --format=ninja --depth=$(pwd) \
|
|
||||||
oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gyp
|
|
||||||
$ ninja -C out/Default/
|
|
||||||
$ mkdir /tmp/new_interesting_corpus
|
$ mkdir /tmp/new_interesting_corpus
|
||||||
$ ./out/Default/fuzzer_binary /tmp/new_interesting_corpus \
|
$ ./out/Default/fuzzer_binary /tmp/new_interesting_corpus \
|
||||||
/path/to/fuzz/seed/corpus/folder
|
/path/to/fuzz/seed/corpus/folder
|
||||||
@@ -127,8 +123,9 @@
|
|||||||
$ ./out/Default/fuzzer_binary crash_input_file
|
$ ./out/Default/fuzzer_binary crash_input_file
|
||||||
```
|
```
|
||||||
## Adding a new OEMCrypto fuzz script
|
## Adding a new OEMCrypto fuzz script
|
||||||
* In order to fuzz a new OEMCrypto API in future, a fuzz script can be added to
|
* In order to fuzz a new OEMCrypto API in future, a fuzz script can be added
|
||||||
oemcrypto/test/fuzz_tests folder which ends with _fuzz.cc.
|
to oemcrypto/test/fuzz_tests folder which starts with oemcrypto and ends
|
||||||
|
with fuzz.cc(GCB build script for oemcrypto fuzzers expects the format).
|
||||||
|
|
||||||
* In the program, define the function LLVMFuzzerTestOneInput with the following signature:
|
* In the program, define the function LLVMFuzzerTestOneInput with the following signature:
|
||||||
```
|
```
|
||||||
@@ -164,50 +161,14 @@
|
|||||||
|
|
||||||
### Adding a new fuzz script to the build script:
|
### Adding a new fuzz script to the build script:
|
||||||
|
|
||||||
* In order to update build script such as adding a new fuzzer to build script,
|
* As long as a new fuzz script is added which starts with oemcrypto and ends
|
||||||
we need to update the build script in docker image from cloud repository.
|
with fuzz, the build command can be added to build_oemcrypto_fuzztests.
|
||||||
[Build script.](https://widevine-internal.googlesource.com/cloud/+/refs/heads/master/docker
|
GCB script uses build_oemcrypto_fuzztests script to build fuzz binaries
|
||||||
/cloud_build/oemcrypto/release/ubuntu/fuzz/build.sh)
|
and make them available for clusterfuzz to run continuously.
|
||||||
|
|
||||||
Add the new fuzz script name to fuzzers variable and follow steps in README
|
* If the new fuzzer cannot follow the naming convention OR GCB script needs
|
||||||
to upload new docker image. Make sure you update the tag to be higher than
|
to be updated for any other reason, refer to [this section](https://docs.google.com/document/d/1mdSV2irJZz5Y9uYb5DmSIddBjrAIZU9q8G5Q_BGpA4I/edit#heading=h.bu9yfftdonkg)
|
||||||
latest version in GCR.
|
section.
|
||||||
|
|
||||||
Run the following command from your machine to update the docker image tag
|
|
||||||
in the git trigger.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
stubby call --rpc_creds_file=/tmp/mint.txt \
|
|
||||||
blade:alphasource-ci-proctor-metadata-service-prod \
|
|
||||||
ProctorMetadataService.UpdateTrigger --proto2 <<EOF
|
|
||||||
trigger {
|
|
||||||
cloud_project_number: 257246079067
|
|
||||||
name: "cdm-git-trigger"
|
|
||||||
id: "e8939c9a-d971-4c05-91b5-e0544abf872b"
|
|
||||||
state: LIVE
|
|
||||||
git_trigger {
|
|
||||||
url: "https://widevine-internal.googlesource.com/cdm"
|
|
||||||
branch_name: "master"
|
|
||||||
}
|
|
||||||
build_configs {
|
|
||||||
build {
|
|
||||||
steps {
|
|
||||||
name: "gcr.io/google.com/blockbuster-1154/
|
|
||||||
cloud-build-oemcrypto-release-ubuntu-fuzz:LATEST_TAG_VERSION"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result_config {
|
|
||||||
email_config {
|
|
||||||
notify_condition {
|
|
||||||
condition: ON_FAILURE
|
|
||||||
}
|
|
||||||
to_address: "wideving-engprod@google.com"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
|
|
||||||
## Generate code coverage reports locally
|
## Generate code coverage reports locally
|
||||||
|
|
||||||
|
|||||||
16
libwvdrmengine/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests
Executable file
16
libwvdrmengine/oemcrypto/test/fuzz_tests/build_oemcrypto_fuzztests
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
export CXX=clang++
|
||||||
|
export CC=clang
|
||||||
|
export GYP_DEFINES="$GYP_DEFINES clang=1"
|
||||||
|
|
||||||
|
export PATH_TO_CDM_DIR=.
|
||||||
|
gyp --format=ninja --depth=$(pwd) oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gyp
|
||||||
|
ninja -C out/Default
|
||||||
|
# oemcrypto_odkitee_fuzztests.gypi has flags to instrument all the gyp targets
|
||||||
|
# with fuzzer flags.
|
||||||
|
gyp --format=ninja --depth=$(pwd) \
|
||||||
|
--include=oemcrypto/test/fuzz_tests/oemcrypto_odkitee_fuzztests.gypi \
|
||||||
|
oemcrypto/test/fuzz_tests/oemcrypto_odkitee_fuzztests.gyp
|
||||||
|
ninja -C out/Default
|
||||||
@@ -144,26 +144,29 @@ Test_PST_Report::Test_PST_Report(const std::string& pst_in,
|
|||||||
|
|
||||||
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
|
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
|
||||||
class CoreResponse, class ResponseData>
|
class CoreResponse, class ResponseData>
|
||||||
void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
|
OEMCryptoResult
|
||||||
ResponseData>::SignAndVerifyRequest() {
|
RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse, ResponseData>::
|
||||||
|
SignAndCreateRequestWithCustomBufferLengths(bool verify_request) {
|
||||||
// In the real world, a message should be signed by the client and
|
// In the real world, a message should be signed by the client and
|
||||||
// verified by the server. This simulates that.
|
// verified by the server. This simulates that.
|
||||||
size_t gen_signature_length = 0;
|
size_t gen_signature_length = 0;
|
||||||
size_t core_message_length = 0;
|
size_t core_message_length = 0;
|
||||||
constexpr size_t small_size = 42; // arbitrary.
|
constexpr size_t small_size = 42; // arbitrary.
|
||||||
size_t message_size =
|
uint32_t session_id = session()->session_id();
|
||||||
std::max(required_message_size_, core_message_length + small_size);
|
GetDefaultRequestSignatureAndCoreMessageLengths<PrepAndSignRequest>(
|
||||||
vector<uint8_t> data(message_size, 0);
|
session_id, required_message_size_, small_size, &gen_signature_length,
|
||||||
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
|
&core_message_length);
|
||||||
ASSERT_EQ(
|
// Used to test request APIs with varying lengths of core message.
|
||||||
PrepAndSignRequest(session()->session_id(), data.data(), data.size(),
|
core_message_length =
|
||||||
&core_message_length, nullptr, &gen_signature_length),
|
std::max(core_message_length, required_core_message_size_);
|
||||||
OEMCrypto_ERROR_SHORT_BUFFER);
|
// Used to test request APIs with varying lengths of signature.
|
||||||
|
gen_signature_length =
|
||||||
|
std::max(gen_signature_length, required_request_signature_size_);
|
||||||
// Make the message buffer a little bigger than the core message, or the
|
// Make the message buffer a little bigger than the core message, or the
|
||||||
// required size, whichever is larger.
|
// required size, whichever is larger.
|
||||||
message_size =
|
size_t message_size =
|
||||||
std::max(required_message_size_, core_message_length + small_size);
|
std::max(required_message_size_, core_message_length + small_size);
|
||||||
data.resize(message_size);
|
vector<uint8_t> data(message_size);
|
||||||
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
|
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
|
||||||
if (ShouldGenerateCorpus()) {
|
if (ShouldGenerateCorpus()) {
|
||||||
WriteRequestApiCorpus<CoreRequest>(gen_signature_length,
|
WriteRequestApiCorpus<CoreRequest>(gen_signature_length,
|
||||||
@@ -171,17 +174,33 @@ void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vector<uint8_t> gen_signature(gen_signature_length);
|
vector<uint8_t> gen_signature(gen_signature_length);
|
||||||
ASSERT_EQ(PrepAndSignRequest(session()->session_id(), data.data(),
|
OEMCryptoResult result = PrepAndSignRequest(
|
||||||
data.size(), &core_message_length,
|
session()->session_id(), data.data(), data.size(), &core_message_length,
|
||||||
gen_signature.data(), &gen_signature_length),
|
gen_signature.data(), &gen_signature_length);
|
||||||
OEMCrypto_SUCCESS);
|
// We need to fill in core request and verify signature only for calls other
|
||||||
|
// than OEMCryptoMemory buffer overflow test. Any test other than buffer
|
||||||
|
// overflow will pass true.
|
||||||
|
if (!verify_request || result != OEMCrypto_SUCCESS) return result;
|
||||||
if (global_features.api_version >= kCoreMessagesAPI) {
|
if (global_features.api_version >= kCoreMessagesAPI) {
|
||||||
ASSERT_GT(data.size(), core_message_length);
|
|
||||||
std::string core_message(reinterpret_cast<char*>(data.data()),
|
std::string core_message(reinterpret_cast<char*>(data.data()),
|
||||||
core_message_length);
|
core_message_length);
|
||||||
FillAndVerifyCoreRequest(core_message);
|
FillAndVerifyCoreRequest(core_message);
|
||||||
}
|
}
|
||||||
VerifyRequestSignature(data, gen_signature, core_message_length);
|
VerifyRequestSignature(data, gen_signature, core_message_length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <PrepAndSignRequest_t PrepAndSignRequest>
|
||||||
|
void GetDefaultRequestSignatureAndCoreMessageLengths(
|
||||||
|
uint32_t& session_id, size_t& required_message_size,
|
||||||
|
const size_t& small_size, size_t* gen_signature_length,
|
||||||
|
size_t* core_message_length) {
|
||||||
|
vector<uint8_t> data(small_size);
|
||||||
|
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
|
||||||
|
ASSERT_EQ(
|
||||||
|
PrepAndSignRequest(session_id, data.data(), data.size(),
|
||||||
|
core_message_length, nullptr, gen_signature_length),
|
||||||
|
OEMCrypto_ERROR_SHORT_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
|
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
|
||||||
@@ -306,10 +325,26 @@ void ProvisioningRoundTrip::EncryptAndSignResponse() {
|
|||||||
&encrypted_response_data_);
|
&encrypted_response_data_);
|
||||||
core_response_.enc_private_key.length =
|
core_response_.enc_private_key.length =
|
||||||
encrypted_response_data_.rsa_key_length;
|
encrypted_response_data_.rsa_key_length;
|
||||||
|
SignResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need this for provisioning response out of range tests where
|
||||||
|
// core response substring lengths are modified.
|
||||||
|
void ProvisioningRoundTrip::
|
||||||
|
EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength() {
|
||||||
|
encryptor_.PadAndEncryptProvisioningMessage(&response_data_,
|
||||||
|
&encrypted_response_data_);
|
||||||
|
SignResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProvisioningRoundTrip::SignResponse() {
|
||||||
if (global_features.api_version >= kCoreMessagesAPI) {
|
if (global_features.api_version >= kCoreMessagesAPI) {
|
||||||
ASSERT_TRUE(
|
ASSERT_TRUE(
|
||||||
oemcrypto_core_message::serialize::CreateCoreProvisioningResponse(
|
oemcrypto_core_message::serialize::CreateCoreProvisioningResponse(
|
||||||
core_response_, core_request_, &serialized_core_message_));
|
core_response_, core_request_, &serialized_core_message_));
|
||||||
|
// Resizing for huge core message length unit tests.
|
||||||
|
serialized_core_message_.resize(
|
||||||
|
std::max(required_core_message_size_, serialized_core_message_.size()));
|
||||||
}
|
}
|
||||||
// Make the message buffer a just big enough, or the
|
// Make the message buffer a just big enough, or the
|
||||||
// required size, whichever is larger.
|
// required size, whichever is larger.
|
||||||
@@ -689,6 +724,10 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
|||||||
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse(
|
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse(
|
||||||
core_response_, core_request_, request_hash_string,
|
core_response_, core_request_, request_hash_string,
|
||||||
&serialized_core_message_));
|
&serialized_core_message_));
|
||||||
|
// Resize serialize core message to be just big enough or required core
|
||||||
|
// message size, whichever is larger.
|
||||||
|
serialized_core_message_.resize(
|
||||||
|
std::max(required_core_message_size_, serialized_core_message_.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the message buffer a just big enough, or the
|
// Make the message buffer a just big enough, or the
|
||||||
@@ -701,7 +740,6 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
|||||||
for (size_t i = 0; i < encrypted_response_.size(); i++) {
|
for (size_t i = 0; i < encrypted_response_.size(); i++) {
|
||||||
encrypted_response_[i] = i % 0x100;
|
encrypted_response_[i] = i % 0x100;
|
||||||
}
|
}
|
||||||
ASSERT_GE(kMaxCoreMessage, serialized_core_message_.size());
|
|
||||||
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
|
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
|
||||||
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
|
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
|
||||||
serialized_core_message_.size());
|
serialized_core_message_.size());
|
||||||
@@ -716,6 +754,11 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
|
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
|
||||||
|
return LoadResponse(session, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session,
|
||||||
|
bool verify_keys) {
|
||||||
EXPECT_NE(session, nullptr);
|
EXPECT_NE(session, nullptr);
|
||||||
// Write corpus for oemcrypto_load_license_fuzz. Fuzz script expects
|
// Write corpus for oemcrypto_load_license_fuzz. Fuzz script expects
|
||||||
// unecnrypted response from license server as input corpus data.
|
// unecnrypted response from license server as input corpus data.
|
||||||
@@ -762,7 +805,7 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
|
|||||||
encrypted_response_.size(), serialized_core_message_.size(),
|
encrypted_response_.size(), serialized_core_message_.size(),
|
||||||
response_signature_.data(), response_signature_.size());
|
response_signature_.data(), response_signature_.size());
|
||||||
}
|
}
|
||||||
if (result == OEMCrypto_SUCCESS) {
|
if (verify_keys && result == OEMCrypto_SUCCESS) {
|
||||||
// Give the session object a copy of the license truth data so that it can
|
// Give the session object a copy of the license truth data so that it can
|
||||||
// call SelectKey, use key control information, and so that it has key data
|
// call SelectKey, use key control information, and so that it has key data
|
||||||
// to verify decrypt operations.
|
// to verify decrypt operations.
|
||||||
@@ -861,6 +904,18 @@ void EntitledMessage::MakeOneKey(size_t entitlement_key_index) {
|
|||||||
key_data->content_key_data_iv, sizeof(key_data->content_key_data_iv));
|
key_data->content_key_data_iv, sizeof(key_data->content_key_data_iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OEMCrypto_EntitledContentKeyObject* EntitledMessage::entitled_key_array() {
|
||||||
|
return entitled_key_array_;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntitledContentKeyData* EntitledMessage::entitled_key_data() {
|
||||||
|
return entitled_key_data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t EntitledMessage::entitled_key_data_size() {
|
||||||
|
return sizeof(entitled_key_data_);
|
||||||
|
}
|
||||||
|
|
||||||
void EntitledMessage::SetEntitlementKeyId(unsigned int index,
|
void EntitledMessage::SetEntitlementKeyId(unsigned int index,
|
||||||
const std::string& key_id) {
|
const std::string& key_id) {
|
||||||
ASSERT_LT(index, num_keys_);
|
ASSERT_LT(index, num_keys_);
|
||||||
@@ -884,6 +939,32 @@ OEMCrypto_Substring EntitledMessage::FindSubstring(const void* ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
|
void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
|
||||||
|
EncryptContentKey();
|
||||||
|
ASSERT_EQ(expected_sts,
|
||||||
|
OEMCrypto_LoadEntitledContentKeys(
|
||||||
|
license_messages_->session()->session_id(),
|
||||||
|
reinterpret_cast<const uint8_t*>(entitled_key_data_),
|
||||||
|
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
|
||||||
|
if (expected_sts != OEMCrypto_SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VerifyEntitlementTestKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult EntitledMessage::LoadKeys(const vector<uint8_t>& message) {
|
||||||
|
return OEMCrypto_LoadEntitledContentKeys(
|
||||||
|
license_messages_->session()->session_id(), message.data(),
|
||||||
|
message.size(), num_keys_, entitled_key_array_);
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult EntitledMessage::LoadKeys() {
|
||||||
|
return OEMCrypto_LoadEntitledContentKeys(
|
||||||
|
license_messages_->session()->session_id(),
|
||||||
|
reinterpret_cast<const uint8_t*>(entitled_key_data_),
|
||||||
|
sizeof(entitled_key_data_), num_keys_, entitled_key_array_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntitledMessage::EncryptContentKey() {
|
||||||
for (size_t i = 0; i < num_keys_; ++i) {
|
for (size_t i = 0; i < num_keys_; ++i) {
|
||||||
EntitledContentKeyData* key_data = &entitled_key_data_[i];
|
EntitledContentKeyData* key_data = &entitled_key_data_[i];
|
||||||
const size_t entitlement_key_index = key_data->key_index;
|
const size_t entitlement_key_index = key_data->key_index;
|
||||||
@@ -912,15 +993,6 @@ void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
|
|||||||
AppendToFile(file_name, reinterpret_cast<const char*>(entitled_key_array_),
|
AppendToFile(file_name, reinterpret_cast<const char*>(entitled_key_array_),
|
||||||
num_keys_);
|
num_keys_);
|
||||||
}
|
}
|
||||||
ASSERT_EQ(expected_sts,
|
|
||||||
OEMCrypto_LoadEntitledContentKeys(
|
|
||||||
license_messages_->session()->session_id(),
|
|
||||||
reinterpret_cast<const uint8_t*>(entitled_key_data_),
|
|
||||||
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
|
|
||||||
if (expected_sts != OEMCrypto_SUCCESS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
VerifyEntitlementTestKeys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function verifies that the key control block reported by OEMCrypto agree
|
// This function verifies that the key control block reported by OEMCrypto agree
|
||||||
@@ -1035,6 +1107,10 @@ void RenewalRoundTrip::EncryptAndSignResponse() {
|
|||||||
} else {
|
} else {
|
||||||
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreRenewalResponse(
|
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreRenewalResponse(
|
||||||
core_request_, renewal_duration_seconds_, &serialized_core_message_));
|
core_request_, renewal_duration_seconds_, &serialized_core_message_));
|
||||||
|
// Resize serialize core message to be just big enough or required core
|
||||||
|
// message size, whichever is larger.
|
||||||
|
serialized_core_message_.resize(
|
||||||
|
std::max(required_core_message_size_, serialized_core_message_.size()));
|
||||||
}
|
}
|
||||||
// Make the message buffer a just big enough, or the
|
// Make the message buffer a just big enough, or the
|
||||||
// required size, whichever is larger.
|
// required size, whichever is larger.
|
||||||
@@ -1047,7 +1123,6 @@ void RenewalRoundTrip::EncryptAndSignResponse() {
|
|||||||
encrypted_response_[i] = i % 0x100;
|
encrypted_response_[i] = i % 0x100;
|
||||||
}
|
}
|
||||||
// Concatenate the core message and the response.
|
// Concatenate the core message and the response.
|
||||||
ASSERT_GE(kMaxCoreMessage, serialized_core_message_.size());
|
|
||||||
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
|
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
|
||||||
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
|
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
|
||||||
serialized_core_message_.size());
|
serialized_core_message_.size());
|
||||||
|
|||||||
@@ -155,12 +155,25 @@ class RoundTrip {
|
|||||||
core_response_(),
|
core_response_(),
|
||||||
response_data_(),
|
response_data_(),
|
||||||
encrypted_response_data_(),
|
encrypted_response_data_(),
|
||||||
required_message_size_(0) {}
|
required_message_size_(0),
|
||||||
|
required_core_message_size_(0),
|
||||||
|
required_request_signature_size_(0) {}
|
||||||
virtual ~RoundTrip() {}
|
virtual ~RoundTrip() {}
|
||||||
|
|
||||||
// Have OEMCrypto sign a request message and then verify the signature and the
|
// Have OEMCrypto sign a request message and then verify the signature and the
|
||||||
// core message.
|
// core message.
|
||||||
virtual void SignAndVerifyRequest();
|
virtual void SignAndVerifyRequest() {
|
||||||
|
// Boolean true generates core request and verifies the request.
|
||||||
|
// Custom message sizes are 0 by default, so the behavior of following
|
||||||
|
// functions will be sign and verify request without any custom buffers
|
||||||
|
// sizes.
|
||||||
|
ASSERT_EQ(SignAndCreateRequestWithCustomBufferLengths(true),
|
||||||
|
OEMCrypto_SUCCESS);
|
||||||
|
}
|
||||||
|
// Have OEMCrypto sign and call create request APIs. Buffer parameters in API
|
||||||
|
// can be set to custom values to test with varying lengths of buffers.
|
||||||
|
virtual OEMCryptoResult SignAndCreateRequestWithCustomBufferLengths(
|
||||||
|
bool verify_request = false);
|
||||||
// Used for OEMCrypto Fuzzing: Function to convert fuzzer data to valid
|
// Used for OEMCrypto Fuzzing: Function to convert fuzzer data to valid
|
||||||
// License/Provisioning/Renwal request data that can be serialized.
|
// License/Provisioning/Renwal request data that can be serialized.
|
||||||
virtual void InjectFuzzedRequestData(uint8_t* data, size_t size);
|
virtual void InjectFuzzedRequestData(uint8_t* data, size_t size);
|
||||||
@@ -189,6 +202,16 @@ class RoundTrip {
|
|||||||
|
|
||||||
// Set the size of the buffer used the encrypted license.
|
// Set the size of the buffer used the encrypted license.
|
||||||
void set_message_size(size_t size) { required_message_size_ = size; }
|
void set_message_size(size_t size) { required_message_size_ = size; }
|
||||||
|
// Set core message size to test OEMCrypto request APIs for varying core
|
||||||
|
// message lengths.
|
||||||
|
void set_core_message_size(size_t size) {
|
||||||
|
required_core_message_size_ = size;
|
||||||
|
}
|
||||||
|
// Set signature size to test OEMCrypto request APIs for varying signature
|
||||||
|
// lengths.
|
||||||
|
void set_request_signature_size(size_t size) {
|
||||||
|
required_request_signature_size_ = size;
|
||||||
|
}
|
||||||
std::vector<uint8_t>& response_signature() { return response_signature_; }
|
std::vector<uint8_t>& response_signature() { return response_signature_; }
|
||||||
const std::string& serialized_core_message() const {
|
const std::string& serialized_core_message() const {
|
||||||
return serialized_core_message_;
|
return serialized_core_message_;
|
||||||
@@ -217,6 +240,8 @@ class RoundTrip {
|
|||||||
// Message buffers will be at least this big. Tests for loading and signing
|
// Message buffers will be at least this big. Tests for loading and signing
|
||||||
// messages will increase all buffers to this size.
|
// messages will increase all buffers to this size.
|
||||||
size_t required_message_size_;
|
size_t required_message_size_;
|
||||||
|
size_t required_core_message_size_;
|
||||||
|
size_t required_request_signature_size_;
|
||||||
std::vector<uint8_t> response_signature_;
|
std::vector<uint8_t> response_signature_;
|
||||||
std::string serialized_core_message_;
|
std::string serialized_core_message_;
|
||||||
std::vector<uint8_t> encrypted_response_;
|
std::vector<uint8_t> encrypted_response_;
|
||||||
@@ -239,6 +264,8 @@ class ProvisioningRoundTrip
|
|||||||
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);
|
virtual void PrepareSession(const wvoec::WidevineKeybox& keybox);
|
||||||
void CreateDefaultResponse() override;
|
void CreateDefaultResponse() override;
|
||||||
void EncryptAndSignResponse() override;
|
void EncryptAndSignResponse() override;
|
||||||
|
void EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength();
|
||||||
|
void SignResponse();
|
||||||
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
||||||
OEMCryptoResult LoadResponse(Session* session) override;
|
OEMCryptoResult LoadResponse(Session* session) override;
|
||||||
void VerifyLoadFailed();
|
void VerifyLoadFailed();
|
||||||
@@ -318,6 +345,7 @@ class LicenseRoundTrip
|
|||||||
void EncryptAndSignResponse() override;
|
void EncryptAndSignResponse() override;
|
||||||
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
||||||
OEMCryptoResult LoadResponse(Session* session) override;
|
OEMCryptoResult LoadResponse(Session* session) override;
|
||||||
|
OEMCryptoResult LoadResponse(Session* session, bool verify_keys);
|
||||||
// Reload an offline license into a different session. This derives new mac
|
// Reload an offline license into a different session. This derives new mac
|
||||||
// keys and then calls LoadResponse.
|
// keys and then calls LoadResponse.
|
||||||
OEMCryptoResult ReloadResponse(Session* session);
|
OEMCryptoResult ReloadResponse(Session* session);
|
||||||
@@ -442,11 +470,19 @@ class EntitledMessage {
|
|||||||
void FillKeyArray();
|
void FillKeyArray();
|
||||||
void MakeOneKey(size_t entitlement_key_index);
|
void MakeOneKey(size_t entitlement_key_index);
|
||||||
void LoadKeys(OEMCryptoResult expected_sts);
|
void LoadKeys(OEMCryptoResult expected_sts);
|
||||||
|
OEMCryptoResult LoadKeys(const vector<uint8_t>& message);
|
||||||
|
OEMCryptoResult LoadKeys();
|
||||||
|
void EncryptContentKey();
|
||||||
void set_num_keys(uint32_t num_keys) { num_keys_ = num_keys; }
|
void set_num_keys(uint32_t num_keys) { num_keys_ = num_keys; }
|
||||||
uint32_t num_keys() const { return num_keys_; }
|
uint32_t num_keys() const { return num_keys_; }
|
||||||
void SetEntitlementKeyId(unsigned int index, const std::string& key_id);
|
void SetEntitlementKeyId(unsigned int index, const std::string& key_id);
|
||||||
// Verify that key control blocks of the loaded keys.
|
// Verify that key control blocks of the loaded keys.
|
||||||
void VerifyEntitlementTestKeys();
|
void VerifyEntitlementTestKeys();
|
||||||
|
OEMCrypto_EntitledContentKeyObject* entitled_key_array();
|
||||||
|
// Returns entitled_key_data_ which is used as input message buffer to
|
||||||
|
// load entitled content keys API.
|
||||||
|
EntitledContentKeyData* entitled_key_data();
|
||||||
|
size_t entitled_key_data_size();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Find the offset of the give pointer, relative to |entitled_key_data_|.
|
// Find the offset of the give pointer, relative to |entitled_key_data_|.
|
||||||
@@ -631,6 +667,11 @@ bool ConvertByteToValidBoolean(const bool* in);
|
|||||||
template <class CoreRequest>
|
template <class CoreRequest>
|
||||||
void WriteRequestApiCorpus(size_t signature_length, size_t core_message_length,
|
void WriteRequestApiCorpus(size_t signature_length, size_t core_message_length,
|
||||||
vector<uint8_t>& data);
|
vector<uint8_t>& data);
|
||||||
|
template <PrepAndSignRequest_t PrepAndSignRequest>
|
||||||
|
void GetDefaultRequestSignatureAndCoreMessageLengths(
|
||||||
|
uint32_t& session_id, size_t& required_message_size,
|
||||||
|
const size_t& small_size, size_t* gen_signature_length,
|
||||||
|
size_t* core_message_length);
|
||||||
} // namespace wvoec
|
} // namespace wvoec
|
||||||
|
|
||||||
#endif // CDM_OEC_SESSION_UTIL_H_
|
#endif // CDM_OEC_SESSION_UTIL_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user