Copy submitted odk fuzzing changes from cdm repository to android
Merging odk changes from http://go/wvgerrit/98084 Copy submitted changes for oemcrypto/odk/test/fuzzing from cdm repository to android so that fuzzer scripts in odk can be run using go/android-fuzzing Google3 CLs: http://cl/301943247 http://cl/304011238 http://cl/307142293 http://cl/307087692 Bug: 150900870 Test: The fuzzer scripts can be built once the code is moved to android tree. Odk fuzzer scripts have been verified and successfully running in google3 Change-Id: I92b8a357c32b145c7f80bdc93d05214862368957
This commit is contained in:
168
libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp
Normal file
168
libwvdrmengine/oemcrypto/odk/test/fuzzing/Android.bp
Normal file
@@ -0,0 +1,168 @@
|
||||
// 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.
|
||||
|
||||
cc_defaults {
|
||||
name: "odk_fuzz_library_defaults",
|
||||
srcs: [
|
||||
"odk_fuzz_helper.cpp",
|
||||
],
|
||||
include_dirs: [
|
||||
"vendor/widevine/libwvdrmengine/oemcrypto/odk/test",
|
||||
"vendor/widevine/libwvdrmengine/oemcrypto/odk/include",
|
||||
"vendor/widevine/libwvdrmengine/oemcrypto/odk/src",
|
||||
],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_license_request_fuzz",
|
||||
srcs: [
|
||||
"odk_license_request_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/license_request_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_renewal_request_fuzz",
|
||||
srcs: [
|
||||
"odk_renewal_request_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/renewal_request_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_provisioning_request_fuzz",
|
||||
srcs: [
|
||||
"odk_provisioning_request_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/provisioning_request_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_license_response_fuzz",
|
||||
srcs: [
|
||||
"odk_license_response_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/license_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_renewal_response_fuzz",
|
||||
srcs: [
|
||||
"odk_renewal_response_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/renewal_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_provisioning_response_fuzz",
|
||||
srcs: [
|
||||
"odk_provisioning_response_fuzz.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/provisioning_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_license_response_fuzz_with_mutator",
|
||||
srcs: [
|
||||
"odk_license_response_fuzz_with_mutator.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/license_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_renewal_response_fuzz_with_mutator",
|
||||
srcs: [
|
||||
"odk_renewal_response_fuzz_with_mutator.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/renewal_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "odk_provisioning_response_fuzz_with_mutator",
|
||||
srcs: [
|
||||
"odk_provisioning_response_fuzz_with_mutator.cpp",
|
||||
],
|
||||
fuzz_config: {
|
||||
componentid: 425099,
|
||||
},
|
||||
corpus: ["corpus/arm64/provisioning_response_corpus/*"],
|
||||
static_libs: [
|
||||
"libwv_kdo",
|
||||
"libwv_odk",
|
||||
],
|
||||
defaults: ["odk_fuzz_library_defaults"],
|
||||
proprietary: true,
|
||||
}
|
||||
19
libwvdrmengine/oemcrypto/odk/test/fuzzing/README.md
Normal file
19
libwvdrmengine/oemcrypto/odk/test/fuzzing/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# ODK Fuzzing
|
||||
|
||||
## Objective
|
||||
|
||||
* Run fuzzing on ODK and KDO serialize and deserialize APIs using google
|
||||
supported fuzzer engines to find security vulnerabilities. Any issues found
|
||||
by clusterfuzz will be reported to
|
||||
[odk fuzz buganizer](https://b.corp.google.com/issues?q=componentid:425099%20status:open%20reporter:cluster-fuzz-googleplex@google.com).
|
||||
|
||||
## Run fuzz target on local machine
|
||||
|
||||
* In order to run fuzz target locally and see code coverage, save binary input
|
||||
to be tested against fuzz target into a temporary corpus directory and
|
||||
execute following commands
|
||||
|
||||
```shell
|
||||
$ blaze build --config=asan-fuzzer //your:target
|
||||
$ blaze-bin/your/target FULL_CORPUS_DIR
|
||||
```
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"componentid":425099}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,76 @@
|
||||
# Objective
|
||||
|
||||
The Idea behind the corpus generator code is to intercept OEMCrypto unit test
|
||||
calls to odk APIs using LD_PRELOAD and read the data into corpus files which can
|
||||
be fed as corpus to fuzzer scripts.
|
||||
|
||||
LD_PRELOAD command needs to be run from cdm repository while running oemcrypto
|
||||
unit tests.
|
||||
|
||||
## Get OEMCrypto and Build OEMCrypto unit tests:
|
||||
|
||||
* 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
|
||||
```
|
||||
|
||||
* We need to run odk as a dynamic library in order to use LD_PRELOAD, apply
|
||||
patch from go/wvgerrit/95090 to locally cloned repo which has changes to run
|
||||
odk as dynamic library:
|
||||
|
||||
```shell
|
||||
$ cd /path/to/cdm/repo
|
||||
$ git fetch origin 209721cc901745999e08e35466e74f708321267e
|
||||
$ git cherry-pick FETCH_HEAD
|
||||
```
|
||||
|
||||
* Build OEMCrypto unit tests:
|
||||
|
||||
```shell
|
||||
$ cd /path/to/cdm/repo
|
||||
$ export PATH_TO_CDM_DIR=..
|
||||
$ gyp --format=ninja --depth=$(pwd) oemcrypto/oemcrypto_unittests.gyp
|
||||
$ ninja -C out/Default/
|
||||
```
|
||||
|
||||
## Capture corpus for odk fuzzer by intercepting OEMCrypto unit tests:
|
||||
|
||||
When we run LD_PRELOAD command odk_corpus_generator.so gets preloaded before
|
||||
oemcrypto_unittests and odk_corpus_generator has functions to intercept calls to
|
||||
ODK request and response APIs. Each call to odk API from oemcrypto_unittests
|
||||
gets intercepted and input to ODK de serialize response APIs and output from ODK
|
||||
serialize request APIs is captured in binary format and stored into corpus files
|
||||
|
||||
In order to run LD_PRELOAD command, we need to compile corpus generator shared
|
||||
library and need to preload that before OEMCrypto unit tests run
|
||||
|
||||
* Compile shared library
|
||||
|
||||
```shell
|
||||
$ cd /path/to/cdm/repo
|
||||
$ gyp --format=ninja --depth=$(pwd) oemcrypto/odk/test/fuzzing/corpus_generator/odk_fuzz_corpus_generator.gyp
|
||||
$ ninja -C out/Default/
|
||||
```
|
||||
|
||||
* Preload the shared library before running OEMCrypto unit tests
|
||||
|
||||
```shell
|
||||
$ LD_PRELOAD=out/Default/lib/libodk_corpus_generator.so ./out/Default/oemcrypto_unittests
|
||||
```
|
||||
|
||||
LD_PRELOAD command runs oemcrypto_unittests with odk_corpus_generator as
|
||||
interceptor. We should see unit tests being executed. The corpus files in binary
|
||||
format will be captured into `oemcrypto/odk/test/fuzzing/corpus` path. These
|
||||
files can be used as input corpus for ODK request and response fuzzer scripts.
|
||||
|
||||
The generated corpus files can be minimized using go/testcorpus#minimize and
|
||||
uploaded into google3 repository under following directory under respective
|
||||
corpus types
|
||||
`fuzzing/corpus`
|
||||
@@ -0,0 +1,173 @@
|
||||
/* 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. */
|
||||
|
||||
/* We must define this macro to get RTLD_NEXT definition from <dlfcn.h> */
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "fuzzing/corpus_generator/odk_corpus_generator_helper.h"
|
||||
#include "fuzzing/odk_fuzz_structs.h"
|
||||
#include "odk_structs.h"
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreLicenseRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
OEMCryptoResult (*original_function)(uint8_t*, size_t, size_t*,
|
||||
const ODK_NonceValues*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreLicenseRequest");
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, nonce_values);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("license_request_corpus");
|
||||
|
||||
/* License Request format expected by fuzzer - [Core License Request] */
|
||||
AppendToFile(file_name, (const char*)message, *core_message_length);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_ParseLicense(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
bool initial_license_load, bool usage_entry_present,
|
||||
const uint8_t* request_hash, ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values, ODK_NonceValues* nonce_values,
|
||||
ODK_ParsedLicense* parsed_license) {
|
||||
struct ODK_ParseLicense_Args parse_license_args;
|
||||
parse_license_args.nonce_values = *nonce_values;
|
||||
memcpy(parse_license_args.request_hash, request_hash, ODK_SHA256_HASH_SIZE);
|
||||
parse_license_args.timer_limits = *timer_limits;
|
||||
parse_license_args.clock_values = *clock_values;
|
||||
parse_license_args.usage_entry_present = usage_entry_present;
|
||||
parse_license_args.initial_license_load = initial_license_load;
|
||||
OEMCryptoResult (*original_function)(
|
||||
const uint8_t*, size_t, size_t, bool, bool, const uint8_t*,
|
||||
ODK_TimerLimits*, ODK_ClockValues*, ODK_NonceValues*, ODK_ParsedLicense*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_ParseLicense");
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, initial_license_load,
|
||||
usage_entry_present, request_hash, timer_limits, clock_values,
|
||||
nonce_values, parsed_license);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("license_response_corpus");
|
||||
|
||||
/* License Response format expected by fuzzer - [ODK_ParseLicense_Args][Core
|
||||
*/
|
||||
/* License Response] */
|
||||
AppendToFile(file_name, (const char*)&parse_license_args,
|
||||
sizeof(struct ODK_ParseLicense_Args));
|
||||
AppendToFile(file_name, (const char*)message, core_message_length);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t* core_message_size,
|
||||
ODK_NonceValues* nonce_values,
|
||||
ODK_ClockValues* clock_values,
|
||||
uint64_t system_time_seconds) {
|
||||
OEMCryptoResult (*original_function)(
|
||||
uint8_t*, size_t, size_t*, ODK_NonceValues*, ODK_ClockValues*, uint64_t);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreRenewalRequest");
|
||||
OEMCryptoResult oem_crypto_result =
|
||||
(*original_function)(message, message_length, core_message_size,
|
||||
nonce_values, clock_values, system_time_seconds);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("renewal_request_corpus");
|
||||
|
||||
/* License Request format expected by fuzzer - [ODK_ClockValues][Core */
|
||||
/* License Request] */
|
||||
AppendToFile(file_name, (const char*)clock_values, sizeof(ODK_ClockValues));
|
||||
AppendToFile(file_name, (const char*)message, *core_message_size);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values,
|
||||
uint64_t system_time,
|
||||
const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
uint64_t* timer_value) {
|
||||
struct ODK_ParseRenewal_Args parse_renewal_args;
|
||||
parse_renewal_args.nonce_values = *nonce_values;
|
||||
parse_renewal_args.clock_values = *clock_values;
|
||||
parse_renewal_args.timer_limits = *timer_limits;
|
||||
parse_renewal_args.system_time = system_time;
|
||||
OEMCryptoResult (*original_function)(
|
||||
const uint8_t*, size_t, size_t, const ODK_NonceValues*, uint64_t,
|
||||
const ODK_TimerLimits*, ODK_ClockValues*, uint64_t*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_ParseRenewal");
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, nonce_values, system_time,
|
||||
timer_limits, clock_values, timer_value);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("renewal_response_corpus");
|
||||
|
||||
/* Renewal Response format expected by fuzzer - [ODK_ParseRenewal_Args][Core
|
||||
*/
|
||||
/* Renewal Response] */
|
||||
AppendToFile(file_name, (const char*)&parse_renewal_args,
|
||||
sizeof(struct ODK_ParseRenewal_Args));
|
||||
AppendToFile(file_name, (const char*)message, core_message_length);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length) {
|
||||
OEMCryptoResult (*original_function)(uint8_t*, size_t, size_t*,
|
||||
const ODK_NonceValues*, const uint8_t*,
|
||||
size_t);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreProvisioningRequest");
|
||||
OEMCryptoResult oem_crypto_result =
|
||||
(*original_function)(message, message_length, core_message_length,
|
||||
nonce_values, device_id, device_id_length);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("provisioning_request_corpus");
|
||||
|
||||
/* Provisioning Request format expected by fuzzer - [Core Provisioning */
|
||||
/* Request] */
|
||||
AppendToFile(file_name, (const char*)message, *core_message_length);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_ParseProvisioning(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length, ODK_ParsedProvisioning* parsed_response) {
|
||||
struct ODK_ParseProvisioning_Args parse_provisioning_args;
|
||||
parse_provisioning_args.nonce_values = *nonce_values;
|
||||
memcpy(parse_provisioning_args.device_id, device_id, device_id_length);
|
||||
parse_provisioning_args.device_id_length = device_id_length;
|
||||
OEMCryptoResult (*original_function)(const uint8_t*, size_t, size_t,
|
||||
const ODK_NonceValues*, const uint8_t*,
|
||||
size_t, ODK_ParsedProvisioning*);
|
||||
original_function = dlsym(RTLD_NEXT, "ODK_ParseProvisioning");
|
||||
OEMCryptoResult oem_crypto_result = (*original_function)(
|
||||
message, message_length, core_message_length, nonce_values, device_id,
|
||||
device_id_length, parsed_response);
|
||||
if (OEMCrypto_SUCCESS == oem_crypto_result) {
|
||||
char* file_name = GetFileName("provisioning_response_corpus");
|
||||
|
||||
/* Provisioning Response format expected by fuzzer - */
|
||||
/* [ODK_ParseProvisioning_Args][Core Provisioning Response] */
|
||||
AppendToFile(file_name, (const char*)&parse_provisioning_args,
|
||||
sizeof(struct ODK_ParseProvisioning_Args));
|
||||
AppendToFile(file_name, (const char*)message, core_message_length);
|
||||
free(file_name);
|
||||
}
|
||||
return oem_crypto_result;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/* 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 "fuzzing/corpus_generator/odk_corpus_generator_helper.h"
|
||||
|
||||
void AppendToFile(const char* file_name, const char* message,
|
||||
const size_t message_size) {
|
||||
FILE* fptr;
|
||||
if ((fptr = fopen(file_name, "ab")) == NULL) {
|
||||
printf("Error! opening file %s", file_name);
|
||||
return;
|
||||
}
|
||||
fwrite(message, message_size, 1, fptr);
|
||||
fclose(fptr);
|
||||
}
|
||||
|
||||
char* GetFileName(const char* directory) {
|
||||
char* file_name;
|
||||
file_name = malloc(150);
|
||||
sprintf(file_name, "%s%s/%d", PATH_TO_CORPUS, directory, rand());
|
||||
return file_name;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* 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 WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
|
||||
#define PATH_TO_CORPUS "./oemcrypto/odk/test/fuzzing/corpus/"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void AppendToFile(const char* file_name, const char* message,
|
||||
const size_t message_size);
|
||||
|
||||
char* GetFileName(const char* directory);
|
||||
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_ \
|
||||
*/
|
||||
151
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp
Normal file
151
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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 "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
bool convert_byte_to_valid_boolean(const bool* in) {
|
||||
const char* buf = reinterpret_cast<const char*>(in);
|
||||
for (int i = 0; i < sizeof(bool); i++) {
|
||||
if (buf[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConvertDataToValidBools(ODK_ParsedLicense* t) {
|
||||
// Convert boolean flags in parsed_license to valid bytes to
|
||||
// avoid errors from msan
|
||||
t->nonce_required = convert_byte_to_valid_boolean(&t->nonce_required);
|
||||
t->timer_limits.soft_enforce_playback_duration =
|
||||
convert_byte_to_valid_boolean(
|
||||
&t->timer_limits.soft_enforce_playback_duration);
|
||||
t->timer_limits.soft_enforce_rental_duration = convert_byte_to_valid_boolean(
|
||||
&t->timer_limits.soft_enforce_rental_duration);
|
||||
}
|
||||
|
||||
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t) {}
|
||||
|
||||
void ConvertDataToValidBools(ODK_ParsedProvisioning* t) {}
|
||||
|
||||
OEMCryptoResult odk_serialize_LicenseRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_LicenseRequest& core_license_request,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_serialize_RenewalRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_RenewalRequest& core_renewal, ODK_NonceValues* nonce_values) {
|
||||
ODK_ClockValues clock{};
|
||||
memcpy(&clock, in, sizeof(ODK_ClockValues));
|
||||
uint64_t system_time_seconds = core_renewal.playback_time_seconds;
|
||||
return ODK_PrepareCoreRenewalRequest(out, SIZE_MAX, size, nonce_values,
|
||||
&clock, system_time_seconds);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_serialize_ProvisioningRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_ProvisioningRequest& core_provisioning,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
const std::string& device_id = core_provisioning.device_id;
|
||||
return ODK_PrepareCoreProvisioningRequest(
|
||||
out, SIZE_MAX, size, nonce_values,
|
||||
reinterpret_cast<const uint8_t*>(device_id.data()), device_id.size());
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
|
||||
size_t core_message_length,
|
||||
ODK_ParseLicense_Args* a,
|
||||
ODK_NonceValues* nonce_values,
|
||||
ODK_ParsedLicense* parsed_lic) {
|
||||
return ODK_ParseLicense(message, SIZE_MAX, core_message_length,
|
||||
static_cast<bool>(a->initial_license_load),
|
||||
static_cast<bool>(a->usage_entry_present),
|
||||
a->request_hash, &a->timer_limits, &a->clock_values,
|
||||
nonce_values, parsed_lic);
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
const uint8_t* buf, size_t len, ODK_ParseRenewal_Args* a,
|
||||
ODK_NonceValues* nonce_values, ODK_PreparedRenewalRequest* renewal_msg) {
|
||||
/* Address Sanitizer doesn't like values other than 0 OR 1 for boolean
|
||||
* variables. Input from fuzzer can be parsed and any random bytes can be
|
||||
* assigned to boolean variables. Using the workaround to mitigate sanitizer
|
||||
* errors in fuzzer code and converting random bytes to 0 OR 1.
|
||||
* This has no negative security impact*/
|
||||
a->timer_limits.soft_enforce_playback_duration =
|
||||
convert_byte_to_valid_boolean(
|
||||
&a->timer_limits.soft_enforce_playback_duration);
|
||||
a->timer_limits.soft_enforce_rental_duration = convert_byte_to_valid_boolean(
|
||||
&a->timer_limits.soft_enforce_rental_duration);
|
||||
uint64_t timer_value = 0;
|
||||
OEMCryptoResult err =
|
||||
ODK_ParseRenewal(buf, SIZE_MAX, len, nonce_values, a->system_time,
|
||||
&a->timer_limits, &a->clock_values, &timer_value);
|
||||
if (OEMCrypto_SUCCESS == err) {
|
||||
Message* msg = nullptr;
|
||||
AllocateMessage(&msg, message_block);
|
||||
InitMessage(msg, const_cast<uint8_t*>(buf), len);
|
||||
SetSize(msg, len);
|
||||
Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg);
|
||||
assert(ValidMessage(msg));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_deserialize_ProvisioningResponse(
|
||||
const uint8_t* buf, size_t len, ODK_ParseProvisioning_Args* a,
|
||||
ODK_NonceValues* nonce_values, ODK_ParsedProvisioning* parsed_prov) {
|
||||
return ODK_ParseProvisioning(buf, SIZE_MAX, len, nonce_values, a->device_id,
|
||||
a->device_id_length, parsed_prov);
|
||||
}
|
||||
|
||||
bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
|
||||
const ODK_ParsedLicense& parsed_lic,
|
||||
std::string* oemcrypto_core_message) {
|
||||
const auto& nonce_values = args->nonce_values;
|
||||
ODK_LicenseRequest core_request{nonce_values.api_minor_version,
|
||||
nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id};
|
||||
std::string core_request_sha_256(
|
||||
reinterpret_cast<const char*>(args->request_hash), ODK_SHA256_HASH_SIZE);
|
||||
return serialize::CreateCoreLicenseResponse(
|
||||
parsed_lic, core_request, core_request_sha_256, oemcrypto_core_message);
|
||||
}
|
||||
|
||||
bool kdo_serialize_RenewalResponse(
|
||||
const ODK_ParseRenewal_Args* args,
|
||||
const ODK_PreparedRenewalRequest& renewal_msg,
|
||||
std::string* oemcrypto_core_message) {
|
||||
const auto& nonce_values = args->nonce_values;
|
||||
ODK_RenewalRequest core_request{
|
||||
nonce_values.api_minor_version, nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id, renewal_msg.playback_time};
|
||||
return serialize::CreateCoreRenewalResponse(
|
||||
core_request, args->timer_limits.initial_renewal_duration_seconds,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
|
||||
bool kdo_serialize_ProvisioningResponse(
|
||||
const ODK_ParseProvisioning_Args* args,
|
||||
const ODK_ParsedProvisioning& parsed_prov,
|
||||
std::string* oemcrypto_core_message) {
|
||||
const auto& nonce_values = args->nonce_values;
|
||||
if (args->device_id_length > sizeof(args->device_id)) {
|
||||
return false;
|
||||
}
|
||||
ODK_ProvisioningRequest core_request{
|
||||
nonce_values.api_minor_version, nonce_values.api_major_version,
|
||||
nonce_values.nonce, nonce_values.session_id,
|
||||
std::string(reinterpret_cast<const char*>(args->device_id),
|
||||
args->device_id_length)};
|
||||
return serialize::CreateCoreProvisioningResponse(parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
206
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.h
Normal file
206
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_helper.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/* 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 WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "core_message_serialize.h"
|
||||
#include "fuzzing/odk_fuzz_structs.h"
|
||||
#include "odk_serialize.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
bool convert_byte_to_valid_boolean(const bool* in);
|
||||
|
||||
OEMCryptoResult odk_serialize_LicenseRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_LicenseRequest& core_license_request,
|
||||
const ODK_NonceValues* nonce_values);
|
||||
|
||||
OEMCryptoResult odk_serialize_RenewalRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_RenewalRequest& core_renewal, ODK_NonceValues* nonce_values);
|
||||
|
||||
OEMCryptoResult odk_serialize_ProvisioningRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_ProvisioningRequest& core_provisioning,
|
||||
const ODK_NonceValues* nonce_values);
|
||||
|
||||
OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
|
||||
size_t core_message_length,
|
||||
ODK_ParseLicense_Args* a,
|
||||
ODK_NonceValues* nonce_values,
|
||||
ODK_ParsedLicense* parsed_lic);
|
||||
|
||||
OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
const uint8_t* buf, size_t len, ODK_ParseRenewal_Args* a,
|
||||
ODK_NonceValues* nonce_values, ODK_PreparedRenewalRequest* renewal_msg);
|
||||
|
||||
OEMCryptoResult odk_deserialize_ProvisioningResponse(
|
||||
const uint8_t* buf, size_t len, ODK_ParseProvisioning_Args* a,
|
||||
ODK_NonceValues* nonce_values, ODK_ParsedProvisioning* parsed_prov);
|
||||
|
||||
bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
|
||||
const ODK_ParsedLicense& parsed_lic,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
bool kdo_serialize_RenewalResponse(
|
||||
const ODK_ParseRenewal_Args* args,
|
||||
const ODK_PreparedRenewalRequest& renewal_msg,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
bool kdo_serialize_ProvisioningResponse(
|
||||
const ODK_ParseProvisioning_Args* args,
|
||||
const ODK_ParsedProvisioning& parsed_prov,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
/* Idea behind having three different functions is: */
|
||||
/* Only ODK_ParseLicense structure had fields which needed additional */
|
||||
/* procession. Having a single function with templated parameter T was */
|
||||
/* failing during compile time because other two structures doesn't have */
|
||||
/* fields that need additional processing. Hence to reduce code redundance and
|
||||
*/
|
||||
/* make us of common FuzzerMutateResponse across three response fuzzers, */
|
||||
/* three independent functions were defined and renewal and provisioning */
|
||||
/* functions would be empty as no additional processing is needed for them. */
|
||||
void ConvertDataToValidBools(ODK_ParsedLicense* t);
|
||||
|
||||
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t);
|
||||
|
||||
void ConvertDataToValidBools(ODK_ParsedProvisioning* t);
|
||||
|
||||
/* Forward-declare the libFuzzer's mutator callback. Mark it weak so that */
|
||||
/* the program links successfully even outside of --config=asan-fuzzer */
|
||||
/* (apparently the only config in which LLVM uses our custom mutator). */
|
||||
extern "C" size_t LLVMFuzzerMutate(uint8_t* Data, size_t Size, size_t MaxSize)
|
||||
__attribute__((weak));
|
||||
|
||||
template <typename A, typename T, typename F, typename G>
|
||||
size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
|
||||
const F& odk_deserialize_fun,
|
||||
const G& kdo_serialize_fun) {
|
||||
const size_t kArgsSize = sizeof(A);
|
||||
const size_t kCoreResponseSize = sizeof(T);
|
||||
const size_t kTotalResponseSize = kArgsSize + kCoreResponseSize;
|
||||
|
||||
/* Deserializing data in order to make sure it deserializes properly. */
|
||||
/* Input byte array format: [function arguments][data to parse]. */
|
||||
std::shared_ptr<A> _args(new A());
|
||||
A* args = _args.get();
|
||||
memcpy(args, data, kArgsSize);
|
||||
ODK_NonceValues nonce_values = args->nonce_values;
|
||||
args->nonce_values.api_major_version = ODK_MAJOR_VERSION;
|
||||
const uint8_t* buf = data + kArgsSize;
|
||||
T t = {};
|
||||
OEMCryptoResult result =
|
||||
odk_deserialize_fun(buf, size - kArgsSize, args, &nonce_values, &t);
|
||||
|
||||
/* If data doesn't deserialize successfully, We copy random bytes into */
|
||||
/* T and serialize using kdo function */
|
||||
/* which will create a valid oemcrypto core message using */
|
||||
/* nonce and request hash from function args. OEMCrypto core message acts as
|
||||
*/
|
||||
/* input to odk_kdo. */
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
if (max_size < kTotalResponseSize) {
|
||||
return 0;
|
||||
}
|
||||
/* Initialize remaining bytes needed in data to zero. */
|
||||
if (size < kTotalResponseSize) {
|
||||
memset(data + size, 0, kTotalResponseSize - size);
|
||||
}
|
||||
t = {};
|
||||
memcpy(&t, buf, kCoreResponseSize);
|
||||
}
|
||||
|
||||
/* Ask LLVM to run its usual mutations, hopefully giving us interesting */
|
||||
/* inputs. We copy deserialized data into pointer data, run mutations */
|
||||
/* and copy back the mutated data to args and t */
|
||||
memcpy(data + kArgsSize, &t, kCoreResponseSize);
|
||||
LLVMFuzzerMutate(data, kTotalResponseSize, kTotalResponseSize);
|
||||
memcpy(args, data, kArgsSize);
|
||||
memcpy(&t, data + kArgsSize, kCoreResponseSize);
|
||||
/* Convert boolean flags in parsed message to valid bytes to */
|
||||
/* avoid errors from msan. Only needed for parsed license. */
|
||||
ConvertDataToValidBools(&t);
|
||||
/* Serialize the data after mutation. */
|
||||
std::string oemcrypto_core_message;
|
||||
if (!kdo_serialize_fun(args, t, &oemcrypto_core_message)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy mutated and serialized oemcrypto_core_message to data */
|
||||
/* so that it acts as input to odk_kdo function. */
|
||||
memcpy(data + kArgsSize, oemcrypto_core_message.data(),
|
||||
oemcrypto_core_message.size());
|
||||
return kArgsSize + oemcrypto_core_message.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Template arguments:
|
||||
* A: struct holding function arguments
|
||||
* T: odk deserialize output/kdo serialize input structure
|
||||
* F: odk deserialize function
|
||||
* G: kdo serialize function
|
||||
*
|
||||
* raw bytes -> F deserialize -> struct T -> G serialize -> raw bytes
|
||||
*/
|
||||
template <typename A, typename T, typename F, typename G>
|
||||
void odk_kdo(const F& odk_fun, const G& kdo_fun, const uint8_t* in,
|
||||
const size_t size, const size_t args_size, uint8_t* out) {
|
||||
T t = {};
|
||||
/* Input byte array format: [function arguments][data to parse] */
|
||||
if (size < args_size) {
|
||||
return;
|
||||
}
|
||||
const uint8_t* buf = in + args_size;
|
||||
std::shared_ptr<A> _args(new A());
|
||||
A* args = _args.get();
|
||||
memcpy(args, in, args_size);
|
||||
args->nonce_values.api_major_version = ODK_MAJOR_VERSION;
|
||||
ODK_NonceValues nonce_values = args->nonce_values;
|
||||
|
||||
OEMCryptoResult result =
|
||||
odk_fun(buf, size - args_size, args, &nonce_values, &t);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
std::string oemcrypto_core_message;
|
||||
if (!kdo_fun(args, t, &oemcrypto_core_message)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template arguments:
|
||||
* T: kdo deserialize output/odk serialize input structure
|
||||
* F: kdo deserialize function
|
||||
* G: odk serialize function
|
||||
*
|
||||
* raw bytes -> F deserialize -> struct T -> G serialize -> raw bytes
|
||||
*/
|
||||
template <typename T, typename F, typename G>
|
||||
static void kdo_odk(const F& kdo_fun, const G& odk_fun, const uint8_t* in,
|
||||
size_t size, const size_t clock_value_size, uint8_t* out) {
|
||||
if (size <= clock_value_size) {
|
||||
return;
|
||||
}
|
||||
/* Input byte array format: [Clock Values][data to parse]. */
|
||||
/* Only Renewal Request expects clock values to be present. */
|
||||
std::string input(reinterpret_cast<const char*>(in) + clock_value_size,
|
||||
size - clock_value_size);
|
||||
T t = {};
|
||||
if (!kdo_fun(input, &t)) {
|
||||
return;
|
||||
}
|
||||
ODK_NonceValues nonce_values = {t.api_minor_version, t.api_major_version,
|
||||
t.nonce, t.session_id};
|
||||
OEMCryptoResult err = odk_fun(in, out, &size, t, &nonce_values);
|
||||
if (OEMCrypto_SUCCESS != err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} /* namespace oemcrypto_core_message */
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_ */
|
||||
28
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_structs.h
Normal file
28
libwvdrmengine/oemcrypto/odk/test/fuzzing/odk_fuzz_structs.h
Normal 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. */
|
||||
#ifndef WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
#define WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
|
||||
#include "odk_structs.h"
|
||||
|
||||
struct ODK_ParseLicense_Args {
|
||||
ODK_NonceValues nonce_values;
|
||||
uint8_t initial_license_load;
|
||||
uint8_t usage_entry_present;
|
||||
uint8_t request_hash[ODK_SHA256_HASH_SIZE];
|
||||
ODK_TimerLimits timer_limits;
|
||||
ODK_ClockValues clock_values;
|
||||
};
|
||||
struct ODK_ParseRenewal_Args {
|
||||
ODK_NonceValues nonce_values;
|
||||
uint64_t system_time;
|
||||
ODK_TimerLimits timer_limits;
|
||||
ODK_ClockValues clock_values;
|
||||
};
|
||||
struct ODK_ParseProvisioning_Args {
|
||||
ODK_NonceValues nonce_values;
|
||||
size_t device_id_length;
|
||||
uint8_t device_id[64];
|
||||
};
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_ */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "core_message_deserialize.h"
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
std::vector<uint8_t> out(size);
|
||||
const size_t kClockValueSize = 0;
|
||||
kdo_odk<ODK_LicenseRequest>(CoreLicenseRequestFromMessage,
|
||||
odk_serialize_LicenseRequest, data, size,
|
||||
kClockValueSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,20 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kLicenseResponseArgsSize = sizeof(ODK_ParseLicense_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseLicense_Args, ODK_ParsedLicense>(
|
||||
odk_deserialize_LicenseResponse, kdo_serialize_LicenseResponse, data,
|
||||
size, kLicenseResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,35 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size, unsigned int seed) {
|
||||
const size_t kLicenseResponseArgsSize = sizeof(ODK_ParseLicense_Args);
|
||||
if (size < kLicenseResponseArgsSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Mutate input data and return mutated input size.
|
||||
return FuzzerMutateResponse<ODK_ParseLicense_Args, ODK_ParsedLicense>(
|
||||
data, size, max_size, odk_deserialize_LicenseResponse,
|
||||
kdo_serialize_LicenseResponse);
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kLicenseResponseArgsSize = sizeof(ODK_ParseLicense_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseLicense_Args, ODK_ParsedLicense>(
|
||||
odk_deserialize_LicenseResponse, kdo_serialize_LicenseResponse, data,
|
||||
size, kLicenseResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,22 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "core_message_deserialize.h"
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
std::vector<uint8_t> out(size);
|
||||
const size_t kClockValueSize = 0;
|
||||
kdo_odk<ODK_ProvisioningRequest>(CoreProvisioningRequestFromMessage,
|
||||
odk_serialize_ProvisioningRequest, data,
|
||||
size, kClockValueSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,21 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kProvisioningResponseArgsSize =
|
||||
sizeof(ODK_ParseProvisioning_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseProvisioning_Args, ODK_ParsedProvisioning>(
|
||||
odk_deserialize_ProvisioningResponse, kdo_serialize_ProvisioningResponse,
|
||||
data, size, kProvisioningResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,38 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size, unsigned int seed) {
|
||||
const size_t kProvisioningResponseArgsSize =
|
||||
sizeof(ODK_ParseProvisioning_Args);
|
||||
if (size < kProvisioningResponseArgsSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Mutate input data and return mutated input size.
|
||||
return FuzzerMutateResponse<ODK_ParseProvisioning_Args,
|
||||
ODK_ParsedProvisioning>(
|
||||
data, size, max_size, odk_deserialize_ProvisioningResponse,
|
||||
kdo_serialize_ProvisioningResponse);
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kProvisioningResponseArgsSize =
|
||||
sizeof(ODK_ParseProvisioning_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseProvisioning_Args, ODK_ParsedProvisioning>(
|
||||
odk_deserialize_ProvisioningResponse, kdo_serialize_ProvisioningResponse,
|
||||
data, size, kProvisioningResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,22 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "core_message_deserialize.h"
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
std::vector<uint8_t> out(size);
|
||||
const size_t kClockValueSize = sizeof(ODK_ClockValues);
|
||||
kdo_odk<ODK_RenewalRequest>(CoreRenewalRequestFromMessage,
|
||||
odk_serialize_RenewalRequest, data, size,
|
||||
kClockValueSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,20 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseRenewal_Args, ODK_PreparedRenewalRequest>(
|
||||
odk_deserialize_RenewalResponse, kdo_serialize_RenewalResponse, data,
|
||||
size, kRenewalResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
@@ -0,0 +1,36 @@
|
||||
/* 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 <vector>
|
||||
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// The custom mutator: Ensure that each input can be deserialized properly
|
||||
// by ODK function after mutation.
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||
size_t max_size, unsigned int seed) {
|
||||
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
|
||||
if (size < kRenewalResponseArgsSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Mutate input data and return mutated input size.
|
||||
return FuzzerMutateResponse<ODK_ParseRenewal_Args,
|
||||
ODK_PreparedRenewalRequest>(
|
||||
data, size, max_size, odk_deserialize_RenewalResponse,
|
||||
kdo_serialize_RenewalResponse);
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
const size_t kRenewalResponseArgsSize = sizeof(ODK_ParseRenewal_Args);
|
||||
std::vector<uint8_t> out(size);
|
||||
odk_kdo<ODK_ParseRenewal_Args, ODK_PreparedRenewalRequest>(
|
||||
odk_deserialize_RenewalResponse, kdo_serialize_RenewalResponse, data,
|
||||
size, kRenewalResponseArgsSize, out.data());
|
||||
return 0;
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
Reference in New Issue
Block a user