Clean up fuzz helper classes

- Remove OEMCrypto state changes hidden in constructors and destructors.
- Use composition instead of inheritance to structure classes.
- Avoid calling non-trivial destructors for objects with static
  lifetime.

Merged from https://widevine-internal-review.googlesource.com/168497
Merged from https://widevine-internal-review.googlesource.com/171170
Merged from https://widevine-internal-review.googlesource.com/171171
Merged from https://widevine-internal-review.googlesource.com/171870

Change-Id: I20476a7b1132d11f011b8650ec01e3c2dc3fc0e8
This commit is contained in:
Ian Benz
2023-03-20 17:46:15 +00:00
committed by Robert Shih
parent af070601b0
commit 53fe55cb72
30 changed files with 518 additions and 398 deletions

View File

@@ -7,31 +7,39 @@
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
namespace {
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
// OEMCrypto_DestBufferDesc and a buffer from which data needs to be copied
// are expected as inputs to copy buffer API.
// Input fuzzed data is interpreted as:
// (OEMCrypto_DestBufferDesc | subsample_flags | input_buffer)
OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) {
return 0;
}
FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_BufferType_MaxValue,
&fuzzed_structure.dest_buffer_desc.type);
fuzzed_structure.dest_buffer_desc.buffer_config %= MAX_FUZZ_OUTPUT_LENGTH + 1;
wvoec::ConvertDataToValidEnum(OEMCrypto_BufferType_MaxValue,
&fuzzed_structure.dest_buffer_desc.type);
fuzzed_structure.dest_buffer_desc.buffer_config %=
wvoec::MAX_FUZZ_OUTPUT_LENGTH + 1;
const std::vector<OEMCrypto_SharedMemory> input_buffer =
fuzzed_data.ConsumeRemainingBytes<OEMCrypto_SharedMemory>();
OEMCryptoLicenseAPIFuzz license_api_fuzz;
const uint32_t session_id = license_api_fuzz.session()->session_id();
const uint32_t session_id = license_api_fuzz.session().session_id();
// Initialize output buffer.
OEMCrypto_DestBufferDesc dest_buffer_desc;
@@ -79,5 +87,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0;
}
} // namespace wvoec

View File

@@ -5,15 +5,15 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedLicense) + sizeof(MessageData)) {
wvoec::RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedLicense) + sizeof(wvoec::MessageData)) {
return 0;
}
OEMCryptoLicenseAPIFuzz license_api_fuzz;
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
license_api_fuzz.license_messages().set_license_type(
OEMCrypto_EntitlementLicense);
license_api_fuzz.license_messages().SignAndVerifyRequest();
@@ -29,6 +29,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
OEMCrypto_RemoveEntitledKeySession(key_session_id);
license_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,29 +2,28 @@
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
LicenseWithUsageEntryFuzz entry;
wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
entry.CreateUsageTableHeader();
// Open a session, create a usage entry.
Session* session = entry.license_messages().session();
wvoec::Session* session = entry.license_messages().session();
session->open();
entry.InstallTestDrmKey(session);
session->CreateNewUsageEntry();
session->GenerateNonce();
vector<uint8_t> encrypted_usage_header;
std::vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
// LoadLicense sets the pst for usage entry.
entry.LoadLicense();
OEMCrypto_DeactivateUsageEntry(session->session_id(), data, size);
session->close();
OEMCrypto_Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,42 +2,55 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
namespace {
// Limit output buffer size to 5 MB as 4 MB is maximum size specified by
// resource rating tier documentation.
const size_t MAX_FUZZ_SAMPLE_SIZE = 5 * MB;
constexpr size_t MAX_FUZZ_SAMPLE_SIZE = 5 * wvoec::MB;
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
license_api_fuzz.LoadLicense();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
// Split data using separator.
const std::vector<FuzzedData> inputs = SplitFuzzedData(data, size);
const std::vector<wvoec::FuzzedData> inputs =
wvoec::SplitFuzzedData(data, size);
if (inputs.size() < 3) {
return 0;
}
// Read cipher mode and pattern from fuzzed data.
OEMCrypto_Decrypt_Cenc_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Decrypt_Cenc_Fuzz fuzzed_structure;
if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0;
}
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
// Allocate sample descriptions.
std::vector<OEMCrypto_SampleDescription> sample_descriptions(
fuzzed_data.remaining_bytes() / sizeof(OEMCrypto_SampleDescription_Fuzz));
fuzzed_data.remaining_bytes() /
sizeof(wvoec::OEMCrypto_SampleDescription_Fuzz));
// Allocate input buffers for each sample description.
std::vector<std::vector<OEMCrypto_SharedMemory>> input_buffers(
@@ -50,8 +63,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::vector<std::vector<OEMCrypto_SubSampleDescription>> subsamples(
sample_descriptions.size());
OEMCryptoLicenseAPIFuzz license_api_fuzz;
const uint32_t session_id = license_api_fuzz.session()->session_id();
const uint32_t session_id = license_api_fuzz.session().session_id();
// Free first given number of output buffers.
const auto FreeOutputBuffers = [&sample_descriptions, session_id,
@@ -81,12 +93,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider subsample_data(inputs[2].data, inputs[2].size);
for (size_t i = 0; i < sample_descriptions.size(); i++) {
// Read and normalize sample description fuzzed properties.
OEMCrypto_SampleDescription_Fuzz fuzzed_sample_description;
wvoec::OEMCrypto_SampleDescription_Fuzz fuzzed_sample_description;
sample_description_data.ConsumeData(&fuzzed_sample_description,
sizeof(fuzzed_sample_description));
fuzzed_sample_description.buffers.input_data_length %=
MAX_FUZZ_SAMPLE_SIZE + 1;
ConvertDataToValidEnum(
wvoec::ConvertDataToValidEnum(
OEMCrypto_BufferType_MaxValue,
&fuzzed_sample_description.buffers.output_descriptor.type);
fuzzed_sample_description.buffers.output_descriptor.buffer_config %=
@@ -126,7 +138,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Initialize output buffer.
OEMCrypto_DestBufferDesc& output_descriptor =
sample_descriptions[i].buffers.output_descriptor;
const OEMCrypto_DestBufferDesc_Fuzz& fuzzed_output_descriptor =
const wvoec::OEMCrypto_DestBufferDesc_Fuzz& fuzzed_output_descriptor =
fuzzed_sample_description.buffers.output_descriptor;
output_descriptor.type = fuzzed_output_descriptor.type;
switch (output_descriptor.type) {
@@ -154,11 +166,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
}
// Load license and call decrypt_cenc API.
license_api_fuzz.LoadLicense();
const MessageKeyData& key = license_api_fuzz.session()->license().keys[0];
vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session_id, key.key_id, key.key_id_length,
fuzzed_structure.cipher_mode, key_handle);
const wvoec::MessageKeyData& key =
license_api_fuzz.session().license().keys[0];
std::vector<uint8_t> key_handle;
wvoec::GetKeyHandleIntoVector(session_id, key.key_id, key.key_id_length,
fuzzed_structure.cipher_mode, key_handle);
OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(),
sample_descriptions.data(), sample_descriptions.size(),
&fuzzed_structure.pattern);
@@ -168,5 +180,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0;
}
} // namespace wvoec

View File

@@ -9,23 +9,21 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
using namespace wvoec;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
OEMCryptoLicenseAPIFuzz license_api_fuzz;
FuzzedDataProvider fuzzed_data(data, size);
if (fuzzed_data.ConsumeBool()) {
license_api_fuzz.license_messages().set_control(
license_api_fuzz.license_messages().control() |
kControlAllowHashVerification);
wvoec::kControlAllowHashVerification);
}
const uint32_t session_id = license_api_fuzz.session()->session_id();
const uint32_t session_id = license_api_fuzz.session().session_id();
const std::array<uint8_t, 16> content_key_id{};
const uint32_t frame_number = fuzzed_data.ConsumeIntegral<uint32_t>();
std::array<OEMCrypto_SharedMemory, 1> sample_buffer{};
@@ -62,13 +60,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
license_api_fuzz.LoadLicense();
std::vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session_id, content_key_id.data(),
content_key_id.size(), OEMCrypto_CipherMode_CENC,
key_handle);
wvoec::GetKeyHandleIntoVector(session_id, content_key_id.data(),
content_key_id.size(),
OEMCrypto_CipherMode_CENC, key_handle);
OEMCrypto_SetDecryptHash(session_id, frame_number, hash.data(), hash.size());
OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), &sample, 1,
&pattern);
OEMCrypto_GetHashErrorCode(session_id, failed_frame_number);
license_api_fuzz.Terminate();
return 0;
}

View File

@@ -1,9 +1,12 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
void RedirectStdoutToFile() { freopen("log.txt", "a", stdout); }
std::vector<FuzzedData> SplitFuzzedData(const uint8_t* data, size_t size) {
@@ -22,6 +25,26 @@ std::vector<FuzzedData> SplitFuzzedData(const uint8_t* data, size_t size) {
return result;
}
void InitializeFuzz(SessionUtil& session_util) {
wvoec::global_features.Initialize();
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
OEMCrypto_Initialize();
OEMCrypto_EnterTestMode();
session_util.EnsureTestROT();
}
void OEMCryptoLicenseAPIFuzz::Initialize() {
InitializeFuzz(session_util_);
session_.open();
session_util_.InstallTestDrmKey(&session_);
session_.GenerateNonce();
}
void OEMCryptoLicenseAPIFuzz::Terminate() {
session_.close();
OEMCrypto_Terminate();
}
void OEMCryptoLicenseAPIFuzz::LoadLicense() {
license_messages_.SignAndVerifyRequest();
license_messages_.CreateDefaultResponse();
@@ -30,6 +53,18 @@ void OEMCryptoLicenseAPIFuzz::LoadLicense() {
CheckStatusAndExitFuzzerOnFailure(sts, OEMCrypto_SUCCESS);
}
void OEMCryptoProvisioningAPIFuzz::Intialize() {
InitializeFuzz(session_util_);
// Opens a session and Generates Nonce.
provisioning_messages_.PrepareSession(session_util_.keybox_);
}
void OEMCryptoProvisioningAPIFuzz::Terminate() {
session_.close();
OEMCrypto_Terminate();
}
void OEMCryptoProvisioningAPIFuzz::LoadProvisioning() {
provisioning_messages_.SignAndVerifyRequest();
provisioning_messages_.CreateDefaultResponse();
@@ -62,4 +97,5 @@ void CheckStatusAndExitFuzzerOnFailure(OEMCryptoResult result,
abort();
}
}
} // namespace wvoec

View File

@@ -1,28 +1,29 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#ifndef OEMCRYPTO_FUZZ_HELPER_H_
#define OEMCRYPTO_FUZZ_HELPER_H_
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oec_device_features.h"
#include "oemcrypto_corpus_generator_helper.h"
#include "oemcrypto_session_tests_helper.h"
namespace wvoec {
// Forward-declare the libFuzzer's mutator callback. Mark it weak so that
// the program links successfully even outside of --config=asan-fuzzer
// (apparently the only config in which LLVM uses our custom mutator).
extern "C" size_t LLVMFuzzerMutate(uint8_t* Data, size_t Size, size_t MaxSize)
__attribute__((weak));
const size_t KB = 1024;
namespace wvoec {
constexpr size_t KB = 1024;
// Default maximum length of fuzzing output parameters.
const size_t MAX_FUZZ_OUTPUT_LENGTH = 5 * KB;
constexpr size_t MAX_FUZZ_OUTPUT_LENGTH = 5 * KB;
// Fuzzed data region.
struct FuzzedData {
@@ -33,89 +34,115 @@ struct FuzzedData {
// Initial setup to create a valid OEMCrypto state such as initializing crypto
// firmware/hardware, installing golden key box etc. in order to fuzz
// OEMCrypto APIs.
class InitializeFuzz : public SessionUtil {
void InitializeFuzz(SessionUtil& session_util);
class OEMCryptoLicenseAPIFuzz {
public:
InitializeFuzz() {
wvoec::global_features.Initialize();
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
OEMCrypto_Initialize();
OEMCrypto_EnterTestMode();
EnsureTestROT();
}
OEMCryptoLicenseAPIFuzz() : license_messages_(&session_) {}
~InitializeFuzz() { OEMCrypto_Terminate(); }
};
void Initialize();
class OEMCryptoLicenseAPIFuzz : public InitializeFuzz {
public:
OEMCryptoLicenseAPIFuzz() : license_messages_(&session_) {
session_.open();
InstallTestDrmKey(&session_);
session_.GenerateNonce();
}
~OEMCryptoLicenseAPIFuzz() { session_.close(); }
LicenseRoundTrip& license_messages() { return license_messages_; }
Session* session() { return &session_; }
uint32_t session_id() { return session_.session_id(); }
void Terminate();
void LoadLicense();
LicenseRoundTrip& license_messages() { return license_messages_; }
const LicenseRoundTrip& license_messages() const { return license_messages_; }
Session& session() { return session_; }
const Session& session() const { return session_; }
private:
SessionUtil session_util_;
Session session_;
LicenseRoundTrip license_messages_;
};
class OEMCryptoProvisioningAPIFuzz : public InitializeFuzz {
class OEMCryptoProvisioningAPIFuzz {
public:
OEMCryptoProvisioningAPIFuzz()
: provisioning_messages_(&session_, encoded_rsa_key_) {
// Opens a session and Generates Nonce.
provisioning_messages_.PrepareSession(keybox_);
}
: provisioning_messages_(&session_, session_util_.encoded_rsa_key_) {}
~OEMCryptoProvisioningAPIFuzz() { session_.close(); }
void Intialize();
void Terminate();
void LoadProvisioning();
ProvisioningRoundTrip& provisioning_messages() {
return provisioning_messages_;
}
Session* session() { return &session_; }
const ProvisioningRoundTrip& provisioning_messages() const {
return provisioning_messages_;
}
Session& session() { return session_; }
const Session& session() const { return session_; }
private:
SessionUtil session_util_;
Session session_;
ProvisioningRoundTrip provisioning_messages_;
};
// Initial setup to create a valid state such as creating session, installing
// golden key box etc. in order to fuzz Load Renewal API.
class OEMCryptoRenewalAPIFuzz : public OEMCryptoLicenseAPIFuzz {
class OEMCryptoRenewalAPIFuzz {
public:
OEMCryptoRenewalAPIFuzz() : renewal_messages_(&license_messages()) {}
OEMCryptoRenewalAPIFuzz()
: renewal_messages_(&license_api_fuzz_.license_messages()) {}
void Intialize() { license_api_fuzz_.Initialize(); }
void Terminate() { license_api_fuzz_.Terminate(); }
LicenseRoundTrip& license_messages() {
return license_api_fuzz_.license_messages();
}
const LicenseRoundTrip& license_messages() const {
return license_api_fuzz_.license_messages();
}
RenewalRoundTrip& renewal_messages() { return renewal_messages_; }
const RenewalRoundTrip& renewal_messages() const { return renewal_messages_; }
private:
OEMCryptoLicenseAPIFuzz license_api_fuzz_;
RenewalRoundTrip renewal_messages_;
};
class LicenseWithUsageEntryFuzz : public InitializeFuzz {
class LicenseWithUsageEntryFuzz {
public:
LicenseWithUsageEntryFuzz() : license_messages_(&session_) {
license_messages_.set_pst("my_pst");
}
void CreateUsageTableHeader();
LicenseRoundTrip& license_messages() { return license_messages_; }
const vector<uint8_t>& encrypted_usage_header() {
return encrypted_usage_header_;
void Initialize() { InitializeFuzz(session_util_); }
void InstallTestDrmKey(Session* session) {
session_util_.InstallTestDrmKey(session);
}
void CreateUsageTableHeader();
void LoadLicense();
LicenseRoundTrip& license_messages() { return license_messages_; }
const LicenseRoundTrip& license_messages() const { return license_messages_; }
const vector<uint8_t>& encrypted_usage_header() const {
return encrypted_usage_header_;
}
private:
SessionUtil session_util_;
vector<uint8_t> encrypted_usage_header_;
LicenseRoundTrip license_messages_;
Session session_;
@@ -146,6 +173,7 @@ std::vector<FuzzedData> SplitFuzzedData(const uint8_t* data, size_t size);
// called to check status of APIs which are called to setup state for fuzzers.
void CheckStatusAndExitFuzzerOnFailure(OEMCryptoResult result,
OEMCryptoResult expected_status);
} // namespace wvoec
#endif // OEMCRYPTO_FUZZ_HELPER_H_

View File

@@ -8,33 +8,42 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
using namespace wvoec;
namespace {
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoProvisioningAPIFuzz& provisioning_api_fuzz =
*new wvoec::OEMCryptoProvisioningAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
provisioning_api_fuzz.Intialize();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
static OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
FuzzedDataProvider fuzzed_data(data, size);
// public_key and public_key_length parameters
size_t public_key_length_data =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
size_t public_key_length_data = fuzzed_data.ConsumeIntegralInRange<size_t>(
0, wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> public_key(public_key_length_data);
size_t* const public_key_length =
fuzzed_data.ConsumeBool() ? &public_key_length_data : nullptr;
// public_key_signature and public_key_signature_length parameters
size_t public_key_signature_length_data =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
fuzzed_data.ConsumeIntegralInRange<size_t>(0,
wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> public_key_signature(public_key_signature_length_data);
size_t* const public_key_signature_length =
fuzzed_data.ConsumeBool() ? &public_key_signature_length_data : nullptr;
// wrapped_private_key and wrapped_private_key_length parameters
size_t wrapped_private_key_length_data =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
fuzzed_data.ConsumeIntegralInRange<size_t>(0,
wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> wrapped_private_key(wrapped_private_key_length_data);
size_t* const wrapped_private_key_length =
fuzzed_data.ConsumeBool() ? &wrapped_private_key_length_data : nullptr;
@@ -45,7 +54,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzed_data.ConsumeBool() ? &key_type_data : nullptr;
OEMCrypto_GenerateCertificateKeyPair(
provisioning_api_fuzz.session()->session_id(), public_key.data(),
provisioning_api_fuzz.session().session_id(), public_key.data(),
public_key_length, public_key_signature.data(),
public_key_signature_length, wrapped_private_key.data(),
wrapped_private_key_length, key_type);

View File

@@ -2,36 +2,33 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
#include "oemcrypto_fuzz_structs.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) {
return 0;
}
FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
fuzzed_structure.signature_length %= wvoec::MAX_FUZZ_OUTPUT_LENGTH + 1;
const std::vector<uint8_t> message =
fuzzed_data.ConsumeRemainingBytes<uint8_t>();
// Creates wrapped rsa key and calls load drm private key.
static OEMCryptoLicenseAPIFuzz license_api_fuzz;
// We cannot allocate buffers of random huge lengths in memory.
// This also slows down the fuzzer.
fuzzed_structure.signature_length %= MAX_FUZZ_OUTPUT_LENGTH + 1;
std::vector<uint8_t> signature(fuzzed_structure.signature_length);
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
OEMCrypto_GenerateRSASignature(
license_api_fuzz.session()->session_id(), message.data(), message.size(),
license_api_fuzz.session().session_id(), message.data(), message.size(),
signature.data(), &fuzzed_structure.signature_length,
fuzzed_structure.padding_scheme);
license_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -1,13 +1,13 @@
#include "properties.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_session_tests_helper.h"
using namespace wvoec;
#include "properties.h"
static bool is_init = false;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
SessionUtil session_helper;
wvoec::SessionUtil session_helper;
if (!is_init) {
wvoec::RedirectStdoutToFile();
wvoec::global_features.Initialize();
wvoec::global_features.RestrictFilter("*");
wvutil::Properties::Init();
@@ -18,7 +18,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
OEMCrypto_EnterTestMode();
session_helper.EnsureTestROT();
Session s;
wvoec::Session s;
s.open();
s.GenerateDerivedKeysFromKeybox(session_helper.keybox_);
@@ -32,6 +32,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
s.close();
OEMCrypto_Terminate();
return 0;
}

View File

@@ -2,37 +2,47 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_types.h"
namespace wvoec {
namespace {
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
license_api_fuzz.LoadLicense();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
// Split data using separator.
const std::vector<FuzzedData> inputs = SplitFuzzedData(data, size);
const std::vector<wvoec::FuzzedData> inputs =
wvoec::SplitFuzzedData(data, size);
if (inputs.size() < 2) {
return 0;
}
OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0;
}
// Copy OEMCrypto_Generic_Api_Fuzz from input data.
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
// Copy iv from input data.
const std::vector<uint8_t> iv = fuzzed_data.ConsumeRemainingBytes<uint8_t>();
@@ -41,19 +51,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
inputs[1].data + inputs[1].size);
std::vector<uint8_t> clear_buffer(encrypted_buffer.size());
OEMCryptoLicenseAPIFuzz license_api_fuzz;
Session* session = license_api_fuzz.session();
// Load license and call generic_decrypt API.
license_api_fuzz.LoadLicense();
vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session->session_id(),
session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
wvoec::Session& session = license_api_fuzz.session();
std::vector<uint8_t> key_handle;
wvoec::GetKeyHandleIntoVector(session.session_id(),
session.license().keys[0].key_id,
session.license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
OEMCrypto_Generic_Decrypt(key_handle.data(), key_handle.size(),
encrypted_buffer.data(), encrypted_buffer.size(),
iv.data(), fuzzed_structure.algorithm,
clear_buffer.data());
return 0;
}
} // namespace wvoec

View File

@@ -2,37 +2,47 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_types.h"
namespace wvoec {
namespace {
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
license_api_fuzz.LoadLicense();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
// Split data using separator.
const std::vector<FuzzedData> inputs = SplitFuzzedData(data, size);
const std::vector<wvoec::FuzzedData> inputs =
wvoec::SplitFuzzedData(data, size);
if (inputs.size() < 2) {
return 0;
}
OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0;
}
// Copy OEMCrypto_Generic_Api_Fuzz from input data.
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
// Copy iv from input data.
const std::vector<uint8_t> iv = fuzzed_data.ConsumeRemainingBytes<uint8_t>();
@@ -41,19 +51,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
inputs[1].data + inputs[1].size);
std::vector<uint8_t> encrypted_buffer(clear_buffer.size());
OEMCryptoLicenseAPIFuzz license_api_fuzz;
Session* session = license_api_fuzz.session();
// Load license and call generic_encrypt API.
license_api_fuzz.LoadLicense();
vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session->session_id(),
session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
wvoec::Session& session = license_api_fuzz.session();
std::vector<uint8_t> key_handle;
wvoec::GetKeyHandleIntoVector(session.session_id(),
session.license().keys[0].key_id,
session.license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
OEMCrypto_Generic_Encrypt(key_handle.data(), key_handle.size(),
clear_buffer.data(), clear_buffer.size(), iv.data(),
fuzzed_structure.algorithm,
encrypted_buffer.data());
return 0;
}
} // namespace wvoec

View File

@@ -2,44 +2,50 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_types.h"
namespace wvoec {
namespace {
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
license_api_fuzz.LoadLicense();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
wvoec::OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) {
return 0;
}
// Copy OEMCrypto_Generic_Api_Fuzz from input data.
FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode);
wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm);
// Copy clear buffer from input data.
const std::vector<uint8_t> clear_buffer =
fuzzed_data.ConsumeRemainingBytes<uint8_t>();
OEMCryptoLicenseAPIFuzz license_api_fuzz;
Session* session = license_api_fuzz.session();
// Load license and call generic_sign API.
license_api_fuzz.LoadLicense();
vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session->session_id(),
session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
wvoec::Session& session = license_api_fuzz.session();
std::vector<uint8_t> key_handle;
wvoec::GetKeyHandleIntoVector(session.session_id(),
session.license().keys[0].key_id,
session.license().keys[0].key_id_length,
fuzzed_structure.cipher_mode, key_handle);
size_t signature_length = 0;
OEMCrypto_Generic_Sign(key_handle.data(), key_handle.size(),
clear_buffer.data(), clear_buffer.size(),
@@ -52,4 +58,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
&signature_length);
return 0;
}
} // namespace wvoec

View File

@@ -2,18 +2,19 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
#include "oemcrypto_types.h"
namespace wvoec {
namespace {
// Properties deserialized from fuzzed data.
struct FuzzedProperties {
OEMCrypto_Generic_Api_Fuzz structure;
wvoec::OEMCrypto_Generic_Api_Fuzz structure;
std::vector<uint8_t> buffer;
std::vector<uint8_t> signature;
};
@@ -24,12 +25,15 @@ struct OptionalFuzzedProperties {
bool has_value;
};
OEMCryptoLicenseAPIFuzz license_api_fuzz;
// Avoid calling non-trivial destructor.
wvoec::OEMCryptoLicenseAPIFuzz& license_api_fuzz =
*new wvoec::OEMCryptoLicenseAPIFuzz;
OptionalFuzzedProperties DeserializeFuzzedData(const uint8_t* data,
size_t size) {
OptionalFuzzedProperties fuzzed_properties;
const std::vector<FuzzedData> inputs = SplitFuzzedData(data, size);
const std::vector<wvoec::FuzzedData> inputs =
wvoec::SplitFuzzedData(data, size);
if (inputs.size() < 2 ||
inputs[0].size < sizeof(fuzzed_properties.value.structure)) {
fuzzed_properties.has_value = false;
@@ -38,10 +42,10 @@ OptionalFuzzedProperties DeserializeFuzzedData(const uint8_t* data,
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_properties.value.structure,
sizeof(fuzzed_properties.value.structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_properties.value.structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_properties.value.structure.algorithm);
wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_properties.value.structure.cipher_mode);
wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_properties.value.structure.algorithm);
fuzzed_properties.value.buffer = fuzzed_data.ConsumeRemainingBytes<uint8_t>();
fuzzed_properties.value.signature.assign(inputs[1].data,
inputs[1].data + inputs[1].size);
@@ -49,8 +53,11 @@ OptionalFuzzedProperties DeserializeFuzzedData(const uint8_t* data,
return fuzzed_properties;
}
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
license_api_fuzz.Initialize();
license_api_fuzz.LoadLicense();
return 0;
}
@@ -64,12 +71,12 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
return 0;
}
// Get key handle for signing and verifying.
Session* const session = license_api_fuzz.session();
vector<uint8_t> key_handle;
OEMCryptoResult result = GetKeyHandleIntoVector(
session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
// Select key and perform verification.
wvoec::Session& session = license_api_fuzz.session();
std::vector<uint8_t> key_handle;
OEMCryptoResult result = wvoec::GetKeyHandleIntoVector(
session.session_id(), session.license().keys[0].key_id,
session.license().keys[0].key_id_length,
fuzzed_properties.value.structure.cipher_mode, key_handle);
if (result == OEMCrypto_SUCCESS) {
// Generate a new signature if verification fails.
@@ -96,7 +103,8 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
&signature_length);
const size_t signature_offset =
sizeof(fuzzed_properties.value.structure) +
fuzzed_properties.value.buffer.size() + sizeof(kFuzzDataSeparator);
fuzzed_properties.value.buffer.size() +
sizeof(wvoec::kFuzzDataSeparator);
size = signature_offset + signature_length;
if (size > max_size) {
return 0;
@@ -118,11 +126,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
}
// Select key and perform verification.
Session* const session = license_api_fuzz.session();
vector<uint8_t> key_handle;
GetKeyHandleIntoVector(
session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
wvoec::Session& session = license_api_fuzz.session();
std::vector<uint8_t> key_handle;
wvoec::GetKeyHandleIntoVector(
session.session_id(), session.license().keys[0].key_id,
session.license().keys[0].key_id_length,
fuzzed_properties.value.structure.cipher_mode, key_handle);
OEMCrypto_Generic_Verify(key_handle.data(), key_handle.size(),
fuzzed_properties.value.buffer.data(),
@@ -132,5 +140,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
fuzzed_properties.value.signature.size());
return 0;
}
} // namespace wvoec

View File

@@ -8,26 +8,27 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
using namespace wvoec;
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
wvoec::SessionUtil session_util;
wvoec::InitializeFuzz(session_util);
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
static InitializeFuzz initialize_fuzz;
FuzzedDataProvider fuzzed_data(data, size);
// bcc and bcc_length parameters
size_t bcc_length_data =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
size_t bcc_length_data = fuzzed_data.ConsumeIntegralInRange<size_t>(
0, wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> bcc(bcc_length_data);
size_t* const bcc_length =
fuzzed_data.ConsumeBool() ? &bcc_length_data : nullptr;
// additional_signature and additional_signature_length parameters
size_t additional_signature_length_data =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
fuzzed_data.ConsumeIntegralInRange<size_t>(0,
wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> additional_signature(additional_signature_length_data);
size_t* const additional_signature_length =
fuzzed_data.ConsumeBool() ? &additional_signature_length_data : nullptr;

View File

@@ -6,20 +6,18 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
if (size < sizeof(OEMCrypto_PrivateKeyType)) {
return 0;
}
LicenseWithUsageEntryFuzz entry;
wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
entry.CreateUsageTableHeader();
// Open a session, create a usage entry.
Session* session = entry.license_messages().session();
wvoec::Session* session = entry.license_messages().session();
session->open();
entry.InstallTestDrmKey(session);
session->GenerateNonce();
@@ -27,15 +25,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
FuzzedDataProvider fuzzed_data(data, size);
const OEMCrypto_PrivateKeyType key_type =
ConvertDataToValidEnum(fuzzed_data, OEMCrypto_PrivateKeyType_MaxValue);
const OEMCrypto_PrivateKeyType key_type = wvoec::ConvertDataToValidEnum(
fuzzed_data, OEMCrypto_PrivateKeyType_MaxValue);
const std::vector<uint8_t> wrapped_private_key =
fuzzed_data.ConsumeRemainingBytes<uint8_t>();
OEMCrypto_InstallOemPrivateKey(session->session_id(), key_type,
wrapped_private_key.data(),
wrapped_private_key.size());
session->close();
OEMCrypto_Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,27 +2,26 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
// Reject the input if it is less than fuzz data structure size.
if (size < sizeof(OEMCrypto_Request_Fuzz)) {
if (size < sizeof(wvoec::OEMCrypto_Request_Fuzz)) {
return 0;
}
// Input for license request API will be modified by OEMCrypto, hence it
// cannot be a const. Fuzzer complains if const identifier is removed of data,
// hence copying data into a non const pointer.
uint8_t* input = new uint8_t[size];
memcpy(input, data, size);
OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.license_messages().InjectFuzzedRequestData(input, size);
delete[] input;
std::vector<uint8_t> input(data, data + size);
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
license_api_fuzz.license_messages().InjectFuzzedRequestData(input.data(),
input.size());
license_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,27 +2,24 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
// Corpus format is as below, let | be separator.
// message buffer with key data | entitled content key object array with
// offsets and lengths to read key data from message buffer.
// Split data using separator.
const std::vector<FuzzedData> inputs = SplitFuzzedData(data, size);
const std::vector<wvoec::FuzzedData> inputs =
wvoec::SplitFuzzedData(data, size);
if (inputs.size() < 2) {
return 0;
}
const std::vector<uint8_t> message(inputs[0].data,
inputs[0].data + inputs[0].size);
// Copy data to OEMCrypto_EntitledContentKeyObject array.
std::vector<OEMCrypto_EntitledContentKeyObject> entitled_content_keys(
inputs[1].size / sizeof(OEMCrypto_EntitledContentKeyObject));
@@ -32,8 +29,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
sizeof(OEMCrypto_EntitledContentKeyObject));
}
// Load default entitlement license.
OEMCryptoLicenseAPIFuzz license_api_fuzz;
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
// Setting up state. Load default entitlement license to load entitlement
// keys into sessions key table.
license_api_fuzz.license_messages().set_license_type(
OEMCrypto_EntitlementLicense);
license_api_fuzz.LoadLicense();
@@ -41,15 +41,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Create entitled key session.
OEMCrypto_SESSION key_session;
const OEMCryptoResult result = OEMCrypto_CreateEntitledKeySession(
license_api_fuzz.session()->session_id(), &key_session);
CheckStatusAndExitFuzzerOnFailure(result, OEMCrypto_SUCCESS);
license_api_fuzz.session().session_id(), &key_session);
wvoec::CheckStatusAndExitFuzzerOnFailure(result, OEMCrypto_SUCCESS);
// Call OEMCrypto_LoadEntitledContentKeys with fuzzed buffers.
OEMCrypto_LoadEntitledContentKeys(key_session, message.data(), message.size(),
entitled_content_keys.size(),
entitled_content_keys.data());
const std::vector<uint8_t> message(inputs[0].data,
inputs[0].data + inputs[0].size);
OEMCrypto_LoadEntitledContentKeys(
license_api_fuzz.session().session_id(), message.data(), message.size(),
entitled_content_keys.size(), entitled_content_keys.data());
license_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -4,27 +4,26 @@
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedLicense) + sizeof(MessageData)) {
wvoec::RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedLicense) + sizeof(wvoec::MessageData)) {
return 0;
}
OEMCryptoLicenseAPIFuzz license_api_fuzz;
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
license_api_fuzz.license_messages().SignAndVerifyRequest();
// Interpreting input fuzz data as unencrypted (core_response + license
// message data) from license server.
license_api_fuzz.license_messages().InjectFuzzedResponseData(data, size);
// Convert OEMCrypto_LicenseType in core_response to a valid enum value.
ConvertDataToValidEnum(
wvoec::ConvertDataToValidEnum(
OEMCrypto_LicenseType_MaxValue,
&license_api_fuzz.license_messages().core_response().license_type);
license_api_fuzz.license_messages().EncryptAndSignResponse();
license_api_fuzz.license_messages().LoadResponse();
license_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -4,17 +4,16 @@
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedProvisioning) + sizeof(RSAPrivateKeyMessage)) {
wvoec::RedirectStdoutToFile();
if (size <
sizeof(ODK_ParsedProvisioning) + sizeof(wvoec::RSAPrivateKeyMessage)) {
return 0;
}
OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
wvoec::OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
provisioning_api_fuzz.Intialize();
provisioning_api_fuzz.provisioning_messages().SignAndVerifyRequest();
// Interpreting input fuzz data as unencrypted(core_response + provisioning
// message data) from provisioning server.
@@ -22,6 +21,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size);
provisioning_api_fuzz.provisioning_messages().EncryptAndSignResponse();
provisioning_api_fuzz.provisioning_messages().LoadResponse();
provisioning_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,41 +2,41 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include "FuzzedDataProvider.h"
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(OEMCrypto_Renewal_Response_Fuzz)) {
return 0;
}
wvoec::RedirectStdoutToFile();
// Copy input data to OEMCrypto_Renewal_Response_Fuzz and rest of message
// into encrypted license_renewal_response.
OEMCrypto_Renewal_Response_Fuzz fuzzed_data;
memcpy(&fuzzed_data, data, sizeof(fuzzed_data));
const uint8_t* renewal_response =
data + sizeof(OEMCrypto_Renewal_Response_Fuzz);
const size_t renewal_response_size =
size - sizeof(OEMCrypto_Renewal_Response_Fuzz);
wvoec::OEMCrypto_Renewal_Response_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) {
return 0;
}
FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
const std::vector<uint8_t> renewal_response =
fuzzed_data.ConsumeRemainingBytes<uint8_t>();
OEMCryptoRenewalAPIFuzz renewal_response_fuzz;
wvoec::OEMCryptoRenewalAPIFuzz renewal_response_fuzz;
renewal_response_fuzz.Intialize();
renewal_response_fuzz.license_messages().SignAndVerifyRequest();
renewal_response_fuzz.license_messages().CreateDefaultResponse();
// Inject timer limits from fuzzed input to timer_limits field from
// core license response.
renewal_response_fuzz.license_messages().InjectFuzzedTimerLimits(fuzzed_data);
renewal_response_fuzz.license_messages().InjectFuzzedTimerLimits(
fuzzed_structure);
renewal_response_fuzz.license_messages().EncryptAndSignResponse();
renewal_response_fuzz.license_messages().LoadResponse();
// Call renewal response API using fuzzed data.
renewal_response_fuzz.renewal_messages().SignAndVerifyRequest();
renewal_response_fuzz.renewal_messages().InjectFuzzedResponseData(
fuzzed_data, renewal_response, renewal_response_size);
fuzzed_structure, renewal_response.data(), renewal_response.size());
renewal_response_fuzz.renewal_messages().LoadResponse();
renewal_response_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -5,9 +5,10 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
namespace {
LicenseWithUsageEntryFuzz entry;
// Avoid calling non-trivial destructor.
wvoec::LicenseWithUsageEntryFuzz& entry = *new wvoec::LicenseWithUsageEntryFuzz;
OEMCryptoResult LoadUsageEntryWithFuzzedData(OEMCrypto_SESSION session,
const uint8_t* data, size_t size) {
@@ -22,11 +23,19 @@ OEMCryptoResult LoadUsageEntryWithFuzzedData(OEMCrypto_SESSION session,
buffer.size());
}
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
entry.Initialize();
return 0;
}
// The custom mutator to mutate created encrypted usage entry.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session();
wvoec::Session* s = entry.license_messages().session();
s->open();
entry.InstallTestDrmKey(s);
if (LoadUsageEntryWithFuzzedData(s->session_id(), data, size) !=
@@ -51,15 +60,9 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
Session s;
wvoec::Session s;
s.open();
LoadUsageEntryWithFuzzedData(s.session_id(), data, size);
s.close();
return 0;
}
} // namespace wvoec

View File

@@ -5,12 +5,11 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
// The custom mutator to mutate created encrypted usage table header.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
LicenseWithUsageEntryFuzz entry;
wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
if (OEMCrypto_LoadUsageTableHeader(data, size) != OEMCrypto_SUCCESS) {
entry.CreateUsageTableHeader();
size = entry.encrypted_usage_header().size();
@@ -21,17 +20,17 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
memcpy(data, entry.encrypted_usage_header().data(),
entry.encrypted_usage_header().size());
}
OEMCrypto_Terminate();
return LLVMFuzzerMutate(data, size, max_size);
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
// Initialize OEMCrypto and call API.
InitializeFuzz initialize_fuzz;
wvoec::SessionUtil session_util;
InitializeFuzz(session_util);
OEMCrypto_LoadUsageTableHeader(data, size);
OEMCrypto_Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -5,29 +5,35 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
LicenseWithUsageEntryFuzz entry;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
namespace {
uint32_t usage_entry_number = 0;
// Avoid calling non-trivial destructor.
wvoec::LicenseWithUsageEntryFuzz& entry = *new wvoec::LicenseWithUsageEntryFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
entry.Initialize();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
uint32_t usage_entry_number;
if (size < sizeof(usage_entry_number)) {
return 0;
}
memcpy(&usage_entry_number, data, sizeof(usage_entry_number));
entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session();
wvoec::Session* s = entry.license_messages().session();
s->open();
entry.InstallTestDrmKey(s);
memcpy(&usage_entry_number, data, sizeof(uint32_t));
s->CreateNewUsageEntry();
vector<uint8_t> encrypted_usage_header;
std::vector<uint8_t> encrypted_usage_header;
s->UpdateUsageEntry(&encrypted_usage_header);
OEMCrypto_MoveEntry(s->session_id(), usage_entry_number);
s ->close();
s->close();
return 0;
}
} // namespace wvoec

View File

@@ -3,7 +3,7 @@
#include "opk_dispatcher.h"
#include "opk_init.h"
namespace wvoec {
namespace {
void OpenOEMCryptoTASession() {
uint8_t request_body[] = {
@@ -35,6 +35,8 @@ void InitializeOEMCryptoTA() {
OPK_DispatchMessage(&request, &response);
}
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
OPK_Initialize();
InitializeOEMCryptoTA();
@@ -51,5 +53,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
OPK_DispatchMessage(&request, &response);
return 0;
}
} // namespace wvoec

View File

@@ -2,27 +2,26 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
// If input size is less than fuzz data structure size, reject the input.
if (size < sizeof(OEMCrypto_Request_Fuzz)) {
if (size < sizeof(wvoec::OEMCrypto_Request_Fuzz)) {
return 0;
}
// Input for provisioning request API will be modified by OEMCrypto, hence it
// cannot be a const. Fuzzer complains if const identifier is removed of data,
// hence copying data into a non const pointer.
uint8_t* input = new uint8_t[size];
memcpy(input, data, size);
OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
provisioning_api_fuzz.provisioning_messages().InjectFuzzedRequestData(input,
size);
delete[] input;
std::vector<uint8_t> input(data, data + size);
wvoec::OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
provisioning_api_fuzz.Intialize();
provisioning_api_fuzz.provisioning_messages().InjectFuzzedRequestData(
input.data(), input.size());
provisioning_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,26 +2,26 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
// If input size is less than fuzz data structure, reject the input.
if (size < sizeof(OEMCrypto_Request_Fuzz)) {
if (size < sizeof(wvoec::OEMCrypto_Request_Fuzz)) {
return 0;
}
// Input for renewal request API will be modified by OEMCrypto, hence it
// cannot be a const. Fuzzer complains if const identifier is removed of data,
// hence copying data into a non const pointer.
uint8_t* input = new uint8_t[size];
memcpy(input, data, size);
OEMCryptoRenewalAPIFuzz renewal_api_fuzz;
renewal_api_fuzz.renewal_messages().InjectFuzzedRequestData(input, size);
delete[] input;
std::vector<uint8_t> input(data, data + size);
wvoec::OEMCryptoRenewalAPIFuzz renewal_api_fuzz;
renewal_api_fuzz.Intialize();
renewal_api_fuzz.renewal_messages().InjectFuzzedRequestData(input.data(),
input.size());
renewal_api_fuzz.Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -2,29 +2,34 @@
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
const size_t MAX_FUZZ_PST_REPORT_BUFFER_LENGTH = 5 * MB;
namespace {
constexpr size_t MAX_FUZZ_PST_REPORT_BUFFER_LENGTH = 5 * wvoec::MB;
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
if (size < sizeof(size_t)) {
return 0;
}
LicenseWithUsageEntryFuzz entry;
wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
entry.CreateUsageTableHeader();
// Open a session, create a usage entry.
Session* session = entry.license_messages().session();
wvoec::Session* session = entry.license_messages().session();
session->open();
entry.InstallTestDrmKey(session);
session->CreateNewUsageEntry();
session->GenerateNonce();
vector<uint8_t> encrypted_usage_header;
std::vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
// Sets pst for usage entry.
entry.LoadLicense();
@@ -38,6 +43,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
OEMCrypto_ReportUsage(session->session_id(), pst.data(), pst.size(),
pst_report_buffer.data(), &pst_report_buffer_length);
session->close();
OEMCrypto_Terminate();
return 0;
}
} // namespace wvoec

View File

@@ -5,29 +5,35 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
LicenseWithUsageEntryFuzz entry;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
namespace {
uint32_t usage_entry_number = 0;
// Avoid calling non-trivial destructor.
wvoec::LicenseWithUsageEntryFuzz& entry = *new wvoec::LicenseWithUsageEntryFuzz;
} // namespace
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
wvoec::RedirectStdoutToFile();
entry.Initialize();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
uint32_t usage_entry_number;
if (size < sizeof(usage_entry_number)) {
return 0;
}
memcpy(&usage_entry_number, data, sizeof(usage_entry_number));
entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session();
wvoec::Session* s = entry.license_messages().session();
s->open();
entry.InstallTestDrmKey(s);
s->CreateNewUsageEntry();
s->close();
s->open();
memcpy(&usage_entry_number, data, sizeof(uint32_t));
OEMCrypto_ReuseUsageEntry(s->session_id(), usage_entry_number);
s->close();
return 0;
}
} // namespace wvoec

View File

@@ -2,30 +2,29 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <vector>
#include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
wvoec::RedirectStdoutToFile();
if (size < sizeof(uint32_t) + sizeof(size_t)) {
return 0;
}
LicenseWithUsageEntryFuzz entry;
wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
entry.CreateUsageTableHeader();
FuzzedDataProvider fuzzed_data(data, size);
const uint32_t new_entry_count = fuzzed_data.ConsumeIntegral<uint32_t>();
size_t header_buffer_length =
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH);
size_t header_buffer_length = fuzzed_data.ConsumeIntegralInRange<size_t>(
0, wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> header_buffer(header_buffer_length);
OEMCrypto_ShrinkUsageTableHeader(new_entry_count, header_buffer.data(),
&header_buffer_length);
OEMCrypto_Terminate();
return 0;
}
} // namespace wvoec