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 rootfollowed by
- Optional: watch logs by invoking
adb logcatin 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.
vdc command ("Volume Daemon Client") communicated with
vold (Volume Daemon) has some subcommands like
cryptfs for encryption. The
enablecrypto subcommand has two modes:
/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
66 in hex,
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
/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
encryptable=footer) is present, then 16 KiB at the end of the data partition is used to store encryption metadata.
For further reading, see:
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
Wow @Lekensteyn thank you for taking the time to write this. I'll have to spend some time this weekend trying to set this up. In case I eff up, I can just wipe everything from TWRP and try again, right?– ZlattyAug 17, 2015 at 14:43
1Yes, it is just the data partition. I deliberately wiped mine several times when I was experimenting. Aug 17, 2015 at 16:06
2LPT: As of 6.0 (Marshmallow) vdc does use password not ascii encoded as parameter (=cleartext). It was pretty nice to practice with the ASCII table once I found out this thing - just minutes after I was asked to enter my password om boot. I had to put my password in ASCII because of my fault lol Nov 24, 2015 at 23:25
For me, the original answer did not work as expected. It looked like it encrypted successfully, but the UI came back very quickly and the "Encryption" setting did not show that the devices was encrypted. I then applied the commands given in the update, but it still didn't work. I then reduced the size of the data partition and it encrypted successfully. I.e.
mount | grep data to find the actual block device of the data partition. Let's assume it is
umount /data for the ext-tools to work.
e2fsck -f -p /dev/block/mmcblk0p26 to not run into trouble for the upcoming resizing.
tune2fs -l /dev/block/mmcblk0p26 to obtain the Block count. Let's assume it is
resize2fs /dev/block/mmcblk0p26 3057375, i.e. substract a sufficient amount like 20 from the original block count.
e2fsck -f -p /dev/block/mmcblk0p26 found a wrongly placed inode for me.
I also needed to mount the
/system partition in order to get hold of
resize2fs. On my system, that binary was linked against a 64bit version of libc, but the TWRP I was used did not seem to provide that. So I needed to prefix the commands with
As of CM12.1 2015-10-15 the answer by Lekensteyn no longer works.
Apparently the mkfs.f2fs which is needed to create the file system, has been moved from
Also we have to contend with SELINUX. This means that we need to do several additional steps:
mount -oremount,rw /system
ln -s /sbin/mkfs.f2fs /system/bin/mkfs.f2fs
vdc cryptfs enablecrypto wipe password 666f6f
Another update- CM13 Jan 9, 2016 build, using Nubia Z7 Max, NX505J phone
This command (
ln -s /sbin/mkfs.f2fs /system/bin/mkfs.f2fs) is no longer needed as the file lives here again. There is no need to create a symbolic link.
This command no longer needs to be in HEX and if you enter hex your PW will be hex.
cryptfs enablecrypto wipe password 666f6f -
This literally created a password for me of
I am still researching this issue because I got past the extra blocks needed for the meta data. I now need to get past the fact the GUI and the manual commands to encrypt both result in encryption that is viable only through one boot cycle. I will report back when I have a successful encryption.
Right now I encrypt and it works fine and I boot the first time and it says the phone is encrypted. Using TWRP I can confirm /data is encrypted but the HEX and ASCI passwords I try in TWRP both do not work. On the next reboot the Android OS cannot fully boot CM13. It confirms I have the correct encryption password and then I only get 1 encrypted boot. After the first successful encrypted startup it locks on the animation stage of boot cycle thereafter. Security best practices now recommends AES256 phone encryption.
How reliable has the system been with the AES256 phone encryption in CM13? I opened a thread about the thing here android.stackexchange.com/q/134981/9897 Jan 22, 2016 at 12:37
Having a Moto X 2013 running Cyanogenmod 12.1 I also was not able to get it encrypted. Finally, I succeeded with these steps:
- Enable root in Developer Settings on the phone and open a shell (Terminal app, can also be enabled in Developer Settings)
su, and confirm root access
- Now open Settings, go to Security and select Encrypt Phone. Android will then reboot and start encrypting the phone.
I came to this solution by combining Art's answer and this forum thread.
Didn't work for me. Btw, can you set the SELinux status back to 1 after this? May 30, 2016 at 3:48
After 6 hours of mental pain and sweat I might have stumbled on a solution what worked for me. And it was an accident too. I did this for the Samsung S4 Mini with CyanogenMod 13.0 and Android 6.0.1. Important key factor here is, that I started it off from a clean phone (fresh firmware and unrooted), because when the phone was previously rooted, then the phone didn't want to work at all.
I used the Firelord's and Lekensteyn's solution to the problem, but I managed to to forget one line from the commands.
Here is how I did it:
I turned on the Android debugging and Root access to ADB only in the Developer Options.
In the ADB Command Prompt I used the
adb shellcommand. After that I opened another ADB Command Prompt and used the
In the first ADB shell, I went forward with
setenforce 0and after that
vdc cryptfs enablecrypto wipe password YOUR-PASSWORD.
IMPORTANT NOTICE: The password command might vary from the Android version what you are using. If you are using Android 5.X, you must use the hexadecimal system (In the Chr line is the symbol in your password the hexadecimal value is on the Hx line). If you are using Android 6.X, then the YOUR-PASSWORD will be the password what you entered there.
As you notice then I forgot to use the
mount -oremount,rw /system command. After that I the screen will go black. When I saw, that the ADB shell with the log stopped and finished, then I rebooted the phone. But as for everyone, the problem is, that CyanogenMod wont load. And I managed to fix it quite easily:
- Hold Vol Up & Home & Power down till the TWRP boots up. It will ask you for your encryption password.
- Do the CyanogenMod install part with the additional Google Apps (The second part of the guide).
- After it is done, then reboot the device. When it boots up, then it will take a while. First it will start up the phone, then it will ask the encryption password and then it will take a while till it boots up.
There you go, it should work. At first, when the phone set up comes up, then let it be for a minute. There might be a little crash for the Setup Wizard if you rush it too quickly, but it will automatically restart when it crashes.
In my very small knowledge of how the CyanogenMod and the Android Encryption works, I think during the format it deletes some important Cyanogen or Android files, what stop it from booting.
Encrypting didn't work on my phone (SGS5; CM13, TWRP 3.0.2-2) - I always got a black screen.
I didn't want to use shell commands, so I found another way :
I had SuperSU installed, I uninstalled it in the App and then flashed the SU-Remover.
After that, I was able to use the encryption from the menu.
- Encryption deleted all of my Data & Apps (including Files on internal SD), so make a backup first!
- After Encryption, i only had 2 GB internal Space left (normally 11 GB) - I had to do a full wipe (also removing Cyanogenmod itself), reinstall Cyanogenmod and another encryption attempt to get my Space back.
- You also have to reactivate root, i used BETA-SuperSU-v2.68-20160228150503 for that (flash with twrp).