Restore "Add "Unlocked device required" parameter to keys"

Add a keymaster parameter for keys that should be inaccessible when
the device screen is locked. "Locked" here is a state where the device
can be used or accessed without any further trust factor such as a
PIN, password, fingerprint, or trusted face or voice.

This parameter is added to the Java keystore interface for key
creation and import, as well as enums specified by and for the native
keystore process.

This reverts commit 1b75929a58c32882d21d04ee1df2a60a199923bd.

Test: CTS tests in I8a5affd1eaed176756175158e3057e44934fffed

Bug: 67752510

Change-Id: I4becf698f8bc34b7a9d53ab2200480480fdd1a9c
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 9e882e4..8b2cb62 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -84,6 +84,7 @@
     srcs: ["keystore_cli.cpp"],
     shared_libs: [
         "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libbinder",
         "libcrypto",
         "libcutils",
@@ -109,8 +110,8 @@
     srcs: ["keystore_cli_v2.cpp"],
     shared_libs: [
         "android.hardware.confirmationui@1.0",
-        "android.hardware.keymaster@3.0",
         "libbinder",
+        "android.hardware.keymaster@4.0",
         "libchrome",
         "libutils",
         "libhidlbase",
diff --git a/keystore/binder/android/security/IKeystoreService.aidl b/keystore/binder/android/security/IKeystoreService.aidl
index 738eb68..45bc070 100644
--- a/keystore/binder/android/security/IKeystoreService.aidl
+++ b/keystore/binder/android/security/IKeystoreService.aidl
@@ -71,7 +71,7 @@
         in byte[] entropy);
     int abort(IBinder handle);
     boolean isOperationAuthorized(IBinder token);
-    int addAuthToken(in byte[] authToken);
+    int addAuthToken(in byte[] authToken, in int userId);
     int onUserAdded(int userId, int parentId);
     int onUserRemoved(int userId);
     int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);
diff --git a/keystore/include/keystore/keymaster_types.h b/keystore/include/keystore/keymaster_types.h
index 62b43be..bd61294 100644
--- a/keystore/include/keystore/keymaster_types.h
+++ b/keystore/include/keystore/keymaster_types.h
@@ -83,6 +83,7 @@
 using keymaster::TAG_RSA_PUBLIC_EXPONENT;
 using keymaster::TAG_USAGE_EXPIRE_DATETIME;
 using keymaster::TAG_USER_AUTH_TYPE;
+using keymaster::TAG_USER_ID;
 using keymaster::TAG_USER_SECURE_ID;
 
 using keymaster::NullOr;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 89c31a5..bee9fee 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -372,6 +372,7 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(true, userId);
     mKeyStore->lock(userId);
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
@@ -400,6 +401,7 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(false, userId);
     const String8 password8(pw);
     // read master key, decrypt with password, initialize mMasterKey*.
     *aidl_return = static_cast<int32_t>(mKeyStore->readMasterKey(password8, userId));
@@ -1466,7 +1468,7 @@
 }
 
 Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
-                                     int32_t* aidl_return) {
+                                     int32_t userId, int32_t* aidl_return) {
 
     // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
     // receive a HardwareAuthToken, rather than an opaque byte array.
@@ -1488,6 +1490,8 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(false, userId);
+
     mAuthTokenTable.AddAuthenticationToken(hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index ce809f8..b238dc4 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -145,7 +145,7 @@
                                     int32_t* _aidl_return) override;
     ::android::binder::Status isOperationAuthorized(const ::android::sp<::android::IBinder>& token,
                                                     bool* _aidl_return) override;
-    ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
+    ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken, int32_t userId,
                                            int32_t* _aidl_return) override;
     ::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
                                           int32_t* _aidl_return) override;
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index d78a5a6..5a6e591 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -223,6 +223,8 @@
     bool caller_nonce_authorized_by_key = false;
     bool authentication_required = false;
     bool auth_token_matched = false;
+    bool unlocked_device_required = false;
+    int32_t user_id = -1;
 
     for (auto& param : auth_set) {
 
@@ -282,10 +284,18 @@
             }
             break;
 
+        case Tag::USER_ID:
+            user_id = authorizationValue(TAG_USER_ID, param).value();
+            break;
+
         case Tag::CALLER_NONCE:
             caller_nonce_authorized_by_key = true;
             break;
 
+        case Tag::UNLOCKED_DEVICE_REQUIRED:
+            unlocked_device_required = true;
+            break;
+
         /* Tags should never be in key auths. */
         case Tag::INVALID:
         case Tag::ROOT_OF_TRUST:
@@ -356,6 +366,19 @@
         }
     }
 
+    if (unlocked_device_required && is_device_locked(user_id)) {
+        switch (purpose) {
+        case KeyPurpose::ENCRYPT:
+        case KeyPurpose::VERIFY:
+            /* These are okay */
+            break;
+        case KeyPurpose::DECRYPT:
+        case KeyPurpose::SIGN:
+        case KeyPurpose::WRAP_KEY:
+            return ErrorCode::DEVICE_LOCKED;
+        };
+    }
+
     if (authentication_required && !auth_token_matched) {
         ALOGE("Auth required but no matching auth token found");
         return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
index d7b27fc..6e6c54f 100644
--- a/keystore/keymaster_enforcement.h
+++ b/keystore/keymaster_enforcement.h
@@ -142,6 +142,11 @@
      */
     virtual bool ValidateTokenSignature(const HardwareAuthToken& token) const = 0;
 
+    /*
+     * Returns true if the device screen is currently locked for the specified user.
+     */
+    virtual bool is_device_locked(int32_t userId) const = 0;
+
   private:
     ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
                                       const HardwareAuthToken& auth_token, uint64_t op_handle);
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index 3cdf649..e114ea9 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -84,6 +84,19 @@
         // signing key. Assume the token is good.
         return true;
     }
+
+    bool is_device_locked(int32_t userId) const override {
+        // If we haven't had a set call for this user yet, assume the device is locked.
+        if (mIsDeviceLockedForUser.count(userId) == 0) return true;
+        return mIsDeviceLockedForUser.find(userId)->second;
+    }
+
+    void set_device_locked(bool isLocked, int32_t userId) {
+        mIsDeviceLockedForUser[userId] = isLocked;
+    }
+
+  private:
+    std::map<int32_t, bool> mIsDeviceLockedForUser;
 };
 
 } // namespace keystore