Update Partner Repo
This update brings the partner repo up-to-date with commit ae93405f980295f9a783bd04e2132a2370720107 in the internal repo.
This commit is contained in:
@@ -1,8 +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. */
|
||||
// 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> */
|
||||
// We must define this macro to get RTLD_NEXT definition from <dlfcn.h>
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <dlfcn.h>
|
||||
@@ -21,7 +21,7 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
|
||||
message, message_length, core_message_length, nonce_values);
|
||||
char* file_name = GetFileName("license_request_corpus");
|
||||
|
||||
/* License Request format expected by fuzzer - [Core License Request] */
|
||||
// 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;
|
||||
@@ -50,9 +50,8 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
nonce_values, parsed_license);
|
||||
char* file_name = GetFileName("license_response_corpus");
|
||||
|
||||
/* License Response format expected by fuzzer - [ODK_ParseLicense_Args][Core
|
||||
*/
|
||||
/* License Response] */
|
||||
// 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);
|
||||
@@ -74,8 +73,8 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
|
||||
nonce_values, clock_values, system_time_seconds);
|
||||
char* file_name = GetFileName("renewal_request_corpus");
|
||||
|
||||
/* License Request format expected by fuzzer - [ODK_ClockValues][Core */
|
||||
/* License Request] */
|
||||
// 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);
|
||||
@@ -103,9 +102,8 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
timer_limits, clock_values, timer_value);
|
||||
char* file_name = GetFileName("renewal_response_corpus");
|
||||
|
||||
/* Renewal Response format expected by fuzzer - [ODK_ParseRenewal_Args][Core
|
||||
*/
|
||||
/* Renewal Response] */
|
||||
// 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);
|
||||
@@ -126,8 +124,8 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
|
||||
nonce_values, device_id, device_id_length);
|
||||
char* file_name = GetFileName("provisioning_request_corpus");
|
||||
|
||||
/* Provisioning Request format expected by fuzzer - [Core Provisioning */
|
||||
/* Request] */
|
||||
// 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;
|
||||
@@ -150,8 +148,8 @@ OEMCryptoResult ODK_ParseProvisioning(
|
||||
device_id_length, parsed_response);
|
||||
char* file_name = GetFileName("provisioning_response_corpus");
|
||||
|
||||
/* Provisioning Response format expected by fuzzer - */
|
||||
/* [ODK_ParseProvisioning_Args][Core Provisioning Response] */
|
||||
// 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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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. */
|
||||
// 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,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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. */
|
||||
// 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_
|
||||
|
||||
@@ -15,5 +15,4 @@ void AppendToFile(const char* file_name, const char* message,
|
||||
|
||||
char* GetFileName(const char* directory);
|
||||
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_ \
|
||||
*/
|
||||
#endif // WIDEVINE_ODK_TEST_FUZZING_CORPUS_GENERATOR_ODK_CORPUS_GENERATOR_HELPER_H_
|
||||
|
||||
@@ -28,13 +28,13 @@ void ConvertDataToValidBools(ODK_ParsedLicense* t) {
|
||||
&t->timer_limits.soft_enforce_rental_duration);
|
||||
}
|
||||
|
||||
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t) {}
|
||||
void ConvertDataToValidBools(ODK_PreparedRenewalRequest* t UNUSED) {}
|
||||
|
||||
void ConvertDataToValidBools(ODK_ParsedProvisioning* t) {}
|
||||
void ConvertDataToValidBools(ODK_ParsedProvisioning* t UNUSED) {}
|
||||
|
||||
OEMCryptoResult odk_serialize_LicenseRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const ODK_LicenseRequest& core_license_request,
|
||||
const void* in UNUSED, uint8_t* out, size_t* size,
|
||||
const ODK_LicenseRequest& core_license_request UNUSED,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ OEMCryptoResult odk_serialize_RenewalRequest(
|
||||
}
|
||||
|
||||
OEMCryptoResult odk_serialize_ProvisioningRequest(
|
||||
const void* in, uint8_t* out, size_t* size,
|
||||
const void* in UNUSED, 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;
|
||||
@@ -99,11 +99,9 @@ OEMCryptoResult odk_deserialize_RenewalResponse(
|
||||
// odk_kdo method, we call Unpack_ODK_PreparedRenewalRequest private method.
|
||||
// playback_time cannot be captured from publicly exposed API
|
||||
// ODK_ParseRenewal.
|
||||
Message* msg = nullptr;
|
||||
AllocateMessage(&msg, message_block);
|
||||
InitMessage(msg, const_cast<uint8_t*>(buf), len);
|
||||
SetSize(msg, len);
|
||||
Unpack_ODK_PreparedRenewalRequest(msg, renewal_msg);
|
||||
ODK_Message msg = ODK_Message_Create(const_cast<uint8_t*>(buf), len);
|
||||
ODK_Message_SetSize(&msg, len);
|
||||
Unpack_ODK_PreparedRenewalRequest(&msg, renewal_msg);
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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. */
|
||||
// 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_
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "core_message_serialize.h"
|
||||
#include "fuzzing/odk_fuzz_structs.h"
|
||||
#include "odk_attributes.h"
|
||||
#include "odk_serialize.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
@@ -56,24 +57,23 @@ bool kdo_serialize_ProvisioningResponse(
|
||||
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. */
|
||||
// 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). */
|
||||
// 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));
|
||||
|
||||
@@ -85,8 +85,8 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
|
||||
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]. */
|
||||
// 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);
|
||||
@@ -97,17 +97,16 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
|
||||
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 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. */
|
||||
// Initialize remaining bytes needed in data to zero.
|
||||
if (size < kTotalResponseSize) {
|
||||
memset(data + size, 0, kTotalResponseSize - size);
|
||||
}
|
||||
@@ -115,24 +114,24 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
|
||||
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 */
|
||||
// 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. */
|
||||
// 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. */
|
||||
// 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. */
|
||||
// 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();
|
||||
@@ -149,9 +148,9 @@ size_t FuzzerMutateResponse(uint8_t* data, size_t size, size_t max_size,
|
||||
*/
|
||||
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) {
|
||||
const size_t size, const size_t args_size, uint8_t* out UNUSED) {
|
||||
T t = {};
|
||||
/* Input byte array format: [function arguments][data to parse] */
|
||||
// Input byte array format: [function arguments][data to parse]
|
||||
if (size < args_size) {
|
||||
return;
|
||||
}
|
||||
@@ -187,8 +186,8 @@ static void kdo_odk(const F& kdo_fun, const G& odk_fun, const uint8_t* in,
|
||||
if (size <= clock_value_size) {
|
||||
return;
|
||||
}
|
||||
/* Input byte array format: [Clock Values][data to parse]. */
|
||||
/* Only Renewal Request expects clock values to be present. */
|
||||
// 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 = {};
|
||||
@@ -202,5 +201,5 @@ static void kdo_odk(const F& kdo_fun, const G& odk_fun, const uint8_t* in,
|
||||
return;
|
||||
}
|
||||
}
|
||||
} /* namespace oemcrypto_core_message */
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_ */
|
||||
} // namespace oemcrypto_core_message
|
||||
#endif // WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_HELPER_H_
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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. */
|
||||
// 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_
|
||||
|
||||
@@ -25,4 +25,4 @@ struct ODK_ParseProvisioning_Args {
|
||||
size_t device_id_length;
|
||||
uint8_t device_id[64];
|
||||
};
|
||||
#endif /* WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_ */
|
||||
#endif // WIDEVINE_ODK_TEST_FUZZING_ODK_FUZZ_STRUCTS_H_
|
||||
|
||||
@@ -12,7 +12,8 @@ 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) {
|
||||
size_t max_size,
|
||||
unsigned int seed UNUSED) {
|
||||
const size_t kLicenseResponseArgsSize = sizeof(ODK_ParseLicense_Args);
|
||||
if (size < kLicenseResponseArgsSize) {
|
||||
return 0;
|
||||
|
||||
@@ -35,6 +35,16 @@ using oemcrypto_core_message::serialize::CreateCoreRenewalResponse;
|
||||
|
||||
constexpr uint32_t kExtraPayloadSize = 128u;
|
||||
|
||||
/* Used to parameterize tests by version number. The request is given one
|
||||
* version number, and we will expect the response to have another version
|
||||
* number. */
|
||||
struct VersionParameters {
|
||||
uint16_t request_major_version;
|
||||
uint16_t request_minor_version;
|
||||
uint16_t response_major_version;
|
||||
uint16_t response_minor_version;
|
||||
};
|
||||
|
||||
template <typename T, typename F, typename G>
|
||||
void ValidateRequest(uint32_t message_type,
|
||||
const std::vector<ODK_Field>& extra_fields,
|
||||
@@ -113,12 +123,13 @@ void ValidateRequest(uint32_t message_type,
|
||||
* G: kdo serializer
|
||||
*/
|
||||
template <typename T, typename F, typename G>
|
||||
void ValidateResponse(ODK_CoreMessage* core_message,
|
||||
void ValidateResponse(const VersionParameters& versions,
|
||||
ODK_CoreMessage* core_message,
|
||||
const std::vector<ODK_Field>& extra_fields,
|
||||
const F& odk_parse_func, const G& kdo_prepare_func) {
|
||||
T t = {};
|
||||
t.api_minor_version = core_message->nonce_values.api_minor_version;
|
||||
t.api_major_version = core_message->nonce_values.api_major_version;
|
||||
t.api_major_version = versions.request_major_version;
|
||||
t.api_minor_version = versions.request_minor_version;
|
||||
t.nonce = core_message->nonce_values.nonce;
|
||||
t.session_id = core_message->nonce_values.session_id;
|
||||
|
||||
@@ -132,7 +143,7 @@ void ValidateResponse(ODK_CoreMessage* core_message,
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, ODK_IterFields(ODK_READ, zero, buf_size,
|
||||
&bytes_read, extra_fields));
|
||||
|
||||
// parse buf with odk
|
||||
// Parse buf with odk
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, odk_parse_func(buf, buf_size));
|
||||
|
||||
size_t size_out = 0;
|
||||
@@ -209,8 +220,10 @@ TEST(OdkTest, SerializeFieldsStress) {
|
||||
|
||||
TEST(OdkTest, NullRequestTest) {
|
||||
size_t core_message_length = 0;
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_ClockValues clock_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
|
||||
// Assert that nullptr does not cause a core dump.
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest(
|
||||
@@ -250,10 +263,12 @@ TEST(OdkTest, NullResponseTest) {
|
||||
uint8_t message[message_size] = {0};
|
||||
size_t core_message_length = message_size;
|
||||
uint8_t request_hash[ODK_SHA256_HASH_SIZE] = {0};
|
||||
ODK_TimerLimits timer_limits{0};
|
||||
ODK_TimerLimits timer_limits;
|
||||
ODK_ParsedLicense parsed_license;
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_ClockValues clock_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
|
||||
// Assert that nullptr does not cause a core dump.
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
@@ -322,7 +337,8 @@ TEST(OdkTest, NullResponseTest) {
|
||||
TEST(OdkTest, PrepareCoreLicenseRequest) {
|
||||
uint8_t license_message[ODK_LICENSE_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(license_message);
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreLicenseRequest(
|
||||
license_message, sizeof(license_message),
|
||||
&core_message_length, &nonce_values));
|
||||
@@ -331,7 +347,8 @@ TEST(OdkTest, PrepareCoreLicenseRequest) {
|
||||
TEST(OdkTest, PrepareCoreLicenseRequestSize) {
|
||||
uint8_t license_message[ODK_LICENSE_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(license_message);
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
// message length smaller than core message length
|
||||
size_t core_message_length_invalid = core_message_length + 1;
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
@@ -349,8 +366,10 @@ TEST(OdkTest, PrepareCoreLicenseRequestSize) {
|
||||
TEST(OdkTest, PrepareCoreRenewalRequest) {
|
||||
uint8_t renewal_message[ODK_RENEWAL_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(renewal_message);
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_ClockValues clock_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
constexpr uint64_t system_time_seconds = 10;
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS,
|
||||
ODK_PrepareCoreRenewalRequest(
|
||||
@@ -363,7 +382,8 @@ TEST(OdkTest, PrepareCoreRenewalRequestTimer) {
|
||||
size_t core_message_length = sizeof(renewal_message);
|
||||
ODK_NonceValues nonce_values{2, 16, 0, 0};
|
||||
constexpr uint64_t system_time_seconds = 10;
|
||||
ODK_ClockValues clock_values_updated{0};
|
||||
ODK_ClockValues clock_values_updated;
|
||||
memset(&clock_values_updated, 0, sizeof(clock_values_updated));
|
||||
// system time smaller than first decrypt time
|
||||
clock_values_updated.time_of_first_decrypt = system_time_seconds + 1;
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
@@ -383,7 +403,8 @@ TEST(OdkTest, PrepareCoreRenewalRequestTimer) {
|
||||
TEST(OdkTest, PrepareCoreProvisioningRequest) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
EXPECT_EQ(
|
||||
OEMCrypto_SUCCESS,
|
||||
@@ -395,7 +416,8 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) {
|
||||
TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
|
||||
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
|
||||
size_t core_message_length = sizeof(provisioning_message);
|
||||
ODK_NonceValues nonce_values{0};
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
uint8_t device_id_invalid[ODK_DEVICE_ID_LEN_MAX + 1] = {0};
|
||||
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
|
||||
ODK_PrepareCoreProvisioningRequest(
|
||||
@@ -423,7 +445,8 @@ TEST(OdkTest, RenewalRequestRoundtrip) {
|
||||
const std::vector<ODK_Field> extra_fields = {
|
||||
{ODK_UINT64, &playback_time, "playback_time"},
|
||||
};
|
||||
ODK_ClockValues clock_values = {0};
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
clock_values.time_of_first_decrypt = playback_start;
|
||||
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
|
||||
ODK_NonceValues* nonce_values) {
|
||||
@@ -550,10 +573,23 @@ TEST(OdkTest, ParsePrivisioningErrorDeviceId) {
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
class OdkVersionTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<VersionParameters> {
|
||||
protected:
|
||||
template <typename P>
|
||||
void SetRequestVersion(P* params) {
|
||||
params->core_message.nonce_values.api_major_version =
|
||||
GetParam().response_major_version;
|
||||
params->core_message.nonce_values.api_minor_version =
|
||||
GetParam().response_minor_version;
|
||||
}
|
||||
};
|
||||
|
||||
// Serialize and de-serialize license response
|
||||
TEST(OdkTest, LicenseResponseRoundtrip) {
|
||||
TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
|
||||
ODK_LicenseResponseParams params;
|
||||
ODK_SetDefaultLicenseResponseParams(¶ms);
|
||||
SetRequestVersion(¶ms);
|
||||
// save a copy of params.request_hash as it will be zero out during the test
|
||||
uint8_t request_hash_read[ODK_SHA256_HASH_SIZE];
|
||||
memcpy(request_hash_read, params.request_hash, sizeof(request_hash_read));
|
||||
@@ -573,14 +609,15 @@ TEST(OdkTest, LicenseResponseRoundtrip) {
|
||||
request_hash_string,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_LicenseRequest>(&(params.core_message),
|
||||
ValidateResponse<ODK_LicenseRequest>(GetParam(), &(params.core_message),
|
||||
params.extra_fields, odk_parse_func,
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
TEST(OdkTest, RenewalResponseRoundtrip) {
|
||||
TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
|
||||
ODK_RenewalResponseParams params;
|
||||
ODK_SetDefaultRenewalResponseParams(¶ms);
|
||||
SetRequestVersion(¶ms);
|
||||
const uint64_t playback_clock = params.playback_clock;
|
||||
const uint64_t renewal_duration = params.renewal_duration;
|
||||
auto odk_parse_func = [&](const uint8_t* buf, size_t size) {
|
||||
@@ -602,14 +639,15 @@ TEST(OdkTest, RenewalResponseRoundtrip) {
|
||||
return CreateCoreRenewalResponse(core_request, renewal_duration,
|
||||
oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_RenewalRequest>(&(params.core_message),
|
||||
ValidateResponse<ODK_RenewalRequest>(GetParam(), &(params.core_message),
|
||||
params.extra_fields, odk_parse_func,
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
TEST(OdkTest, ProvisionResponseRoundtrip) {
|
||||
TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
|
||||
ODK_ProvisioningResponseParams params;
|
||||
ODK_SetDefaultProvisioningResponseParams(¶ms);
|
||||
SetRequestVersion(¶ms);
|
||||
// save a copy of params.device_id as it will be zero out during the test
|
||||
const uint32_t device_id_length = params.device_id_length;
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
|
||||
@@ -628,11 +666,48 @@ TEST(OdkTest, ProvisionResponseRoundtrip) {
|
||||
return CreateCoreProvisioningResponse(params.parsed_provisioning,
|
||||
core_request, oemcrypto_core_message);
|
||||
};
|
||||
ValidateResponse<ODK_ProvisioningRequest>(&(params.core_message),
|
||||
ValidateResponse<ODK_ProvisioningRequest>(GetParam(), &(params.core_message),
|
||||
params.extra_fields, odk_parse_func,
|
||||
kdo_prepare_func);
|
||||
}
|
||||
|
||||
// If the minor version is positive, we can test an older minor version.
|
||||
const uint16_t kOldMinor = ODK_MINOR_VERSION > 0 ? ODK_MINOR_VERSION - 1 : 0;
|
||||
// Similarly, if this isn't the first major version, we can test an older major
|
||||
// version.
|
||||
// TODO(b/163416999): Remove it in the future. This will be unecessarily
|
||||
// complicated after we upgrade to version 17.
|
||||
const uint16_t kOldMajor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION
|
||||
? ODK_MAJOR_VERSION - 1
|
||||
: ODK_FIRST_VERSION;
|
||||
// If there is an older major, then we should accept any minor version.
|
||||
// Otherwise, this test won't make sense and we should just use a minor of 0.
|
||||
const uint16_t kOldMajorMinor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION ? 42 : 0;
|
||||
|
||||
// List of major and minor versions to test.
|
||||
std::vector<VersionParameters> TestCases() {
|
||||
std::vector<VersionParameters> test_cases{
|
||||
// Fields: request major, request minor, response major, response minor
|
||||
{ODK_MAJOR_VERSION, ODK_MINOR_VERSION, ODK_MAJOR_VERSION,
|
||||
ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, ODK_MINOR_VERSION + 1, ODK_MAJOR_VERSION,
|
||||
ODK_MINOR_VERSION},
|
||||
{ODK_MAJOR_VERSION, kOldMinor, ODK_MAJOR_VERSION, kOldMinor},
|
||||
{ODK_MAJOR_VERSION, 0, ODK_MAJOR_VERSION, 0},
|
||||
{ODK_MAJOR_VERSION + 1, 42, ODK_MAJOR_VERSION, ODK_MINOR_VERSION},
|
||||
{kOldMajor, 0, kOldMajor, 0},
|
||||
{kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor},
|
||||
// Here are some known good versions. Make extra sure they work.
|
||||
{16, 3, 16, 3},
|
||||
{16, 4, 16, 4},
|
||||
{16, 5, 16, 5},
|
||||
};
|
||||
return test_cases;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(OdkVersionTests, OdkVersionTest,
|
||||
::testing::ValuesIn(TestCases()));
|
||||
|
||||
TEST(OdkSizeTest, LicenseRequest) {
|
||||
uint8_t* message = nullptr;
|
||||
size_t message_length = 0;
|
||||
|
||||
@@ -409,9 +409,30 @@ OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf,
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
std::vector<ODK_Field> ODK_MakeTotalFields(
|
||||
const std::vector<ODK_Field>& extra_fields, ODK_CoreMessage* core_message) {
|
||||
std::vector<ODK_Field> total_fields = {
|
||||
{ODK_UINT32, &(core_message->message_type), "message_type"},
|
||||
{ODK_UINT32, &(core_message->message_length), "message_size"},
|
||||
{ODK_UINT16, &(core_message->nonce_values.api_minor_version),
|
||||
"api_minor_version"},
|
||||
{ODK_UINT16, &(core_message->nonce_values.api_major_version),
|
||||
"api_major_version"},
|
||||
{ODK_UINT32, &(core_message->nonce_values.nonce), "nonce"},
|
||||
{ODK_UINT32, &(core_message->nonce_values.session_id), "session_id"},
|
||||
};
|
||||
total_fields.insert(total_fields.end(), extra_fields.begin(),
|
||||
extra_fields.end());
|
||||
return total_fields;
|
||||
}
|
||||
|
||||
// Expect the two buffers of size n to be equal. If not, dump the messages.
|
||||
void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
|
||||
const std::vector<ODK_Field>& fields) {
|
||||
if (memcmp(s1, s2, n) != 0) {
|
||||
ODK_CoreMessage core_message;
|
||||
std::vector<ODK_Field> total_fields =
|
||||
ODK_MakeTotalFields(fields, &core_message);
|
||||
const void* buffers[] = {s1, s2};
|
||||
for (int i = 0; i < 2; i++) {
|
||||
char _tmp[] = "/tmp/fileXXXXXX";
|
||||
@@ -430,7 +451,7 @@ void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
|
||||
size_t bytes_written;
|
||||
uint8_t* buf =
|
||||
const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(buffers[i]));
|
||||
ODK_IterFields(ODK_DUMP, buf, n, &bytes_written, fields);
|
||||
ODK_IterFields(ODK_DUMP, buf, n, &bytes_written, total_fields);
|
||||
}
|
||||
FAIL();
|
||||
}
|
||||
@@ -453,24 +474,9 @@ void ODK_BuildMessageBuffer(ODK_CoreMessage* core_message,
|
||||
uint8_t** buf, uint32_t* buf_size) {
|
||||
ASSERT_TRUE(core_message != nullptr);
|
||||
ASSERT_TRUE(buf_size != nullptr);
|
||||
std::vector<ODK_Field> total_fields = {
|
||||
{ODK_UINT32, &(core_message->message_type), "message_type"},
|
||||
{ODK_UINT32, &(core_message->message_length), "message_size"},
|
||||
{ODK_UINT16, &(core_message->nonce_values.api_minor_version),
|
||||
"api_minor_version"},
|
||||
{ODK_UINT16, &(core_message->nonce_values.api_major_version),
|
||||
"api_major_version"},
|
||||
{ODK_UINT32, &(core_message->nonce_values.nonce), "nonce"},
|
||||
{ODK_UINT32, &(core_message->nonce_values.session_id), "session_id"},
|
||||
};
|
||||
std::vector<ODK_Field> total_fields =
|
||||
ODK_MakeTotalFields(extra_fields, core_message);
|
||||
|
||||
uint32_t header_size = 0;
|
||||
for (auto& field : total_fields) {
|
||||
header_size += ODK_FieldLength(field.type);
|
||||
}
|
||||
|
||||
total_fields.insert(total_fields.end(), extra_fields.begin(),
|
||||
extra_fields.end());
|
||||
for (auto& field : total_fields) {
|
||||
*buf_size += ODK_FieldLength(field.type);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Copyright 2019 Google LLC. All rights reserved. This file and proprietary */
|
||||
/* source code may only be used and distributed under the Widevine Master */
|
||||
/* License Agreement. */
|
||||
// Copyright 2019 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_ODK_TEST_HELPER_H_
|
||||
#define WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
|
||||
@@ -66,7 +66,7 @@ struct ODK_ProvisioningResponseParams {
|
||||
std::vector<ODK_Field> extra_fields;
|
||||
};
|
||||
|
||||
/* Default values in core_message for testing */
|
||||
// Default values in core_message for testing
|
||||
void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
|
||||
uint32_t message_type);
|
||||
void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params);
|
||||
@@ -77,9 +77,9 @@ void ODK_SetDefaultProvisioningResponseParams(
|
||||
size_t ODK_FieldLength(ODK_FieldType type);
|
||||
size_t ODK_AllocSize(ODK_FieldType type);
|
||||
|
||||
/* Copy ODK_Field to buf */
|
||||
// Copy ODK_Field to buf
|
||||
OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field);
|
||||
/* Load buf to ODK_Field */
|
||||
// Load buf to ODK_Field
|
||||
OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, const ODK_Field* field);
|
||||
OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, const ODK_Field* field);
|
||||
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf,
|
||||
@@ -89,11 +89,11 @@ void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
|
||||
const std::vector<ODK_Field>& fields);
|
||||
void ODK_ResetOdkFields(std::vector<ODK_Field>* fields);
|
||||
|
||||
/* Serialize core_message and extra_fields into buf */
|
||||
// Serialize core_message and extra_fields into buf
|
||||
void ODK_BuildMessageBuffer(ODK_CoreMessage* core_message,
|
||||
const std::vector<ODK_Field>& extra_fields,
|
||||
uint8_t** buf, uint32_t* buf_size);
|
||||
|
||||
} /* namespace wvodk_test */
|
||||
} // namespace wvodk_test
|
||||
|
||||
#endif /* WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_ */
|
||||
#endif // WIDEVINE_ODK_TEST_ODK_TEST_HELPER_H_
|
||||
|
||||
@@ -35,6 +35,7 @@ TEST(OdkTimerBasicTest, NullTest) {
|
||||
TEST(OdkTimerBasicTest, Init) {
|
||||
// Verify that basic initialization sets all of the fields.
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
uint64_t time = 42;
|
||||
ODK_InitializeClockValues(&clock_values, time);
|
||||
EXPECT_EQ(clock_values.time_of_license_signed, time);
|
||||
@@ -50,6 +51,7 @@ TEST(OdkTimerBasicTest, Reload) {
|
||||
// Verify that reloading clock values uses the same values
|
||||
// for fields that can be saved, and sets others to 0.
|
||||
ODK_ClockValues clock_values;
|
||||
memset(&clock_values, 0, sizeof(clock_values));
|
||||
uint64_t time = 42u;
|
||||
uint64_t lic_signed = 1u;
|
||||
uint64_t first_decrypt = 2u;
|
||||
@@ -1223,6 +1225,7 @@ TEST_F(ODKUseCase_LimitedDurationLicense, Case5) {
|
||||
TEST_F(RenewalTest, V15Test) {
|
||||
const uint32_t key_duration = 25;
|
||||
ODK_NonceValues nonce_values;
|
||||
memset(&nonce_values, 0, sizeof(nonce_values));
|
||||
const uint64_t license_loaded = GetSystemTime(10);
|
||||
EXPECT_EQ(
|
||||
ODK_InitializeV15Values(&timer_limits_, &clock_values_, &nonce_values,
|
||||
|
||||
Reference in New Issue
Block a user