Thursday, March 3, 2011

Device Encryption in Android 3.0

Transparent encryption of block devices in Android 3.0


The Motorola Xoom and a number of new tablets on the market run Android 3.0, Honeycomb. Android 3.0 is built on the 2.6.36 Linux kernel. Most, if not all, of the Android tablets that are coming to market feature an Invidia Tegra 2 processor. The 2.6.36 Linux kernel on these Android 3.0 Tegra 2 tablets introduces transparent, whole disk encryption to the everyday user. Transparent, whole disk encryption is provided by the dm-crypt device-mapper target in the Linux kernel. This target provides a virtual layer on top of an existing block device and uses the crypto APIs in the Linux kernel for encryption and decryption of the underlying block devices.

Whether you are typing commands via a shell over a serial port or you are using the e-mail application to check your e-mail, reads and writes to the file system are performed in the same manner with no changes to the upper level applications.

After pressing the power button on the back of the Xoom tablet, the tablet boots and the user is presented with the desktop environment; from which he or she may choose to play a game, check e-mail, or read an e-book.By tapping on settings and then Location & security, one can choose to "Encrypt tablet" from this screen. Upon doing so, the encryption process takes about 1.0 hours and the user is presented with a few basic screens.

After the encryption process is finished, the tablet is powered down. Upon rebooting the tablet, the user is prompted to input a pin code which is used to unlock the device. Upon typing the correct pin code, the tablet powers up as normal and the user can proceed with performing his or her standard activities - checking e-mail, reading e-books, etc.

The Linux 2.6.36 kernel supports what is called the device mapper framework. The Device Mapper Framework allows you to map virtual layers on top of block devices for doing things like striping and mirroring. device-mapper also provides a convenient target called dm-crypt. dm-crypt is a device-mapper crypto target. the dm-crypt target provides transparent encryption of block devices.

Before the encryption operation above, here is the output of the mount command which shows the device name and mount point. This is an important partition because it is where the user's data is stored. Consequently, this is the partition that will get encrypted.

/dev/block/platform/sdhci-tegra.3/by-name/userdata on /data type ext4 (rw,nosuid,nodev,noatime,barrier=1,data=ordered)

A few mount options to take note of: noatime, barriers and data=ordered

...And after the encryption operation

/dev/block/dm-0 /data ext4 rw,nosuid,nodev,noatime,barrier=1,data=ordered 0 0
dmsetup will give us more information. As you can see from the below command, a dm-crypto device mapper target called crypt, has been setup in the kernel. The dm-crypt target provides transparent encryption and decryption of data on the block device using the crypto APIs in the Linux kernel.

# dmsetup targets

crypt v1.7.0
striped v1.3.0
linear v1.1.0
error v1.0.1


# dmsetup status

datadev: 0 61326304 crypt


Albeit the details surrounding key storage (see kernel source), supported ciphers (cat /proc/crypto), and hardware acceleration (see kernel source), here are some rudimentary performance tests that I ran before and after encrypting /data. For the interested reader, there are some kernel level details related to the Tegra 2 processor which one can discover by going through the source code for the Linux 2.6.36 Tegra 2 branch.

The initial results of the the basic tests look good. There is a dedicated kernel thread for handling IO. The read latency appears to be related to the kernel IO thread since reads on flash based storage devices can usually be performed in near constant time.


Unencrypted (2 GB Write - 104857 2k blocks)/data/local/tmp

# time dd if=/dev/zero of=ofile bs=2k count=1048572

1048572+0 records in
1048572+0 records out
2147475456 bytes (2.0GB) copied, 255.912521 seconds, 8.0MB/s
real 4m 17.25s
user 0m 0.73s
sys 0m 24.55s


Unencrypted (2 GB Read - 104857 2k blocks)/data/local/tmp 

# time dd of=/dev/null if=ofile bs=2k count=1048572

1048572+0 records in
1048572+0 records out
2147475456 bytes (2.0GB) copied, 101.749864 seconds, 20.1MB/s
real 1m 41.79s
user 0m 1.15s
sys 0m 17.62s


Encrypted (2 GB Write - 104857 2k blocks)/data/local/tmp

# time dd if=/dev/zero of=ofile bs=2k count=1048572

1048572+0 records in
1048572+0 records out
2147475456 bytes (2.0GB) copied, 260.219584 seconds, 7.9MB/s
real 4m 26.94s
user 0m 0.64s
sys 0m 24.12s


Encrypted (2 GB Read - 104857 2k blocks)/data/local/tmp 

# time dd of=/dev/null if=ofile bs=2k count=1048572

1048572+0 records in
1048572+0 records out
2147475456 bytes (2.0GB) copied, 124.291204 seconds, 16.5MB/s
real 2m 4.31s
user 0m 0.47s
sys 0m 7.74s


As a side note: After performing the encryption operation, and subsequently building a Tegra 2 kernel for experimentation, I noticed that when I booted into the bootloader and ran fastboot boot myKernelBootImg, I was prompted with an error message which stated that the "fastboot boot" command is not allowed on consumer devices

In conclusion, the devicer-mapper target, dm-crypt, provides transparent, whole-disk encryption for Android 3.0 based tablet devices. It is something worthy of heavy consideration.

* get the block size for a device blockdev --getbsz /dev/block/dm-0