Loading core/java/android/security/keymaster/KeymasterDefs.java +1 −1 Original line number Diff line number Diff line Loading @@ -154,7 +154,7 @@ public final class KeymasterDefs { // User authenticators. public static final int HW_AUTH_PASSWORD = 1 << 0; public static final int HW_AUTH_FINGERPRINT = 1 << 1; public static final int HW_AUTH_BIOMETRIC = 1 << 1; // Error codes. public static final int KM_ERROR_OK = 0; Loading keystore/java/android/security/KeyStore.java +25 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.Application; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Binder; import android.os.IBinder; Loading Loading @@ -1254,7 +1255,7 @@ public class KeyStore { return new UserNotAuthenticatedException(); } long fingerprintOnlySid = getFingerprintOnlySid(); final long fingerprintOnlySid = getFingerprintOnlySid(); if ((fingerprintOnlySid != 0) && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) { // One of the key's SIDs is the current fingerprint SID -- user can be Loading @@ -1262,6 +1263,14 @@ public class KeyStore { return new UserNotAuthenticatedException(); } final long faceOnlySid = getFaceOnlySid(); if ((faceOnlySid != 0) && (keySids.contains(KeymasterArguments.toUint64(faceOnlySid)))) { // One of the key's SIDs is the current face SID -- user can be // authenticated against that SID. return new UserNotAuthenticatedException(); } // None of the key's SIDs can ever be authenticated return new KeyPermanentlyInvalidatedException(); } Loading @@ -1272,6 +1281,21 @@ public class KeyStore { } } private long getFaceOnlySid() { final PackageManager packageManager = mContext.getPackageManager(); if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { return 0; } FaceManager faceManager = mContext.getSystemService(FaceManager.class); if (faceManager == null) { return 0; } // TODO: Restore USE_BIOMETRIC or USE_BIOMETRIC_INTERNAL permission check in // FaceManager.getAuthenticatorId once the ID is no longer needed here. return faceManager.getAuthenticatorId(); } private long getFingerprintOnlySid() { final PackageManager packageManager = mContext.getPackageManager(); if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { Loading keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java +2 −2 Original line number Diff line number Diff line Loading @@ -182,8 +182,8 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED); boolean invalidatedByBiometricEnrollment = false; if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) { if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC) { // Fingerprint-only key; will be invalidated if the root SID isn't in the SID list. invalidatedByBiometricEnrollment = keymasterSecureUserIds != null && !keymasterSecureUserIds.isEmpty() Loading keystore/java/android/security/keystore/KeymasterUtils.java +26 −15 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package android.security.keystore; import android.app.ActivityManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.security.GateKeeper; import android.security.KeyStore; Loading @@ -24,6 +24,8 @@ import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import java.security.ProviderException; import java.util.ArrayList; import java.util.List; /** * @hide Loading Loading @@ -121,35 +123,44 @@ public abstract class KeymasterUtils { if (spec.getUserAuthenticationValidityDurationSeconds() == -1) { // Every use of this key needs to be authorized by the user. This currently means // fingerprint-only auth. // fingerprint or face auth. FingerprintManager fingerprintManager = KeyStore.getApplicationContext().getSystemService(FingerprintManager.class); FaceManager faceManager = KeyStore.getApplicationContext().getSystemService(FaceManager.class); // TODO: Restore USE_FINGERPRINT permission check in // FingerprintManager.getAuthenticatorId once the ID is no longer needed here. long fingerprintOnlySid = final long fingerprintOnlySid = (fingerprintManager != null) ? fingerprintManager.getAuthenticatorId() : 0; if (fingerprintOnlySid == 0) { final long faceOnlySid = (faceManager != null) ? faceManager.getAuthenticatorId() : 0; if (fingerprintOnlySid == 0 && faceOnlySid == 0) { throw new IllegalStateException( "At least one fingerprint must be enrolled to create keys requiring user" "At least one biometric must be enrolled to create keys requiring user" + " authentication for every use"); } long sid; List<Long> sids = new ArrayList<>(); if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) { sid = spec.getBoundToSpecificSecureUserId(); sids.add(spec.getBoundToSpecificSecureUserId()); } else if (spec.isInvalidatedByBiometricEnrollment()) { // The fingerprint-only SID will change on fingerprint enrollment or removal of all, // enrolled fingerprints, invalidating the key. sid = fingerprintOnlySid; // The biometric-only SIDs will change on biometric enrollment or removal of all // enrolled templates, invalidating the key. sids.add(fingerprintOnlySid); sids.add(faceOnlySid); } else { // The root SID will *not* change on fingerprint enrollment, or removal of all // enrolled fingerprints, allowing the key to remain valid. sid = getRootSid(); sids.add(getRootSid()); } for (int i = 0; i < sids.size(); i++) { args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sids.get(i))); } args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_BIOMETRIC); args.addUnsignedLong( KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid)); args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT); if (spec.isUserAuthenticationValidWhileOnBody()) { throw new ProviderException("Key validity extension while device is on-body is not " + "supported for keys requiring fingerprint authentication"); Loading @@ -166,7 +177,7 @@ public abstract class KeymasterUtils { args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid)); args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT); KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_BIOMETRIC); args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, spec.getUserAuthenticationValidityDurationSeconds()); if (spec.isUserAuthenticationValidWhileOnBody()) { Loading Loading
core/java/android/security/keymaster/KeymasterDefs.java +1 −1 Original line number Diff line number Diff line Loading @@ -154,7 +154,7 @@ public final class KeymasterDefs { // User authenticators. public static final int HW_AUTH_PASSWORD = 1 << 0; public static final int HW_AUTH_FINGERPRINT = 1 << 1; public static final int HW_AUTH_BIOMETRIC = 1 << 1; // Error codes. public static final int KM_ERROR_OK = 0; Loading
keystore/java/android/security/KeyStore.java +25 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.Application; import android.app.KeyguardManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.os.Binder; import android.os.IBinder; Loading Loading @@ -1254,7 +1255,7 @@ public class KeyStore { return new UserNotAuthenticatedException(); } long fingerprintOnlySid = getFingerprintOnlySid(); final long fingerprintOnlySid = getFingerprintOnlySid(); if ((fingerprintOnlySid != 0) && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) { // One of the key's SIDs is the current fingerprint SID -- user can be Loading @@ -1262,6 +1263,14 @@ public class KeyStore { return new UserNotAuthenticatedException(); } final long faceOnlySid = getFaceOnlySid(); if ((faceOnlySid != 0) && (keySids.contains(KeymasterArguments.toUint64(faceOnlySid)))) { // One of the key's SIDs is the current face SID -- user can be // authenticated against that SID. return new UserNotAuthenticatedException(); } // None of the key's SIDs can ever be authenticated return new KeyPermanentlyInvalidatedException(); } Loading @@ -1272,6 +1281,21 @@ public class KeyStore { } } private long getFaceOnlySid() { final PackageManager packageManager = mContext.getPackageManager(); if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) { return 0; } FaceManager faceManager = mContext.getSystemService(FaceManager.class); if (faceManager == null) { return 0; } // TODO: Restore USE_BIOMETRIC or USE_BIOMETRIC_INTERNAL permission check in // FaceManager.getAuthenticatorId once the ID is no longer needed here. return faceManager.getAuthenticatorId(); } private long getFingerprintOnlySid() { final PackageManager packageManager = mContext.getPackageManager(); if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { Loading
keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java +2 −2 Original line number Diff line number Diff line Loading @@ -182,8 +182,8 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED); boolean invalidatedByBiometricEnrollment = false; if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_FINGERPRINT) { if (keymasterSwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC || keymasterHwEnforcedUserAuthenticators == KeymasterDefs.HW_AUTH_BIOMETRIC) { // Fingerprint-only key; will be invalidated if the root SID isn't in the SID list. invalidatedByBiometricEnrollment = keymasterSecureUserIds != null && !keymasterSecureUserIds.isEmpty() Loading
keystore/java/android/security/keystore/KeymasterUtils.java +26 −15 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package android.security.keystore; import android.app.ActivityManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; import android.security.GateKeeper; import android.security.KeyStore; Loading @@ -24,6 +24,8 @@ import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import java.security.ProviderException; import java.util.ArrayList; import java.util.List; /** * @hide Loading Loading @@ -121,35 +123,44 @@ public abstract class KeymasterUtils { if (spec.getUserAuthenticationValidityDurationSeconds() == -1) { // Every use of this key needs to be authorized by the user. This currently means // fingerprint-only auth. // fingerprint or face auth. FingerprintManager fingerprintManager = KeyStore.getApplicationContext().getSystemService(FingerprintManager.class); FaceManager faceManager = KeyStore.getApplicationContext().getSystemService(FaceManager.class); // TODO: Restore USE_FINGERPRINT permission check in // FingerprintManager.getAuthenticatorId once the ID is no longer needed here. long fingerprintOnlySid = final long fingerprintOnlySid = (fingerprintManager != null) ? fingerprintManager.getAuthenticatorId() : 0; if (fingerprintOnlySid == 0) { final long faceOnlySid = (faceManager != null) ? faceManager.getAuthenticatorId() : 0; if (fingerprintOnlySid == 0 && faceOnlySid == 0) { throw new IllegalStateException( "At least one fingerprint must be enrolled to create keys requiring user" "At least one biometric must be enrolled to create keys requiring user" + " authentication for every use"); } long sid; List<Long> sids = new ArrayList<>(); if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) { sid = spec.getBoundToSpecificSecureUserId(); sids.add(spec.getBoundToSpecificSecureUserId()); } else if (spec.isInvalidatedByBiometricEnrollment()) { // The fingerprint-only SID will change on fingerprint enrollment or removal of all, // enrolled fingerprints, invalidating the key. sid = fingerprintOnlySid; // The biometric-only SIDs will change on biometric enrollment or removal of all // enrolled templates, invalidating the key. sids.add(fingerprintOnlySid); sids.add(faceOnlySid); } else { // The root SID will *not* change on fingerprint enrollment, or removal of all // enrolled fingerprints, allowing the key to remain valid. sid = getRootSid(); sids.add(getRootSid()); } for (int i = 0; i < sids.size(); i++) { args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sids.get(i))); } args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_BIOMETRIC); args.addUnsignedLong( KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid)); args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT); if (spec.isUserAuthenticationValidWhileOnBody()) { throw new ProviderException("Key validity extension while device is on-body is not " + "supported for keys requiring fingerprint authentication"); Loading @@ -166,7 +177,7 @@ public abstract class KeymasterUtils { args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid)); args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT); KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_BIOMETRIC); args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, spec.getUserAuthenticationValidityDurationSeconds()); if (spec.isUserAuthenticationValidWhileOnBody()) { Loading