Fix InjectFuzzedResponseData unused size parameter

Merge from Widevine repo of http://go/wvgerrit/159077

ProvisioningRoundTrip::InjectFuzzedResponseData and
LicenseRoundTrip::InjectFuzzedResponseData were unsafe as they ignored
their size parameter.

Test: tested with http://go/ag/20420224

Change-Id: I9b5647a283d98bc960caa458b1adf433a3f0ae17
This commit is contained in:
Ian Benz
2022-11-08 13:52:29 -08:00
committed by Fred Gylys-Colwell
parent d9567c66fd
commit 2e9cbaf30f

View File

@@ -58,6 +58,27 @@ using oemcrypto_core_message::features::CoreMessageFeatures;
constexpr size_t kTestSubsampleSectionSize = 256;
// Fill objects by consuming a source buffer of fuzzed data.
class FuzzedData {
public:
FuzzedData(const uint8_t* source, size_t source_size)
: source_(source), source_size_(source_size) {}
// Fill the destination buffer with fuzzed data.
void Fill(void* destination, size_t destination_size) {
if (source_ && destination) {
const size_t fill_size = std::min(source_size_, destination_size);
memcpy(destination, source_, fill_size);
source_ += fill_size;
source_size_ -= fill_size;
}
}
private:
const uint8_t* source_;
size_t source_size_;
};
// Encrypt a block of data using CTR mode.
void EncryptCTR(const vector<uint8_t>& in_buffer, const uint8_t* key,
const uint8_t* starting_iv, vector<uint8_t>* out_buffer) {
@@ -440,14 +461,16 @@ void ProvisioningRoundTrip::SignResponse() {
}
void ProvisioningRoundTrip::InjectFuzzedResponseData(const uint8_t* data,
size_t size UNUSED) {
size_t size) {
// Interpreting fuzz data as unencrypted core_response + message_data
const size_t core_response_size = sizeof(ODK_ParsedProvisioning);
FuzzedData fuzzed_data(data, size);
// Copy core_response from data and serialize.
memcpy(&core_response_, data, core_response_size);
fuzzed_data.Fill(&core_response_, sizeof(core_response_));
// Copy provisioning message data into response_data.
memcpy(&response_data_, data + core_response_size, sizeof(response_data_));
fuzzed_data.Fill(&response_data_, sizeof(response_data_));
// Set nonce to one from session to pass nonce checks.
response_data_.nonce = session()->nonce();
}
@@ -661,11 +684,13 @@ void LicenseRoundTrip::InjectFuzzedTimerLimits(
}
void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data,
size_t size UNUSED) {
size_t size) {
// Interpreting fuzz data as unencrypted core_response + message_data
const size_t core_response_size = sizeof(ODK_ParsedLicense);
FuzzedData fuzzed_data(data, size);
// Copy core_response from data.
memcpy(&core_response_, data, core_response_size);
fuzzed_data.Fill(&core_response_, sizeof(core_response_));
// Maximum number of keys could be kMaxNumKeys(30). key_array_length can be
// any random value as it is read from fuzz data.
// Key data array(MessageKeyData keys[kMaxNumKeys]) will be looped over
@@ -676,10 +701,12 @@ void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data,
if (core_response_.key_array_length > kMaxNumKeys) {
core_response_.key_array_length = kMaxNumKeys;
}
// For corpus data, this value gets set to 4, but we need to test other
// scenarios too, hence reading key_array_length value.
set_num_keys(core_response_.key_array_length);
ConvertDataToValidBools(&core_response_);
// TODO(b/157520981): Once assertion bug is fixed, for loop can be removed.
// Workaround for the above bug: key_data.length and key_id.length are being
// used in AES decryption process and are expected to be a multiple of 16. An
@@ -700,7 +727,7 @@ void LicenseRoundTrip::InjectFuzzedResponseData(const uint8_t* data,
// Copy response_data from data and set nonce to match one in request to pass
// nonce validations.
memcpy(&response_data_, data + core_response_size, sizeof(response_data_));
fuzzed_data.Fill(&response_data_, sizeof(response_data_));
for (uint32_t i = 0; i < num_keys_; ++i) {
response_data_.keys[i].control.nonce = session()->nonce();
}