/* * Copyright (C) 2021 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 namespace keymaster::V4_0::ng::fuzzer { using ::android::hardware::hidl_string; using ::android::hardware::keymaster::V4_0::AuthorizationSet; using ::android::hardware::keymaster::V4_0::AuthorizationSetBuilder; using ::android::hardware::keymaster::V4_0::Digest; using ::android::hardware::keymaster::V4_0::KeyFormat; using ::android::hardware::keymaster::V4_0::KeyPurpose; using ::android::hardware::keymaster::V4_0::PaddingMode; constexpr SecurityLevel kSecurityLevel[] = { SecurityLevel::SOFTWARE, SecurityLevel::TRUSTED_ENVIRONMENT, SecurityLevel::STRONGBOX, }; constexpr PaddingMode kPaddingMode[] = { PaddingMode::NONE, PaddingMode::RSA_OAEP, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_ENCRYPT, PaddingMode::RSA_PKCS1_1_5_SIGN, PaddingMode::PKCS7, }; constexpr Digest kDigest[] = { Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512, }; constexpr KeyFormat kKeyFormat[] = { KeyFormat::X509, KeyFormat::PKCS8, KeyFormat::RAW, }; constexpr KeyPurpose kKeyPurpose[] = { KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT, KeyPurpose::SIGN, KeyPurpose::VERIFY, KeyPurpose::WRAP_KEY, }; constexpr uint32_t kRSAKeySize[] = {1024, 2048, 3072, 4096}; constexpr uint32_t kECCKeySize[] = {224, 256, 384, 521}; constexpr size_t kMinBytes = 0; constexpr size_t kMaxBytes = 100; class KeyMaster4DeviceFuzzer { public: bool init(const uint8_t* data, size_t size); void process(); private: AuthorizationSet getAuthorizationSet(); sp mKeymaster = nullptr; std::unique_ptr mFdp = nullptr; }; AuthorizationSet KeyMaster4DeviceFuzzer::getAuthorizationSet() { auto keyMasterFunction = mFdp->PickValueInArray< const std::function>({ [&]() { return AuthorizationSetBuilder() .RsaSigningKey(mFdp->PickValueInArray(kRSAKeySize), mFdp->ConsumeIntegral()) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .EcdsaKey(mFdp->PickValueInArray(kECCKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .AesKey(mFdp->PickValueInArray(kECCKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .TripleDesKey(mFdp->PickValueInArray(kRSAKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .HmacKey(mFdp->PickValueInArray(kRSAKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .RsaEncryptionKey(mFdp->PickValueInArray(kRSAKeySize), mFdp->ConsumeIntegral()) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .EcdsaSigningKey(mFdp->PickValueInArray(kRSAKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .AesEncryptionKey(mFdp->PickValueInArray(kECCKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .TripleDesEncryptionKey(mFdp->PickValueInArray(kRSAKeySize)) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, [&]() { return AuthorizationSetBuilder() .RsaKey(mFdp->PickValueInArray(kRSAKeySize), mFdp->ConsumeIntegral()) .Digest(mFdp->PickValueInArray(kDigest)) .Padding(mFdp->PickValueInArray(kPaddingMode)); }, }); return keyMasterFunction(); } bool KeyMaster4DeviceFuzzer::init(const uint8_t* data, size_t size) { mFdp = std::make_unique(data, size); mKeymaster = CreateKeymasterDevice(mFdp->PickValueInArray(kSecurityLevel)); if (!mKeymaster) { return false; } return true; } void KeyMaster4DeviceFuzzer::process() { std::vector dataVec = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->addRngEntropy(dataVec); hidl_vec keyBlob = {}; mKeymaster->generateKey(getAuthorizationSet().hidl_data(), [&]([[maybe_unused]] ErrorCode hidlError, const hidl_vec& hidlKeyBlob, [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) { keyBlob = hidlKeyBlob; }); mKeymaster->attestKey( keyBlob, getAuthorizationSet().hidl_data(), [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const hidl_vec>& hidlCertificateChain) {}); mKeymaster->upgradeKey(keyBlob, hidl_vec(), [&]([[maybe_unused]] ErrorCode error, [[maybe_unused]] const hidl_vec& upgraded_blob) {}); std::vector clientId = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); std::vector appData = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->getKeyCharacteristics( keyBlob, clientId, appData, [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {}); KeyFormat keyFormat = mFdp->PickValueInArray(kKeyFormat); std::vector keyData; keyData = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->importKey( getAuthorizationSet().hidl_data(), keyFormat, keyData, [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const hidl_vec& hidlKeyBlob, [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {}); std::vector wrappedKey, wrappingKey, maskingKey; wrappedKey = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); wrappingKey = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); maskingKey = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); uint64_t passwordSid = mFdp->ConsumeIntegral(); uint64_t biometricSid = mFdp->ConsumeIntegral(); mKeymaster->importWrappedKey( wrappedKey, wrappingKey, maskingKey, getAuthorizationSet().hidl_data(), passwordSid, biometricSid, [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const hidl_vec& hidlKeyBlob, [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {}); std::vector keyBlobExportKey = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->exportKey(keyFormat, keyBlobExportKey, clientId, appData, [&]([[maybe_unused]] ErrorCode hidlErrorCode, [[maybe_unused]] const hidl_vec& hidlKeyMaterial) {}); KeyPurpose keyPurpose = mFdp->PickValueInArray(kKeyPurpose); mKeymaster->begin(keyPurpose, keyBlob, getAuthorizationSet().hidl_data(), HardwareAuthToken(), [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const hidl_vec& hidlOutParams, [[maybe_unused]] uint64_t hidlOpHandle) {}); uint64_t operationHandle = mFdp->ConsumeIntegral(); std::vector input = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->update(operationHandle, getAuthorizationSet().hidl_data(), input, HardwareAuthToken(), VerificationToken(), [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] uint32_t hidlInputConsumed, [[maybe_unused]] const hidl_vec& hidlOutParams, [[maybe_unused]] const hidl_vec& hidlOutput) {}); std::vector signature = mFdp->ConsumeBytes(mFdp->ConsumeIntegralInRange(kMinBytes, kMaxBytes)); mKeymaster->finish(operationHandle, getAuthorizationSet().hidl_data(), input, signature, HardwareAuthToken(), VerificationToken(), [&]([[maybe_unused]] ErrorCode hidlError, [[maybe_unused]] const hidl_vec& hidlOutParams, [[maybe_unused]] const hidl_vec& hidlOutput) {}); mKeymaster->deleteKey(keyBlob); mKeymaster->deleteAllKeys(); mKeymaster->abort(mFdp->ConsumeIntegral()); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { KeyMaster4DeviceFuzzer km4DeviceFuzzer; if (km4DeviceFuzzer.init(data, size)) { km4DeviceFuzzer.process(); } return 0; } } // namespace keymaster::V4_0::ng::fuzzer