summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason parks <jparks@google.com>2010-11-29 09:05:25 -0600
committerJason parks <jparks@google.com>2011-01-05 12:32:49 -0600
commit5af0b916f850486cff4797355bf9e7dc3352fe00 (patch)
tree596919e498d72eadbc42b3307ac4f81542d34746
parentcf7775a88f8c88fc3a902799fc1d5100f6f7e0d6 (diff)
downloadframeworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.zip
frameworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.tar.gz
frameworks_base-5af0b916f850486cff4797355bf9e7dc3352fe00.tar.bz2
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
-rw-r--r--core/java/android/os/storage/IMountService.java32
-rw-r--r--include/storage/IMountService.h1
-rw-r--r--libs/storage/IMountService.cpp18
-rw-r--r--services/java/com/android/server/MountService.java37
4 files changed, 86 insertions, 2 deletions
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 3a2add4..23ed31f 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -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;
}
diff --git a/include/storage/IMountService.h b/include/storage/IMountService.h
index 51f9aeb..68ccd95 100644
--- a/include/storage/IMountService.h
+++ b/include/storage/IMountService.h
@@ -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;
};
// ----------------------------------------------------------------------------
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index b5f9c47..a7ab824 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -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");
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 64cd661..bf81457 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -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);
}