diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
index 81231400..1ad4e09f 100644
--- a/fuzzer/Android.bp
+++ b/fuzzer/Android.bp
@@ -134,3 +134,9 @@ cc_fuzz {
srcs: ["device_files_fuzzer.cpp"],
defaults: ["libcdm_fuzzer_defaults"],
}
+
+cc_fuzz{
+ name: "cdm_session_fuzzer",
+ srcs: ["cdm_session_fuzzer.cpp"],
+ defaults: ["libcdm_fuzzer_defaults"]
+}
diff --git a/fuzzer/README.md b/fuzzer/README.md
index d313f2f0..33cbe1df 100644
--- a/fuzzer/README.md
+++ b/fuzzer/README.md
@@ -13,6 +13,7 @@
+ [cdm_engine_fuzzer](#CdmEngine)
+ [certificate_provisioning_fuzzer](#CertificateProvisioning)
+ [device_files_fuzzer](#DeviceFile)
++ [cdm_session_fuzzer](#CdmSession)
# Fuzzer for PolicyEngine
@@ -304,3 +305,27 @@ DeviceFile supports the following parameters:
$ adb sync data
$ adb shell /data/fuzz/arm64/device_files_fuzzer/vendor/device_files_fuzzer
```
+
+# Fuzzer for CdmSession
+
+CdmSession supports the following parameters:
+1. CdmKeyResponse (parameter name: "key_response")
+2. CdmSessionId (parameter name: "forced_session_id")
+3. KeyId (parameter name:"key_id")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`key_response`| `String` |Value obtained from FuzzedDataProvider|
+|`forced_session_id`| `String` |Value obtained from FuzzedDataProvider|
+|`key_id`| `String` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) cdm_session_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/cdm_session_fuzzer/vendor/cdm_session_fuzzer
+```
diff --git a/fuzzer/cdm_session_fuzzer.cpp b/fuzzer/cdm_session_fuzzer.cpp
new file mode 100644
index 00000000..38905589
--- /dev/null
+++ b/fuzzer/cdm_session_fuzzer.cpp
@@ -0,0 +1,569 @@
+/*
+ * 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 "cdm_client_property_set.h"
+#include "cdm_random.h"
+#include "cdm_session.h"
+#include "cdm_session_map.h"
+#include "device_files.h"
+#include "license.h"
+#include "metrics_collections.h"
+#include "timer_metric.h"
+#include "vendor_widevine_fuzz_helper.h"
+#include "wv_cdm_event_listener.h"
+#include "wv_cdm_types.h"
+#include
+
+using namespace wvcdm;
+using namespace wvcdm::metrics;
+using namespace wvutil;
+
+static constexpr int32_t kMinByte = 0;
+static constexpr int32_t kMaxByte = 256;
+static constexpr int32_t kMaxId = 100;
+static constexpr int32_t kMinId = 0;
+static constexpr int8_t kMaxSize = 16;
+static std::string kSessionId = "sid";
+static std::string kKeyId = "k" + kSessionId;
+
+std::string kInitType[] = {ISO_BMFF_VIDEO_MIME_TYPE, ISO_BMFF_AUDIO_MIME_TYPE,
+ WEBM_VIDEO_MIME_TYPE, WEBM_AUDIO_MIME_TYPE,
+ CENC_INIT_DATA_FORMAT, HLS_INIT_DATA_FORMAT,
+ WEBM_INIT_DATA_FORMAT};
+
+class FuzzEventListener : public WvCdmEventListener {
+ void OnSessionRenewalNeeded(const CdmSessionId & /*session_id*/) {}
+ void OnSessionKeysChange(const CdmSessionId & /*session_id*/,
+ const CdmKeyStatusMap & /*keys_status*/,
+ bool /*has_new_usable_key*/) {}
+ void OnExpirationUpdate(const CdmSessionId & /*session_id*/,
+ int64_t /*new_expiry_time_seconds*/) {}
+};
+
+class CdmSessionFuzzer {
+public:
+ CdmSessionFuzzer(const uint8_t *data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ FuzzedDataProvider mFdp;
+ void invokeCdmSessionAPIs(CdmSession *cdmSession);
+ void invokeCdmSessionMapAPIs();
+ CdmResponseType
+ initCdmSession(CdmSession *cdmSession,
+ FuzzCdmClientPropertySet *fuzzCdmClientPropertySet,
+ CdmSessionId forcedsessionId,
+ FuzzEventListener *fuzzeventListener, bool forcedLevel);
+ void createResponse(CdmKeyResponse *response);
+ void setLicenseMsg(std::string *msg);
+ void storeLicense(DeviceFiles::CdmLicenseData licenseData);
+};
+
+class FuzzFile : public File {
+public:
+ FuzzFile(FuzzedDataProvider *fdp) : mFdp(fdp) {}
+
+ ssize_t Read(char *buffer, size_t bytes) {
+ std::vector initData = mFdp->ConsumeBytes(
+ mFdp->ConsumeIntegralInRange(kMinByte, bytes));
+ buffer = initData.data();
+ return initData.size();
+ };
+
+ ssize_t Write(const char * /* buffer*/, size_t bytes) {
+ return mFdp->ConsumeIntegralInRange(kMinByte, bytes);
+ };
+
+private:
+ FuzzedDataProvider *mFdp;
+};
+
+class FuzzFileSystem : public FileSystem {
+public:
+ FuzzFileSystem(FuzzedDataProvider *fdp) : mFdp(fdp) {}
+
+ std::unique_ptr Open(const std::string &, int) {
+ return std::unique_ptr(new FuzzFile(mFdp));
+ }
+
+ bool Exists(const std::string &) { return mFdp->ConsumeBool(); }
+
+ bool Remove(const std::string &) { return mFdp->ConsumeBool(); }
+
+ ssize_t FileSize(const std::string &) {
+ return mFdp->ConsumeIntegralInRange(kMinByte, kMaxByte);
+ }
+
+ bool List(const std::string &, std::vector *) {
+ return mFdp->ConsumeBool();
+ }
+
+private:
+ FuzzedDataProvider *mFdp;
+};
+
+void policySetBool(std::function function,
+ FuzzedDataProvider *fdp) {
+ if (fdp->ConsumeBool()) {
+ function(fdp->ConsumeBool());
+ }
+}
+
+void CdmSessionFuzzer::setLicenseMsg(std::string *msg) {
+ video_widevine::License license;
+
+ if (mFdp.ConsumeBool()) {
+ std::string provider_client_token =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ license.set_provider_client_token(provider_client_token);
+ }
+ if (mFdp.ConsumeBool()) {
+ uint32_t scheme = mFdp.ConsumeIntegral();
+ license.set_protection_scheme(scheme);
+ }
+
+ video_widevine::License::KeyContainer *container = license.add_key();
+
+ if (mFdp.ConsumeBool()) {
+ uint32_t keyType = mFdp.ConsumeIntegralInRange(
+ video_widevine::License::KeyContainer::SIGNING,
+ video_widevine::License::KeyContainer::ENTITLEMENT);
+ container->set_type((video_widevine::License_KeyContainer_KeyType)keyType);
+ }
+
+ if (mFdp.ConsumeBool()) {
+ container->mutable_iv();
+ }
+
+ if (mFdp.ConsumeBool()) {
+ std::string keyString = mFdp.ConsumeRandomLengthString(kMaxByte);
+ container->set_key(keyString);
+ }
+
+ if (mFdp.ConsumeBool()) {
+ container->mutable_id();
+ }
+
+ if (mFdp.ConsumeBool()) {
+ container->mutable_track_label();
+ }
+
+ video_widevine::License_KeyContainer_KeyControl *keyControl =
+ container->mutable_key_control();
+ if (mFdp.ConsumeBool()) {
+ keyControl->mutable_key_control_block();
+ }
+
+ if (mFdp.ConsumeBool()) {
+ keyControl->mutable_iv();
+ }
+
+ if (mFdp.ConsumeBool()) {
+ video_widevine::License_Policy *policy = license.mutable_policy();
+ policySetBool(std::bind(&video_widevine::License_Policy::set_can_persist,
+ policy, std::placeholders::_1),
+ &mFdp);
+ if (mFdp.ConsumeBool()) {
+ std::string server_url = mFdp.ConsumeRandomLengthString(kMaxByte);
+ policy->set_renewal_server_url(server_url);
+ }
+ policySetBool(
+ std::bind(&video_widevine::License_Policy::set_always_include_client_id,
+ policy, std::placeholders::_1),
+ &mFdp);
+ }
+
+ LicenseIdentification *id = license.mutable_id();
+ if (mFdp.ConsumeBool()) {
+ id->set_type(mFdp.ConsumeBool() ? video_widevine::STREAMING
+ : video_widevine::OFFLINE);
+ }
+ if (mFdp.ConsumeBool()) {
+ std::string provider_session_token =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ id->set_provider_session_token(provider_session_token);
+ }
+ license.SerializeToString(msg);
+}
+
+void CdmSessionFuzzer::createResponse(CdmKeyResponse *response) {
+ video_widevine::SignedMessage signed_message;
+ video_widevine::SignedMessage type;
+ signed_message.set_type(video_widevine::SignedMessage::LICENSE);
+ signed_message.mutable_service_version_info();
+ std::string sign = mFdp.ConsumeRandomLengthString(kMaxByte);
+ sign.resize(kMaxId, '0');
+ signed_message.set_signature(sign);
+ std::string key = mFdp.ConsumeRandomLengthString(kMaxByte);
+ key.resize(kMaxId, '0');
+ signed_message.set_session_key(key);
+ std::string message = mFdp.ConsumeRandomLengthString(kMaxByte);
+ message.resize(kMaxId, '0');
+ signed_message.set_oemcrypto_core_message(message);
+ signed_message.set_using_secondary_key(mFdp.ConsumeBool());
+ std::string setMsg = mFdp.ConsumeRandomLengthString(kMaxByte);
+ signed_message.set_msg(setMsg);
+ signed_message.SerializeToString(response);
+}
+
+CdmResponseType CdmSessionFuzzer::initCdmSession(
+ CdmSession *cdmSession, FuzzCdmClientPropertySet *fuzzCdmClientPropertySet,
+ CdmSessionId forcedsessionId, FuzzEventListener *fuzzeventListener,
+ bool forcedLevel) {
+ CdmResponseType result;
+ if (mFdp.ConsumeBool()) {
+ result =
+ cdmSession->Init(fuzzCdmClientPropertySet /*cdm_client_property_set*/,
+ &forcedsessionId /*forced_session_id*/,
+ fuzzeventListener /*event_listener*/, forcedLevel);
+ } else {
+ result =
+ cdmSession->Init(fuzzCdmClientPropertySet /*cdm_client_property_set*/);
+ }
+ return result;
+}
+
+void CdmSessionFuzzer::storeLicense(DeviceFiles::CdmLicenseData licenseData) {
+ FuzzFileSystem fileSystemdev(&mFdp);
+ DeviceFiles deviceFiles(mFdp.ConsumeBool() ? &fileSystemdev : nullptr);
+ deviceFiles.Init((CdmSecurityLevel)mFdp.ConsumeIntegralInRange(
+ kSecurityLevelL1, kSecurityLevelL3));
+ std::map appParameters;
+
+ appParameters[mFdp.ConsumeBytesAsString(kMaxByte)] =
+ mFdp.ConsumeBytesAsString(kMaxByte);
+ licenseData.key_set_id =
+ std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ licenseData.state =
+ (CdmOfflineLicenseState)mFdp.ConsumeIntegralInRange(
+ kLicenseStateActive, kLicenseStateUnknown);
+ licenseData.pssh_data = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.license_request = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.license = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.license_renewal_request =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.license_renewal = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.release_server_url = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.playback_start_time = mFdp.ConsumeIntegral();
+ licenseData.last_playback_time = mFdp.ConsumeIntegral();
+ licenseData.grace_period_end_time = mFdp.ConsumeIntegral();
+ licenseData.app_parameters = appParameters;
+ licenseData.usage_entry = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.usage_entry_index = mFdp.ConsumeIntegral();
+ licenseData.drm_certificate = mFdp.ConsumeRandomLengthString(kMaxByte);
+ licenseData.wrapped_private_key = CryptoWrappedKey(
+ (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange(
+ CryptoWrappedKey::kUninitialized, CryptoWrappedKey::kEcc),
+ mFdp.ConsumeRandomLengthString(kMaxByte));
+
+ DeviceFiles::ResponseType result;
+ deviceFiles.StoreLicense(licenseData, &result);
+}
+
+void CdmSessionFuzzer::invokeCdmSessionAPIs(CdmSession *cdmSession) {
+ CdmKeyResponse response;
+ createResponse(&response);
+ CdmKeyRequest keyRequest;
+ CdmKeyMessage signedRequest;
+ keyRequest.message = signedRequest;
+ keyRequest.type = (CdmKeyRequestType)mFdp.ConsumeIntegralInRange(
+ kKeyRequestTypeUnknown, kKeyRequestTypeRelease);
+ std::string url;
+ keyRequest.url = url;
+ while (mFdp.remaining_bytes()) {
+ auto invokeCdmSessionAPI = mFdp.PickValueInArray<
+ const std::function>(
+ {[&]() { cdmSession->AddKey(response /*key_response*/); },
+ [&]() {
+ FuzzCdmClientPropertySet propertyset(&mFdp);
+ propertyset.enable_privacy_mode();
+ propertyset.set_service_certificate(kTestSignedCertificate);
+ PropertiesTestPeer::ForceReinit();
+ PropertiesTestPeer::AddSessionPropertySet(
+ mFdp.ConsumeBool() ? kTestSessionId1
+ : mFdp.ConsumeRandomLengthString(kMaxByte),
+ &propertyset);
+ std::string rawServiceCertificate;
+ PropertiesTestPeer::GetServiceCertificate(
+ mFdp.ConsumeBool() ? kTestSessionId1
+ : mFdp.ConsumeRandomLengthString(kMaxByte),
+ &rawServiceCertificate);
+ cdmSession->SetServiceCertificate(
+ rawServiceCertificate /*service_certificate*/);
+ },
+ [&]() {
+ CdmQueryMap queryResponse;
+ cdmSession->QueryKeyStatus(&queryResponse /*query_response*/);
+ },
+ [&]() {
+ const std::string oecVersion = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ std::string dataType = mFdp.PickValueInArray(kInitType);
+ std::unique_ptr initData(new InitializationData(
+ dataType, a2bs_hex(mFdp.ConsumeRandomLengthString(kMaxByte)),
+ oecVersion));
+ CdmLicenseType licenseType =
+ (CdmLicenseType)mFdp.ConsumeIntegralInRange(
+ kLicenseTypeOffline, kLicenseTypeEmbeddedKeyData);
+ CdmAppParameterMap appParameters;
+ cdmSession->GenerateKeyRequest(
+ *initData /*init_data*/, licenseType /*license_type*/,
+ appParameters /*app_parameters*/, &keyRequest /*key_request*/);
+ },
+ [&]() {
+ CdmQueryMap queryResponse;
+ cdmSession->QueryStatus(&queryResponse /*query_response*/);
+ },
+ [&]() {
+ DeviceFiles::CdmLicenseData licenseData;
+ storeLicense(licenseData);
+ std::string randomData = mFdp.ConsumeRandomLengthString(kMaxByte);
+ const CdmKeySetId keySetId =
+ mFdp.ConsumeBool()
+ ? (kKeyId + wvutil::b2a_hex(randomData))
+ : std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ CdmLicenseType licenseType =
+ (CdmLicenseType)mFdp.ConsumeIntegralInRange(
+ kLicenseTypeOffline, kLicenseTypeEmbeddedKeyData);
+ int errorDetail = mFdp.ConsumeIntegral();
+ cdmSession->RestoreOfflineSession(keySetId /*key_set_id*/,
+ licenseType /*license_type*/,
+ &errorDetail /*error_detail*/);
+ },
+ [&]() {
+ DeviceFiles::CdmUsageData usageData;
+ usageData.provider_session_token =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ usageData.license_request = mFdp.ConsumeRandomLengthString(kMaxByte);
+ usageData.license = mFdp.ConsumeRandomLengthString(kMaxByte);
+ std::string randomData = mFdp.ConsumeRandomLengthString(kMaxByte);
+ usageData.key_set_id =
+ mFdp.ConsumeBool()
+ ? (kKeyId + wvutil::b2a_hex(randomData))
+ : std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ usageData.usage_entry = mFdp.ConsumeRandomLengthString(kMaxByte);
+ usageData.usage_entry_index = mFdp.ConsumeIntegral();
+ usageData.drm_certificate = mFdp.ConsumeRandomLengthString(kMaxByte);
+ usageData.wrapped_private_key = CryptoWrappedKey(
+ (CryptoWrappedKey::Type)mFdp.ConsumeIntegralInRange(
+ CryptoWrappedKey::kUninitialized, CryptoWrappedKey::kEcc),
+ mFdp.ConsumeRandomLengthString(kMaxByte));
+ int errorDetail = mFdp.ConsumeIntegral();
+ cdmSession->RestoreUsageSession(usageData /*usage_data*/,
+ &errorDetail /*error_detail*/);
+ },
+ [&]() {
+ const std::string keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ CdmKeyAllowedUsage keyUsage;
+ cdmSession->QueryKeyAllowedUsage(keyId /*key_id*/,
+ &keyUsage /*key_usage*/);
+ },
+ [&]() {
+ CdmQueryMap queryResponse;
+ cdmSession->QueryOemCryptoSessionId(
+ &queryResponse /*query_response*/);
+ },
+ [&]() {
+ const KeyId keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ CdmDecryptionParametersV16 params(keyId);
+ const uint8_t encryptBufferParam = mFdp.ConsumeIntegral();
+ void *decryptBufferParam;
+ size_t decryptbufferOffsetParam = mFdp.ConsumeIntegral();
+ size_t length = mFdp.ConsumeIntegral();
+ const std::vector iv = mFdp.ConsumeBytes(kMaxSize);
+ CdmDecryptionSample sample(&encryptBufferParam, decryptBufferParam,
+ decryptbufferOffsetParam, length, iv);
+ CdmDecryptionSubsample subsample(mFdp.ConsumeIntegral(),
+ mFdp.ConsumeIntegral());
+ sample.subsamples.push_back(subsample);
+ params.samples.push_back(sample);
+ cdmSession->Decrypt(params /*parameters*/);
+ },
+ [&]() {
+ cdmSession->GenerateRenewalRequest(&keyRequest /*key_request*/);
+ },
+ [&]() { cdmSession->RenewKey(response /*key_response*/); },
+ [&]() {
+ const KeyId keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ cdmSession->IsKeyLoaded(keyId /*key_id*/);
+ },
+ [&]() { cdmSession->GetDurationRemaining(); },
+ [&]() {
+ cdmSession->NotifyResolution(
+ mFdp.ConsumeIntegral() /*width*/,
+ mFdp.ConsumeIntegral() /*height*/);
+ },
+ [&]() {
+ cdmSession->OnTimerEvent(mFdp.ConsumeBool() /*update_usage*/);
+ },
+ [&]() {
+ const CdmKeySetId keySetId =
+ kKeyId + mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->OnKeyReleaseEvent(keySetId /*key_set_id*/);
+ },
+ [&]() {
+ std::string appId =
+ kSessionId +
+ std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ cdmSession->GetApplicationId(&appId /*app_id*/);
+ },
+ [&]() { cdmSession->UpdateUsageEntryInformation(); },
+ [&]() { cdmSession->GenerateSessionId(); },
+ [&]() {
+ const std::string inBuffer =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ const std::string keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ const std::string iv = mFdp.ConsumeRandomLengthString(kMaxByte);
+ CdmEncryptionAlgorithm algorithm =
+ mFdp.ConsumeBool()
+ ? CdmEncryptionAlgorithm::kEncryptionAlgorithmAesCbc128
+ : CdmEncryptionAlgorithm::kEncryptionAlgorithmUnknown;
+ std::string outBuffer = mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->GenericEncrypt(inBuffer /*in_buffer*/, keyId /*key_id*/,
+ iv, algorithm, &outBuffer /*out_buffer*/);
+ },
+ [&]() {
+ const std::string inBuffer =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ const std::string keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ const std::string iv = mFdp.ConsumeRandomLengthString(kMaxByte);
+ CdmEncryptionAlgorithm algorithm =
+ mFdp.ConsumeBool()
+ ? CdmEncryptionAlgorithm::kEncryptionAlgorithmAesCbc128
+ : CdmEncryptionAlgorithm::kEncryptionAlgorithmUnknown;
+ std::string outBuffer = mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->GenericDecrypt(inBuffer /*in_buffer*/, keyId /*key_id*/,
+ iv, algorithm, &outBuffer /*out_buffer*/);
+ },
+ [&]() {
+ const std::string message = mFdp.ConsumeRandomLengthString(kMaxByte);
+ const std::string keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ CdmSigningAlgorithm algorithm =
+ mFdp.ConsumeBool()
+ ? CdmSigningAlgorithm::kSigningAlgorithmHmacSha256
+ : CdmSigningAlgorithm::kSigningAlgorithmUnknown;
+ std::string signature = mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->GenericSign(message, keyId /*key_id*/, algorithm,
+ &signature);
+ },
+ [&]() {
+ const std::string message = mFdp.ConsumeRandomLengthString(kMaxByte);
+ const std::string keyId = std::to_string(
+ mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ CdmSigningAlgorithm algorithm =
+ mFdp.ConsumeBool()
+ ? CdmSigningAlgorithm::kSigningAlgorithmHmacSha256
+ : CdmSigningAlgorithm::kSigningAlgorithmUnknown;
+ const std::string signature =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->GenericVerify(message, keyId /*key_id*/, algorithm,
+ signature);
+ },
+ [&]() {
+ uint32_t frameNumber = mFdp.ConsumeIntegral();
+ const std::string hash = mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->SetDecryptHash(frameNumber /*frame_number*/, hash);
+ },
+ [&]() {
+ std::string hashErrorString =
+ mFdp.ConsumeRandomLengthString(kMaxByte);
+ cdmSession->GetDecryptHashError(
+ &hashErrorString /*hash_error_string*/);
+ },
+ [&]() { cdmSession->ReleaseKey(response /*key_response*/); },
+ [&]() {
+ cdmSession->GenerateReleaseRequest(&keyRequest /*key_request*/);
+ }});
+ invokeCdmSessionAPI();
+ }
+ UsageEntryIndex entryIndex = mFdp.ConsumeIntegral();
+ cdmSession->DeleteUsageEntry(entryIndex /*usage_entry_index*/);
+ cdmSession->DeleteLicenseFile();
+ cdmSession->RemoveKeys();
+ cdmSession->RemoveLicense();
+}
+
+void CdmSessionFuzzer::invokeCdmSessionMapAPIs() {
+ FuzzFileSystem fileSystemMap(&mFdp);
+ CdmSessionMap cdmsessionMap;
+ std::shared_ptr CdmMetricsMap(
+ new metrics::SessionMetrics);
+ CdmSession *session = new CdmSession(&fileSystemMap, CdmMetricsMap);
+ const CdmSessionId forcedSessionId =
+ kSessionId +
+ std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ cdmsessionMap.Add(forcedSessionId /*id*/, session /*session*/);
+ while (mFdp.remaining_bytes()) {
+ auto invokeCdmSessionMapAPI =
+ mFdp.PickValueInArray>({
+ [&]() { cdmsessionMap.Exists(forcedSessionId /*id*/); },
+ [&]() { cdmsessionMap.Size(); },
+ [&]() {
+ std::shared_ptr cdmsessionShared =
+ std::make_shared(&fileSystemMap, CdmMetricsMap);
+ cdmsessionMap.FindSession(forcedSessionId /*id*/,
+ &cdmsessionShared /*session*/);
+ },
+ [&]() {
+ CdmSessionList sessions;
+ cdmsessionMap.GetSessionList(sessions);
+ },
+ });
+ invokeCdmSessionMapAPI();
+ cdmsessionMap.CloseSession(forcedSessionId);
+ }
+}
+
+void CdmSessionFuzzer::process() {
+ if (mFdp.ConsumeBool()) {
+ FuzzFileSystem fileSystem(&mFdp);
+ FuzzEventListener fuzzeventListener;
+ std::shared_ptr metrics =
+ std::make_shared();
+ std::unique_ptr cdmSession =
+ std::make_unique(&fileSystem, metrics);
+ std::unique_ptr fuzzCdmClientPropertySet(
+ new FuzzCdmClientPropertySet(&mFdp));
+ const CdmSessionId forcedSessionId =
+ kSessionId +
+ std::to_string(mFdp.ConsumeIntegralInRange(kMinId, kMaxId));
+ bool forcedLevel = mFdp.ConsumeBool();
+ CdmResponseType result =
+ initCdmSession(cdmSession.get(), fuzzCdmClientPropertySet.get(),
+ forcedSessionId, &fuzzeventListener, forcedLevel);
+ if (result == NO_ERROR) {
+ invokeCdmSessionAPIs(cdmSession.get());
+ }
+ } else {
+ invokeCdmSessionMapAPIs();
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ CdmSessionFuzzer cdmSessionFuzzer(data, size);
+ cdmSessionFuzzer.process();
+ return 0;
+}