Merge "Keystore 2.0: Add Keystore CTS test cases to presubmit."
diff --git a/keystore/Android.bp b/keystore/Android.bp
index ad4b4b1..50d4432 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -63,7 +63,7 @@
 
 // Library used by both keystore and credstore for generating the ASN.1 stored
 // in Tag::ATTESTATION_APPLICATION_ID
-cc_library_shared {
+cc_library {
     name: "libkeystore-attestation-application-id",
     defaults: ["keystore_defaults"],
 
diff --git a/keystore/tests/fuzzer/Android.bp b/keystore/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..589cef7
--- /dev/null
+++ b/keystore/tests/fuzzer/Android.bp
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_security_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_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,
+    },
+}
+
+cc_defaults {
+    name: "keystoreAttestation_defaults",
+    static_libs: [
+        "libkeystore-attestation-application-id",
+        "liblog",
+        "libutils",
+        "libbase",
+        "libhidlbase",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libcrypto",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
+
+cc_fuzz {
+    name: "keystoreSignature_fuzzer",
+    srcs: [
+        "keystoreSignature_fuzzer.cpp",
+    ],
+    defaults: [
+        "keystoreAttestation_defaults",
+    ],
+}
+
+cc_fuzz {
+    name: "keystorePackageInfo_fuzzer",
+    srcs: [
+        "keystorePackageInfo_fuzzer.cpp",
+    ],
+    defaults: [
+        "keystoreAttestation_defaults",
+    ],
+}
+
+cc_fuzz {
+    name: "keystoreApplicationId_fuzzer",
+    srcs: [
+        "keystoreApplicationId_fuzzer.cpp",
+    ],
+    defaults: [
+        "keystoreAttestation_defaults",
+    ],
+}
+
+cc_fuzz {
+    name: "keystoreAttestationId_fuzzer",
+    srcs: [
+        "keystoreAttestationId_fuzzer.cpp",
+    ],
+    defaults: [
+        "keystoreAttestation_defaults",
+    ],
+}
diff --git a/keystore/tests/fuzzer/README.md b/keystore/tests/fuzzer/README.md
new file mode 100644
index 0000000..25d53ab
--- /dev/null
+++ b/keystore/tests/fuzzer/README.md
@@ -0,0 +1,103 @@
+# Fuzzer for libkeystore
+## Table of contents
++ [libkeystore-get-wifi-hidl](#libkeystore-get-wifi-hidl)
++ [libkeystore_attestation_application_id](#libkeystore_attestation_application_id)
+
+# <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
+```
+
+# <a name="libkeystore_attestation_application_id"></a> Fuzzer for libkeystore_attestation_application_id
+## Plugin Design Considerations
+The fuzzer plugin for libkeystore-attestation-application-id are 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-attestation-application-id supports the following parameters:
+1. Package Name (parameter name: `packageName`)
+2. Version Code (parameter name: `versionCode`)
+3. Uid (parameter name: `uid`)
+
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `packageName` | `String` | Value obtained from FuzzedDataProvider|
+| `versionCode` | `INT64_MIN` to `INT64_MAX` | Value obtained from FuzzedDataProvider|
+| `uid` | `0` to `1000` | Value obtained from FuzzedDataProvider|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugins feed the entire input data to the libkeystore_attestation_application_id 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 keystoreSignature_fuzzer, keystorePackageInfo_fuzzer, keystoreApplicationId_fuzzer and keystoreAttestationId_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) keystoreSignature_fuzzer
+  $ mm -j$(nproc) keystorePackageInfo_fuzzer
+  $ mm -j$(nproc) keystoreApplicationId_fuzzer
+  $ mm -j$(nproc) keystoreAttestationId_fuzzer
+```
+#### Steps to run
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/keystoreSignature_fuzzer/keystoreSignature_fuzzer
+  $ adb shell /data/fuzz/${TARGET_ARCH}/keystorePackageInfo_fuzzer/keystorePackageInfo_fuzzer
+  $ adb shell /data/fuzz/${TARGET_ARCH}/keystoreApplicationId_fuzzer/keystoreApplicationId_fuzzer
+  $ adb shell /data/fuzz/${TARGET_ARCH}/keystoreAttestationId_fuzzer/keystoreAttestationId_fuzzer
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp b/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp
new file mode 100644
index 0000000..0eddb9a
--- /dev/null
+++ b/keystore/tests/fuzzer/keystoreApplicationId_fuzzer.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 "keystoreCommon.h"
+#include <keystore/KeyAttestationApplicationId.h>
+
+using ::security::keymaster::KeyAttestationApplicationId;
+
+constexpr size_t kPackageVectorSizeMin = 1;
+constexpr size_t kPackageVectorSizeMax = 10;
+
+class KeystoreApplicationId {
+  public:
+    void process(const uint8_t* data, size_t size);
+    ~KeystoreApplicationId() {}
+
+  private:
+    void invokeApplicationId();
+    std::unique_ptr<FuzzedDataProvider> mFdp;
+};
+
+void KeystoreApplicationId::invokeApplicationId() {
+    std::optional<KeyAttestationApplicationId> applicationId;
+    bool shouldUsePackageInfoVector = mFdp->ConsumeBool();
+    if (shouldUsePackageInfoVector) {
+        KeyAttestationApplicationId::PackageInfoVector packageInfoVector;
+        int32_t packageVectorSize =
+            mFdp->ConsumeIntegralInRange<int32_t>(kPackageVectorSizeMin, kPackageVectorSizeMax);
+        for (int32_t packageSize = 0; packageSize < packageVectorSize; ++packageSize) {
+            auto packageInfoData = initPackageInfoData(mFdp.get());
+            packageInfoVector.push_back(make_optional<KeyAttestationPackageInfo>(
+                String16((packageInfoData.packageName).c_str()), packageInfoData.versionCode,
+                packageInfoData.sharedSignaturesVector));
+        }
+        applicationId = KeyAttestationApplicationId(std::move(packageInfoVector));
+    } else {
+        auto packageInfoData = initPackageInfoData(mFdp.get());
+        applicationId = KeyAttestationApplicationId(make_optional<KeyAttestationPackageInfo>(
+            String16((packageInfoData.packageName).c_str()), packageInfoData.versionCode,
+            packageInfoData.sharedSignaturesVector));
+    }
+    invokeReadWriteParcel(&applicationId.value());
+}
+
+void KeystoreApplicationId::process(const uint8_t* data, size_t size) {
+    mFdp = std::make_unique<FuzzedDataProvider>(data, size);
+    invokeApplicationId();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    KeystoreApplicationId keystoreApplicationId;
+    keystoreApplicationId.process(data, size);
+    return 0;
+}
diff --git a/keystore/tests/fuzzer/keystoreAttestationId_fuzzer.cpp b/keystore/tests/fuzzer/keystoreAttestationId_fuzzer.cpp
new file mode 100644
index 0000000..581da46
--- /dev/null
+++ b/keystore/tests/fuzzer/keystoreAttestationId_fuzzer.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 <keystore/keystore_attestation_id.h>
+
+#include "fuzzer/FuzzedDataProvider.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+    uint32_t uid = fdp.ConsumeIntegral<uint32_t>();
+    auto result = android::security::gather_attestation_application_id(uid);
+    result.isOk();
+    result.status();
+    result.value();
+    return 0;
+}
diff --git a/keystore/tests/fuzzer/keystoreCommon.h b/keystore/tests/fuzzer/keystoreCommon.h
new file mode 100644
index 0000000..7af3ba8
--- /dev/null
+++ b/keystore/tests/fuzzer/keystoreCommon.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+#ifndef KEYSTORECOMMON_H
+#define KEYSTORECOMMON_H
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <keystore/KeyAttestationPackageInfo.h>
+#include <keystore/Signature.h>
+#include <vector>
+
+#include "fuzzer/FuzzedDataProvider.h"
+
+using namespace android;
+using namespace std;
+using ::content::pm::Signature;
+using ::security::keymaster::KeyAttestationPackageInfo;
+
+constexpr size_t kSignatureSizeMin = 1;
+constexpr size_t kSignatureSizeMax = 1000;
+constexpr size_t kRandomStringLength = 256;
+constexpr size_t kSignatureVectorSizeMin = 1;
+constexpr size_t kSignatureVectorSizeMax = 1000;
+
+struct PackageInfoData {
+    string packageName;
+    int64_t versionCode;
+    KeyAttestationPackageInfo::SharedSignaturesVector sharedSignaturesVector;
+};
+
+inline void invokeReadWriteParcel(Parcelable* obj) {
+    Parcel parcel;
+    obj->writeToParcel(&parcel);
+    parcel.setDataPosition(0);
+    obj->readFromParcel(&parcel);
+}
+
+inline vector<uint8_t> initSignatureData(FuzzedDataProvider* fdp) {
+    size_t signatureSize = fdp->ConsumeIntegralInRange(kSignatureSizeMin, kSignatureSizeMax);
+    vector<uint8_t> signatureData = fdp->ConsumeBytes<uint8_t>(signatureSize);
+    return signatureData;
+}
+
+inline PackageInfoData initPackageInfoData(FuzzedDataProvider* fdp) {
+    PackageInfoData packageInfoData;
+    packageInfoData.packageName = fdp->ConsumeRandomLengthString(kRandomStringLength);
+    packageInfoData.versionCode = fdp->ConsumeIntegral<int64_t>();
+    size_t signatureVectorSize =
+        fdp->ConsumeIntegralInRange(kSignatureVectorSizeMin, kSignatureVectorSizeMax);
+    KeyAttestationPackageInfo::SignaturesVector signatureVector;
+    for (size_t size = 0; size < signatureVectorSize; ++size) {
+        bool shouldUseParameterizedConstructor = fdp->ConsumeBool();
+        if (shouldUseParameterizedConstructor) {
+            vector<uint8_t> signatureData = initSignatureData(fdp);
+            signatureVector.push_back(make_optional<Signature>(signatureData));
+        } else {
+            signatureVector.push_back(std::nullopt);
+        }
+    }
+    packageInfoData.sharedSignaturesVector =
+        make_shared<KeyAttestationPackageInfo::SignaturesVector>(move(signatureVector));
+    return packageInfoData;
+}
+#endif  // KEYSTORECOMMON_H
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;
+}
diff --git a/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp b/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp
new file mode 100644
index 0000000..63899ff
--- /dev/null
+++ b/keystore/tests/fuzzer/keystorePackageInfo_fuzzer.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "keystoreCommon.h"
+
+class KeystorePackageInfoFuzzer {
+  public:
+    void process(const uint8_t* data, size_t size);
+    ~KeystorePackageInfoFuzzer() {}
+
+  private:
+    void invokePackageInfo();
+    std::unique_ptr<FuzzedDataProvider> mFdp;
+};
+
+void KeystorePackageInfoFuzzer::invokePackageInfo() {
+    auto packageInfoData = initPackageInfoData(mFdp.get());
+    KeyAttestationPackageInfo packageInfo(String16((packageInfoData.packageName).c_str()),
+                                          packageInfoData.versionCode,
+                                          packageInfoData.sharedSignaturesVector);
+    invokeReadWriteParcel(&packageInfo);
+}
+
+void KeystorePackageInfoFuzzer::process(const uint8_t* data, size_t size) {
+    mFdp = std::make_unique<FuzzedDataProvider>(data, size);
+    invokePackageInfo();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    KeystorePackageInfoFuzzer keystorePackageInfoFuzzer;
+    keystorePackageInfoFuzzer.process(data, size);
+    return 0;
+}
diff --git a/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp b/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp
new file mode 100644
index 0000000..b8f8a73
--- /dev/null
+++ b/keystore/tests/fuzzer/keystoreSignature_fuzzer.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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 "keystoreCommon.h"
+#include <keystore/Signature.h>
+
+class KeystoreSignatureFuzzer {
+  public:
+    void process(const uint8_t* data, size_t size);
+    ~KeystoreSignatureFuzzer() {}
+
+  private:
+    void invokeSignature();
+    std::unique_ptr<FuzzedDataProvider> mFdp;
+};
+
+void KeystoreSignatureFuzzer::invokeSignature() {
+    std::optional<Signature> signature;
+    bool shouldUseParameterizedConstructor = mFdp->ConsumeBool();
+    if (shouldUseParameterizedConstructor) {
+        std::vector<uint8_t> signatureData = initSignatureData(mFdp.get());
+        signature = Signature(signatureData);
+    } else {
+        signature = Signature();
+    }
+    invokeReadWriteParcel(&signature.value());
+}
+
+void KeystoreSignatureFuzzer::process(const uint8_t* data, size_t size) {
+    mFdp = std::make_unique<FuzzedDataProvider>(data, size);
+    invokeSignature();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    KeystoreSignatureFuzzer keystoreSignatureFuzzer;
+    keystoreSignatureFuzzer.process(data, size);
+    return 0;
+}