From 41a6f51c13823eeff83703665a6453bdd77f2594 Mon Sep 17 00:00:00 2001 From: kunal rai Date: Tue, 17 Jan 2023 11:55:13 +0530 Subject: [PATCH] Added system_id_extractor_fuzzer exec/s: 316 Test: ./system_id_extractor_fuzzer Bug: 265234582 Change-Id: I9ef8d2747f875bfe287fff51edc90c862a4f4d66 --- fuzzer/Android.bp | 6 + fuzzer/README.md | 25 ++ fuzzer/system_fuzz_helper.h | 380 ++++++++++++++++++++++++++ fuzzer/system_id_extractor_fuzzer.cpp | 205 ++++++++++++++ 4 files changed, 616 insertions(+) create mode 100644 fuzzer/system_fuzz_helper.h create mode 100644 fuzzer/system_id_extractor_fuzzer.cpp diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index 5d1da141..19550b6f 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -75,3 +75,9 @@ cc_fuzz { srcs: ["content_decryption_fuzzer.cpp"], defaults: ["libcdm_fuzzer_defaults"], } + +cc_fuzz { + name: "system_id_extractor_fuzzer", + srcs: ["system_id_extractor_fuzzer.cpp"], + defaults: ["libcdm_fuzzer_defaults"], +} diff --git a/fuzzer/README.md b/fuzzer/README.md index adce4395..d9dc9b6b 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -3,6 +3,7 @@ ## Table of contents + [policy_engine_fuzzer](#PolicyEngine) + [content_decryption_fuzzer](#ContentDecryption) ++ [system_id_extractor_fuzzer](#SystemIdExtractor) # Fuzzer for PolicyEngine @@ -51,3 +52,27 @@ ContentDecryption supports the following parameters: $ adb sync data $ adb shell /data/fuzz/arm64/content_decryption_fuzzer/vendor/content_decryption_fuzzer ``` + +# Fuzzer for SystemIdExtractor + +SystemIdExtractor supports the following parameters: +1. OEM Cert (parameter name: "oemCert") +2. Key Data (parameter name: "keyData") +3. System Id (parameter name: "mSystemId") + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +|`oemCert`| `String` |Value obtained from FuzzedDataProvider| +|`keyData`| `String` |Value obtained from FuzzedDataProvider| +|`mSystemId`| `Integer in range 0 to 256` |Value obtained from FuzzedDataProvider| + +#### Steps to run +1. Build the fuzzer +``` + $ mm -j$(nproc) system_id_extractor_fuzzer +``` +2. Run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/system_id_extractor_fuzzer/vendor/system_id_extractor_fuzzer +``` diff --git a/fuzzer/system_fuzz_helper.h b/fuzzer/system_fuzz_helper.h new file mode 100644 index 00000000..668afce9 --- /dev/null +++ b/fuzzer/system_fuzz_helper.h @@ -0,0 +1,380 @@ +/* + * 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. + * + */ +#ifndef SYSTEM_FUZZ_HELPER_H_ +#define SYSTEM_FUZZ_HELPER_H_ + +#include + +using namespace wvcdm; + +const CdmResponseEnum kCdmResponseEnums[] = { + NO_ERROR, + UNKNOWN_ERROR, + KEY_ADDED, + KEY_ERROR, + KEY_MESSAGE, + NEED_KEY, + KEY_CANCELED, + NEED_PROVISIONING, + DEVICE_REVOKED, + INSUFFICIENT_CRYPTO_RESOURCES, + ADD_KEY_ERROR, + CERT_PROVISIONING_GET_KEYBOX_ERROR_1, + + CERT_PROVISIONING_INVALID_CERT_TYPE, + CERT_PROVISIONING_REQUEST_ERROR_1, + CERT_PROVISIONING_NONCE_GENERATION_ERROR, + + CERT_PROVISIONING_REQUEST_ERROR_4, + CERT_PROVISIONING_RESPONSE_ERROR_1, + CERT_PROVISIONING_RESPONSE_ERROR_2, + CERT_PROVISIONING_RESPONSE_ERROR_3, + CERT_PROVISIONING_RESPONSE_ERROR_4, + CERT_PROVISIONING_RESPONSE_ERROR_7, + CERT_PROVISIONING_RESPONSE_ERROR_8, + DECRYPT_NOT_READY, + DEVICE_CERTIFICATE_ERROR_1, + DEVICE_CERTIFICATE_ERROR_2, + DEVICE_CERTIFICATE_ERROR_3, + DEVICE_CERTIFICATE_ERROR_4, + EMPTY_KEY_DATA_1, + EMPTY_KEY_DATA_2, + EMPTY_KEYSET_ID, + EMPTY_KEYSET_ID_ENG_1, + EMPTY_KEYSET_ID_ENG_2, + EMPTY_KEYSET_ID_ENG_3, + EMPTY_KEYSET_ID_ENG_4, + EMPTY_LICENSE_RENEWAL, + EMPTY_LICENSE_RESPONSE_1, + EMPTY_LICENSE_RESPONSE_2, + EMPTY_PROVISIONING_CERTIFICATE_1, + EMPTY_PROVISIONING_RESPONSE, + EMPTY_SESSION_ID, + GENERATE_DERIVED_KEYS_ERROR, + LICENSE_RENEWAL_NONCE_GENERATION_ERROR, + GENERATE_USAGE_REPORT_ERROR, + GET_LICENSE_ERROR, + GET_RELEASED_LICENSE_ERROR, + GET_USAGE_INFO_ERROR_1, + GET_USAGE_INFO_ERROR_2, + GET_USAGE_INFO_ERROR_3, + GET_USAGE_INFO_ERROR_4, + INIT_DATA_NOT_FOUND, + + INVALID_DECRYPT_PARAMETERS_ENG_1, + INVALID_DECRYPT_PARAMETERS_ENG_2, + INVALID_DECRYPT_PARAMETERS_ENG_3, + INVALID_DECRYPT_PARAMETERS_ENG_4, + INVALID_DEVICE_CERTIFICATE_TYPE, + INVALID_KEY_SYSTEM, + INVALID_LICENSE_RESPONSE, + INVALID_LICENSE_TYPE, + PARAMETER_NULL, + INVALID_PARAMETERS_LIC_1, + INVALID_PARAMETERS_LIC_2, + INVALID_PROVISIONING_PARAMETERS_1, + INVALID_PROVISIONING_PARAMETERS_2, + INVALID_PROVISIONING_REQUEST_PARAM_1, + INVALID_PROVISIONING_REQUEST_PARAM_2, + INVALID_QUERY_KEY, + INVALID_SESSION_ID, + KEY_REQUEST_ERROR_1, + KEY_SIZE_ERROR_1, + KEYSET_ID_NOT_FOUND_1, + KEYSET_ID_NOT_FOUND_2, + KEYSET_ID_NOT_FOUND_3, + LICENSE_ID_NOT_FOUND, + LICENSE_PARSER_INIT_ERROR, + LICENSE_PARSER_NOT_INITIALIZED_1, + LICENSE_PARSER_NOT_INITIALIZED_2, + LICENSE_PARSER_NOT_INITIALIZED_3, + LICENSE_RESPONSE_NOT_SIGNED, + LICENSE_RESPONSE_PARSE_ERROR_1, + LICENSE_RESPONSE_PARSE_ERROR_2, + LICENSE_RESPONSE_PARSE_ERROR_3, + LOAD_KEY_ERROR, + NO_CONTENT_KEY, + REFRESH_KEYS_ERROR, + REMOVE_ALL_USAGE_INFO_ERROR_1, + REMOVE_ALL_USAGE_INFO_ERROR_2, + RELEASE_KEY_ERROR, + RELEASE_KEY_REQUEST_ERROR, + RELEASE_LICENSE_ERROR_1, + RELEASE_LICENSE_ERROR_2, + RELEASE_USAGE_INFO_ERROR, + RENEW_KEY_ERROR_1, + RENEW_KEY_ERROR_2, + RESTORE_OFFLINE_LICENSE_ERROR_2, + NOT_INITIALIZED_ERROR, + REINIT_ERROR, + SESSION_NOT_FOUND_1, + SESSION_NOT_FOUND_2, + SESSION_NOT_FOUND_3, + SESSION_NOT_FOUND_4, + SESSION_NOT_FOUND_5, + SESSION_NOT_FOUND_6, + SESSION_NOT_FOUND_7, + SESSION_NOT_FOUND_8, + SESSION_NOT_FOUND_9, + SESSION_NOT_FOUND_10, + SESSION_NOT_FOUND_FOR_DECRYPT, + SESSION_KEYS_NOT_FOUND, + SIGNATURE_NOT_FOUND, + STORE_LICENSE_ERROR_1, + STORE_LICENSE_ERROR_2, + STORE_USAGE_INFO_ERROR, + UNPROVISION_ERROR_1, + UNPROVISION_ERROR_2, + UNPROVISION_ERROR_3, + UNPROVISION_ERROR_4, + UNSUPPORTED_INIT_DATA, + USAGE_INFO_NOT_FOUND, + PARSE_SERVICE_CERTIFICATE_ERROR, + CLIENT_ID_GENERATE_RANDOM_ERROR, + CLIENT_ID_AES_INIT_ERROR, + CLIENT_ID_AES_ENCRYPT_ERROR, + CLIENT_ID_RSA_INIT_ERROR, + CLIENT_ID_RSA_ENCRYPT_ERROR, + LICENSE_PARSER_NOT_INITIALIZED_4, + INVALID_PARAMETERS_LIC_3, + INVALID_PARAMETERS_LIC_4, + + INVALID_PARAMETERS_LIC_6, + INVALID_PARAMETERS_LIC_7, + LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR, + CENC_INIT_DATA_UNAVAILABLE, + PREPARE_CENC_CONTENT_ID_FAILED, + WEBM_INIT_DATA_UNAVAILABLE, + PREPARE_WEBM_CONTENT_ID_FAILED, + UNSUPPORTED_INIT_DATA_FORMAT, + LICENSE_REQUEST_NONCE_GENERATION_ERROR, + + EMPTY_LICENSE_REQUEST, + SECURE_BUFFER_REQUIRED, + DUPLICATE_SESSION_ID_SPECIFIED, + LICENSE_RENEWAL_PROHIBITED, + EMPTY_PROVISIONING_CERTIFICATE_2, + OFFLINE_LICENSE_PROHIBITED, + STORAGE_PROHIBITED, + EMPTY_KEYSET_ID_ENG_5, + SESSION_NOT_FOUND_11, + LOAD_USAGE_INFO_FILE_ERROR, + LOAD_USAGE_INFO_MISSING, + SESSION_FILE_HANDLE_INIT_ERROR, + INCORRECT_CRYPTO_MODE, + INVALID_PARAMETERS_ENG_5, + DECRYPT_ERROR, + INSUFFICIENT_OUTPUT_PROTECTION, + SESSION_NOT_FOUND_12, + KEY_NOT_FOUND_1, + KEY_NOT_FOUND_2, + KEY_CONFLICT_1, + SESSION_NOT_FOUND_13, + SESSION_NOT_FOUND_14, + SESSION_NOT_FOUND_15, + SESSION_NOT_FOUND_16, + KEY_NOT_FOUND_3, + KEY_NOT_FOUND_4, + KEY_NOT_FOUND_5, + KEY_NOT_FOUND_6, + INVALID_SESSION_1, + NO_DEVICE_KEY_1, + NO_CONTENT_KEY_2, + INVALID_PARAMETERS_ENG_13, + INVALID_PARAMETERS_ENG_14, + INVALID_PARAMETERS_ENG_15, + INVALID_PARAMETERS_ENG_16, + CLIENT_IDENTIFICATION_TOKEN_ERROR_1, + ANALOG_OUTPUT_ERROR, + UNKNOWN_SELECT_KEY_ERROR_1, + UNKNOWN_SELECT_KEY_ERROR_2, + CREATE_USAGE_TABLE_ERROR, + LOAD_USAGE_HEADER_GENERATION_SKEW, + LOAD_USAGE_HEADER_SIGNATURE_FAILURE, + LOAD_USAGE_HEADER_BAD_MAGIC, + LOAD_USAGE_HEADER_UNKNOWN_ERROR, + CREATE_USAGE_ENTRY_UNKNOWN_ERROR, + LOAD_USAGE_ENTRY_GENERATION_SKEW, + LOAD_USAGE_ENTRY_SIGNATURE_FAILURE, + LOAD_USAGE_ENTRY_UNKNOWN_ERROR, + UPDATE_USAGE_ENTRY_UNKNOWN_ERROR, + SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR, + MOVE_USAGE_ENTRY_UNKNOWN_ERROR, + COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR, + INVALID_PARAMETERS_ENG_22, + LIST_LICENSE_ERROR_1, + LIST_LICENSE_ERROR_2, + INVALID_PARAMETERS_ENG_23, + USAGE_INFORMATION_SUPPORT_FAILED, + USAGE_SUPPORT_GET_API_FAILED, + UNEXPECTED_EMPTY_USAGE_ENTRY, + INVALID_USAGE_ENTRY_NUMBER_MODIFICATION, + USAGE_INVALID_NEW_ENTRY, + USAGE_INVALID_PARAMETERS_1, + USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED, + USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED, + USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE, + USAGE_ENTRY_NUMBER_MISMATCH, + USAGE_STORE_LICENSE_FAILED, + USAGE_STORE_USAGE_INFO_FAILED, + USAGE_INVALID_LOAD_ENTRY, + REMOVE_ALL_USAGE_INFO_ERROR_5, + RELEASE_USAGE_INFO_FAILED, + INCORRECT_USAGE_SUPPORT_TYPE_1, + INCORRECT_USAGE_SUPPORT_TYPE_2, + KEY_PROHIBITED_FOR_SECURITY_LEVEL, + KEY_NOT_FOUND_IN_SESSION, + NO_USAGE_ENTRIES, + LIST_USAGE_ERROR_1, + LIST_USAGE_ERROR_2, + DELETE_USAGE_ERROR_1, + DELETE_USAGE_ERROR_2, + DELETE_USAGE_ERROR_3, + PRIVACY_MODE_ERROR_1, + PRIVACY_MODE_ERROR_2, + PRIVACY_MODE_ERROR_3, + EMPTY_RESPONSE_ERROR_1, + INVALID_PARAMETERS_ENG_24, + PARSE_RESPONSE_ERROR_1, + PARSE_RESPONSE_ERROR_2, + PARSE_RESPONSE_ERROR_3, + PARSE_RESPONSE_ERROR_4, + USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED, + USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED, + USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE, + REMOVE_ALL_USAGE_INFO_ERROR_6, + REMOVE_ALL_USAGE_INFO_ERROR_7, + CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE, + LOAD_SYSTEM_ID_ERROR, + REMOVE_USAGE_INFO_ERROR_1, + REMOVE_USAGE_INFO_ERROR_2, + REMOVE_USAGE_INFO_ERROR_3, + NOT_AN_ENTITLEMENT_SESSION, + NO_MATCHING_ENTITLEMENT_KEY, + LOAD_ENTITLED_CONTENT_KEYS_ERROR, + GET_PROVISIONING_METHOD_ERROR, + INVALID_SESSION_2, + SESSION_NOT_FOUND_18, + NO_CONTENT_KEY_3, + DEVICE_CANNOT_REPROVISION, + SESSION_NOT_FOUND_19, + KEY_SIZE_ERROR_2, + SET_DECRYPT_HASH_ERROR, + GET_DECRYPT_HASH_ERROR, + SESSION_NOT_FOUND_20, + INVALID_DECRYPT_HASH_FORMAT, + EMPTY_LICENSE_REQUEST_2, + EMPTY_LICENSE_REQUEST_3, + EMPTY_LICENSE_RESPONSE_3, + EMPTY_LICENSE_RESPONSE_4, + PARSE_REQUEST_ERROR_1, + PARSE_REQUEST_ERROR_2, + INVALID_LICENSE_REQUEST_TYPE_1, + INVALID_LICENSE_REQUEST_TYPE_2, + LICENSE_RESPONSE_PARSE_ERROR_4, + LICENSE_RESPONSE_PARSE_ERROR_5, + INVALID_LICENSE_TYPE_2, + SIGNATURE_NOT_FOUND_2, + SESSION_KEYS_NOT_FOUND_2, + GET_OFFLINE_LICENSE_STATE_ERROR_1, + GET_OFFLINE_LICENSE_STATE_ERROR_2, + REMOVE_OFFLINE_LICENSE_ERROR_1, + REMOVE_OFFLINE_LICENSE_ERROR_2, + SESSION_NOT_FOUND_21, + OUTPUT_TOO_LARGE_ERROR, + SESSION_LOST_STATE_ERROR, + GENERATE_DERIVED_KEYS_ERROR_2, + LOAD_DEVICE_RSA_KEY_ERROR, + NONCE_GENERATION_ERROR, + GENERATE_SIGNATURE_ERROR, + UNKNOWN_CLIENT_TOKEN_TYPE, + DEACTIVATE_USAGE_ENTRY_ERROR, + SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY, + SYSTEM_INVALIDATED_ERROR, + OPEN_CRYPTO_SESSION_ERROR, + LOAD_SRM_ERROR, + RANDOM_GENERATION_ERROR, + CRYPTO_SESSION_NOT_INITIALIZED, + GET_DEVICE_ID_ERROR, + GET_TOKEN_FROM_OEM_CERT_ERROR, + CRYPTO_SESSION_NOT_OPEN, + GET_TOKEN_FROM_KEYBOX_ERROR, + KEYBOX_TOKEN_TOO_SHORT, + EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR, + RSA_SIGNATURE_GENERATION_ERROR, + GET_HDCP_CAPABILITY_FAILED, + GET_NUMBER_OF_OPEN_SESSIONS_ERROR, + GET_MAX_NUMBER_OF_OPEN_SESSIONS_ERROR, + NOT_IMPLEMENTED_ERROR, + GET_SRM_VERSION_ERROR, + REWRAP_DEVICE_RSA_KEY_ERROR, + LOAD_PROVISIONING_ERROR, + INVALID_SRM_LIST, + KEYSET_ID_NOT_FOUND_4, + SESSION_NOT_FOUND_22, + USAGE_INVALID_PARAMETERS_2, + CORE_MESSAGE_NOT_FOUND, + LOAD_LICENSE_ERROR, + LOAD_RENEWAL_ERROR, + CANNOT_DECRYPT_ZERO_SAMPLES, + CANNOT_DECRYPT_ZERO_SUBSAMPLES, + SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH, + INVALID_IV_SIZE, + PROVISIONING_NOT_ALLOWED_FOR_ATSC, + MOVE_USAGE_ENTRY_DESTINATION_IN_USE, + SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE, + LICENSE_USAGE_ENTRY_MISSING, + LOAD_USAGE_ENTRY_INVALID_SESSION, + RESTORE_OFFLINE_LICENSE_ERROR_3, + NO_SRM_VERSION, + SESSION_NOT_FOUND_23, + CERT_PROVISIONING_RESPONSE_ERROR_9, + CERT_PROVISIONING_RESPONSE_ERROR_10, + CLIENT_TOKEN_NOT_SET, + USAGE_ENTRY_ALREADY_LOADED, + PARSE_OKP_RESPONSE_ERROR, + OKP_ALREADY_PROVISIONED, + + PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR, + GET_BOOT_CERTIFICATE_CHAIN_ERROR, + GENERATE_CERTIFICATE_KEY_PAIR_ERROR, + GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR, + LOAD_OEM_CERTIFICATE_PRIVATE_KEY_ERROR, + PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN, + PROVISIONING_4_FILE_SYSTEM_IS_NULL, + PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES, + PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE, + PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS, + PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE, + PROVISIONING_4_NO_PRIVATE_KEY, + PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2, + PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE, + PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE, + PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3, + GET_SIGNATURE_HASH_ALGORITHM_ERROR_1, + GET_SIGNATURE_HASH_ALGORITHM_ERROR_2, + GET_SIGNATURE_HASH_ALGORITHM_ERROR_3, + UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_1, + UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_2, + UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_3, + UNSUPPORTED_SIGNATURE_HASH_ALGORITHM_4, + STORE_ATSC_LICENSE_DEVICE_FILES_INIT_ERROR, + STORE_ATSC_LICENSE_ERROR, + +}; + +#endif // SYSTEM_FUZZ_HELPER_H_ diff --git a/fuzzer/system_id_extractor_fuzzer.cpp b/fuzzer/system_id_extractor_fuzzer.cpp new file mode 100644 index 00000000..3d38b7fc --- /dev/null +++ b/fuzzer/system_id_extractor_fuzzer.cpp @@ -0,0 +1,205 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +using namespace wvcdm; +using namespace wvutil; +using namespace wvcdm::metrics; + +static constexpr int32_t kMinByte = 0; +static constexpr int32_t kMaxByte = 256; +static constexpr int32_t kMaxEnum = 4; +static constexpr int32_t kMinEnum = 0; +static constexpr int32_t kMaxRequestedSecurityLevel = 1; +static constexpr int32_t kMinRequestedSecurityLevel = 0; + +class FuzzDeviceFiles : public DeviceFiles { +public: + FuzzDeviceFiles(wvutil::FileSystem *fs, FuzzedDataProvider *fdp) + : DeviceFiles(fs), mFdp(fdp) {} + + bool Init(CdmSecurityLevel) override { return mFdp->ConsumeBool(); } + + DeviceFiles::CertificateState + RetrieveOemCertificate(std::string *certificate, + CryptoWrappedKey * /*wrapped_private_key*/) override { + *certificate = mFdp->ConsumeRandomLengthString(kMaxByte); + return (DeviceFiles::CertificateState)mFdp->ConsumeIntegralInRange( + kMinEnum, kMaxEnum); + } + +private: + FuzzedDataProvider *mFdp; +}; + +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; +}; + +class FuzzCryptoSession : public CryptoSession { +public: + FuzzCryptoSession(metrics::CryptoMetrics *metrics, FuzzedDataProvider *fdp) + : CryptoSession(metrics) { + mFdp = fdp; + } + + ~FuzzCryptoSession() override {} + + bool IsOpen() override { return mFdp->ConsumeBool(); } + + bool GetCachedSystemId(uint32_t * /*system_id*/) override { + return mFdp->ConsumeBool(); + } + + void SetSystemId(uint32_t /*system_id*/) override {} + CdmSecurityLevel GetSecurityLevel(RequestedSecurityLevel /*level*/) override { + return (CdmSecurityLevel)mFdp->ConsumeIntegralInRange(kMinEnum, kMaxEnum); + } + + CdmResponseType + GetProvisioningMethod(RequestedSecurityLevel /*level*/, + CdmClientTokenType *tokenType) override { + *tokenType = + (CdmClientTokenType)mFdp->ConsumeIntegralInRange(kMinEnum, kMaxEnum); + return CdmResponseType( + mFdp->PickValueInArray(kCdmResponseEnums)); + } + + CdmResponseType GetTokenFromKeybox(RequestedSecurityLevel /*level*/, + std::string *keyData) override { + *keyData = mFdp->ConsumeRandomLengthString(kMaxByte); + return CdmResponseType( + mFdp->PickValueInArray(kCdmResponseEnums)); + } + + CdmResponseType GetTokenFromOemCert(RequestedSecurityLevel /*level*/, + std::string *oemCert) override { + *oemCert = mFdp->ConsumeRandomLengthString(kMaxByte); + return CdmResponseType( + mFdp->PickValueInArray(kCdmResponseEnums)); + } + void SetSystemIdBase(uint32_t /* system_id*/) {} + +private: + FuzzedDataProvider *mFdp; +}; + +class SystemIdExtractorFuzzer { +public: + SystemIdExtractorFuzzer(const uint8_t *data, size_t size) + : mFdp(data, size){}; + void process(); + +private: + FuzzedDataProvider mFdp; +}; + +void SystemIdExtractorFuzzer::process() { + + FuzzFileSystem fuzzFileSystem(&mFdp); + metrics::CryptoMetrics cryptoMetrics; + FuzzDeviceFiles deviceFiles(&fuzzFileSystem, &mFdp); + + RequestedSecurityLevel securityLevel = + (RequestedSecurityLevel)mFdp.ConsumeIntegralInRange( + kMinRequestedSecurityLevel, kMaxRequestedSecurityLevel); + + std::unique_ptr cryptoSessions = + std::make_unique(&cryptoMetrics, &mFdp); + + std::unique_ptr systemIdExtractor = + std::make_unique(securityLevel, cryptoSessions.get(), + &fuzzFileSystem); + + while (mFdp.remaining_bytes()) { + auto invokeSystemIdExtractorAPI = mFdp.PickValueInArray< + const std::function>({ + [&]() { + uint32_t systemId; + systemId = mFdp.ConsumeIntegralInRange(kMinByte, kMaxByte); + systemIdExtractor->ExtractSystemId(&systemId); + }, + [&]() { + uint32_t systemId; + systemId = mFdp.ConsumeIntegralInRange(kMinByte, kMaxByte); + const std::string keyData = mFdp.ConsumeRandomLengthString(kMaxByte); + systemIdExtractor->ExtractSystemIdFromKeyboxData(keyData, &systemId); + }, + [&]() { + uint32_t systemId; + systemId = mFdp.ConsumeIntegralInRange(kMinByte, kMaxByte); + const std::string oemCert = mFdp.ConsumeRandomLengthString(kMaxByte); + systemIdExtractor->ExtractSystemIdFromOemCert(oemCert, &systemId); + }, + [&]() { systemIdExtractor->SetDeviceFilesForTesting(&deviceFiles); }, + }); + invokeSystemIdExtractorAPI(); + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + SystemIdExtractorFuzzer systemIdExtractorFuzzer(data, size); + systemIdExtractorFuzzer.process(); + return 0; +}