Loading core/java/android/os/storage/IMountService.java +35 −12 Original line number Diff line number Diff line Loading @@ -1233,8 +1233,8 @@ public interface IMountService extends IInterface { } @Override public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException { public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { Loading @@ -1242,9 +1242,23 @@ public interface IMountService extends IInterface { _data.writeInt(userId); _data.writeInt(serialNumber); _data.writeByteArray(token); _data.writeByteArray(oldSecret); _data.writeByteArray(newSecret); mRemote.transact(Stub.TRANSACTION_changeUserKey, _data, _reply, 0); _data.writeByteArray(secret); mRemote.transact(Stub.TRANSACTION_addUserKeyAuth, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void fixateNewestUserKeyAuth(int userId) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_fixateNewestUserKeyAuth, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); Loading Loading @@ -1489,7 +1503,9 @@ public interface IMountService extends IInterface { static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69; static final int TRANSACTION_changeUserKey = IBinder.FIRST_CALL_TRANSACTION + 70; static final int TRANSACTION_addUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 70; static final int TRANSACTION_fixateNewestUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 71; /** * Cast an IBinder object into an IMountService interface, generating a Loading Loading @@ -2069,14 +2085,20 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } case TRANSACTION_changeUserKey: { case TRANSACTION_addUserKeyAuth: { data.enforceInterface(DESCRIPTOR); int userId = data.readInt(); int serialNumber = data.readInt(); byte[] token = data.createByteArray(); byte[] oldSecret = data.createByteArray(); byte[] newSecret = data.createByteArray(); changeUserKey(userId, serialNumber, token, oldSecret, newSecret); byte[] secret = data.createByteArray(); addUserKeyAuth(userId, serialNumber, token, secret); reply.writeNoException(); return true; } case TRANSACTION_fixateNewestUserKeyAuth: { data.enforceInterface(DESCRIPTOR); int userId = data.readInt(); fixateNewestUserKeyAuth(userId); reply.writeNoException(); return true; } Loading Loading @@ -2452,8 +2474,9 @@ public interface IMountService extends IInterface { public void createUserKey(int userId, int serialNumber, boolean ephemeral) throws RemoteException; public void destroyUserKey(int userId) throws RemoteException; public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException; public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException; public void fixateNewestUserKeyAuth(int userId) throws RemoteException; public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException; Loading services/core/java/com/android/server/LockSettingsService.java +35 −10 Original line number Diff line number Diff line Loading @@ -790,10 +790,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (isSecure) { tieManagedProfileLockIfNecessary(managedUserId, null); } else { clearUserKeyProtection(managedUserId); getGateKeeperService().clearSecureUserId(managedUserId); mStorage.writePatternHash(null, managedUserId); setKeystorePassword(null, managedUserId); clearUserKeyProtection(managedUserId); fixateNewestUserKeyAuth(managedUserId); mStorage.removeChildProfileLock(managedUserId); removeKeystoreProfileKey(managedUserId); } Loading Loading @@ -828,10 +829,11 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] currentHandle = getCurrentHandle(userId); if (pattern == null) { clearUserKeyProtection(userId); getGateKeeperService().clearSecureUserId(userId); mStorage.writePatternHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); return; } Loading Loading @@ -861,8 +863,12 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, pattern, userId); if (enrolledHandle != null) { CredentialHash willStore = new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER); setUserKeyProtection(userId, pattern, doVerifyPattern(pattern, willStore, true, 0, userId)); mStorage.writePatternHash(enrolledHandle, userId); setUserKeyProtection(userId, pattern, verifyPattern(pattern, 0, userId)); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll pattern"); Loading @@ -885,10 +891,11 @@ public class LockSettingsService extends ILockSettings.Stub { throws RemoteException { byte[] currentHandle = getCurrentHandle(userId); if (password == null) { clearUserKeyProtection(userId); getGateKeeperService().clearSecureUserId(userId); mStorage.writePasswordHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); return; } Loading Loading @@ -916,8 +923,12 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, password, userId); if (enrolledHandle != null) { CredentialHash willStore = new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER); setUserKeyProtection(userId, password, doVerifyPassword(password, willStore, true, 0, userId)); mStorage.writePasswordHash(enrolledHandle, userId); setUserKeyProtection(userId, password, verifyPassword(password, 0, userId)); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll password"); Loading Loading @@ -1022,11 +1033,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (token == null) { throw new RemoteException("Empty payload verifying a credential we just set"); } changeUserKey(userId, token, secretFromCredential(credential)); addUserKeyAuth(userId, token, secretFromCredential(credential)); } private void clearUserKeyProtection(int userId) throws RemoteException { changeUserKey(userId, null, null); addUserKeyAuth(userId, null, null); } private static byte[] secretFromCredential(String credential) throws RemoteException { Loading @@ -1045,18 +1056,23 @@ public class LockSettingsService extends ILockSettings.Stub { } } private void changeUserKey(int userId, byte[] token, byte[] secret) private void addUserKeyAuth(int userId, byte[] token, byte[] secret) throws RemoteException { final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId); final IMountService mountService = getMountService(); final long callingId = Binder.clearCallingIdentity(); try { mountService.changeUserKey(userId, userInfo.serialNumber, token, null, secret); mountService.addUserKeyAuth(userId, userInfo.serialNumber, token, secret); } finally { Binder.restoreCallingIdentity(callingId); } } private void fixateNewestUserKeyAuth(int userId) throws RemoteException { getMountService().fixateNewestUserKeyAuth(userId); } @Override public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException { return doVerifyPattern(pattern, false, 0, userId); Loading @@ -1072,6 +1088,11 @@ public class LockSettingsService extends ILockSettings.Stub { long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); CredentialHash storedHash = mStorage.readPatternHash(userId); return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId); } private VerifyCredentialResponse doVerifyPattern(String pattern, CredentialHash storedHash, boolean hasChallenge, long challenge, int userId) throws RemoteException { boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern; String patternToVerify; Loading Loading @@ -1109,7 +1130,6 @@ public class LockSettingsService extends ILockSettings.Stub { } return response; } @Override Loading Loading @@ -1159,6 +1179,11 @@ public class LockSettingsService extends ILockSettings.Stub { long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); CredentialHash storedHash = mStorage.readPasswordHash(userId); return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId); } private VerifyCredentialResponse doVerifyPassword(String password, CredentialHash storedHash, boolean hasChallenge, long challenge, int userId) throws RemoteException { return verifyCredential(userId, storedHash, password, hasChallenge, challenge, new CredentialUtil() { @Override Loading services/core/java/com/android/server/LockSettingsStorage.java +1 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ class LockSettingsStorage { private SparseArray<Integer> mStoredCredentialType; class CredentialHash { static class CredentialHash { static final int TYPE_NONE = -1; static final int TYPE_PATTERN = 1; static final int TYPE_PASSWORD = 2; Loading services/core/java/com/android/server/MountService.java +25 −4 Original line number Diff line number Diff line Loading @@ -2816,15 +2816,36 @@ class MountService extends IMountService.Stub } } /* * Add this token/secret pair to the set of ways we can recover a disk encryption key. * Changing the token/secret for a disk encryption key is done in two phases: first, adding * a new token/secret pair with this call, then delting all other pairs with * fixateNewestUserKeyAuth. This allows other places where a credential is used, such as * Gatekeeper, to be updated between the two calls. */ @Override public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) { enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); waitForReady(); try { mCryptConnector.execute("cryptfs", "add_user_key_auth", userId, serialNumber, encodeBytes(token), encodeBytes(secret)); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } /* * Delete all disk encryption token/secret pairs except the most recently added one */ @Override public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) { public void fixateNewestUserKeyAuth(int userId) { enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); waitForReady(); try { mCryptConnector.execute("cryptfs", "change_user_key", userId, serialNumber, encodeBytes(token), encodeBytes(oldSecret), encodeBytes(newSecret)); mCryptConnector.execute("cryptfs", "fixate_newest_user_key_auth", userId); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } Loading Loading
core/java/android/os/storage/IMountService.java +35 −12 Original line number Diff line number Diff line Loading @@ -1233,8 +1233,8 @@ public interface IMountService extends IInterface { } @Override public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException { public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { Loading @@ -1242,9 +1242,23 @@ public interface IMountService extends IInterface { _data.writeInt(userId); _data.writeInt(serialNumber); _data.writeByteArray(token); _data.writeByteArray(oldSecret); _data.writeByteArray(newSecret); mRemote.transact(Stub.TRANSACTION_changeUserKey, _data, _reply, 0); _data.writeByteArray(secret); mRemote.transact(Stub.TRANSACTION_addUserKeyAuth, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } @Override public void fixateNewestUserKeyAuth(int userId) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_fixateNewestUserKeyAuth, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); Loading Loading @@ -1489,7 +1503,9 @@ public interface IMountService extends IInterface { static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69; static final int TRANSACTION_changeUserKey = IBinder.FIRST_CALL_TRANSACTION + 70; static final int TRANSACTION_addUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 70; static final int TRANSACTION_fixateNewestUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 71; /** * Cast an IBinder object into an IMountService interface, generating a Loading Loading @@ -2069,14 +2085,20 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } case TRANSACTION_changeUserKey: { case TRANSACTION_addUserKeyAuth: { data.enforceInterface(DESCRIPTOR); int userId = data.readInt(); int serialNumber = data.readInt(); byte[] token = data.createByteArray(); byte[] oldSecret = data.createByteArray(); byte[] newSecret = data.createByteArray(); changeUserKey(userId, serialNumber, token, oldSecret, newSecret); byte[] secret = data.createByteArray(); addUserKeyAuth(userId, serialNumber, token, secret); reply.writeNoException(); return true; } case TRANSACTION_fixateNewestUserKeyAuth: { data.enforceInterface(DESCRIPTOR); int userId = data.readInt(); fixateNewestUserKeyAuth(userId); reply.writeNoException(); return true; } Loading Loading @@ -2452,8 +2474,9 @@ public interface IMountService extends IInterface { public void createUserKey(int userId, int serialNumber, boolean ephemeral) throws RemoteException; public void destroyUserKey(int userId) throws RemoteException; public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException; public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException; public void fixateNewestUserKeyAuth(int userId) throws RemoteException; public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) throws RemoteException; Loading
services/core/java/com/android/server/LockSettingsService.java +35 −10 Original line number Diff line number Diff line Loading @@ -790,10 +790,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (isSecure) { tieManagedProfileLockIfNecessary(managedUserId, null); } else { clearUserKeyProtection(managedUserId); getGateKeeperService().clearSecureUserId(managedUserId); mStorage.writePatternHash(null, managedUserId); setKeystorePassword(null, managedUserId); clearUserKeyProtection(managedUserId); fixateNewestUserKeyAuth(managedUserId); mStorage.removeChildProfileLock(managedUserId); removeKeystoreProfileKey(managedUserId); } Loading Loading @@ -828,10 +829,11 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] currentHandle = getCurrentHandle(userId); if (pattern == null) { clearUserKeyProtection(userId); getGateKeeperService().clearSecureUserId(userId); mStorage.writePatternHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); return; } Loading Loading @@ -861,8 +863,12 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, pattern, userId); if (enrolledHandle != null) { CredentialHash willStore = new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER); setUserKeyProtection(userId, pattern, doVerifyPattern(pattern, willStore, true, 0, userId)); mStorage.writePatternHash(enrolledHandle, userId); setUserKeyProtection(userId, pattern, verifyPattern(pattern, 0, userId)); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll pattern"); Loading @@ -885,10 +891,11 @@ public class LockSettingsService extends ILockSettings.Stub { throws RemoteException { byte[] currentHandle = getCurrentHandle(userId); if (password == null) { clearUserKeyProtection(userId); getGateKeeperService().clearSecureUserId(userId); mStorage.writePasswordHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); return; } Loading Loading @@ -916,8 +923,12 @@ public class LockSettingsService extends ILockSettings.Stub { byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, password, userId); if (enrolledHandle != null) { CredentialHash willStore = new CredentialHash(enrolledHandle, CredentialHash.VERSION_GATEKEEPER); setUserKeyProtection(userId, password, doVerifyPassword(password, willStore, true, 0, userId)); mStorage.writePasswordHash(enrolledHandle, userId); setUserKeyProtection(userId, password, verifyPassword(password, 0, userId)); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll password"); Loading Loading @@ -1022,11 +1033,11 @@ public class LockSettingsService extends ILockSettings.Stub { if (token == null) { throw new RemoteException("Empty payload verifying a credential we just set"); } changeUserKey(userId, token, secretFromCredential(credential)); addUserKeyAuth(userId, token, secretFromCredential(credential)); } private void clearUserKeyProtection(int userId) throws RemoteException { changeUserKey(userId, null, null); addUserKeyAuth(userId, null, null); } private static byte[] secretFromCredential(String credential) throws RemoteException { Loading @@ -1045,18 +1056,23 @@ public class LockSettingsService extends ILockSettings.Stub { } } private void changeUserKey(int userId, byte[] token, byte[] secret) private void addUserKeyAuth(int userId, byte[] token, byte[] secret) throws RemoteException { final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId); final IMountService mountService = getMountService(); final long callingId = Binder.clearCallingIdentity(); try { mountService.changeUserKey(userId, userInfo.serialNumber, token, null, secret); mountService.addUserKeyAuth(userId, userInfo.serialNumber, token, secret); } finally { Binder.restoreCallingIdentity(callingId); } } private void fixateNewestUserKeyAuth(int userId) throws RemoteException { getMountService().fixateNewestUserKeyAuth(userId); } @Override public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException { return doVerifyPattern(pattern, false, 0, userId); Loading @@ -1072,6 +1088,11 @@ public class LockSettingsService extends ILockSettings.Stub { long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); CredentialHash storedHash = mStorage.readPatternHash(userId); return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId); } private VerifyCredentialResponse doVerifyPattern(String pattern, CredentialHash storedHash, boolean hasChallenge, long challenge, int userId) throws RemoteException { boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern; String patternToVerify; Loading Loading @@ -1109,7 +1130,6 @@ public class LockSettingsService extends ILockSettings.Stub { } return response; } @Override Loading Loading @@ -1159,6 +1179,11 @@ public class LockSettingsService extends ILockSettings.Stub { long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); CredentialHash storedHash = mStorage.readPasswordHash(userId); return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId); } private VerifyCredentialResponse doVerifyPassword(String password, CredentialHash storedHash, boolean hasChallenge, long challenge, int userId) throws RemoteException { return verifyCredential(userId, storedHash, password, hasChallenge, challenge, new CredentialUtil() { @Override Loading
services/core/java/com/android/server/LockSettingsStorage.java +1 −1 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ class LockSettingsStorage { private SparseArray<Integer> mStoredCredentialType; class CredentialHash { static class CredentialHash { static final int TYPE_NONE = -1; static final int TYPE_PATTERN = 1; static final int TYPE_PASSWORD = 2; Loading
services/core/java/com/android/server/MountService.java +25 −4 Original line number Diff line number Diff line Loading @@ -2816,15 +2816,36 @@ class MountService extends IMountService.Stub } } /* * Add this token/secret pair to the set of ways we can recover a disk encryption key. * Changing the token/secret for a disk encryption key is done in two phases: first, adding * a new token/secret pair with this call, then delting all other pairs with * fixateNewestUserKeyAuth. This allows other places where a credential is used, such as * Gatekeeper, to be updated between the two calls. */ @Override public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) { enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); waitForReady(); try { mCryptConnector.execute("cryptfs", "add_user_key_auth", userId, serialNumber, encodeBytes(token), encodeBytes(secret)); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } /* * Delete all disk encryption token/secret pairs except the most recently added one */ @Override public void changeUserKey(int userId, int serialNumber, byte[] token, byte[] oldSecret, byte[] newSecret) { public void fixateNewestUserKeyAuth(int userId) { enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); waitForReady(); try { mCryptConnector.execute("cryptfs", "change_user_key", userId, serialNumber, encodeBytes(token), encodeBytes(oldSecret), encodeBytes(newSecret)); mCryptConnector.execute("cryptfs", "fixate_newest_user_key_auth", userId); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } Loading