diff --git a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp index 393fdfb5..efc1a57d 100644 --- a/libwvdrmengine/oemcrypto/test/oec_session_util.cpp +++ b/libwvdrmengine/oemcrypto/test/oec_session_util.cpp @@ -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& in_buffer, const uint8_t* key, const uint8_t* starting_iv, vector* 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(); }