Update August 9th: Just skip to the last line of this post where we realize that we could have spared us all of the hassles and resize2fs from within the running android system ☺.
If you try to enable full disk encryption on Cyanogenmod CM12.1 using the normal settings menu (
Security -> Encrypt Phone) it doesn't work, the phone will just soft-reboot and nothing will have happened.
If you "logcat" the debugging log of your phone (using adb logcat) within the huge amount of data, some hint about what might have gone wrong can be found:
➜ ~ grep Cryptfs logcat_encryption.txt
I/Cryptfs ( 199): Check if PFE is activated on Boot
E/Cryptfs ( 199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs ( 199): Error getting crypt footer and key
E/Cryptfs ( 199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs ( 199): Orig filesystem overlaps crypto footer region. Cannot encrypt in place.
E/Cryptfs ( 199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs ( 199): Orig filesystem overlaps crypto footer region. Cannot encrypt in place.
On android, the footer that tells the operating system that an partition is encrypted resides on the end of the filesystem and it needs a little space between the logical end of the filesystem in a partition, and the physical end of the partition to be squeezed in when converting a phone from unencrypted to encrypted.
http://forum.xda-developers.com/nexus-4/help/looking-encryption-footer-t2676700
Running the recovery system (boot while keeping Volume-Up and Home pressed), we can have a look at the partition sizes and filesystem details. We learn that on my S4 mini, the userdata partition (mmcblk0p24) has a size of 5685231 1k blocks, and the /data filesystem claims a size of 1421307 4k blocks.
$ adb shell
~ # cat /proc/partitions
major minor #blocks name
(...)
179 24 5685231 mmcblk0p24
~ # tune2fs -l /dev/block/mmcblk0p24
(...)
Block count: 1421307
(...)
Block size: 4096
As
5685231-1421307*4 = 3, that's only 3 meager 1k blocks at the end of the filesystem, whereas the encryption footer needs a space of at least 16k, the allmighty internet tells me. So, let's build a filesystem that leaves 128kByte of free space on the end as I don't know if Android 5 has enlarged the footer from what the websites I had found claims, or if there's some alignment requirement for it. So I'll be generous.
(5685231-128)/4=1421275.75 so I'll create a ext4 filesystem occupying
1421275 4k blocks:
~ # mke2fs -b4096 -T ext4 /dev/block/platform/msm_sdcc.1/by-name/userdata 142127(note: I made a mistake, ch0pped off the 5!)
mke2fs 1.41.14 (22-Dec-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
35600 inodes, 142127 blocks
7106 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=146800640
5 block groups
32768 blocks per group, 32768 fragments per group
7120 inodes per group
Superblock backups stored on blocks:
32768, 98304
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
Do I really have to mention at this point that this will erase all your files? Alternatively one could try "resizefs" to resize the filesystem, but that program isn't included in my recovery. Anyhow, it seems to be prudent to try encryption on an otherwise virgin install, as one risks data loss anyhow when performing the encryption process and there are reports of phones not booting up correctly after encyption had been enabled.
Then reboot the phone, do a half-hearted initial setup of the device, configure a simple PIN for testing, and encrypt your phone. (I also enabled debugging so that I can run logcat again to catch errors).
$ grep Cryptfs logcat_encryption_newfs.txt
(...)
I/Cryptfs ( 196): Check if PFE is activated on Boot
E/Cryptfs ( 196): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs ( 196): Error getting crypt footer and key
E/Cryptfs ( 196): not running with encryption, aborting
E/Cryptfs ( 196): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
D/Cryptfs ( 196): Just asked init to shut down class main
D/Cryptfs ( 196): unmounting /mnt/shell/emulated succeeded
D/Cryptfs ( 196): unmounting /data succeeded
I/Cryptfs ( 196): keymaster version is 2
I/Cryptfs ( 196): Using scrypt for cryptfs KDF
D/Cryptfs ( 196): Just triggered post_fs_data
D/Cryptfs ( 196): post_fs_data done
D/Cryptfs ( 196): Just triggered restart_min_framework
I/Cryptfs ( 196): Using scrypt for cryptfs KDF
I/Cryptfs ( 196): Enabling support for allow_discards in dmcrypt.
I/Cryptfs ( 196): load_crypto_mapping_table: target_type = crypt
I/Cryptfs ( 196): load_crypto_mapping_table: real_blk_name = /dev/block/platform/msm_sdcc.1/by-name/userdata, extra_params = 1 allow_discards
I/Cryptfs ( 196): Encrypting ext4 filesystem in place...
I/Cryptfs ( 196): Encrypting group 0
I/Cryptfs ( 196): Encrypting from sector 0
I/Cryptfs ( 196): Encrypting group 1
I/Cryptfs ( 196): Encrypted to sector 1356288
I/Cryptfs ( 196): Encrypting from sector 16777216
I/Cryptfs ( 196): Encrypted to sector 16867328
I/Cryptfs ( 196): Encrypting from sector 16874496
I/Cryptfs ( 196): Encrypted to sector 17014784
The phone will now reboot and ask for the PIN you entered. Unfortunately this takes *ages*! But if everything is fine, you can now setup your phone to your heart's content and set up a real password to have a securely encrypted phone. We'll have to see how stable this encrypted phone will be in daily use.
Update: I made a mistake and chopped off the "5" at the end, so my filesystem only occupies 1/10 of the available space and has a completely unusable size of 500 MB :-(. So, to not have to start all over again, I'll try to resize the file system in place.
Login to your android device, and check the filesystem size. Indeed /data is completely ridiculous at 500MB.
➜ e2fs adb shell
shell@serranoltexx:/ $ su
root@serranoltexx:/ # df
Filesystem Size Used Free Blksize
(...)
/data 553.0M 490.2M 62.8M 4096
Check the sizes of the underlaying block device, and the dmcrypt mapper:
root@serranoltexx:/ # cat /proc/partitions
major minor #blocks name
(...)
179 24 5685231 mmcblk0p24
(...)
254 0 5685215 dm-0
Indeed, the crypted partition is exactly 16kB smaller (the crypt footer) than the raw block device. So we can hopefully let resize2fs autodiscover the target size. Unfortunately, we cannot access the block device hosting /data, and we can't umount /data because the android framework is still running. So we use the same method as the volume daemon to shutdown most of android. (your device will not no longer react to user input on the buttons or touch secreen):
root@serranoltexx:/ # setprop vold.decrypt trigger_shutdown_framework
root@serranoltexx:/ # umount /data
root@serranoltexx:/ # e2fsck -f /dev/block/dm-0
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
(...)
(fix problems as they appear here)
root@serranoltexx:/ # resize2fs /dev/block/dm-0
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/block/dm-0 to 1421303 (4k) blocks.
The filesystem on /dev/block/dm-0 is now 1421303 blocks long.
I rebooted the phone the hard way via sync; echo b >/proc/sysrq-trigger.
Now /data is at the expected size of 5.5 GB.
➜ ~ adb shell df
Filesystem Size Used Free Blksize
(...)
/data 5.4G 734.3M 4.7G 4096
Of course, now that we have found out how to resize an ext4 filesystem in place from within android, we realize that we could have made it that way from the beginning 😉. Without data loss. Just run the last 4 commands but using the physical emmc device and append the right number of blocks we need to resize2fs while the device is still unencrypted...
e2fsck /dev/block/mmcblk0p24
resize2fs /dev/block/mmcblk0p24 14221303
That should do the trick. Reboot and run the normal encryption process.