Thursday, 30 August 2018

Crypted Android device startup sequence

This blog deals with Android Marshmallow, things might have changed since then, especially as newer version support FBE (File-Based Encryption). M and older only supported FDE (Full-Disk Encryption) and the way it works is far from obvious but can be explained relatively concisely. I'll try to explain the flow below without getting stuck into too much detail.

Partition mounting starts in system/core/init/builtins.cpp, function do_mount_all(). This calls function fs_mgr_mount_all() and takes note of the return value. fs_mgr_mount_all() tries to mount each partition. If it fails, then the function checks if "encrypted" option is set for that partition in the fstab file. In this case it returns FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED.

If do_mount_all() receives this return value, it will set three properties:

ro.crypto.state = encrypted
ro.crypto.type = block
vold.decrypt = trigger_default_encryption

So at this point the system has seen there exist an encrypted device but does not know whether it has already been encrypted or not because this could be the very first boot.

trigger_default_encryption causes cryptfs_mount_default_encrypted() to be run. I.e. it starts the process of running the default encryption which is run the first time (with the default password). This function will check the type of password and if it has a valid value which is not CRYPT_TYPE_DEFAULT (i.e. user has changed it) it sets an important property:

vold.decrypt = trigger_restart_min_framework.

This starts the minimum framework which mounts the encrypted partition (/data in practice) to a temporary RAM disk and starts Zygote which then prompts the encryption password from the user. After user supplies the correct password, vold.decrypt is set to trigger_restart_framework, partition is decrypted and mounted (to /data) and Zygote is restarted. If the device wasn't encrypted (/data did not have the encrypted option) then init skips straight to this part.

This is, IMO, a pretty ugly solution and probably the easiest one for Google to handle encryption. It involves starting the almost the entire framework just to open a very simple view for the user to enter the password.

No comments:

Post a comment