Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit faeb3eb0 authored by Paul Crowley's avatar Paul Crowley
Browse files

Password security for FBE disk encryption keys

Add the means to protect FBE keys with a combination of an auth token
from Gatekeeper, and a hash of the password. Both of these must be
passed to unlock_user_key. Keys are created unprotected, and
change_user_key changes the way they are protected.

Bug: 22950892
Change-Id: Ie13bc6f82059ce941b0e664a5b60355e52b45f30
parent e64f3da7
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -1126,14 +1126,19 @@ public class Am extends BaseCommand {
        }
    }

    private byte[] argToBytes(String arg) {
        if (arg.equals("!")) {
            return null;
        } else {
            return HexDump.hexStringToByteArray(arg);
        }
    }

    private void runUnlockUser() throws Exception {
        int userId = Integer.parseInt(nextArgRequired());
        String tokenHex = nextArg();
        byte[] token = null;
        if (tokenHex != null) {
            token = HexDump.hexStringToByteArray(tokenHex);
        }
        boolean success = mAm.unlockUser(userId, token);
        byte[] token = argToBytes(nextArgRequired());
        byte[] secret = argToBytes(nextArgRequired());
        boolean success = mAm.unlockUser(userId, token, secret);
        if (success) {
            System.out.println("Success: user unlocked");
        } else {
+4 −2
Original line number Diff line number Diff line
@@ -2080,7 +2080,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            int userId = data.readInt();
            byte[] token = data.createByteArray();
            boolean result = unlockUser(userId, token);
            byte[] secret = data.createByteArray();
            boolean result = unlockUser(userId, token, secret);
            reply.writeNoException();
            reply.writeInt(result ? 1 : 0);
            return true;
@@ -5571,12 +5572,13 @@ class ActivityManagerProxy implements IActivityManager
        return result;
    }

    public boolean unlockUser(int userId, byte[] token) throws RemoteException {
    public boolean unlockUser(int userId, byte[] token, byte[] secret) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(userId);
        data.writeByteArray(token);
        data.writeByteArray(secret);
        mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
        reply.readException();
        boolean result = reply.readInt() != 0;
+1 −1
Original line number Diff line number Diff line
@@ -426,7 +426,7 @@ public interface IActivityManager extends IInterface {
    // Multi-user APIs
    public boolean switchUser(int userid) throws RemoteException;
    public boolean startUserInBackground(int userid) throws RemoteException;
    public boolean unlockUser(int userid, byte[] token) throws RemoteException;
    public boolean unlockUser(int userid, byte[] token, byte[] secret) throws RemoteException;
    public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
    public UserInfo getCurrentUser() throws RemoteException;
    public boolean isUserRunning(int userid, int flags) throws RemoteException;
+42 −3
Original line number Diff line number Diff line
@@ -1233,7 +1233,8 @@ public interface IMountService extends IInterface {
            }

            @Override
            public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException {
            public void changeUserKey(int userId, int serialNumber,
                    byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                try {
@@ -1241,6 +1242,27 @@ 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);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public void unlockUserKey(int userId, int serialNumber,
                    byte[] token, byte[] secret) throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(userId);
                    _data.writeInt(serialNumber);
                    _data.writeByteArray(token);
                    _data.writeByteArray(secret);
                    mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
                    _reply.readException();
                } finally {
@@ -1448,6 +1470,8 @@ 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;

        /**
         * Cast an IBinder object into an IMountService interface, generating a
         * proxy if needed.
@@ -2026,12 +2050,24 @@ public interface IMountService extends IInterface {
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_changeUserKey: {
                    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);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_unlockUserKey: {
                    data.enforceInterface(DESCRIPTOR);
                    int userId = data.readInt();
                    int serialNumber = data.readInt();
                    byte[] token = data.createByteArray();
                    unlockUserKey(userId, serialNumber, token);
                    byte[] secret = data.createByteArray();
                    unlockUserKey(userId, serialNumber, token, secret);
                    reply.writeNoException();
                    return true;
                }
@@ -2383,8 +2419,11 @@ 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 unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException;
    public void unlockUserKey(int userId, int serialNumber,
            byte[] token, byte[] secret) throws RemoteException;
    public void lockUserKey(int userId) throws RemoteException;
    public boolean isUserKeyUnlocked(int userId) throws RemoteException;

+2 −2
Original line number Diff line number Diff line
@@ -991,9 +991,9 @@ public class StorageManager {
    }

    /** {@hide} */
    public void unlockUserKey(int userId, int serialNumber, byte[] token) {
    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
        try {
            mMountService.unlockUserKey(userId, serialNumber, token);
            mMountService.unlockUserKey(userId, serialNumber, token, secret);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
Loading