OSDN Git Service

Add "Unlocked device required" key API
authorBrian Young <bcyoung@google.com>
Fri, 23 Feb 2018 18:04:20 +0000 (18:04 +0000)
committerBrian C. Young <bcyoung@google.com>
Wed, 28 Mar 2018 15:38:56 +0000 (08:38 -0700)
This adds the API methods and values for keyguard-bound keys, but
contains none of the actual functionality.

Test: CTS tests in CtsKeystoreTestCases

Bug: 67752510

Merged-In: Iccd7dafd77258d903d11353e02ba3ab956050c40
Change-Id: Iccd7dafd77258d903d11353e02ba3ab956050c40
(cherry picked from commit fd75c7232aebc8690f004de3486b3b9a44f3e0b0)

core/java/android/security/keymaster/KeymasterDefs.java
keystore/java/android/security/KeyStore.java
keystore/java/android/security/keystore/KeyGenParameterSpec.java
keystore/java/android/security/keystore/KeyProtection.java
keystore/java/android/security/keystore/KeymasterUtils.java
services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java

index 1d13335..f4dcce1 100644 (file)
@@ -75,6 +75,7 @@ public final class KeymasterDefs {
     public static final int KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506;
     public static final int KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED = KM_BOOL | 507;
     public static final int KM_TAG_TRUSTED_CONFIRMATION_REQUIRED = KM_BOOL | 508;
+    public static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 509;
 
     public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
     public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
@@ -216,6 +217,7 @@ public final class KeymasterDefs {
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
+    public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
     public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -262,6 +264,7 @@ public final class KeymasterDefs {
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
+        sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
     }
index 1924bbe..33ce582 100644 (file)
@@ -278,7 +278,7 @@ public class KeyStore {
     /**
      * Attempt to lock the keystore for {@code user}.
      *
-     * @param user Android user to lock.
+     * @param userId Android user to lock.
      * @return whether {@code user}'s keystore was locked.
      */
     public boolean lock(int userId) {
@@ -299,7 +299,7 @@ public class KeyStore {
      * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
      * created.
      *
-     * @param user Android user ID to operate on
+     * @param userId Android user ID to operate on
      * @param password user's keystore password. Should be the most recent value passed to
      * {@link #onUserPasswordChanged} for the user.
      *
@@ -545,6 +545,7 @@ public class KeyStore {
         try {
             args = args != null ? args : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
+            // TODO(67752510): Apply USER_ID tag
             return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
index 4b9f3c8..5d596cb 100644 (file)
@@ -266,6 +266,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
     private final boolean mInvalidatedByBiometricEnrollment;
     private final boolean mIsStrongBoxBacked;
     private final boolean mUserConfirmationRequired;
+    private final boolean mUnlockedDeviceRequired;
 
     /**
      * @hide should be built with Builder
@@ -296,7 +297,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             boolean isStrongBoxBacked,
-            boolean userConfirmationRequired) {
+            boolean userConfirmationRequired,
+            boolean unlockedDeviceRequired) {
         if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
         }
@@ -345,6 +347,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mIsStrongBoxBacked = isStrongBoxBacked;
         mUserConfirmationRequired = userConfirmationRequired;
+        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -670,6 +673,15 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
     }
 
     /**
+     * @hide Returns {@code true} if the key cannot be used unless the device screen is unlocked.
+     *
+     * @see Builder#setUnlockedDeviceRequired(boolean)
+     */
+    public boolean isUnlockedDeviceRequired() {
+        return mUnlockedDeviceRequired;
+    }
+
+    /**
      * @hide
      */
     public long getBoundToSpecificSecureUserId() {
@@ -707,6 +719,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mIsStrongBoxBacked = false;
         private boolean mUserConfirmationRequired;
+        private boolean mUnlockedDeviceRequired = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -1275,6 +1288,18 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
         }
 
         /**
+         * @hide Sets whether the keystore requires the screen to be unlocked before allowing decryption
+         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
+         * while the screen is locked will fail. A locked device requires a PIN, password,
+         * fingerprint, or other trusted factor to access.
+         */
+        @NonNull
+        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
+            mUnlockedDeviceRequired = unlockedDeviceRequired;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@code KeyGenParameterSpec}.
          */
         @NonNull
@@ -1305,7 +1330,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
                     mIsStrongBoxBacked,
-                    mUserConfirmationRequired);
+                    mUserConfirmationRequired,
+                    mUnlockedDeviceRequired);
         }
     }
 }
index 95eeec7..cc7870c 100644 (file)
@@ -224,12 +224,13 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
     private final boolean mRandomizedEncryptionRequired;
     private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
-    private final boolean mTrustedUserPresenceRequred;
+    private final boolean mTrustedUserPresenceRequired;
     private final boolean mUserAuthenticationValidWhileOnBody;
     private final boolean mInvalidatedByBiometricEnrollment;
     private final long mBoundToSecureUserId;
     private final boolean mCriticalToDeviceEncryption;
     private final boolean mUserConfirmationRequired;
+    private final boolean mUnlockedDeviceRequired;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -243,12 +244,13 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
             boolean randomizedEncryptionRequired,
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
-            boolean trustedUserPresenceRequred,
+            boolean trustedUserPresenceRequired,
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
             long boundToSecureUserId,
             boolean criticalToDeviceEncryption,
-            boolean userConfirmationRequired) {
+            boolean userConfirmationRequired,
+            boolean unlockedDeviceRequired) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -262,12 +264,13 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
         mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
-        mTrustedUserPresenceRequred = trustedUserPresenceRequred;
+        mTrustedUserPresenceRequired = trustedUserPresenceRequired;
         mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mBoundToSecureUserId = boundToSecureUserId;
         mCriticalToDeviceEncryption = criticalToDeviceEncryption;
         mUserConfirmationRequired = userConfirmationRequired;
+        mUnlockedDeviceRequired = unlockedDeviceRequired;
     }
 
     /**
@@ -444,7 +447,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
      * been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
      */
     public boolean isTrustedUserPresenceRequired() {
-        return mTrustedUserPresenceRequred;
+        return mTrustedUserPresenceRequired;
     }
 
     /**
@@ -505,6 +508,15 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
     }
 
     /**
+     * @hide Returns {@code true} if the key cannot be used unless the device screen is unlocked.
+     *
+     * @see Builder#setUnlockedDeviceRequired(boolean)
+     */
+    public boolean isUnlockedDeviceRequired() {
+        return mUnlockedDeviceRequired;
+    }
+
+    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -524,6 +536,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
         private boolean mUserAuthenticationValidWhileOnBody;
         private boolean mInvalidatedByBiometricEnrollment = true;
         private boolean mUserConfirmationRequired;
+        private boolean mUnlockedDeviceRequired = false;
+
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         private boolean mCriticalToDeviceEncryption = false;
 
@@ -914,6 +928,18 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
         }
 
         /**
+         * @hide Sets whether the keystore requires the screen to be unlocked before allowing decryption
+         * using this key. If this is set to {@code true}, any attempt to decrypt using this key
+         * while the screen is locked will fail. A locked device requires a PIN, password,
+         * fingerprint, or other trusted factor to access.
+         */
+        @NonNull
+        public Builder setUnlockedDeviceRequired(boolean unlockedDeviceRequired) {
+            mUnlockedDeviceRequired = unlockedDeviceRequired;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -937,7 +963,8 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
                     mInvalidatedByBiometricEnrollment,
                     mBoundToSecureUserId,
                     mCriticalToDeviceEncryption,
-                    mUserConfirmationRequired);
+                    mUserConfirmationRequired,
+                    mUnlockedDeviceRequired);
         }
     }
 }
index 0ef08f2..d194f0b 100644 (file)
@@ -101,8 +101,9 @@ public abstract class KeymasterUtils {
      *         state (e.g., secure lock screen not set up) for generating or importing keys that
      *         require user authentication.
      */
-    public static void addUserAuthArgs(KeymasterArguments args,
-            UserAuthArgs spec) {
+    public static void addUserAuthArgs(KeymasterArguments args, UserAuthArgs spec) {
+        // TODO (67752510): Implement "unlocked device required"
+
         if (spec.isUserConfirmationRequired()) {
             args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
         }
index 941cd44..37e79e7 100644 (file)
@@ -130,4 +130,4 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
         pw.println(prefix + "mTrusted=" + mTrusted);
         pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
     }
-}
\ No newline at end of file
+}