Source release 16.3.0

This commit is contained in:
John W. Bruce
2020-07-24 14:30:03 -07:00
parent b830b1d1fb
commit 160df9f57a
74 changed files with 4632 additions and 2561 deletions

View File

@@ -0,0 +1,187 @@
# OEMCRYPTO Fuzzing
## Objective
* Run fuzzing on OEMCrypto public APIs on linux using google supported
clusterfuzz infrastructure to find security vulnerabilities.
Design Document - https://docs.google.com/document/d/1mdSV2irJZz5Y9uYb5DmSIddBjrAIZU9q8G5Q_BGpA4I/edit?usp=sharing
Fuzzing at google -
[go/fuzzing](https://g3doc.corp.google.com/security/fuzzing/g3doc/fuzzing_resources.md?cl=head)
## Monitoring
### Cluster fuzz statistics
* Performance of OEMCrypto fuzz binaries running continuously using cluster
fuzz infrastructure can be monitored
[here](https://clusterfuzz.corp.google.com/fuzzer-stats).
The options to select are `Job type: libfuzzer_asan_oemcrypto` and `Fuzzer:
fuzzer name you are looking for`
Example: [load_license_fuzz](https://clusterfuzz.corp.google.com/fuzzer-stats?group_by=by-day&date_start=2020-07-11&date_end=2020-07-17&fuzzer=libFuzzer_oemcrypto_load_license_fuzz&job=libfuzzer_asan_oemcrypto)
### Issues filed by clusterfuzz - Fixing those issues
* Any issues found with the fuzz target under test are reported by clusterfuzz
[here](https://b.corp.google.com/hotlists/2442954).
* The bug will have a link to the test case that generated the bug. Download
the test case and follow the steps from
[testing fuzzer locally](#testing-fuzzer-locally) section to run the fuzzer
locally using the test case that caused the crash.
* Once the issue is fixed, consider adding the test case that caused the crash
to the seed corpus zip file. Details about seed corpus and their location
are mentioned in
[this section](#build-oemcrypto-unit-tests-to-generate-corpus).
## Corpus
* Once the fuzzer scripts are ready and running continuously using clusterfuzz
or android infrastructure, we can measure the efficiency of fuzzers by
looking at code coverage and number of new features that have been
discovered by fuzzer scripts here Fuzz script statistics.
A fuzzer which tries to start from random inputs and figure out intelligent
inputs to crash the libraries can be time consuming and not effective. A way
to make fuzzers more effective is by providing a set of valid and invalid
inputs of the library so that fuzzer can use those as a starting point.
These sets of valid and invalid inputs are called corpus.
The idea is to run OEMCrypto unit tests and read required data into binary
corpus files before calling into respective OEMCrypto APIs under test.
Writing corpus data to binary files is controlled by --generate_corpus flag.
### Build OEMCrypto unit tests to generate corpus
* Install Pre-requisites
```shell
$ sudo apt-get install gyp ninja-build
```
* download cdm source code (including ODK & OEMCrypto unit tests):
```shell
$ git clone sso://widevine-internal/cdm
```
* Build OEMCrypto unit tests and run with --generate_corpus flag to generate
corpus files:
```shell
$ cd /path/to/cdm/repo
$ export CDM_DIR=/path/to/cdm/repo
$ export PATH_TO_CDM_DIR=..
$ gyp --format=ninja --depth=$(pwd) oemcrypto/oemcrypto_unittests.gyp
$ ninja -C out/Default/
$ ./out/Default/oemcrypto_unittests --generate_corpus
```
* To avoid uploading huge binary files to git repository, the corpus files
will be saved in fuzzername_seed_corpus.zip format in blockbuster project's
oemcrypto_fuzzing_corpus GCS bucket using gsutil. If you need permissions
for blockbuster project, contact widevine-engprod@google.com.
```shell
$ gsutil cp gs://oemcrypto_fuzzing_corpus/<fuzzername_seed_corpus.zip> \
<destination_path>
```
## Testing fuzzer locally
* Corpus needed to run fuzz tests locally are available in blockbuster
project's oemcrypto_fuzzing_corpus GCS bucket. If you need permissions for
this project, contact widevine-engprod@google.com. Download corpus.
```shell
$ gsutil cp gs://oemcrypto_fuzzing_corpus/<fuzzername_seed_corpus.zip> \
<destination_path>
```
* Add flags to generate additional debugging information. Add '-g3' flag to
oemcrypto_fuzztests.gypi cflags_cc in order to generate additional debug
information locally.
* Build and test fuzz scripts locally using:
```shell
$ export CXX=clang++
$ export CC=clang
$ export GYP_DEFINES="clang=1"
$ cd /path/to/cdm/repo
$ export PATH_TO_CDM_DIR=.
$ gyp --format=ninja --depth=$(pwd) \
oemcrypto/test/fuzz_tests/oemcrypto_fuzztests.gyp
$ ninja -C out/Default/
$ mkdir /tmp/new_interesting_corpus
$ ./out/Default/fuzzer_binary /tmp/new_interesting_corpus \
/path/to/fuzz/seed/corpus/folder
```
* In order to run fuzz script against a crash input, follow the above steps
and run the fuzz binary against crash input rather than seed corpus.
```shell
$ ./out/Default/fuzzer_binary crash_input_file
```
## Adding a new OEMCrypto fuzz script
* In order to fuzz a new OEMCrypto API in future, a fuzz script can be added to
oemcrypto/test/fuzz_tests folder which ends with _fuzz.cc.
* In the program, define the function LLVMFuzzerTestOneInput with the following signature:
```
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
<your test code goes here>
return 0;
}
```
*Note*: Make sure LLVMFuzzerTestOneInput calls the function you want to fuzz.
* Add a new target to oemcrypto_fuzztests.gyp file and follow instructions in
[testing fuzzer locally](#testing-fuzzer-locally) to build and test locally.
## Generate code coverage reports locally
* Code coverage is a means of measuring fuzzer performance. We want to make
sure that our fuzzer covers all the paths in our code and make any tweeks to
fuzzer logic so we can maximize coverage to get better results.
Coverage reports for git on borg project is not automated and needs to be
generated manually. Future plan is to build a dashboard for git on borg
coverage reports.
* In order to generate coverage reports, we need to compile fuzzer binary with
flags to enable coverage. We can remove
`-fsanitize=fuzzer,address,undefined` from oemcrypto_fuzztests.gypi file as
that is needed only while fuzzing. Add following flags to both cflags_cc and
ldflags of oemcrypto_fuzztests.gypi and build fuzz binaries as mentioned in
`Testing fuzzer locally` section.
```
'-fprofile-instr-generate',
'-fcoverage-mapping',
```
* We need to run fuzzer binary against the corpus downloaded from
[clusterfuzz](https://clusterfuzz.corp.google.com/fuzzer-stats). Clock on
download link from corpus_backup column. Use gsutil command to download the
entire corpus for the fuzz binary.
* Use the following commands to generate raw profile data file with coverage
information and generate a html coverage report for a single fuzzer. More
information about clang source based coverage can be found
[here](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html). Follow
[this](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html) for steps
to combine code coverage reports of multiple fuzzers.
```shell
# Run fuzz binary against corpus backup to generate default.profraw file.
$ ./out/Default/fuzz_binary path/to/corpus/backup -runs=0
# Index raw profile files to generate coverage reports.
$ llvm-profdata merge -sparse default.profraw -o default.profdata
# Generate html coverage file.
$ llvm-cov show ./out/Default/fuzz_binary -format=html \
-instr-profile=default.profdata -o default.html
```

View File

@@ -0,0 +1,8 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
void RedirectStdoutToFile() { freopen("log.txt", "a", stdout); }
} // namespace wvoec

View File

@@ -0,0 +1,94 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// 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 "oec_session_util.h"
#include "oemcrypto_corpus_generator_helper.h"
#include "oemcrypto_session_tests_helper.h"
namespace wvoec {
// 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 {
public:
InitializeFuzz() {
wvoec::global_features.Initialize();
OEMCrypto_SetSandbox(kTestSandbox, sizeof(kTestSandbox));
OEMCrypto_Initialize();
EnsureTestKeys();
}
~InitializeFuzz() { OEMCrypto_Terminate(); }
};
class OEMCryptoLicenseAPIFuzz : public InitializeFuzz {
public:
OEMCryptoLicenseAPIFuzz() : license_messages_(&session_) {
session_.open();
InstallTestRSAKey(&session_);
session_.GenerateNonce();
}
~OEMCryptoLicenseAPIFuzz() {
session_.close();
}
LicenseRoundTrip& license_messages() { return license_messages_; }
private:
Session session_;
LicenseRoundTrip license_messages_;
};
class OEMCryptoProvisioningAPIFuzz : public InitializeFuzz {
public:
OEMCryptoProvisioningAPIFuzz()
: provisioning_messages_(&session_, encoded_rsa_key_) {
// Opens a session and Generates Nonce.
provisioning_messages_.PrepareSession(keybox_);
}
~OEMCryptoProvisioningAPIFuzz() { session_.close(); }
ProvisioningRoundTrip& provisioning_messages() {
return provisioning_messages_;
}
private:
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 {
public:
OEMCryptoRenewalAPIFuzz() : renewal_messages_(&license_messages()) {}
RenewalRoundTrip& renewal_messages() { return renewal_messages_; }
private:
RenewalRoundTrip renewal_messages_;
};
// Convert data to valid enum value.
template <typename T>
void ConvertDataToValidEnum(T max_enum_value, T* t) {
FuzzedDataProvider fuzzed_enum_data(reinterpret_cast<uint8_t*>(t), sizeof(T));
*t = static_cast<T>(fuzzed_enum_data.ConsumeIntegralInRange<uint32_t>(
0, static_cast<uint32_t>(max_enum_value)));
}
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
void RedirectStdoutToFile();
} // namespace wvoec
#endif // OEMCRYPTO_FUZZ_HELPER_H_

View File

@@ -0,0 +1,31 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef OEMCRYPTO_FUZZ_STRUCTS_H_
#define OEMCRYPTO_FUZZ_STRUCTS_H_
namespace wvoec {
struct OEMCrypto_Renewal_Response_Fuzz {
// Timer limits in core license response needs to be fuzzed as load renewal
// depends on timer limits loaded from license response.
ODK_TimerLimits timer_limits;
// message(core_response + license_renewal_response) which mimics
// response from license renewal server needs to be fuzzed. core_request
// will be used to generate serialized core response.
oemcrypto_core_message::ODK_RenewalRequest core_request;
// Renewal duration seconds needs to be fuzzed which is part of serialized
// core message from license renewal server.
uint64_t renewal_duration_seconds;
// license_renewal_response is of variable length and not included in this
// structure.
};
struct OEMCrypto_Request_Fuzz {
// We would like to fuzz computed signature_length, input core_message_length
// that ODK parses and actual message buffer to the request APIs.
size_t signature_length;
size_t core_message_length;
};
} // namespace wvoec
#endif // OEMCRYPTO_FUZZ_STRUCTS_H_

View File

@@ -5,20 +5,48 @@
# Builds under the CDM ./build.py (target platform) build system
# Refer to the distribution package's README for details.
{
'variables': {
'oemcrypto_lib%': '',
'target_defaults': {
'type': 'executable',
'includes': [
'oemcrypto_fuzztests.gypi',
],
},
'targets': [
{
'target_name': 'wv_ce_cdm_oemcrypto_generate_signature_fuzz_test',
'type': 'executable',
'target_name': 'oemcrypto_load_license_fuzz',
'sources': [
# The test runner and the testing device certificate.
'oemcrypto_generate_signature.cc',
'oemcrypto_load_license_fuzz.cc',
],
'includes': [
'oemcrypto_fuzztests.gypi',
},
{
'target_name': 'oemcrypto_load_provisioning_fuzz',
'sources': [
'oemcrypto_load_provisioning_fuzz.cc',
],
},
},
{
'target_name': 'oemcrypto_load_renewal_fuzz',
'sources': [
'oemcrypto_load_renewal_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_license_request_fuzz',
'sources': [
'oemcrypto_license_request_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_provisioning_request_fuzz',
'sources': [
'oemcrypto_provisioning_request_fuzz.cc',
],
},
{
'target_name': 'oemcrypto_renewal_request_fuzz',
'sources': [
'oemcrypto_renewal_request_fuzz.cc',
],
},
],
}

View File

@@ -1,48 +1,82 @@
# Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
#source code may only be used and distributed under the Widevine Master License
#Agreement.
#
# Include this in any custom unit test targets.
# Does not include the test runner main.
{
'variables': {
'boringssl_libcrypto_path%': '../../../third_party/boringssl/boringssl.gyp:crypto',
'boringssl_libssl_path%': '../../../third_party/boringssl/boringssl.gyp:ssl',
'oemcrypto_dir': '../..',
'platform_specific_dir': '../../../linux/src',
'privacy_crypto_impl%': 'boringssl',
# Flag used to generate source based code coverage reports.
'generate_code_coverage_report%': 'false',
'util_dir': '../../../util',
},
'sources': [
'../../odk/src/core_message_deserialize.cpp',
'../../odk/src/core_message_serialize.cpp',
'../oec_device_features.cpp',
'../oec_key_deriver.cpp',
'../oemcrypto_corpus_generator_helper.cpp',
'../oec_session_util.cpp',
'../oemcrypto_corpus_generator_helper.cpp',
'oemcrypto_fuzz_helper.cc',
'../oemcrypto_session_tests_helper.cpp',
'../oemcrypto_session_tests_helper.h',
'../../../cdm/test/device_cert.cpp',
'../../../cdm/test/device_cert.h',
'<(platform_specific_dir)/file_store.cpp',
'<(platform_specific_dir)/log.cpp',
'<(util_dir)/src/platform.cpp',
'<(util_dir)/src/rw_lock.cpp',
'<(util_dir)/src/string_conversions.cpp',
'<(util_dir)/test/test_sleep.cpp',
'<(util_dir)/test/test_clock.cpp',
],
'include_dirs': [
'../../../core/include', # log.h
'../../include',
'../../ref/src', # oemcrypto_key_ref.h
'../',
'../../../cdm/test',
'../../../third_party/fuzz',
'<(util_dir)/include',
'<(util_dir)/test',
'<(oemcrypto_dir)/include',
'<(oemcrypto_dir)/ref/src',
'<(oemcrypto_dir)/test',
'<(oemcrypto_dir)/test/fuzz_tests',
'<(oemcrypto_dir)/odk/include',
'<(oemcrypto_dir)/odk/src',
],
'defines': [
'OEMCRYPTO_TESTS',
'OEMCRYPTO_FUZZ_TESTS',
],
'libraries': [
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
'includes': [
'../../../util/libssl_dependency.gypi',
'../../ref/oec_ref.gypi',
],
'dependencies': [
'../../../cdm/cdm.gyp:widevine_ce_cdm_shared',
'../../../third_party/gmock.gyp:gmock',
'../../../third_party/gmock.gyp:gtest',
'../../../third_party/gmock.gyp:gmock',
],
'defines': [
'OEMCRYPTO_FUZZ_TESTS',
],
'conditions': [
['oemcrypto_lib==""', {
'includes': [
'../../ref/oec_ref.gypi',
],
}, {
'libraries': [
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
'<(oemcrypto_lib)',
],
['generate_code_coverage_report=="false"', {
# Include flags to build fuzzer binaries for cluster fuzz.
'cflags_cc': [
'-std=c++11',
'-fsanitize=fuzzer,address,undefined',
# Need -g flag to include source line numbers in error stack trace.
'-g',
],
}],
['generate_code_coverage_report=="true"', {
# Include flags to build fuzzer binaries to generate source based code coverage reports.
'cflags_cc': [
'-std=c++11',
'-fprofile-instr-generate',
'-fcoverage-mapping',
],
}],
], # conditions
'ldflags': [
'-fPIC',
'-fsanitize=fuzzer,address,undefined',
],
'libraries': [
'-lpthread',
],
}

View File

@@ -0,0 +1,28 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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();
// Reject the input if it is less than fuzz data structure size.
if (size < sizeof(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;
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,30 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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)) {
return 0;
}
OEMCryptoLicenseAPIFuzz license_api_fuzz;
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(
OEMCrypto_LicenstType_MaxValue,
&license_api_fuzz.license_messages().core_response().license_type);
license_api_fuzz.license_messages().EncryptAndSignResponse();
license_api_fuzz.license_messages().LoadResponse();
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,27 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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)) {
return 0;
}
OEMCryptoProvisioningAPIFuzz provisioning_api_fuzz;
provisioning_api_fuzz.provisioning_messages().SignAndVerifyRequest();
// Interpreting input fuzz data as unencrypted(core_response + provisioning
// message data) from provisioning server.
provisioning_api_fuzz.provisioning_messages().InjectFuzzedResponseData(data,
size);
provisioning_api_fuzz.provisioning_messages().EncryptAndSignResponse();
provisioning_api_fuzz.provisioning_messages().LoadResponse();
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,42 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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;
}
// 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);
OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.license_messages().SignAndVerifyRequest();
license_api_fuzz.license_messages().CreateDefaultResponse();
// Inject timer limits from fuzzed input to timer_limits field from
// core license response.
license_api_fuzz.license_messages().InjectFuzzedTimerLimits(fuzzed_data);
license_api_fuzz.license_messages().EncryptAndSignResponse();
license_api_fuzz.license_messages().LoadResponse();
OEMCryptoRenewalAPIFuzz renewal_response_fuzz;
renewal_response_fuzz.renewal_messages().SignAndVerifyRequest();
renewal_response_fuzz.renewal_messages().InjectFuzzedResponseData(
fuzzed_data, renewal_response, renewal_response_size);
renewal_response_fuzz.renewal_messages().LoadResponse();
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,28 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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 input size is less than fuzz data structure size, reject the input.
if (size < sizeof(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;
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,27 @@
// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#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 input size is less than fuzz data structure, reject the input.
if (size < sizeof(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;
return 0;
}
} // namespace wvoec