Added keystoreGetWifiHidl_fuzzer

Test: ./keystoreGetWifiHidl_fuzzer
Bug: 187130384

Change-Id: If64eb1a8b2aa22b9a2711e27449744bc7a0f0296
diff --git a/keystore/tests/fuzzer/Android.bp b/keystore/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..b05effd
--- /dev/null
+++ b/keystore/tests/fuzzer/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+cc_fuzz {
+    name: "keystoreGetWifiHidl_fuzzer",
+    vendor: true,
+    srcs: [
+        "keystoreGetWifiHidl_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libkeystore-wifi-hidl",
+        "libutils",
+    ],
+    shared_libs: [
+        "android.system.wifi.keystore@1.0",
+        "libhidlbase",
+        "liblog",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/keystore/tests/fuzzer/README.md b/keystore/tests/fuzzer/README.md
new file mode 100644
index 0000000..0861e5e
--- /dev/null
+++ b/keystore/tests/fuzzer/README.md
@@ -0,0 +1,49 @@
+# Fuzzer for libkeystore
+## Table of contents
++ [libkeystore-get-wifi-hidl](#libkeystore-get-wifi-hidl)
+
+# <a name="libkeystore-get-wifi-hidl"></a> Fuzzer for libkeystore-get-wifi-hidl
+## Plugin Design Considerations
+The fuzzer plugin for libkeystore-get-wifi-hidl is designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libkeystore-get-wifi-hidl supports the following parameters:
+1. Key (parameter name: `key`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `key` | `String` | Value obtained from FuzzedDataProvider|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the libkeystore-get-wifi-hidl module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build keystoreGetWifiHidl_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) keystoreGetWifiHidl_fuzzer
+```
+#### Steps to run
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/keystoreGetWifiHidl_fuzzer/keystoreGetWifiHidl_fuzzer
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/keystore/tests/fuzzer/keystoreGetWifiHidl_fuzzer.cpp b/keystore/tests/fuzzer/keystoreGetWifiHidl_fuzzer.cpp
new file mode 100644
index 0000000..1e033c8
--- /dev/null
+++ b/keystore/tests/fuzzer/keystoreGetWifiHidl_fuzzer.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 "fuzzer/FuzzedDataProvider.h"
+#include <inttypes.h>
+#include <keystore/keystore_get.h>
+
+using namespace std;
+
+constexpr int32_t kMaxKeySize = 256;
+const string kValidStrKeyPrefix[] = {"USRSKEY_",
+                                     "PLATFORM_VPN_",
+                                     "USRPKEY_",
+                                     "CACERT_",
+                                     "VPN_"
+                                     "USRCERT_",
+                                     "WIFI_"};
+constexpr char kStrGrantKeyPrefix[] = "ks2_keystore-engine_grant_id:";
+constexpr char kStrKeySuffix[] = "LOCKDOWN_VPN";
+constexpr size_t kGrantIdSize = 20;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    size_t keyLength = fdp.ConsumeIntegralInRange<size_t>(0, kMaxKeySize);
+    bool usePrefix = fdp.ConsumeBool();
+    string strKeyPrefix;
+    size_t strKeyPrefixLength = 0;
+    size_t strKeySuffixLength = min(fdp.remaining_bytes(), keyLength);
+    if (usePrefix) {
+        strKeyPrefix = fdp.PickValueInArray(kValidStrKeyPrefix);
+        strKeyPrefixLength = sizeof(strKeyPrefix);
+        strKeySuffixLength =
+            (strKeySuffixLength > strKeyPrefixLength) ? strKeySuffixLength - strKeyPrefixLength : 0;
+    }
+    string strKeySuffix =
+        fdp.ConsumeBool() ? string(kStrKeySuffix) : fdp.ConsumeBytesAsString(strKeySuffixLength);
+    string strKey;
+    strKey = usePrefix ? strKeyPrefix + strKeySuffix : strKeySuffix;
+    if (fdp.ConsumeBool()) {
+        uint64_t grant = fdp.ConsumeIntegral<uint64_t>();
+        char grantId[kGrantIdSize] = "";
+        snprintf(grantId, kGrantIdSize, "%" PRIx64, grant);
+        strKey = strKey + string(kStrGrantKeyPrefix) + grantId;
+    }
+    const char* key = strKey.c_str();
+    uint8_t* value = nullptr;
+    keystore_get(key, strlen(key), &value);
+    free(value);
+    return 0;
+}