Android Data Partition Encryption on i.MX6

Document created by JayTu Employee on Nov 6, 2012Last modified by Jodi Paul on May 9, 2013
Version 4Show Document
  • View in full screen mode

Introduction

 

Disk encryption on Android is based on dm-crypt, which is a kernel feature that works at the block device layer. Therefore, it is not usable with YAFFS, which talks directly to a raw nand flash chip, but does work with emmc and similar flash devices which present themselves to the kernel as a block device. The current preferred filesystem to use on these devices is ext4, though that is independent of whether encryption is used or not. [1]

 

Let's encrypt!

 

I will show the whole process first, and then point out the issue I noticed on i.MX6.

To use this feature, go to settings and security as below:

setting.png

Encrypted phones need to set the numeric PIN, so click Screen lock to set password:

pin.png

Choose PIN:

pin2.png

After setting up PIN code, the Screen lock is showed "Secured with PIN" as below:

pin3.png

We can then click Encrypt phone to start:

encrypt.png

Note the words on this page, it needs start with a charged battery and the charger needs to be on.

Click Encrypt phone button and it will ask PIN code setup before:

encrypt2.png

Enter the PIN code and then has the confirmed page:

encrypt3.png

Click Encrypt phone, it will reset framework and starting to encrypt:

encrypt_now.png

After running 100%:

encryption_done.png

It then reset the device. When it boots, it will ask you enter the PIN to enter system.

Check Setting -> Security again:

encrypted.png

The status showed Encrypted under Encrypt phone.

 

Errors While Doing Encryption on i.MX6

 

In the following, I list the error I met and the way to fix.

  • Orig filesystem overlaps crypto footer region.  Cannot encrypt in place

It needs to make sure the filesystem doesn't extend into the last 16 Kbytes of the partition where the crypto footer is kept. The encryption in place and get_fs_size() in system/vold/cryptfs.c will check it, so needs to re-make data partition.

sudo mke2fs -t ext4 /dev/sde7 1034000 -Ldata

The original size is larger than 103400, so I used this value to reserved 16 Kbytes for crypto footer.

  • device-mapper: table: 254:0: crypt: Error creating IV
  • E/Cryptfs ( 2221): Cannot load dm-crypt mapping table.

The actual encryption used for the filesystem for first release is 128 AES with CBC and ESSIV:SHA256. The master key is encrypted with 128 bit AES via calls to the openssl library.

This is done by enable CONFIG_CRYPTO_SHA256 in kernel.

  • Enable post_fs_data_done

Vold sets the property vold.post_fs_data_done to "0", and then sets vold.decrypt to "trigger_post_fs_dat". This causes init.rc to run the post-fs-data commands in init.rc and init..rc. They will create any necessary directories, links, et al, and then set vold.post_fs_data_done to "1". Vold waits until it sees the "1" in that property. Finally, vold sets the property vold.decrypt to "trigger_restart_framework" which causes init.rc to start services in class main again, and also start services in class late_start for the first time since boot.

This is done by:

diff --git a/imx6/etc/init.rc b/imx6/etc/init.rc

index 17cbd4c..f2823f2 100644

--- a/imx6/etc/init.rc

+++ b/imx6/etc/init.rc

@@ -203,7 +203,7 @@ on post-fs-data

     # must uncomment this line, otherwise encrypted filesystems

     # won't work.

     # Set indication (checked by vold) that we have finished this action

-    #setprop vold.post_fs_data_done 1

+    setprop vold.post_fs_data_done 1

  • Don't unmount data partition when cryptfs_restart

After the steps above, it can finish encryption. But I found Android will crash after encryption and reboot. When data partition is encrypted, Android's init to mount /data will fail. The cryptfs.c here to try unmount will fail since the data partition isn't mounted before.

diff --git a/cryptfs.c b/cryptfs.c

index 052c033..fd05259 100644

--- a/cryptfs.c

+++ b/cryptfs.c

@@ -694,7 +694,7 @@ int cryptfs_restart(void)

     if (! get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) {

         SLOGD("Just got orig mount parms\n");

 

-        if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {

+        //if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {

             /* If that succeeded, then mount the decrypted filesystem */

             mount(crypto_blkdev, DATA_MNT_POINT, fs_type, mnt_flags, fs_options);

 

@@ -710,7 +710,7 @@ int cryptfs_restart(void)

 

             /* Give it a few moments to get started */

             sleep(1);

-        }

+        //}

     }

References:

[1]: Notes on the implementation of encryption in Android 3.0 | Android Open Source

Attachments

    Outcomes