How do you encrypt your device running CyanogenMod 12.1? CyanogenMod 12 and 12.1 'Encrypt phone' setting is broken, and has been for quite a while. Is there any way to encrypt the phone in some other fashion? Can CM be sideloaded onto a phone with an encrypted /data directory? Are there any other ways to keep your data safe and sound? The device I'm working on is a Verizon LG G3.
There are low(er)-level commands that can be used in a shell to encrypt your user data partition. Disclaimer/Warning: the following instructions will wipe your data, ensure that you make a backup if needed.

Following these steps, you should be able to wipe your data partition and have it encrypted afterwards (similar to a factory reset):


Boot your phone normally (either recovery does not work anymore, or I ran into a different issue).
Ensure that USB debugging mode (adb) and  Root access for ADB is enabled.
Enter a root shell with adb root followed by adb shell.
Optional: watch logs by invoking adb logcat in another shell.
Enter this command, type your password and press Enter. This will actually set your password. This command reads one line of input (head -1), strips the trailing newline from Enter (tr -d '\n') and converts it to a hexadecimal representation (hexdump ...). If it looks scary or if you are not sure what this command does, see below.

vdc cryptfs enablecrypto wipe password $(head -1 | tr -d '\n' | hexdump -ve '1/1 "%.2x"')

If everything goes okay, your device will set keys and reboot to complete the encryption.


The above vdc command ("Volume Daemon Client") communicated with vold (Volume Daemon) has some subcommands like cryptfs for encryption. The enablecrypto subcommand has two modes: wipe (clear /data completely) and inplace (supposedly applying encryption while copying your original /data inside the container).

Then, four options are available starting with Android 5.0, one of them is password which accepts a single hexadecimal sequence as key. Thus if your password is foo, then the hexadecimal representation is 666f6f (f is 66 in hex, o is 6f, see http://www.asciitable.com/). The command for this is:

vdc cryptfs enablecrypto wipe password 666f6f


This was tested on a Nexus 5 (code name hammerhead, running cm-12.1-20150814) which has a separate partition for storing metadata. It is important that the userdata partition has the encryptable flag set followed by either the path to a partition or the special string footer. An (abbreviated) line from my /fstab.hammerhead file:


  /dev/block/platform/msm_sdcc.1/by-name/userdata     /data           ext4    ...,check,encryptable=/dev/block/platform/msm_sdcc.1/by-name/metadata


When the special string footer (encryptable=footer) is present, then 16 KiB at the end of the data partition is used to store encryption metadata.

For further reading, see:


https://source.android.com/devices/tech/security/encryption/




Appendix: logcat excerpt from the moment I executed the encryption command until it finishes and reboots (omitting unrelated graphics messages at the end). Note that this Nexus 5 has hardware-accelerated crypto (QSEECom).

--------- beginning of main
08-16 12:57:15.459 W/DrmManagerClientImpl(Native)( 2108): DrmManager server died!
08-16 12:57:15.459 I/ServiceManager(  184): service 'drm.drmManager' died
08-16 12:57:15.467 D/Cryptfs (  186): Just asked init to shut down class main
08-16 12:57:15.470 D/Cryptfs (  186): unmounting /mnt/shell/emulated succeeded
08-16 12:57:15.599 I/ServiceManager(  184): service 'media.audio_flinger' died
08-16 12:57:15.599 I/ServiceManager(  184): service 'media.player' died
08-16 12:57:15.599 I/ServiceManager(  184): service 'media.camera' died
...
08-16 12:57:16.695 D/Cryptfs (  186): unmounting /data succeeded
08-16 12:57:16.695 D/QSEECOMAPI: (  186): QSEECom_get_handle sb_length = 0x2000
08-16 12:57:16.696 D/QSEECOMAPI: (  186): App is already loaded QSEE and app id = 2
08-16 12:57:16.697 I/Cryptfs (  186): keymaster version is 3
08-16 12:57:16.697 D/QSEECOMAPI: (  186): QSEECom_dealloc_memory 
08-16 12:57:16.697 D/QSEECOMAPI: (  186): QSEECom_shutdown_app, app_id = 2
08-16 12:57:16.697 D/QSEECOMAPI: (  186): QSEECom_get_handle sb_length = 0x2000
08-16 12:57:16.697 D/QSEECOMAPI: (  186): App is already loaded QSEE and app id = 2
08-16 12:57:18.058 D/QSEECOMAPI: (  186): QSEECom_dealloc_memory 
08-16 12:57:18.058 D/QSEECOMAPI: (  186): QSEECom_shutdown_app, app_id = 2
08-16 12:57:18.058 I/Cryptfs (  186): Using scrypt with keymaster for cryptfs KDF
08-16 12:57:18.208 D/BootAnimation( 2683): Use save memory method, maybe small fps in actual.
08-16 12:57:18.208 E/QCOM PowerHAL( 2683): Failed to acquire lock.
08-16 12:57:18.691 D/QSEECOMAPI: (  186): QSEECom_get_handle sb_length = 0x2000
08-16 12:57:18.691 D/QSEECOMAPI: (  186): App is already loaded QSEE and app id = 2
08-16 12:57:18.692 I/Cryptfs (  186): Signing safely-padded object
08-16 12:57:18.797 D/QSEECOMAPI: (  186): QSEECom_dealloc_memory 
08-16 12:57:18.797 D/QSEECOMAPI: (  186): QSEECom_shutdown_app, app_id = 2
08-16 12:57:20.056 I/Cryptfs (  186): Using scrypt with keymaster for cryptfs KDF
08-16 12:57:20.690 D/QSEECOMAPI: (  186): QSEECom_get_handle sb_length = 0x2000
08-16 12:57:20.691 D/QSEECOMAPI: (  186): App is already loaded QSEE and app id = 2
08-16 12:57:20.691 I/Cryptfs (  186): Signing safely-padded object
08-16 12:57:20.796 D/QSEECOMAPI: (  186): QSEECom_dealloc_memory 
08-16 12:57:20.796 D/QSEECOMAPI: (  186): QSEECom_shutdown_app, app_id = 2
08-16 12:57:21.429 I/Cryptfs (  186): Enabling support for allow_discards in dmcrypt.
08-16 12:57:21.429 I/Cryptfs (  186): load_crypto_mapping_table: target_type = crypt
08-16 12:57:21.429 I/Cryptfs (  186): load_crypto_mapping_table: real_blk_name = /dev/block/platform/msm_sdcc.1/by-name/userdata, extra_params = 1 allow_discards
08-16 12:57:21.431 I/Cryptfs (  186): Making empty filesystem with command /system/bin/make_ext4fs -a /data -l 13725837312 /dev/block/dm-0
08-16 12:57:21.447 I/make_ext4fs(  186): SELinux: Loaded file_contexts from /file_contexts
08-16 12:57:21.447 I/make_ext4fs(  186): Creating filesystem with parameters:
08-16 12:57:21.447 I/make_ext4fs(  186):     Size: 13725835264
08-16 12:57:21.448 I/make_ext4fs(  186):     Block size: 4096
08-16 12:57:21.448 I/make_ext4fs(  186):     Blocks per group: 32768
08-16 12:57:21.448 I/make_ext4fs(  186):     Inodes per group: 8144
08-16 12:57:21.448 I/make_ext4fs(  186):     Inode size: 256
08-16 12:57:21.448 I/make_ext4fs(  186):     Journal blocks: 32768
08-16 12:57:21.449 I/make_ext4fs(  186):     Label: 
08-16 12:57:21.449 I/make_ext4fs(  186):     Transparent compression: none
08-16 12:57:21.449 I/make_ext4fs(  186):     Blocks: 3351034
08-16 12:57:21.449 I/make_ext4fs(  186):     Block groups: 103
08-16 12:57:21.459 I/make_ext4fs(  186):     Reserved block group size: 823
08-16 12:57:21.465 I/make_ext4fs(  186): Created filesystem with 11/838832 inodes and 93654/3351034 blocks
08-16 12:57:21.465 I/make_ext4fs(  186):     Total files: 0
08-16 12:57:21.465 I/make_ext4fs(  186):     Total bytes: 0
08-16 12:57:42.926 D/Cryptfs (  186): Successfully created filesystem on /dev/block/dm-0