Loading security/keymint/support/fuzzer/Android.bp +25 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,20 @@ cc_defaults { ], ], } } cc_defaults { name: "keymint_remote_fuzzer_defaults", static_libs: [ "libkeymint_remote_prov_support", "android.hardware.security.rkp-V3-ndk", ], shared_libs: [ "libcppbor", "libcppcose_rkp", "libjsoncpp", "libkeymaster_portable", ], } cc_fuzz { cc_fuzz { name: "keymint_attestation_fuzzer", name: "keymint_attestation_fuzzer", srcs: [ srcs: [ Loading @@ -67,3 +81,14 @@ cc_fuzz { "keymint_fuzzer_defaults", "keymint_fuzzer_defaults", ], ], } } cc_fuzz { name: "keymint_remote_prov_fuzzer", srcs: [ "keymint_remote_prov_fuzzer.cpp", ], defaults: [ "keymint_fuzzer_defaults", "keymint_remote_fuzzer_defaults", ], } security/keymint/support/fuzzer/README.md +24 −0 Original line number Original line Diff line number Diff line Loading @@ -12,6 +12,7 @@ The plugins feed the entire input data to the module. This ensures that the plug ## Table of contents ## Table of contents + [keymint_attestation_fuzzer](#KeyMintAttestation) + [keymint_attestation_fuzzer](#KeyMintAttestation) + [keymint_authSet_fuzzer](#KeyMintAuthSet) + [keymint_authSet_fuzzer](#KeyMintAuthSet) + [keymint_remote_prov_fuzzer](#KeyMintRemoteProv) # <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation # <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation KeyMintAttestation supports the following parameters: KeyMintAttestation supports the following parameters: Loading Loading @@ -77,3 +78,26 @@ $ mm -j$(nproc) keymint_authSet_fuzzer $ adb sync data $ adb sync data $ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer $ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer ``` ``` # <a name="KeyMintRemoteProv"></a> Fuzzer for KeyMintRemoteProv KeyMintRemoteProv supports the following parameters: 1. ChallengeSize(parameter name: "challengeSize") 2. Challenge(parameter name: "challenge") 3. NumKeys(parameter name: "numKeys") | Parameter| Valid Values| Configured Value| |------------- |--------------| -------------------- | |`challengeSize`| `uint8_t` |Value obtained from FuzzedDataProvider| |`challenge`| `std::vector<uint8_t>` |Value obtained from FuzzedDataProvider| |`numKeys`| `uint8_t` |Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) keymint_remote_prov_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/keymint_remote_prov_fuzzer/keymint_remote_prov_fuzzer ``` security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp 0 → 100644 +103 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2024 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 <android/binder_manager.h> #include <fuzzer/FuzzedDataProvider.h> #include <remote_prov/remote_prov_utils.h> #include <utils/Log.h> namespace android::hardware::security::keymint_support::fuzzer { using namespace cppcose; using namespace aidl::android::hardware::security::keymint; using namespace aidl::android::hardware::security::keymint::remote_prov; constexpr size_t kMinSize = 0; constexpr size_t kSupportedNumKeys = 4; constexpr size_t kChallengeSize = 64; constexpr size_t kMaxBytes = 128; const std::string kServiceName = "android.hardware.security.keymint.IRemotelyProvisionedComponent/default"; std::shared_ptr<IRemotelyProvisionedComponent> gRPC = nullptr; class KeyMintRemoteProv { public: KeyMintRemoteProv(const uint8_t* data, size_t size) : mFdp(data, size){}; void process(); private: std::vector<uint8_t> ExtractPayloadValue(const MacedPublicKey& macedPubKey); FuzzedDataProvider mFdp; }; std::vector<uint8_t> KeyMintRemoteProv::ExtractPayloadValue(const MacedPublicKey& macedPubKey) { std::vector<uint8_t> payloadValue; auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey); if (coseMac0) { // The payload is a bstr holding an encoded COSE_Key auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr(); if (payload != nullptr) { payloadValue = payload->value(); } } return payloadValue; } void KeyMintRemoteProv::process() { std::vector<MacedPublicKey> keysToSign = std::vector<MacedPublicKey>( mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kSupportedNumKeys)); cppbor::Array cborKeysToSign; for (auto& key : keysToSign) { // TODO: b/350649166 - Randomize keysToSign std::vector<uint8_t> privateKeyBlob; gRPC->generateEcdsaP256KeyPair(false /* testMode */, &key, &privateKeyBlob); std::vector<uint8_t> payloadValue = ExtractPayloadValue(key); cborKeysToSign.add(cppbor::EncodedItem(payloadValue)); } uint8_t challengeSize = mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kChallengeSize); std::vector<uint8_t> challenge = mFdp.ConsumeBytes<uint8_t>(challengeSize); std::vector<uint8_t> csr; gRPC->generateCertificateRequestV2(keysToSign, challenge, &csr); while (mFdp.remaining_bytes()) { auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, [&]() { verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, [&]() { isCsrWithProperDiceChain(csr); }, }); invokeProvAPI(); } } extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) { ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str())); gRPC = IRemotelyProvisionedComponent::fromBinder(binder); LOG_ALWAYS_FATAL_IF(!gRPC, "Failed to get IRemotelyProvisionedComponent instance."); return 0; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { KeyMintRemoteProv kmRemoteProv(data, size); kmRemoteProv.process(); return 0; } } // namespace android::hardware::security::keymint_support::fuzzer Loading
security/keymint/support/fuzzer/Android.bp +25 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,20 @@ cc_defaults { ], ], } } cc_defaults { name: "keymint_remote_fuzzer_defaults", static_libs: [ "libkeymint_remote_prov_support", "android.hardware.security.rkp-V3-ndk", ], shared_libs: [ "libcppbor", "libcppcose_rkp", "libjsoncpp", "libkeymaster_portable", ], } cc_fuzz { cc_fuzz { name: "keymint_attestation_fuzzer", name: "keymint_attestation_fuzzer", srcs: [ srcs: [ Loading @@ -67,3 +81,14 @@ cc_fuzz { "keymint_fuzzer_defaults", "keymint_fuzzer_defaults", ], ], } } cc_fuzz { name: "keymint_remote_prov_fuzzer", srcs: [ "keymint_remote_prov_fuzzer.cpp", ], defaults: [ "keymint_fuzzer_defaults", "keymint_remote_fuzzer_defaults", ], }
security/keymint/support/fuzzer/README.md +24 −0 Original line number Original line Diff line number Diff line Loading @@ -12,6 +12,7 @@ The plugins feed the entire input data to the module. This ensures that the plug ## Table of contents ## Table of contents + [keymint_attestation_fuzzer](#KeyMintAttestation) + [keymint_attestation_fuzzer](#KeyMintAttestation) + [keymint_authSet_fuzzer](#KeyMintAuthSet) + [keymint_authSet_fuzzer](#KeyMintAuthSet) + [keymint_remote_prov_fuzzer](#KeyMintRemoteProv) # <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation # <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation KeyMintAttestation supports the following parameters: KeyMintAttestation supports the following parameters: Loading Loading @@ -77,3 +78,26 @@ $ mm -j$(nproc) keymint_authSet_fuzzer $ adb sync data $ adb sync data $ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer $ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer ``` ``` # <a name="KeyMintRemoteProv"></a> Fuzzer for KeyMintRemoteProv KeyMintRemoteProv supports the following parameters: 1. ChallengeSize(parameter name: "challengeSize") 2. Challenge(parameter name: "challenge") 3. NumKeys(parameter name: "numKeys") | Parameter| Valid Values| Configured Value| |------------- |--------------| -------------------- | |`challengeSize`| `uint8_t` |Value obtained from FuzzedDataProvider| |`challenge`| `std::vector<uint8_t>` |Value obtained from FuzzedDataProvider| |`numKeys`| `uint8_t` |Value obtained from FuzzedDataProvider| #### Steps to run 1. Build the fuzzer ``` $ mm -j$(nproc) keymint_remote_prov_fuzzer ``` 2. Run on device ``` $ adb sync data $ adb shell /data/fuzz/arm64/keymint_remote_prov_fuzzer/keymint_remote_prov_fuzzer ```
security/keymint/support/fuzzer/keymint_remote_prov_fuzzer.cpp 0 → 100644 +103 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2024 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 <android/binder_manager.h> #include <fuzzer/FuzzedDataProvider.h> #include <remote_prov/remote_prov_utils.h> #include <utils/Log.h> namespace android::hardware::security::keymint_support::fuzzer { using namespace cppcose; using namespace aidl::android::hardware::security::keymint; using namespace aidl::android::hardware::security::keymint::remote_prov; constexpr size_t kMinSize = 0; constexpr size_t kSupportedNumKeys = 4; constexpr size_t kChallengeSize = 64; constexpr size_t kMaxBytes = 128; const std::string kServiceName = "android.hardware.security.keymint.IRemotelyProvisionedComponent/default"; std::shared_ptr<IRemotelyProvisionedComponent> gRPC = nullptr; class KeyMintRemoteProv { public: KeyMintRemoteProv(const uint8_t* data, size_t size) : mFdp(data, size){}; void process(); private: std::vector<uint8_t> ExtractPayloadValue(const MacedPublicKey& macedPubKey); FuzzedDataProvider mFdp; }; std::vector<uint8_t> KeyMintRemoteProv::ExtractPayloadValue(const MacedPublicKey& macedPubKey) { std::vector<uint8_t> payloadValue; auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey); if (coseMac0) { // The payload is a bstr holding an encoded COSE_Key auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr(); if (payload != nullptr) { payloadValue = payload->value(); } } return payloadValue; } void KeyMintRemoteProv::process() { std::vector<MacedPublicKey> keysToSign = std::vector<MacedPublicKey>( mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kSupportedNumKeys)); cppbor::Array cborKeysToSign; for (auto& key : keysToSign) { // TODO: b/350649166 - Randomize keysToSign std::vector<uint8_t> privateKeyBlob; gRPC->generateEcdsaP256KeyPair(false /* testMode */, &key, &privateKeyBlob); std::vector<uint8_t> payloadValue = ExtractPayloadValue(key); cborKeysToSign.add(cppbor::EncodedItem(payloadValue)); } uint8_t challengeSize = mFdp.ConsumeIntegralInRange<uint8_t>(kMinSize, kChallengeSize); std::vector<uint8_t> challenge = mFdp.ConsumeBytes<uint8_t>(challengeSize); std::vector<uint8_t> csr; gRPC->generateCertificateRequestV2(keysToSign, challenge, &csr); while (mFdp.remaining_bytes()) { auto invokeProvAPI = mFdp.PickValueInArray<const std::function<void()>>({ [&]() { verifyFactoryCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, [&]() { verifyProductionCsr(cborKeysToSign, csr, gRPC.get(), challenge); }, [&]() { isCsrWithProperDiceChain(csr); }, }); invokeProvAPI(); } } extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) { ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str())); gRPC = IRemotelyProvisionedComponent::fromBinder(binder); LOG_ALWAYS_FATAL_IF(!gRPC, "Failed to get IRemotelyProvisionedComponent instance."); return 0; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { KeyMintRemoteProv kmRemoteProv(data, size); kmRemoteProv.process(); return 0; } } // namespace android::hardware::security::keymint_support::fuzzer