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_helper.h"
#include "oemcrypto_fuzz_structs.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) { 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 // OEMCrypto_DestBufferDesc and a buffer from which data needs to be copied
// are expected as inputs to copy buffer API. // are expected as inputs to copy buffer API.
// Input fuzzed data is interpreted as: // Input fuzzed data is interpreted as:
// (OEMCrypto_DestBufferDesc | subsample_flags | input_buffer) // (OEMCrypto_DestBufferDesc | subsample_flags | input_buffer)
OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure; wvoec::OEMCrypto_Copy_Buffer_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) { if (size < sizeof(fuzzed_structure)) {
return 0; return 0;
} }
FuzzedDataProvider fuzzed_data(data, size); FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure)); fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_BufferType_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_BufferType_MaxValue,
&fuzzed_structure.dest_buffer_desc.type); &fuzzed_structure.dest_buffer_desc.type);
fuzzed_structure.dest_buffer_desc.buffer_config %= MAX_FUZZ_OUTPUT_LENGTH + 1; fuzzed_structure.dest_buffer_desc.buffer_config %=
wvoec::MAX_FUZZ_OUTPUT_LENGTH + 1;
const std::vector<OEMCrypto_SharedMemory> input_buffer = const std::vector<OEMCrypto_SharedMemory> input_buffer =
fuzzed_data.ConsumeRemainingBytes<OEMCrypto_SharedMemory>(); 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. // Initialize output buffer.
OEMCrypto_DestBufferDesc dest_buffer_desc; OEMCrypto_DestBufferDesc dest_buffer_desc;
@@ -79,5 +87,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0; return 0;
} }
} // namespace wvoec

View File

@@ -5,15 +5,15 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const 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 wvoec::RedirectStdoutToFile();
// reduce noise
RedirectStdoutToFile(); if (size < sizeof(ODK_ParsedLicense) + sizeof(wvoec::MessageData)) {
if (size < sizeof(ODK_ParsedLicense) + sizeof(MessageData)) {
return 0; return 0;
} }
OEMCryptoLicenseAPIFuzz license_api_fuzz;
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
license_api_fuzz.license_messages().set_license_type( license_api_fuzz.license_messages().set_license_type(
OEMCrypto_EntitlementLicense); OEMCrypto_EntitlementLicense);
license_api_fuzz.license_messages().SignAndVerifyRequest(); 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); OEMCrypto_RemoveEntitledKeySession(key_session_id);
license_api_fuzz.Terminate();
return 0; return 0;
} }
} // namespace wvoec

View File

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

View File

@@ -2,42 +2,55 @@
// source code may only be used and distributed under the Widevine // source code may only be used and distributed under the Widevine
// License Agreement. // License Agreement.
#include <vector>
#include "FuzzedDataProvider.h" #include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oec_session_util.h" #include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h" #include "oemcrypto_fuzz_structs.h"
namespace wvoec { namespace {
// Limit output buffer size to 5 MB as 4 MB is maximum size specified by // Limit output buffer size to 5 MB as 4 MB is maximum size specified by
// resource rating tier documentation. // 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) { 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. // 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) { if (inputs.size() < 3) {
return 0; return 0;
} }
// Read cipher mode and pattern from fuzzed data. // 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)) { if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0; return 0;
} }
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size); FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure)); fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode); &fuzzed_structure.cipher_mode);
// Allocate sample descriptions. // Allocate sample descriptions.
std::vector<OEMCrypto_SampleDescription> 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. // Allocate input buffers for each sample description.
std::vector<std::vector<OEMCrypto_SharedMemory>> input_buffers( 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( std::vector<std::vector<OEMCrypto_SubSampleDescription>> subsamples(
sample_descriptions.size()); 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. // Free first given number of output buffers.
const auto FreeOutputBuffers = [&sample_descriptions, session_id, 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); FuzzedDataProvider subsample_data(inputs[2].data, inputs[2].size);
for (size_t i = 0; i < sample_descriptions.size(); i++) { for (size_t i = 0; i < sample_descriptions.size(); i++) {
// Read and normalize sample description fuzzed properties. // 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, sample_description_data.ConsumeData(&fuzzed_sample_description,
sizeof(fuzzed_sample_description)); sizeof(fuzzed_sample_description));
fuzzed_sample_description.buffers.input_data_length %= fuzzed_sample_description.buffers.input_data_length %=
MAX_FUZZ_SAMPLE_SIZE + 1; MAX_FUZZ_SAMPLE_SIZE + 1;
ConvertDataToValidEnum( wvoec::ConvertDataToValidEnum(
OEMCrypto_BufferType_MaxValue, OEMCrypto_BufferType_MaxValue,
&fuzzed_sample_description.buffers.output_descriptor.type); &fuzzed_sample_description.buffers.output_descriptor.type);
fuzzed_sample_description.buffers.output_descriptor.buffer_config %= 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. // Initialize output buffer.
OEMCrypto_DestBufferDesc& output_descriptor = OEMCrypto_DestBufferDesc& output_descriptor =
sample_descriptions[i].buffers.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; fuzzed_sample_description.buffers.output_descriptor;
output_descriptor.type = fuzzed_output_descriptor.type; output_descriptor.type = fuzzed_output_descriptor.type;
switch (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. // Load license and call decrypt_cenc API.
license_api_fuzz.LoadLicense(); const wvoec::MessageKeyData& key =
const MessageKeyData& key = license_api_fuzz.session()->license().keys[0]; license_api_fuzz.session().license().keys[0];
vector<uint8_t> key_handle; std::vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session_id, key.key_id, key.key_id_length, wvoec::GetKeyHandleIntoVector(session_id, key.key_id, key.key_id_length,
fuzzed_structure.cipher_mode, key_handle); fuzzed_structure.cipher_mode, key_handle);
OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(),
sample_descriptions.data(), sample_descriptions.size(), sample_descriptions.data(), sample_descriptions.size(),
&fuzzed_structure.pattern); &fuzzed_structure.pattern);
@@ -168,5 +180,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0; return 0;
} }
} // namespace wvoec

View File

@@ -9,23 +9,21 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
using namespace wvoec;
extern "C" int LLVMFuzzerTestOneInput(const 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 wvoec::RedirectStdoutToFile();
// reduce noise
RedirectStdoutToFile(); wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
OEMCryptoLicenseAPIFuzz license_api_fuzz;
FuzzedDataProvider fuzzed_data(data, size); FuzzedDataProvider fuzzed_data(data, size);
if (fuzzed_data.ConsumeBool()) { if (fuzzed_data.ConsumeBool()) {
license_api_fuzz.license_messages().set_control( license_api_fuzz.license_messages().set_control(
license_api_fuzz.license_messages().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 std::array<uint8_t, 16> content_key_id{};
const uint32_t frame_number = fuzzed_data.ConsumeIntegral<uint32_t>(); const uint32_t frame_number = fuzzed_data.ConsumeIntegral<uint32_t>();
std::array<OEMCrypto_SharedMemory, 1> sample_buffer{}; 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(); license_api_fuzz.LoadLicense();
std::vector<uint8_t> key_handle; std::vector<uint8_t> key_handle;
GetKeyHandleIntoVector(session_id, content_key_id.data(), wvoec::GetKeyHandleIntoVector(session_id, content_key_id.data(),
content_key_id.size(), OEMCrypto_CipherMode_CENC, content_key_id.size(),
key_handle); OEMCrypto_CipherMode_CENC, key_handle);
OEMCrypto_SetDecryptHash(session_id, frame_number, hash.data(), hash.size()); OEMCrypto_SetDecryptHash(session_id, frame_number, hash.data(), hash.size());
OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), &sample, 1, OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), &sample, 1,
&pattern); &pattern);
OEMCrypto_GetHashErrorCode(session_id, failed_frame_number); OEMCrypto_GetHashErrorCode(session_id, failed_frame_number);
license_api_fuzz.Terminate();
return 0; return 0;
} }

View File

@@ -1,9 +1,12 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary // Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine // source code may only be used and distributed under the Widevine
// License Agreement. // License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec { namespace wvoec {
void RedirectStdoutToFile() { freopen("log.txt", "a", stdout); } void RedirectStdoutToFile() { freopen("log.txt", "a", stdout); }
std::vector<FuzzedData> SplitFuzzedData(const uint8_t* data, size_t size) { 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; 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() { void OEMCryptoLicenseAPIFuzz::LoadLicense() {
license_messages_.SignAndVerifyRequest(); license_messages_.SignAndVerifyRequest();
license_messages_.CreateDefaultResponse(); license_messages_.CreateDefaultResponse();
@@ -30,6 +53,18 @@ void OEMCryptoLicenseAPIFuzz::LoadLicense() {
CheckStatusAndExitFuzzerOnFailure(sts, OEMCrypto_SUCCESS); 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() { void OEMCryptoProvisioningAPIFuzz::LoadProvisioning() {
provisioning_messages_.SignAndVerifyRequest(); provisioning_messages_.SignAndVerifyRequest();
provisioning_messages_.CreateDefaultResponse(); provisioning_messages_.CreateDefaultResponse();
@@ -62,4 +97,5 @@ void CheckStatusAndExitFuzzerOnFailure(OEMCryptoResult result,
abort(); abort();
} }
} }
} // namespace wvoec } // namespace wvoec

View File

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

View File

@@ -8,33 +8,42 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.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) { 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); FuzzedDataProvider fuzzed_data(data, size);
// public_key and public_key_length parameters // public_key and public_key_length parameters
size_t public_key_length_data = size_t public_key_length_data = fuzzed_data.ConsumeIntegralInRange<size_t>(
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH); 0, wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> public_key(public_key_length_data); std::vector<uint8_t> public_key(public_key_length_data);
size_t* const public_key_length = size_t* const public_key_length =
fuzzed_data.ConsumeBool() ? &public_key_length_data : nullptr; fuzzed_data.ConsumeBool() ? &public_key_length_data : nullptr;
// public_key_signature and public_key_signature_length parameters // public_key_signature and public_key_signature_length parameters
size_t public_key_signature_length_data = 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); std::vector<uint8_t> public_key_signature(public_key_signature_length_data);
size_t* const public_key_signature_length = size_t* const public_key_signature_length =
fuzzed_data.ConsumeBool() ? &public_key_signature_length_data : nullptr; fuzzed_data.ConsumeBool() ? &public_key_signature_length_data : nullptr;
// wrapped_private_key and wrapped_private_key_length parameters // wrapped_private_key and wrapped_private_key_length parameters
size_t wrapped_private_key_length_data = 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); std::vector<uint8_t> wrapped_private_key(wrapped_private_key_length_data);
size_t* const wrapped_private_key_length = size_t* const wrapped_private_key_length =
fuzzed_data.ConsumeBool() ? &wrapped_private_key_length_data : nullptr; 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; fuzzed_data.ConsumeBool() ? &key_type_data : nullptr;
OEMCrypto_GenerateCertificateKeyPair( 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_length, public_key_signature.data(),
public_key_signature_length, wrapped_private_key.data(), public_key_signature_length, wrapped_private_key.data(),
wrapped_private_key_length, key_type); wrapped_private_key_length, key_type);

View File

@@ -2,36 +2,33 @@
// source code may only be used and distributed under the Widevine // source code may only be used and distributed under the Widevine
// License Agreement. // License Agreement.
#include <vector>
#include "FuzzedDataProvider.h" #include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const 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 wvoec::RedirectStdoutToFile();
// reduce noise
RedirectStdoutToFile();
OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure; wvoec::OEMCrypto_Generate_RSA_Signature_Fuzz fuzzed_structure;
if (size < sizeof(fuzzed_structure)) { if (size < sizeof(fuzzed_structure)) {
return 0; return 0;
} }
FuzzedDataProvider fuzzed_data(data, size); FuzzedDataProvider fuzzed_data(data, size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure)); fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
fuzzed_structure.signature_length %= wvoec::MAX_FUZZ_OUTPUT_LENGTH + 1;
const std::vector<uint8_t> message = const std::vector<uint8_t> message =
fuzzed_data.ConsumeRemainingBytes<uint8_t>(); 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); std::vector<uint8_t> signature(fuzzed_structure.signature_length);
wvoec::OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.Initialize();
OEMCrypto_GenerateRSASignature( 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, signature.data(), &fuzzed_structure.signature_length,
fuzzed_structure.padding_scheme); fuzzed_structure.padding_scheme);
license_api_fuzz.Terminate();
return 0; return 0;
} }
} // namespace wvoec

View File

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

View File

@@ -2,37 +2,47 @@
// source code may only be used and distributed under the Widevine // source code may only be used and distributed under the Widevine
// License Agreement. // License Agreement.
#include <vector>
#include "FuzzedDataProvider.h" #include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.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) { 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. // 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) { if (inputs.size() < 2) {
return 0; return 0;
} }
OEMCrypto_Generic_Api_Fuzz fuzzed_structure; wvoec::OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
if (inputs[0].size < sizeof(fuzzed_structure)) { if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0; return 0;
} }
// Copy OEMCrypto_Generic_Api_Fuzz from input data. // Copy OEMCrypto_Generic_Api_Fuzz from input data.
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size); FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure)); fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode); &fuzzed_structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm); &fuzzed_structure.algorithm);
// Copy iv from input data. // Copy iv from input data.
const std::vector<uint8_t> iv = fuzzed_data.ConsumeRemainingBytes<uint8_t>(); 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); inputs[1].data + inputs[1].size);
std::vector<uint8_t> clear_buffer(encrypted_buffer.size()); std::vector<uint8_t> clear_buffer(encrypted_buffer.size());
OEMCryptoLicenseAPIFuzz license_api_fuzz; wvoec::Session& session = license_api_fuzz.session();
Session* session = license_api_fuzz.session(); std::vector<uint8_t> key_handle;
// Load license and call generic_decrypt API. wvoec::GetKeyHandleIntoVector(session.session_id(),
license_api_fuzz.LoadLicense(); session.license().keys[0].key_id,
vector<uint8_t> key_handle; session.license().keys[0].key_id_length,
GetKeyHandleIntoVector(session->session_id(), fuzzed_structure.cipher_mode, key_handle);
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(), OEMCrypto_Generic_Decrypt(key_handle.data(), key_handle.size(),
encrypted_buffer.data(), encrypted_buffer.size(), encrypted_buffer.data(), encrypted_buffer.size(),
iv.data(), fuzzed_structure.algorithm, iv.data(), fuzzed_structure.algorithm,
clear_buffer.data()); clear_buffer.data());
return 0; return 0;
} }
} // namespace wvoec

View File

@@ -2,37 +2,47 @@
// source code may only be used and distributed under the Widevine // source code may only be used and distributed under the Widevine
// License Agreement. // License Agreement.
#include <vector>
#include "FuzzedDataProvider.h" #include "FuzzedDataProvider.h"
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_session_util.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
#include "oemcrypto_fuzz_structs.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) { 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. // 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) { if (inputs.size() < 2) {
return 0; return 0;
} }
OEMCrypto_Generic_Api_Fuzz fuzzed_structure; wvoec::OEMCrypto_Generic_Api_Fuzz fuzzed_structure;
if (inputs[0].size < sizeof(fuzzed_structure)) { if (inputs[0].size < sizeof(fuzzed_structure)) {
return 0; return 0;
} }
// Copy OEMCrypto_Generic_Api_Fuzz from input data. // Copy OEMCrypto_Generic_Api_Fuzz from input data.
FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size); FuzzedDataProvider fuzzed_data(inputs[0].data, inputs[0].size);
fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure)); fuzzed_data.ConsumeData(&fuzzed_structure, sizeof(fuzzed_structure));
ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_CipherMode_MaxValue,
&fuzzed_structure.cipher_mode); &fuzzed_structure.cipher_mode);
ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue, wvoec::ConvertDataToValidEnum(OEMCrypto_Algorithm_MaxValue,
&fuzzed_structure.algorithm); &fuzzed_structure.algorithm);
// Copy iv from input data. // Copy iv from input data.
const std::vector<uint8_t> iv = fuzzed_data.ConsumeRemainingBytes<uint8_t>(); 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); inputs[1].data + inputs[1].size);
std::vector<uint8_t> encrypted_buffer(clear_buffer.size()); std::vector<uint8_t> encrypted_buffer(clear_buffer.size());
OEMCryptoLicenseAPIFuzz license_api_fuzz; wvoec::Session& session = license_api_fuzz.session();
Session* session = license_api_fuzz.session(); std::vector<uint8_t> key_handle;
// Load license and call generic_encrypt API. wvoec::GetKeyHandleIntoVector(session.session_id(),
license_api_fuzz.LoadLicense(); session.license().keys[0].key_id,
vector<uint8_t> key_handle; session.license().keys[0].key_id_length,
GetKeyHandleIntoVector(session->session_id(), fuzzed_structure.cipher_mode, key_handle);
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(), OEMCrypto_Generic_Encrypt(key_handle.data(), key_handle.size(),
clear_buffer.data(), clear_buffer.size(), iv.data(), clear_buffer.data(), clear_buffer.size(), iv.data(),
fuzzed_structure.algorithm, fuzzed_structure.algorithm,
encrypted_buffer.data()); encrypted_buffer.data());
return 0; return 0;
} }
} // namespace wvoec

View File

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

View File

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

View File

@@ -8,26 +8,27 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.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) { 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); FuzzedDataProvider fuzzed_data(data, size);
// bcc and bcc_length parameters // bcc and bcc_length parameters
size_t bcc_length_data = size_t bcc_length_data = fuzzed_data.ConsumeIntegralInRange<size_t>(
fuzzed_data.ConsumeIntegralInRange<size_t>(0, MAX_FUZZ_OUTPUT_LENGTH); 0, wvoec::MAX_FUZZ_OUTPUT_LENGTH);
std::vector<uint8_t> bcc(bcc_length_data); std::vector<uint8_t> bcc(bcc_length_data);
size_t* const bcc_length = size_t* const bcc_length =
fuzzed_data.ConsumeBool() ? &bcc_length_data : nullptr; fuzzed_data.ConsumeBool() ? &bcc_length_data : nullptr;
// additional_signature and additional_signature_length parameters // additional_signature and additional_signature_length parameters
size_t additional_signature_length_data = 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); std::vector<uint8_t> additional_signature(additional_signature_length_data);
size_t* const additional_signature_length = size_t* const additional_signature_length =
fuzzed_data.ConsumeBool() ? &additional_signature_length_data : nullptr; fuzzed_data.ConsumeBool() ? &additional_signature_length_data : nullptr;

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,17 +4,16 @@
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const 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 wvoec::RedirectStdoutToFile();
// reduce noise
RedirectStdoutToFile(); if (size <
if (size < sizeof(ODK_ParsedProvisioning) + sizeof(RSAPrivateKeyMessage)) { sizeof(ODK_ParsedProvisioning) + sizeof(wvoec::RSAPrivateKeyMessage)) {
return 0; return 0;
} }
OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz; wvoec::OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
provisioning_api_fuzz.Intialize();
provisioning_api_fuzz.provisioning_messages().SignAndVerifyRequest(); provisioning_api_fuzz.provisioning_messages().SignAndVerifyRequest();
// Interpreting input fuzz data as unencrypted(core_response + provisioning // Interpreting input fuzz data as unencrypted(core_response + provisioning
// message data) from provisioning server. // message data) from provisioning server.
@@ -22,6 +21,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size); size);
provisioning_api_fuzz.provisioning_messages().EncryptAndSignResponse(); provisioning_api_fuzz.provisioning_messages().EncryptAndSignResponse();
provisioning_api_fuzz.provisioning_messages().LoadResponse(); provisioning_api_fuzz.provisioning_messages().LoadResponse();
provisioning_api_fuzz.Terminate();
return 0; return 0;
} }
} // namespace wvoec

View File

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

View File

@@ -5,9 +5,10 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.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, OEMCryptoResult LoadUsageEntryWithFuzzedData(OEMCrypto_SESSION session,
const uint8_t* data, size_t size) { const uint8_t* data, size_t size) {
@@ -22,11 +23,19 @@ OEMCryptoResult LoadUsageEntryWithFuzzedData(OEMCrypto_SESSION session,
buffer.size()); 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. // The custom mutator to mutate created encrypted usage entry.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) { size_t max_size, unsigned int seed) {
entry.CreateUsageTableHeader(); entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session(); wvoec::Session* s = entry.license_messages().session();
s->open(); s->open();
entry.InstallTestDrmKey(s); entry.InstallTestDrmKey(s);
if (LoadUsageEntryWithFuzzedData(s->session_id(), data, size) != 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) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to wvoec::Session s;
// reduce noise
RedirectStdoutToFile();
Session s;
s.open(); s.open();
LoadUsageEntryWithFuzzedData(s.session_id(), data, size); LoadUsageEntryWithFuzzedData(s.session_id(), data, size);
s.close(); s.close();
return 0; return 0;
} }
} // namespace wvoec

View File

@@ -5,12 +5,11 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec {
// The custom mutator to mutate created encrypted usage table header. // The custom mutator to mutate created encrypted usage table header.
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) { size_t max_size, unsigned int seed) {
LicenseWithUsageEntryFuzz entry; wvoec::LicenseWithUsageEntryFuzz entry;
entry.Initialize();
if (OEMCrypto_LoadUsageTableHeader(data, size) != OEMCrypto_SUCCESS) { if (OEMCrypto_LoadUsageTableHeader(data, size) != OEMCrypto_SUCCESS) {
entry.CreateUsageTableHeader(); entry.CreateUsageTableHeader();
size = entry.encrypted_usage_header().size(); 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(), memcpy(data, entry.encrypted_usage_header().data(),
entry.encrypted_usage_header().size()); entry.encrypted_usage_header().size());
} }
OEMCrypto_Terminate();
return LLVMFuzzerMutate(data, size, max_size); return LLVMFuzzerMutate(data, size, max_size);
} }
extern "C" int LLVMFuzzerTestOneInput(const 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 wvoec::RedirectStdoutToFile();
// reduce noise
RedirectStdoutToFile();
// Initialize OEMCrypto and call API. // Initialize OEMCrypto and call API.
InitializeFuzz initialize_fuzz; wvoec::SessionUtil session_util;
InitializeFuzz(session_util);
OEMCrypto_LoadUsageTableHeader(data, size); OEMCrypto_LoadUsageTableHeader(data, size);
OEMCrypto_Terminate();
return 0; return 0;
} }
} // namespace wvoec

View File

@@ -5,29 +5,35 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec { namespace {
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();
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)) { if (size < sizeof(usage_entry_number)) {
return 0; return 0;
} }
memcpy(&usage_entry_number, data, sizeof(usage_entry_number));
entry.CreateUsageTableHeader(); entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session(); wvoec::Session* s = entry.license_messages().session();
s->open(); s->open();
entry.InstallTestDrmKey(s); entry.InstallTestDrmKey(s);
memcpy(&usage_entry_number, data, sizeof(uint32_t));
s->CreateNewUsageEntry(); s->CreateNewUsageEntry();
vector<uint8_t> encrypted_usage_header; std::vector<uint8_t> encrypted_usage_header;
s->UpdateUsageEntry(&encrypted_usage_header); s->UpdateUsageEntry(&encrypted_usage_header);
OEMCrypto_MoveEntry(s->session_id(), usage_entry_number); OEMCrypto_MoveEntry(s->session_id(), usage_entry_number);
s ->close(); s->close();
return 0; return 0;
} }
} // namespace wvoec

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,29 +5,35 @@
#include "OEMCryptoCENC.h" #include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h" #include "oemcrypto_fuzz_helper.h"
namespace wvoec { namespace {
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();
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)) { if (size < sizeof(usage_entry_number)) {
return 0; return 0;
} }
memcpy(&usage_entry_number, data, sizeof(usage_entry_number));
entry.CreateUsageTableHeader(); entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session(); wvoec::Session* s = entry.license_messages().session();
s->open(); s->open();
entry.InstallTestDrmKey(s); entry.InstallTestDrmKey(s);
s->CreateNewUsageEntry(); s->CreateNewUsageEntry();
s->close(); s->close();
s->open(); s->open();
memcpy(&usage_entry_number, data, sizeof(uint32_t));
OEMCrypto_ReuseUsageEntry(s->session_id(), usage_entry_number); OEMCrypto_ReuseUsageEntry(s->session_id(), usage_entry_number);
s->close(); s->close();
return 0; return 0;
} }
} // namespace wvoec

View File

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