Source release 17.1.1
This commit is contained in:
163
oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp
Normal file
163
oemcrypto/odk/test/fuzzing/odk_fuzz_helper.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright 2020 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
#include "fuzzing/odk_fuzz_helper.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "odk.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
using features::CoreMessageFeatures;
|
||||
|
||||
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 UNUSED) {}
|
||||
|
||||
void ConvertDataToValidBools(ODK_ParsedProvisioning* t UNUSED) {}
|
||||
|
||||
OEMCryptoResult odk_serialize_LicenseRequest(
|
||||
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);
|
||||
}
|
||||
|
||||
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 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;
|
||||
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->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);
|
||||
const bool is_parse_renewal_response_successful =
|
||||
err == ODK_SET_TIMER || err == ODK_DISABLE_TIMER ||
|
||||
err == ODK_TIMER_EXPIRED || err == ODK_STALE_RENEWAL;
|
||||
if (!is_parse_renewal_response_successful) {
|
||||
return err;
|
||||
}
|
||||
// In order to capture playback_time information which is part of
|
||||
// renewal_msg and will be later used in kdo_serialize_RenewalResponse in
|
||||
// odk_kdo method, we call Unpack_ODK_PreparedRenewalRequest private method.
|
||||
// playback_time cannot be captured from publicly exposed API
|
||||
// ODK_ParseRenewal.
|
||||
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;
|
||||
}
|
||||
|
||||
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(
|
||||
CoreMessageFeatures::kDefaultFeatures, 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(
|
||||
CoreMessageFeatures::kDefaultFeatures, 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(
|
||||
CoreMessageFeatures::kDefaultFeatures, parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
} // namespace oemcrypto_core_message
|
||||
Reference in New Issue
Block a user