[Nexus One Android Development] joeyhewitt:
Hack to enable encryption

I just got Android's native encryption working on my N1 with this ROM and thought I'd share how, in case it helps someone else. This would need some polishing before it could be incorporated into the ROM, and you'll probably need to be an advanced user. It might be too much work to be worth it, and this solution may be subpar in performance, and may be a bit rough on your flash (rewriting blocks more than the normal setup would.) That said, here's the approximate process:

Compile the kernel with SHA256 hash support. The source is here and the default config is here. The config name to enable is CONFIG_CRYPTO_SHA256.

Apply my patches to the ramdisk init scripts. This should only be necessary for normal boot, not recovery. The function of these patches is to a) set up a loop device/file that is stored on the data partition, b) use a special init command with logic to handle encryption, c) add some directives to communicate with the framework about encryption status.

Flash the new boot image.

Boot into recovery. Wipe /data, mount it, and run something like the following commands:

touch /data/loop
mkfs.ext2 -F /data/loop 204800
dd if=/dev/zero of=/data/keys bs=16384 count=1

This creates an ext2 filesystem in a file on /data, and an empty file to hold encryption keys.

Reboot the phone. If all went well it should come up normally. Now, if you go into Settings -> Security, there should be a new option "Encrypt phone." Select it, and you can set a password, and the phone will reboot several times during the encryption process. If all goes well you will see a progress screen showing the encryption progress. It took about 5 minutes for me. Once that's done, the phone will reboot and ask for the password you chose. Now your data partition is encrypted.

A bit more technical details: the tricky part about doing this on N1 is that the native encryption code is set up expecting a Linux block device. The MTD flash can't be used in that way, so I put a loop device in the yaffs filesystem and use that as the block device. Unfortunately, I think this may have ramifications for the lifetime of the flash (like something similar to write amplification on SSD's). I have done this for at least a few months with Gingerbread and haven't seen any huge issues, though. If my flash wears out, I will probably just move /data to the SD card, which would save me from having to do the loop stuff.

One aspect of this that was a bit disappointing was how slow it takes to boot. Part of the Android framework boots up to accept the passphrase, then unlocks the encrypted file and boots fully, and the whole process seems pretty slow to me. There may be some optimization possible by making sure only the bare minimum is starting up, caches are properly configured, etc. I've never used this feature on a newer phone, to know if it's always that slow.

I am also considering porting my encryption solution for Gingerbread over. The advantage is that it uses WhisperYAFFS, native encryption for YAFFS, so there's probably a bit more speed and safety to the flash. The little framebuffer app (similar to a recovery app) I run during the init script, feels faster than booting up half of Android and then restarting in full.

Anyway, let me know if you have questions, feedback, or there's interest in developing this more fully.