Merge "android.security.*: use versions for imports (2)"
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 39208c6..ad4b4b1 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -102,5 +102,5 @@
 
     export_include_dirs: ["include"],
 
-    vendor_available: true,
+    vendor: true,
 }
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index 63e19b0..4a7b7b4 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -24,7 +24,7 @@
 aidl_interface {
     name: "android.security.attestationmanager",
     srcs: [ "android/security/attestationmanager/*.aidl", ],
-    imports: [ "android.hardware.security.keymint" ],
+    imports: [ "android.hardware.security.keymint-V1" ],
     unstable: true,
     backend: {
         java: {
@@ -45,8 +45,8 @@
     name: "android.security.authorization",
     srcs: [ "android/security/authorization/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
-        "android.hardware.security.secureclock",
+        "android.hardware.security.keymint-V1",
+        "android.hardware.security.secureclock-V1",
     ],
     unstable: true,
     backend: {
@@ -86,9 +86,9 @@
     name: "android.security.compat",
     srcs: [ "android/security/compat/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
-        "android.hardware.security.secureclock",
-        "android.hardware.security.sharedsecret",
+        "android.hardware.security.keymint-V1",
+        "android.hardware.security.secureclock-V1",
+        "android.hardware.security.sharedsecret-V1",
     ],
     unstable: true,
     backend: {
@@ -110,7 +110,7 @@
     name: "android.security.remoteprovisioning",
     srcs: [ "android/security/remoteprovisioning/*.aidl" ],
     imports: [
-        "android.hardware.security.keymint",
+        "android.hardware.security.keymint-V1",
     ],
     unstable: true,
     backend: {
diff --git a/keystore2/src/async_task.rs b/keystore2/src/async_task.rs
index e130024..0515c8f 100644
--- a/keystore2/src/async_task.rs
+++ b/keystore2/src/async_task.rs
@@ -417,7 +417,9 @@
             Err(RecvTimeoutError::Timeout)
         );
         done_receiver.recv().unwrap();
-        idle_done_receiver.recv_timeout(Duration::from_millis(1)).unwrap();
+        // Now that the last low-priority job has completed, the idle task should
+        // fire pretty much immediately.
+        idle_done_receiver.recv_timeout(Duration::from_millis(50)).unwrap();
 
         // Idle callback not executed again even if we wait for a while.
         assert_eq!(
@@ -438,7 +440,7 @@
             Err(RecvTimeoutError::Timeout)
         );
         done_receiver.recv().unwrap();
-        idle_done_receiver.recv_timeout(Duration::from_millis(1)).unwrap();
+        idle_done_receiver.recv_timeout(Duration::from_millis(50)).unwrap();
     }
 
     #[test]
diff --git a/keystore2/src/fuzzers/legacy_blob_fuzzer.rs b/keystore2/src/fuzzers/legacy_blob_fuzzer.rs
index 5c89ca4..7e3e848 100644
--- a/keystore2/src/fuzzers/legacy_blob_fuzzer.rs
+++ b/keystore2/src/fuzzers/legacy_blob_fuzzer.rs
@@ -19,6 +19,8 @@
 use keystore2::legacy_blob::LegacyBlobLoader;
 
 fuzz_target!(|data: &[u8]| {
-    let string = data.iter().filter_map(|c| std::char::from_u32(*c as u32)).collect::<String>();
-    let _res = LegacyBlobLoader::decode_alias(&string);
+    if !data.is_empty() {
+        let string = data.iter().filter_map(|c| std::char::from_u32(*c as u32)).collect::<String>();
+        let _res = LegacyBlobLoader::decode_alias(&string);
+    }
 });
diff --git a/ondevice-signing/Android.bp b/ondevice-signing/Android.bp
index 5219240..efa0389 100644
--- a/ondevice-signing/Android.bp
+++ b/ondevice-signing/Android.bp
@@ -84,7 +84,6 @@
   srcs: [
     "odsign_main.cpp",
     "CertUtils.cpp",
-    "FakeCompOs.cpp",
     "KeystoreKey.cpp",
     "KeystoreHmacKey.cpp",
     "VerityUtils.cpp",
diff --git a/ondevice-signing/FakeCompOs.cpp b/ondevice-signing/FakeCompOs.cpp
deleted file mode 100644
index 596d6e2..0000000
--- a/ondevice-signing/FakeCompOs.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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 "FakeCompOs.h"
-
-#include "CertUtils.h"
-#include "KeyConstants.h"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/result.h>
-#include <android-base/scopeguard.h>
-
-#include <binder/IServiceManager.h>
-
-#include <openssl/nid.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-using android::String16;
-
-using android::hardware::security::keymint::Algorithm;
-using android::hardware::security::keymint::Digest;
-using android::hardware::security::keymint::KeyParameter;
-using android::hardware::security::keymint::KeyParameterValue;
-using android::hardware::security::keymint::KeyPurpose;
-using android::hardware::security::keymint::PaddingMode;
-using android::hardware::security::keymint::SecurityLevel;
-using android::hardware::security::keymint::Tag;
-
-using android::system::keystore2::CreateOperationResponse;
-using android::system::keystore2::Domain;
-
-using android::base::Error;
-using android::base::Result;
-
-using android::binder::Status;
-
-// TODO: Allocate a namespace for CompOS
-const int64_t kCompOsNamespace = 101;
-
-Result<std::unique_ptr<FakeCompOs>>
-FakeCompOs::startInstance(const std::string& /*instanceImagePath*/) {
-    std::unique_ptr<FakeCompOs> compOs(new FakeCompOs);
-    auto init = compOs->initialize();
-    if (init.ok()) {
-        return compOs;
-    } else {
-        return init.error();
-    }
-}
-
-FakeCompOs::FakeCompOs() {}
-
-Result<void> FakeCompOs::initialize() {
-    auto sm = android::defaultServiceManager();
-    if (!sm) {
-        return Error() << "No ServiceManager";
-    }
-    auto rawService = sm->getService(String16("android.system.keystore2.IKeystoreService/default"));
-    if (!rawService) {
-        return Error() << "No Keystore service";
-    }
-    mService = interface_cast<android::system::keystore2::IKeystoreService>(rawService);
-    if (!mService) {
-        return Error() << "Bad Keystore service";
-    }
-
-    // TODO: We probably want SecurityLevel::SOFTWARE here, in the VM, but Keystore doesn't do it
-    auto status = mService->getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT, &mSecurityLevel);
-    if (!status.isOk()) {
-        return Error() << status;
-    }
-
-    return {};
-}
-
-Result<FakeCompOs::ByteVector> FakeCompOs::signData(const ByteVector& keyBlob,
-                                                    const ByteVector& data) const {
-    KeyDescriptor descriptor;
-    descriptor.domain = Domain::BLOB;
-    descriptor.nspace = kCompOsNamespace;
-    descriptor.blob = keyBlob;
-
-    std::vector<KeyParameter> parameters;
-
-    {
-        KeyParameter algo;
-        algo.tag = Tag::ALGORITHM;
-        algo.value = KeyParameterValue::make<KeyParameterValue::algorithm>(Algorithm::RSA);
-        parameters.push_back(algo);
-
-        KeyParameter digest;
-        digest.tag = Tag::DIGEST;
-        digest.value = KeyParameterValue::make<KeyParameterValue::digest>(Digest::SHA_2_256);
-        parameters.push_back(digest);
-
-        KeyParameter padding;
-        padding.tag = Tag::PADDING;
-        padding.value = KeyParameterValue::make<KeyParameterValue::paddingMode>(
-            PaddingMode::RSA_PKCS1_1_5_SIGN);
-        parameters.push_back(padding);
-
-        KeyParameter purpose;
-        purpose.tag = Tag::PURPOSE;
-        purpose.value = KeyParameterValue::make<KeyParameterValue::keyPurpose>(KeyPurpose::SIGN);
-        parameters.push_back(purpose);
-    }
-
-    Status status;
-
-    CreateOperationResponse response;
-    status = mSecurityLevel->createOperation(descriptor, parameters, /*forced=*/false, &response);
-    if (!status.isOk()) {
-        return Error() << "Failed to create operation: " << status;
-    }
-
-    auto operation = response.iOperation;
-    auto abort_guard = android::base::make_scope_guard([&] { operation->abort(); });
-
-    if (response.operationChallenge.has_value()) {
-        return Error() << "Key requires user authorization";
-    }
-
-    std::optional<ByteVector> signature;
-    status = operation->finish(data, {}, &signature);
-    if (!status.isOk()) {
-        return Error() << "Failed to sign data: " << status;
-    }
-
-    abort_guard.Disable();
-
-    if (!signature.has_value()) {
-        return Error() << "No signature received from keystore.";
-    }
-
-    return signature.value();
-}
-
-Result<void> FakeCompOs::loadAndVerifyKey(const ByteVector& keyBlob,
-                                          const ByteVector& publicKey) const {
-    // To verify the key is valid, we use it to sign some data, and then verify the signature using
-    // the supplied public key.
-
-    ByteVector data(32);
-    if (RAND_bytes(data.data(), data.size()) != 1) {
-        return Error() << "No random bytes";
-    }
-
-    auto signature = signData(keyBlob, data);
-    if (!signature.ok()) {
-        return signature.error();
-    }
-
-    std::string signatureString(reinterpret_cast<char*>(signature.value().data()),
-                                signature.value().size());
-    std::string dataString(reinterpret_cast<char*>(data.data()), data.size());
-    return verifyRsaPublicKeySignature(dataString, signatureString, publicKey);
-}
diff --git a/ondevice-signing/FakeCompOs.h b/ondevice-signing/FakeCompOs.h
deleted file mode 100644
index 6c7a445..0000000
--- a/ondevice-signing/FakeCompOs.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <android-base/result.h>
-
-#include <utils/StrongPointer.h>
-
-#include <android/system/keystore2/IKeystoreService.h>
-
-class FakeCompOs {
-    using IKeystoreService = ::android::system::keystore2::IKeystoreService;
-    using IKeystoreSecurityLevel = ::android::system::keystore2::IKeystoreSecurityLevel;
-    using KeyDescriptor = ::android::system::keystore2::KeyDescriptor;
-    using KeyMetadata = ::android::system::keystore2::KeyMetadata;
-
-  public:
-    using ByteVector = std::vector<uint8_t>;
-
-    static android::base::Result<std::unique_ptr<FakeCompOs>>
-    startInstance(const std::string& instanceImagePath);
-
-    android::base::Result<void> loadAndVerifyKey(const ByteVector& keyBlob,
-                                                 const ByteVector& publicKey) const;
-
-  private:
-    FakeCompOs();
-
-    android::base::Result<void> initialize();
-
-    android::base::Result<ByteVector> signData(const ByteVector& keyBlob,
-                                               const ByteVector& data) const;
-
-    KeyDescriptor mDescriptor;
-    android::sp<IKeystoreService> mService;
-    android::sp<IKeystoreSecurityLevel> mSecurityLevel;
-};
diff --git a/ondevice-signing/odsign_main.cpp b/ondevice-signing/odsign_main.cpp
index bba39b8..4a7baad 100644
--- a/ondevice-signing/odsign_main.cpp
+++ b/ondevice-signing/odsign_main.cpp
@@ -32,7 +32,6 @@
 #include <odrefresh/odrefresh.h>
 
 #include "CertUtils.h"
-#include "FakeCompOs.h"
 #include "KeystoreKey.h"
 #include "VerityUtils.h"
 
@@ -40,6 +39,7 @@
 
 using android::base::ErrnoError;
 using android::base::Error;
+using android::base::GetProperty;
 using android::base::Result;
 using android::base::SetProperty;
 
@@ -52,24 +52,20 @@
 const std::string kArtArtifactsDir = "/data/misc/apexdata/com.android.art/dalvik-cache";
 
 constexpr const char* kOdrefreshPath = "/apex/com.android.art/bin/odrefresh";
-
+constexpr const char* kCompOsVerifyPath = "/apex/com.android.compos/bin/compos_verify_key";
 constexpr const char* kFsVerityProcPath = "/proc/sys/fs/verity";
+constexpr const char* kKvmDevicePath = "/dev/kvm";
 
 constexpr bool kForceCompilation = false;
-constexpr bool kUseCompOs = false;  // STOPSHIP if true
+constexpr bool kUseCompOs = true;
 
-constexpr const char* kCompOsApexPath = "/apex/com.android.compos";
 const std::string kCompOsCert = "/data/misc/odsign/compos_key.cert";
-const std::string kCompOsPublicKey = "/data/misc/apexdata/com.android.compos/compos_key.pubkey";
-const std::string kCompOsKeyBlob = "/data/misc/apexdata/com.android.compos/compos_key.blob";
-const std::string kCompOsInstance = "/data/misc/apexdata/com.android.compos/compos_instance.img";
 
+const std::string kCompOsCurrentPublicKey =
+    "/data/misc/apexdata/com.android.compos/current/key.pubkey";
 const std::string kCompOsPendingPublicKey =
-    "/data/misc/apexdata/com.android.compos/compos_pending_key.pubkey";
-const std::string kCompOsPendingKeyBlob =
-    "/data/misc/apexdata/com.android.compos/compos_pending_key.blob";
-const std::string kCompOsPendingInstance =
-    "/data/misc/apexdata/com.android.compos/compos_pending_instance.img";
+    "/data/misc/apexdata/com.android.compos/pending/key.pubkey";
+
 const std::string kCompOsPendingArtifactsDir = "/data/misc/apexdata/com.android.art/compos-pending";
 
 constexpr const char* kOdsignVerificationDoneProp = "odsign.verification.done";
@@ -81,6 +77,8 @@
 
 constexpr const char* kStopServiceProp = "ctl.stop";
 
+enum class CompOsInstance { kCurrent, kPending };
+
 static std::vector<uint8_t> readBytesFromFile(const std::string& path) {
     std::string str;
     android::base::ReadFileToString(path, &str);
@@ -140,7 +138,12 @@
 }
 
 bool compOsPresent() {
-    return access(kCompOsApexPath, F_OK) == 0;
+    return access(kCompOsVerifyPath, X_OK) == 0 && access(kKvmDevicePath, F_OK) == 0;
+}
+
+bool isDebugBuild() {
+    std::string build_type = GetProperty("ro.build.type", "");
+    return build_type == "userdebug" || build_type == "eng";
 }
 
 Result<void> verifyExistingRootCert(const SigningKey& key) {
@@ -203,62 +206,36 @@
     return existingCertInfo.value().subjectRsaPublicKey;
 }
 
-// Attempt to start a CompOS VM from the given instance image and then get it to
-// verify the public key & key blob.  Returns the RsaPublicKey bytes if
-// successful, an empty vector if any of the files are not present, or an error
-// otherwise.
-Result<std::vector<uint8_t>> loadAndVerifyCompOsKey(const std::string& instanceFile,
-                                                    const std::string& publicKeyFile,
-                                                    const std::string& keyBlobFile) {
-    if (access(instanceFile.c_str(), F_OK) != 0 || access(publicKeyFile.c_str(), F_OK) != 0 ||
-        access(keyBlobFile.c_str(), F_OK) != 0) {
-        return {};
+// Attempt to start a CompOS VM for the specified instance to get it to
+// verify ita public key & key blob.
+bool startCompOsAndVerifyKey(CompOsInstance instance) {
+    bool isCurrent = instance == CompOsInstance::kCurrent;
+    const std::string& keyPath = isCurrent ? kCompOsCurrentPublicKey : kCompOsPendingPublicKey;
+    if (access(keyPath.c_str(), R_OK) != 0) {
+        return false;
     }
 
-    auto compOsStatus = FakeCompOs::startInstance(instanceFile);
-    if (!compOsStatus.ok()) {
-        return Error() << "Failed to start CompOs instance " << instanceFile << ": "
-                       << compOsStatus.error();
-    }
-    auto& compOs = compOsStatus.value();
-
-    auto publicKey = readBytesFromFile(publicKeyFile);
-    auto keyBlob = readBytesFromFile(keyBlobFile);
-    auto response = compOs->loadAndVerifyKey(keyBlob, publicKey);
-    if (!response.ok()) {
-        return response.error();
+    const char* const argv[] = {kCompOsVerifyPath, "--instance", isCurrent ? "current" : "pending"};
+    int result =
+        logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG, false, nullptr);
+    if (result == 0) {
+        return true;
     }
 
-    return publicKey;
+    LOG(ERROR) << kCompOsVerifyPath << " returned " << result;
+    return false;
 }
 
 Result<std::vector<uint8_t>> verifyCompOsKey(const SigningKey& signingKey) {
-    std::vector<uint8_t> publicKey;
+    bool verified = false;
 
     // If a pending key has been generated we don't know if it is the correct
     // one for the pending CompOS VM, so we need to start it and ask it.
-    auto pendingPublicKey = loadAndVerifyCompOsKey(kCompOsPendingInstance, kCompOsPendingPublicKey,
-                                                   kCompOsPendingKeyBlob);
-    if (pendingPublicKey.ok()) {
-        if (!pendingPublicKey->empty()) {
-            LOG(INFO) << "Verified pending CompOs key";
-
-            if (rename(kCompOsPendingInstance, kCompOsInstance) &&
-                rename(kCompOsPendingPublicKey, kCompOsPublicKey) &&
-                rename(kCompOsPendingKeyBlob, kCompOsKeyBlob)) {
-                publicKey = std::move(*pendingPublicKey);
-            }
-        }
-    } else {
-        LOG(WARNING) << "Failed to verify pending CompOs key: " << pendingPublicKey.error();
-        // And fall through to dealing with any current key.
+    if (startCompOsAndVerifyKey(CompOsInstance::kPending)) {
+        verified = true;
     }
-    // Whether good or bad, we've finished with these files.
-    unlink(kCompOsPendingInstance.c_str());
-    unlink(kCompOsPendingKeyBlob.c_str());
-    unlink(kCompOsPendingPublicKey.c_str());
 
-    if (publicKey.empty()) {
+    if (!verified) {
         // Alternatively if we signed a cert for the key on a previous boot, then we
         // can use that straight away.
         auto existing_key =
@@ -270,30 +247,25 @@
         }
     }
 
-    // Otherwise, if there is an existing key that we haven't signed yet, then we can sign it
-    // now if CompOS confirms it's OK.
-    if (publicKey.empty()) {
-        auto currentPublicKey =
-            loadAndVerifyCompOsKey(kCompOsInstance, kCompOsPublicKey, kCompOsKeyBlob);
-        if (currentPublicKey.ok()) {
-            if (!currentPublicKey->empty()) {
-                LOG(INFO) << "Verified existing CompOs key";
-                publicKey = std::move(*currentPublicKey);
-            }
-        } else {
-            LOG(WARNING) << "Failed to verify existing CompOs key: " << currentPublicKey.error();
-            // Delete so we won't try again on next boot.
-            unlink(kCompOsInstance.c_str());
-            unlink(kCompOsKeyBlob.c_str());
-            unlink(kCompOsPublicKey.c_str());
-        }
+    // Otherwise, if there is an existing key that we haven't signed yet, then we can sign
+    // it now if CompOS confirms it's OK.
+    if (!verified && startCompOsAndVerifyKey(CompOsInstance::kCurrent)) {
+        verified = true;
     }
 
-    if (publicKey.empty()) {
+    if (!verified) {
         return Error() << "No valid CompOs key present.";
     }
 
-    // One way or another we now have a valid key pair. Persist a certificate so
+    // If the pending key was verified it will have been promoted to current, so
+    // at this stage if there is a key it will be the current one.
+    auto publicKey = readBytesFromFile(kCompOsCurrentPublicKey);
+    if (publicKey.empty()) {
+        // This shouldn`t really happen.
+        return Error() << "Failed to read CompOs key.";
+    }
+
+    // One way or another we now have a valid public key. Persist a certificate so
     // we can simplify the checks on subsequent boots.
 
     auto signFunction = [&](const std::string& to_be_signed) {
@@ -305,6 +277,8 @@
         return Error() << "Failed to create CompOs cert: " << certStatus.error();
     }
 
+    LOG(INFO) << "Verified key, wrote new CompOs cert";
+
     return publicKey;
 }
 
@@ -546,7 +520,8 @@
 
 int main(int /* argc */, char** /* argv */) {
     auto errorScopeGuard = []() {
-        // In case we hit any error, remove the artifacts and tell Zygote not to use anything
+        // In case we hit any error, remove the artifacts and tell Zygote not to use
+        // anything
         removeDirectory(kArtArtifactsDir);
         removeDirectory(kCompOsPendingArtifactsDir);
         // Tell init we don't need to use our key anymore
@@ -576,7 +551,7 @@
         LOG(INFO) << "Device doesn't support fsverity. Falling back to full verification.";
     }
 
-    bool supportsCompOs = kUseCompOs && supportsFsVerity && compOsPresent();
+    bool useCompOs = kUseCompOs && supportsFsVerity && compOsPresent() && isDebugBuild();
 
     if (supportsFsVerity) {
         auto existing_cert = verifyExistingRootCert(*key);
@@ -604,7 +579,7 @@
     art::odrefresh::ExitCode odrefresh_status = art::odrefresh::ExitCode::kCompilationRequired;
     bool digests_verified = false;
 
-    if (supportsCompOs) {
+    if (useCompOs) {
         auto compos_key = addCompOsCertToFsVerityKeyring(*key);
         if (!compos_key.ok()) {
             LOG(WARNING) << compos_key.error();