summaryrefslogtreecommitdiff
path: root/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp')
-rw-r--r--fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp265
1 files changed, 265 insertions, 0 deletions
diff --git a/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp b/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp
new file mode 100644
index 0000000..be60b75
--- /dev/null
+++ b/fuzzer/k4_AndroidKeymaster4Device_fuzzer.cpp
@@ -0,0 +1,265 @@
+/*
+ * 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 <AndroidKeymaster4Device.h>
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <keymasterV4_0/authorization_set.h>
+
+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<IKeymasterDevice> mKeymaster = nullptr;
+ std::unique_ptr<FuzzedDataProvider> mFdp = nullptr;
+};
+
+AuthorizationSet KeyMaster4DeviceFuzzer::getAuthorizationSet() {
+ auto keyMasterFunction = mFdp->PickValueInArray<
+ const std::function<android::hardware::keymaster::V4_0::AuthorizationSet()>>({
+ [&]() {
+ return AuthorizationSetBuilder()
+ .RsaSigningKey(mFdp->PickValueInArray(kRSAKeySize),
+ mFdp->ConsumeIntegral<uint32_t>())
+ .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<uint64_t>())
+ .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<uint64_t>())
+ .Digest(mFdp->PickValueInArray(kDigest))
+ .Padding(mFdp->PickValueInArray(kPaddingMode));
+ },
+ });
+ return keyMasterFunction();
+}
+
+bool KeyMaster4DeviceFuzzer::init(const uint8_t* data, size_t size) {
+ mFdp = std::make_unique<FuzzedDataProvider>(data, size);
+ mKeymaster = CreateKeymasterDevice(mFdp->PickValueInArray(kSecurityLevel));
+ if (!mKeymaster) {
+ return false;
+ }
+ return true;
+}
+
+void KeyMaster4DeviceFuzzer::process() {
+ std::vector<uint8_t> dataVec =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->addRngEntropy(dataVec);
+
+ hidl_vec<uint8_t> keyBlob = {};
+ mKeymaster->generateKey(getAuthorizationSet().hidl_data(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {
+ keyBlob = hidlKeyBlob;
+ });
+
+ mKeymaster->attestKey(
+ keyBlob, getAuthorizationSet().hidl_data(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<hidl_vec<uint8_t>>& hidlCertificateChain) {});
+
+ mKeymaster->upgradeKey(keyBlob, hidl_vec<KeyParameter>(),
+ [&]([[maybe_unused]] ErrorCode error,
+ [[maybe_unused]] const hidl_vec<uint8_t>& upgraded_blob) {});
+
+ std::vector<uint8_t> clientId =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ std::vector<uint8_t> appData =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->getKeyCharacteristics(
+ keyBlob, clientId, appData,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {});
+
+ KeyFormat keyFormat = mFdp->PickValueInArray(kKeyFormat);
+ std::vector<uint8_t> keyData;
+ keyData =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ ErrorCode importKeyError;
+ if (mKeymaster
+ ->importKey(getAuthorizationSet().hidl_data(), keyFormat, keyData,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {
+ importKeyError = hidlError;
+ })
+ .isOk()) {
+ if (importKeyError == ErrorCode::OK) {
+ abort();
+ }
+ }
+
+ std::vector<uint8_t> wrappedKey, wrappingKey, maskingKey;
+ wrappedKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ wrappingKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ maskingKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ uint64_t passwordSid = mFdp->ConsumeIntegral<uint64_t>();
+ uint64_t biometricSid = mFdp->ConsumeIntegral<uint64_t>();
+ mKeymaster->importWrappedKey(
+ wrappedKey, wrappingKey, maskingKey, getAuthorizationSet().hidl_data(), passwordSid,
+ biometricSid,
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyBlob,
+ [[maybe_unused]] const KeyCharacteristics& hidlKeyCharacteristics) {});
+
+ std::vector<uint8_t> keyBlobExportKey =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->exportKey(keyFormat, keyBlobExportKey, clientId, appData,
+ [&]([[maybe_unused]] ErrorCode hidlErrorCode,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlKeyMaterial) {});
+
+ KeyPurpose keyPurpose = mFdp->PickValueInArray(kKeyPurpose);
+ mKeymaster->begin(keyPurpose, keyBlob, getAuthorizationSet().hidl_data(), HardwareAuthToken(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] uint64_t hidlOpHandle) {});
+
+ uint64_t operationHandle = mFdp->ConsumeIntegral<uint64_t>();
+ std::vector<uint8_t> input =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(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<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlOutput) {});
+
+ std::vector<uint8_t> signature =
+ mFdp->ConsumeBytes<uint8_t>(mFdp->ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes));
+ mKeymaster->finish(operationHandle, getAuthorizationSet().hidl_data(), input, signature,
+ HardwareAuthToken(), VerificationToken(),
+ [&]([[maybe_unused]] ErrorCode hidlError,
+ [[maybe_unused]] const hidl_vec<KeyParameter>& hidlOutParams,
+ [[maybe_unused]] const hidl_vec<uint8_t>& hidlOutput) {});
+
+ mKeymaster->deleteKey(keyBlob);
+ mKeymaster->deleteAllKeys();
+ mKeymaster->abort(mFdp->ConsumeIntegral<uint64_t>());
+}
+
+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