/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "license.h" #include "privacy_crypto.h" #include "properties.h" #include "vendor_widevine_fuzz_helper.h" #include "wv_cdm_constants.h" #include using namespace wvcdm; using namespace video_widevine; using video_widevine::DrmCertificate; using video_widevine::SignedDrmCertificate; constexpr int32_t kMaxByte = 256; constexpr int32_t kMinFirstComponent = 0; constexpr int32_t kMaxFirstComponent = 2; constexpr int32_t kMinSecondComponent = 0; constexpr int32_t kMaxSecondComponent = 39; constexpr int32_t kMinNumComponent = 0; constexpr int32_t kMaxNumComponent = 10; class PrivacyCryptoFuzzer { public: PrivacyCryptoFuzzer(const uint8_t *data, size_t size) : fdp_(data, size){}; void Process(); std::string CreateOid() { std::string oid; int32_t first_component = fdp_.ConsumeIntegralInRange( kMinFirstComponent, kMaxFirstComponent); oid += std::to_string(first_component); oid += '.'; uint32_t temp = 0; if (first_component != 2) { temp = fdp_.ConsumeIntegralInRange(kMinSecondComponent, kMaxSecondComponent); } else { temp = fdp_.ConsumeIntegral(); } oid += std::to_string(temp); int32_t num_component = fdp_.ConsumeIntegralInRange( kMinNumComponent, kMaxNumComponent); for (int32_t i = 0; i < num_component; ++i) { oid += '.'; oid += std::to_string(fdp_.ConsumeIntegral()); } return oid; } private: FuzzedDataProvider fdp_; }; void PrivacyCryptoFuzzer::Process() { AesCbcKey aes_cbc_key; RsaPublicKey rsa_pub_key; while (fdp_.remaining_bytes()) { auto privacy_crypto_API = fdp_.PickValueInArray>({ [&]() { /** * This Implementation is required to initialize RSA-public_key * correctly. */ FuzzCdmClientPropertySet property_set(&fdp_); property_set.enable_privacy_mode(); property_set.set_service_certificate(kTestSignedCertificate); PropertiesTestPeer::ForceReinit(); PropertiesTestPeer::AddSessionPropertySet(kTestSessionId1, &property_set); std::string raw_service_certificate; PropertiesTestPeer::GetServiceCertificate(kTestSessionId1, &raw_service_certificate); SignedDrmCertificate signed_root_certificate; std::string root_cert_str( reinterpret_cast(&kRootCertForProd[0]), sizeof(kRootCertForProd)); signed_root_certificate.ParseFromString(root_cert_str); DrmCertificate root_cert; root_cert.ParseFromString(signed_root_certificate.drm_certificate()); rsa_pub_key.Init(fdp_.ConsumeBool() ? root_cert.public_key() : fdp_.ConsumeRandomLengthString(kMaxByte)); }, [&]() { std::string cipher_text; std::string message = fdp_.ConsumeRandomLengthString(kMaxByte); rsa_pub_key.Encrypt(message, &cipher_text); }, [&]() { rsa_pub_key.VerifySignature( fdp_.ConsumeRandomLengthString(kMaxByte) /* message */, fdp_.ConsumeRandomLengthString(kMaxByte) /* signature */); }, [&]() { std::string key = fdp_.ConsumeRandomLengthString(SERVICE_KEY_SIZE); if (fdp_.ConsumeBool()) { key.resize(SERVICE_KEY_SIZE, '0'); } aes_cbc_key.Init(key); }, [&]() { std::string enc_id; std::string iv = fdp_.ConsumeRandomLengthString(KEY_IV_SIZE); if (fdp_.ConsumeBool()) { iv.resize(KEY_IV_SIZE, '0'); } aes_cbc_key.Encrypt(fdp_.ConsumeRandomLengthString(kMaxByte), fdp_.ConsumeBool() ? &enc_id : nullptr, fdp_.ConsumeBool() ? &iv : nullptr); }, [&]() { std::string data = fdp_.ConsumeRandomLengthString(kMaxByte); Md5Hash(data); }, [&]() { std::string data = fdp_.ConsumeRandomLengthString(kMaxByte); Sha256Hash(data); }, [&]() { size_t cert_index = fdp_.ConsumeBool() ? fdp_.ConsumeIntegral() : kOemCertSystemIdIndex; uint32_t value = 0; std::string oid = CreateOid(); ExtractExtensionValueFromCertificate( fdp_.ConsumeBool() ? kOemCertStr : fdp_.ConsumeRandomLengthString(kMaxByte), oid, cert_index, &value); }, }); privacy_crypto_API(); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { PrivacyCryptoFuzzer privacy_crypto_fuzzer(data, size); privacy_crypto_fuzzer.Process(); return 0; }