// Copyright 2023 Google LLC. All Rights Reserved. This file and proprietary // source code may only be used and distributed under the Widevine // License Agreement. #include #include #include "FuzzedDataProvider.h" #include "OEMCryptoCENC.h" #include "oemcrypto_fuzz_helper.h" using namespace wvoec; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Redirect printf and log statements from oemcrypto functions to a file to // reduce noise RedirectStdoutToFile(); OEMCryptoLicenseAPIFuzz license_api_fuzz; FuzzedDataProvider fuzzed_data(data, size); if (fuzzed_data.ConsumeBool()) { license_api_fuzz.license_messages().set_control( license_api_fuzz.license_messages().control() | kControlAllowHashVerification); } const uint32_t session_id = license_api_fuzz.session()->session_id(); const std::array content_key_id{}; const uint32_t frame_number = fuzzed_data.ConsumeIntegral(); std::array sample_buffer{}; OEMCrypto_SubSampleDescription subsample; subsample.num_bytes_clear = 0; subsample.num_bytes_encrypted = sample_buffer.size(); subsample.subsample_flags = OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample; subsample.block_offset = 0; OEMCrypto_SampleDescription sample; sample.buffers.input_data = sample_buffer.data(); sample.buffers.input_data_length = sample_buffer.size(); sample.buffers.output_descriptor.type = OEMCrypto_BufferType_Clear; sample.buffers.output_descriptor.buffer.clear.clear_buffer = sample_buffer.data(); sample.buffers.output_descriptor.buffer.clear.clear_buffer_length = sample_buffer.size(); memset(sample.iv, 0, sizeof(sample.iv)); sample.subsamples = &subsample; sample.subsamples_length = 1; OEMCrypto_CENCEncryptPatternDesc pattern; pattern.encrypt = 0; pattern.skip = 0; uint32_t failed_frame_number_data; uint32_t* const failed_frame_number = fuzzed_data.ConsumeBool() ? &failed_frame_number_data : nullptr; const std::vector hash = fuzzed_data.ConsumeRemainingBytes(); license_api_fuzz.LoadLicense(); std::vector key_handle; GetKeyHandleIntoVector(session_id, content_key_id.data(), content_key_id.size(), OEMCrypto_CipherMode_CENC, key_handle); OEMCrypto_SetDecryptHash(session_id, frame_number, hash.data(), hash.size()); OEMCrypto_DecryptCENC(key_handle.data(), key_handle.size(), &sample, 1, &pattern); OEMCrypto_GetHashErrorCode(session_id, failed_frame_number); return 0; }