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

Commit 5af0b916 authored by Jason parks's avatar Jason parks
Browse files

Add decryption support to MountService.

* Implement the decryptStorage() method on the Mount Service.
  This method makes the calls into vold to decrypt the encrypted
  volumes and mount them.

Change-Id: I4f6e07a111cf0b36611d590debf9f6579c5ac5f7
parent cf7775a8
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -586,6 +586,23 @@ public interface IMountService extends IInterface {
                }
                return _result;
            }

            public int decryptStorage(String password) throws RemoteException {
                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                int _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(password);
                    mRemote.transact(Stub.TRANSACTION_decryptStorage, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        private static final String DESCRIPTOR = "IMountService";
@@ -642,6 +659,8 @@ public interface IMountService extends IInterface {

        static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25;

        static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26;

        /**
         * Cast an IBinder object into an IMountService interface, generating a
         * proxy if needed.
@@ -923,6 +942,14 @@ public interface IMountService extends IInterface {
                    reply.writeInt(emulated ? 1 : 0);
                    return true;
                }
                case TRANSACTION_decryptStorage: {
                    data.enforceInterface(DESCRIPTOR);
                    String password = data.readString();
                    int result = decryptStorage(password);
                    reply.writeNoException();
                    reply.writeInt(result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }
@@ -1082,4 +1109,9 @@ public interface IMountService extends IInterface {
     * Returns whether or not the external storage is emulated.
     */
    public boolean isExternalStorageEmulated() throws RemoteException;

    /**
     * Decrypts any encrypted volumes.
     */
    public int decryptStorage(String password) throws RemoteException;
}
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ public:
            const sp<IObbActionListener>& token, const int32_t nonce) = 0;
    virtual bool isObbMounted(const String16& filename) = 0;
    virtual bool getMountedObbPath(const String16& filename, String16& path) = 0;
    virtual int32_t decryptStorage(const String16& password) = 0;
};

// ----------------------------------------------------------------------------
+18 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ enum {
    TRANSACTION_isObbMounted,
    TRANSACTION_getMountedObbPath,
    TRANSACTION_isExternalStorageEmulated,
    TRANSACTION_decryptStorage,
};

class BpMountService: public BpInterface<IMountService>
@@ -504,6 +505,23 @@ public:
        path = reply.readString16();
        return true;
    }
    
    int32_t decryptStorage(const String16& password)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
        data.writeString16(password);
        if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
            LOGD("decryptStorage could not contact remote\n");
            return -1;
        }
        int32_t err = reply.readExceptionCode();
        if (err < 0) {
            LOGD("decryptStorage caught exception %d\n", err);
            return err;
        }
        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(MountService, "IMountService");
+35 −2
Original line number Diff line number Diff line
@@ -73,8 +73,8 @@ import javax.crypto.spec.PBEKeySpec;
 * @hide - Applications should use android.os.storage.StorageManager
 * to access the MountService.
 */
class MountService extends IMountService.Stub
        implements INativeDaemonConnectorCallbacks {
class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks {

    private static final boolean LOCAL_LOGD = false;
    private static final boolean DEBUG_UNMOUNT = false;
    private static final boolean DEBUG_EVENTS = false;
@@ -334,6 +334,7 @@ class MountService extends IMountService.Stub
            super(l);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case H_UNMOUNT_PM_UPDATE: {
@@ -427,6 +428,7 @@ class MountService extends IMountService.Stub
    }

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

@@ -442,6 +444,7 @@ class MountService extends IMountService.Stub
                    return;
                }
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            String path = Environment.getExternalStorageDirectory().getPath();
@@ -565,6 +568,7 @@ class MountService extends IMountService.Stub
         * we need to do our work in a new thread.
         */
        new Thread() {
            @Override
            public void run() {
                /**
                 * Determine media state and UMS detection status
@@ -678,6 +682,7 @@ class MountService extends IMountService.Stub

            if (code == VoldResponseCode.VolumeDiskInserted) {
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            int rc;
@@ -1007,6 +1012,7 @@ class MountService extends IMountService.Stub
             * USB mass storage disconnected while enabled
             */
            new Thread() {
                @Override
                public void run() {
                    try {
                        int rc;
@@ -1624,6 +1630,29 @@ class MountService extends IMountService.Stub
            Slog.i(TAG, "Send to OBB handler: " + action.toString());
    }

    public int decryptStorage(String password) {
        if (password == null) {
            throw new IllegalArgumentException("password cannot be null");
        }

        // TODO: Enforce a permission

        waitForReady();

        if (DEBUG_EVENTS) {
            Slog.i(TAG, "decrypting storage...");
        }

        try {
            mConnector.doCommand(String.format("cryptfs checkpw %s", password));
        } catch (NativeDaemonConnectorException e) {
            // Decryption failed
            return e.getCode();
        }

        return 0;
    }

    private void addObbStateLocked(ObbState obbState) throws RemoteException {
        final IBinder binder = obbState.getBinder();
        List<ObbState> obbStates = mObbMounts.get(binder);
@@ -1911,6 +1940,7 @@ class MountService extends IMountService.Stub
            mKey = key;
        }

        @Override
        public void handleExecute() throws IOException, RemoteException {
            waitForReady();
            warnOnNotMounted();
@@ -1991,6 +2021,7 @@ class MountService extends IMountService.Stub
            }
        }

        @Override
        public void handleError() {
            sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
        }
@@ -2020,6 +2051,7 @@ class MountService extends IMountService.Stub
            mForceUnmount = force;
        }

        @Override
        public void handleExecute() throws IOException {
            waitForReady();
            warnOnNotMounted();
@@ -2074,6 +2106,7 @@ class MountService extends IMountService.Stub
            }
        }

        @Override
        public void handleError() {
            sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
        }