Transparent encrypted virtual disks for Android (we call it IOCipher)


When using phones, laptops, computers, etc. it feels like a private experience, as if our screen was the same as a piece of paper, and when that paper is gone, then no one can see it anymore. Digital media works very differently. While the user interface portrays the deletion of files as very final, for someone with the right tools, it is actually not hard to recover deleted files. Also, digital information takes up so little space, we now regularly carry vast amounts of information in our pockets. Our phones have become amazingly powerful computers, storing as many photos, videos, documents, etc. in our pockets as would have required a room not so long ago. So when you lose this phone, or it gets stolen, or accessed against your wishes, the lies of the interface are laid bare, and vast troves of your information is now in someone else’s hands. So how can we capitalize on all this power without giving up control of our information?

Encryption provides the building blocks for making the experience no longer a lie. With properly encrypted data, it is possible to throw away the key and delete it, and then no one can get the data ever again. The problem now is how best to use encryption to make our private information actually private with as few complicated decisions or onerous interfaces as possible. Full disk encryption is one popular choice. It does a good job of providing a transparent experience, merely type in a password when you boot up your computer, and the rest is totally normal. But it also offers limited protection. When your full disk encryption is unlocked and your computer is running, that disk behaves no differently than an unencrypted disk. Someone with access to the computer has full access to the files, malware does too, undelete tools will still work, etc. You have to power off the computer to get the protection that full disk encryption provides.

Another option is providing virtual encrypted disks like TrueCrypt or Apple’s encrypted disk images. Then you can decide on what needs to be in which compartment and what is always unlocked versus what is locked away behind a long, cryptic password with a short timeout. This provides good security and privacy when managed properly, but requires a fair amount of skill and time to setup and manage everything. These techniques also require root access since they mount these virtual disks as file systems. We focus a lot on Android, where most people do not have root access.

A related approach is to have a software layer automatically encrypt each file. This is how the EncFS FUSE module and the Certgate MAPL file access work. This provides transparent encryption, but since each file is individually encrypted, a lot of information is still available without decrypting anything: the file size, modification and access times, etc.

We’re working on another approach similar to the approach we took with SQLCipher for Android. We’re calling it IOCipher. In SQLCipher for Android, we took the code from Android’s core android.database.* classes used for working with the built-in SQLite and replaced the guts with the SQLCipher encrypted database. This allows Android app developers to use the familiar and well documented android.database.* API to build in encrypted storage into their apps. With IOCipher, we are again using SQLCipher as the core, but this time we are wrapping it with libsqlfs to make it behave like a filesystem, then grabbing the code to Android’s java.io.* API and replacing the guts with calls to libsqlfs on top of SQLCipher. libsqlfs is also a FUSE(Filesystem in Userspace) module, so it provides an API very similar to the POSIX API for working with files and directories. So that makes it easy to take java.io.File, for example, and replace all the calls to read(), open(), write(), stat(), etc. with calls to sqlfs_proc_read(), sqlfs_proc_open(), sqlfs_proc_write(), sqlfs_proc_stat(), etc. Then all the Android developer needs to do is to java their import java.io.* to import info.guardianproject.iocipher.*, specify the database file to use, and the key to lock/unlock it, and the rest is normal Java programming.

The beauty of using libsqlfs+SQLCipher is that its built of top of SQLite, which gives us a single, very portable file that is the whole filesystem, like a Mac OS X .dmg file or TrueCrypt .tc file. SQLite also allows multiple processes to access the same database file, so that means multiple apps can mount an IOCipher virtual disk, and can use Android permissions and native filesystem permissions to control access to the virtual filesystem. Lastly, libsqlfs is already a FUSE module. FUSE is already nicely integrated into most GNU/Linux distributions, and also available for Mac OS X and BSD. That means that the single file that represents a IOCipher file system could also be easily mounted on GNU/Linux, Mac OS X and BSD (we are already doing this on Debian and Ubuntu, Mac OS X will require some more work).

All in all we think this approach will make filesystem encryption easier to include in Android apps, and also make it possible to have the encryption be trivial to setup and very transparent to the user. Its close to being usable, once it is, we’ll post instructions on how you can use it in your apps. For now, you can follow our progress here:

https://github.com/guardianproject/libsqlfs
https://github.com/guardianproject/IOCipher
https://guardianproject.info/wiki/Products_of_PSST_Work