Loading core/java/android/os/storage/IMountService.java +37 −3 Original line number Diff line number Diff line Loading @@ -642,12 +642,13 @@ public interface IMountService extends IInterface { return _result; } public int changeEncryptionPassword(String password) throws RemoteException { public int changeEncryptionPassword(int type, String password) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(type); _data.writeString(password); mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0); _reply.readException(); Loading Loading @@ -677,6 +678,22 @@ public interface IMountService extends IInterface { return _result; } public int getPasswordType() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } public StorageVolume[] getVolumeList() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); Loading Loading @@ -829,6 +846,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34; static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 36; /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. Loading Loading @@ -1130,8 +1149,9 @@ public interface IMountService extends IInterface { } case TRANSACTION_changeEncryptionPassword: { data.enforceInterface(DESCRIPTOR); int type = data.readInt(); String password = data.readString(); int result = changeEncryptionPassword(password); int result = changeEncryptionPassword(type, password); reply.writeNoException(); reply.writeInt(result); return true; Loading Loading @@ -1181,6 +1201,13 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } case TRANSACTION_getPasswordType: { data.enforceInterface(DESCRIPTOR); int result = getPasswordType(); reply.writeNoException(); reply.writeInt(result); return true; } } return super.onTransact(code, data, reply, flags); } Loading Loading @@ -1375,7 +1402,8 @@ public interface IMountService extends IInterface { /** * Changes the encryption password. */ public int changeEncryptionPassword(String password) throws RemoteException; public int changeEncryptionPassword(int type, String password) throws RemoteException; /** * Verify the encryption password against the stored volume. This method Loading Loading @@ -1412,4 +1440,10 @@ public interface IMountService extends IInterface { * external storage data or OBB directory belonging to calling app. */ public int mkdirs(String callingPkg, String path) throws RemoteException; /** * Determines the type of the encryption password * @return PasswordType */ public int getPasswordType() throws RemoteException; } core/java/android/os/storage/StorageManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -645,4 +645,14 @@ public class StorageManager { return Settings.Global.getLong(mResolver, Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES, DEFAULT_FULL_THRESHOLD_BYTES); } /// Consts to match the password types in cryptfs.h /** @hide */ public static final int CRYPT_TYPE_PASSWORD = 0; /** @hide */ public static final int CRYPT_TYPE_DEFAULT = 1; /** @hide */ public static final int CRYPT_TYPE_PATTERN = 2; /** @hide */ public static final int CRYPT_TYPE_PIN = 3; } core/java/com/android/internal/widget/LockPatternUtils.java +22 −6 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.storage.IMountService; import android.os.storage.StorageManager; import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.view.IWindowManager; import android.view.View; import android.widget.Button; Loading Loading @@ -498,6 +500,13 @@ public class LockPatternUtils { getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId()); DevicePolicyManager dpm = getDevicePolicyManager(); if (pattern != null) { int userHandle = getCurrentOrCallingUserId(); if (userHandle == UserHandle.USER_OWNER) { String stringPattern = patternToString(pattern); updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern); } setBoolean(PATTERN_EVER_CHOSEN_KEY, true); if (!isFallback) { deleteGallery(); Loading Loading @@ -565,7 +574,7 @@ public class LockPatternUtils { } /** Update the encryption password if it is enabled **/ private void updateEncryptionPassword(String password) { private void updateEncryptionPassword(int type, String password) { DevicePolicyManager dpm = getDevicePolicyManager(); if (dpm.getStorageEncryptionStatus(getCurrentOrCallingUserId()) != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) { Loading @@ -580,7 +589,7 @@ public class LockPatternUtils { IMountService mountService = IMountService.Stub.asInterface(service); try { mountService.changeEncryptionPassword(password); mountService.changeEncryptionPassword(type, password); } catch (RemoteException e) { Log.e(TAG, "Error changing encryption password", e); } Loading Loading @@ -623,12 +632,15 @@ public class LockPatternUtils { getLockSettings().setLockPassword(password, userHandle); DevicePolicyManager dpm = getDevicePolicyManager(); if (password != null) { int computedQuality = computePasswordQuality(password); if (userHandle == UserHandle.USER_OWNER) { // Update the encryption password. updateEncryptionPassword(password); int type = computedQuality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC ? StorageManager.CRYPT_TYPE_PIN : StorageManager.CRYPT_TYPE_PASSWORD; updateEncryptionPassword(type, password); } int computedQuality = computePasswordQuality(password); if (!isFallback) { deleteGallery(); setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); Loading Loading @@ -675,8 +687,7 @@ public class LockPatternUtils { 0, 0, 0, 0, 0, 0, 0, userHandle); } // Add the password to the password history. We assume all // password // hashes have the same length for simplicity of implementation. // password hashes have the same length for simplicity of implementation. String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); if (passwordHistory == null) { passwordHistory = new String(); Loading @@ -695,6 +706,11 @@ public class LockPatternUtils { } setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle); } else { if (userHandle == UserHandle.USER_OWNER) { // Update the encryption password. updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, password); } dpm.setActivePasswordState( DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle); Loading services/core/java/com/android/server/MountService.java +51 −9 Original line number Diff line number Diff line Loading @@ -73,13 +73,16 @@ import com.android.server.pm.UserManagerService; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import org.apache.commons.codec.binary.Hex; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; Loading Loading @@ -189,6 +192,12 @@ class MountService extends IMountService.Stub public static final int FstrimCompleted = 700; } /** List of crypto types. * These must match CRYPT_TYPE_XXX in cryptfs.h AND their * corresponding commands in CommandListener.cpp */ public static final String[] CRYPTO_TYPES = { "password", "default", "pattern", "pin" }; private Context mContext; private NativeDaemonConnector mConnector; Loading Loading @@ -2036,6 +2045,14 @@ class MountService extends IMountService.Stub } } private String toHex(String password) { if (password == null) { return null; } byte[] bytes = password.getBytes(StandardCharsets.UTF_8); return new String(Hex.encodeHex(bytes)); } @Override public int decryptStorage(String password) { if (TextUtils.isEmpty(password)) { Loading @@ -2053,7 +2070,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(toHex(password))); final int code = Integer.parseInt(event.getMessage()); if (code == 0) { Loading Loading @@ -2092,7 +2109,8 @@ class MountService extends IMountService.Stub } try { mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password)); mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(toHex(password))); } catch (NativeDaemonConnectorException e) { // Encryption failed return e.getCode(); Loading @@ -2101,11 +2119,11 @@ class MountService extends IMountService.Stub return 0; } public int changeEncryptionPassword(String password) { if (TextUtils.isEmpty(password)) { throw new IllegalArgumentException("password cannot be empty"); } /** Set the password for encrypting the master key. * @param type One of the CRYPTO_TYPE_XXX consts defined in StorageManager. * @param password The password to set. */ public int changeEncryptionPassword(int type, String password) { mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER, "no permission to access the crypt keeper"); Loading @@ -2117,7 +2135,8 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type], new SensitiveArg(toHex(password))); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { // Encryption failed Loading Loading @@ -2150,7 +2169,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(toHex(password))); Slog.i(TAG, "cryptfs verifypw => " + event.getMessage()); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { Loading @@ -2159,6 +2178,29 @@ class MountService extends IMountService.Stub } } /** * Get the type of encryption used to encrypt the master key. * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager. */ @Override public int getPasswordType() throws RemoteException { waitForReady(); final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "getpwtype"); for (int i = 0; i < CRYPTO_TYPES.length; ++i) { if (CRYPTO_TYPES[i].equals(event.getMessage())) return i; } throw new IllegalStateException("unexpected return from cryptfs"); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } @Override public int mkdirs(String callingPkg, String appPath) { final int userId = UserHandle.getUserId(Binder.getCallingUid()); Loading Loading
core/java/android/os/storage/IMountService.java +37 −3 Original line number Diff line number Diff line Loading @@ -642,12 +642,13 @@ public interface IMountService extends IInterface { return _result; } public int changeEncryptionPassword(String password) throws RemoteException { public int changeEncryptionPassword(int type, String password) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(type); _data.writeString(password); mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0); _reply.readException(); Loading Loading @@ -677,6 +678,22 @@ public interface IMountService extends IInterface { return _result; } public int getPasswordType() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } public StorageVolume[] getVolumeList() throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); Loading Loading @@ -829,6 +846,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34; static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 36; /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. Loading Loading @@ -1130,8 +1149,9 @@ public interface IMountService extends IInterface { } case TRANSACTION_changeEncryptionPassword: { data.enforceInterface(DESCRIPTOR); int type = data.readInt(); String password = data.readString(); int result = changeEncryptionPassword(password); int result = changeEncryptionPassword(type, password); reply.writeNoException(); reply.writeInt(result); return true; Loading Loading @@ -1181,6 +1201,13 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } case TRANSACTION_getPasswordType: { data.enforceInterface(DESCRIPTOR); int result = getPasswordType(); reply.writeNoException(); reply.writeInt(result); return true; } } return super.onTransact(code, data, reply, flags); } Loading Loading @@ -1375,7 +1402,8 @@ public interface IMountService extends IInterface { /** * Changes the encryption password. */ public int changeEncryptionPassword(String password) throws RemoteException; public int changeEncryptionPassword(int type, String password) throws RemoteException; /** * Verify the encryption password against the stored volume. This method Loading Loading @@ -1412,4 +1440,10 @@ public interface IMountService extends IInterface { * external storage data or OBB directory belonging to calling app. */ public int mkdirs(String callingPkg, String path) throws RemoteException; /** * Determines the type of the encryption password * @return PasswordType */ public int getPasswordType() throws RemoteException; }
core/java/android/os/storage/StorageManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -645,4 +645,14 @@ public class StorageManager { return Settings.Global.getLong(mResolver, Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES, DEFAULT_FULL_THRESHOLD_BYTES); } /// Consts to match the password types in cryptfs.h /** @hide */ public static final int CRYPT_TYPE_PASSWORD = 0; /** @hide */ public static final int CRYPT_TYPE_DEFAULT = 1; /** @hide */ public static final int CRYPT_TYPE_PATTERN = 2; /** @hide */ public static final int CRYPT_TYPE_PIN = 3; }
core/java/com/android/internal/widget/LockPatternUtils.java +22 −6 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.storage.IMountService; import android.os.storage.StorageManager; import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import android.view.IWindowManager; import android.view.View; import android.widget.Button; Loading Loading @@ -498,6 +500,13 @@ public class LockPatternUtils { getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId()); DevicePolicyManager dpm = getDevicePolicyManager(); if (pattern != null) { int userHandle = getCurrentOrCallingUserId(); if (userHandle == UserHandle.USER_OWNER) { String stringPattern = patternToString(pattern); updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern); } setBoolean(PATTERN_EVER_CHOSEN_KEY, true); if (!isFallback) { deleteGallery(); Loading Loading @@ -565,7 +574,7 @@ public class LockPatternUtils { } /** Update the encryption password if it is enabled **/ private void updateEncryptionPassword(String password) { private void updateEncryptionPassword(int type, String password) { DevicePolicyManager dpm = getDevicePolicyManager(); if (dpm.getStorageEncryptionStatus(getCurrentOrCallingUserId()) != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) { Loading @@ -580,7 +589,7 @@ public class LockPatternUtils { IMountService mountService = IMountService.Stub.asInterface(service); try { mountService.changeEncryptionPassword(password); mountService.changeEncryptionPassword(type, password); } catch (RemoteException e) { Log.e(TAG, "Error changing encryption password", e); } Loading Loading @@ -623,12 +632,15 @@ public class LockPatternUtils { getLockSettings().setLockPassword(password, userHandle); DevicePolicyManager dpm = getDevicePolicyManager(); if (password != null) { int computedQuality = computePasswordQuality(password); if (userHandle == UserHandle.USER_OWNER) { // Update the encryption password. updateEncryptionPassword(password); int type = computedQuality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC ? StorageManager.CRYPT_TYPE_PIN : StorageManager.CRYPT_TYPE_PASSWORD; updateEncryptionPassword(type, password); } int computedQuality = computePasswordQuality(password); if (!isFallback) { deleteGallery(); setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); Loading Loading @@ -675,8 +687,7 @@ public class LockPatternUtils { 0, 0, 0, 0, 0, 0, 0, userHandle); } // Add the password to the password history. We assume all // password // hashes have the same length for simplicity of implementation. // password hashes have the same length for simplicity of implementation. String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); if (passwordHistory == null) { passwordHistory = new String(); Loading @@ -695,6 +706,11 @@ public class LockPatternUtils { } setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle); } else { if (userHandle == UserHandle.USER_OWNER) { // Update the encryption password. updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, password); } dpm.setActivePasswordState( DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle); Loading
services/core/java/com/android/server/MountService.java +51 −9 Original line number Diff line number Diff line Loading @@ -73,13 +73,16 @@ import com.android.server.pm.UserManagerService; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import org.apache.commons.codec.binary.Hex; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; Loading Loading @@ -189,6 +192,12 @@ class MountService extends IMountService.Stub public static final int FstrimCompleted = 700; } /** List of crypto types. * These must match CRYPT_TYPE_XXX in cryptfs.h AND their * corresponding commands in CommandListener.cpp */ public static final String[] CRYPTO_TYPES = { "password", "default", "pattern", "pin" }; private Context mContext; private NativeDaemonConnector mConnector; Loading Loading @@ -2036,6 +2045,14 @@ class MountService extends IMountService.Stub } } private String toHex(String password) { if (password == null) { return null; } byte[] bytes = password.getBytes(StandardCharsets.UTF_8); return new String(Hex.encodeHex(bytes)); } @Override public int decryptStorage(String password) { if (TextUtils.isEmpty(password)) { Loading @@ -2053,7 +2070,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(toHex(password))); final int code = Integer.parseInt(event.getMessage()); if (code == 0) { Loading Loading @@ -2092,7 +2109,8 @@ class MountService extends IMountService.Stub } try { mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password)); mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(toHex(password))); } catch (NativeDaemonConnectorException e) { // Encryption failed return e.getCode(); Loading @@ -2101,11 +2119,11 @@ class MountService extends IMountService.Stub return 0; } public int changeEncryptionPassword(String password) { if (TextUtils.isEmpty(password)) { throw new IllegalArgumentException("password cannot be empty"); } /** Set the password for encrypting the master key. * @param type One of the CRYPTO_TYPE_XXX consts defined in StorageManager. * @param password The password to set. */ public int changeEncryptionPassword(int type, String password) { mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER, "no permission to access the crypt keeper"); Loading @@ -2117,7 +2135,8 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type], new SensitiveArg(toHex(password))); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { // Encryption failed Loading Loading @@ -2150,7 +2169,7 @@ class MountService extends IMountService.Stub final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password)); event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(toHex(password))); Slog.i(TAG, "cryptfs verifypw => " + event.getMessage()); return Integer.parseInt(event.getMessage()); } catch (NativeDaemonConnectorException e) { Loading @@ -2159,6 +2178,29 @@ class MountService extends IMountService.Stub } } /** * Get the type of encryption used to encrypt the master key. * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager. */ @Override public int getPasswordType() throws RemoteException { waitForReady(); final NativeDaemonEvent event; try { event = mConnector.execute("cryptfs", "getpwtype"); for (int i = 0; i < CRYPTO_TYPES.length; ++i) { if (CRYPTO_TYPES[i].equals(event.getMessage())) return i; } throw new IllegalStateException("unexpected return from cryptfs"); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } @Override public int mkdirs(String callingPkg, String appPath) { final int userId = UserHandle.getUserId(Binder.getCallingUid()); Loading