Android full disk encryption
What is full disk encryption?
Full disk encryption uses a key to encrypt all user data on android devices. Once the device is encrypted, all data created by the user will be automatically encrypted before the disk is submitted, and will be automatically decrypted before reading.
What is added in Android 5.0?
A quick encryption is created. This encryption method only encrypts the data of Block devices in the Data Partition to prevent the first startup from taking a long time. Only ext4 and f2fs file systems support quick encryption.
The forceencrypt flag was added at the first startup to encrypt. The mode support and password-less encryption were added. The hardware support for storing keys using trusted execution environments was added.
Note: devices upgraded to Android5.0 and encrypted may return an unencrypted status after the data is restored to the factory. New Android 5.0 devices encrypted at the first startup cannot return to the unencrypted status.
How does Android full disk encryption work?
Android full disk encryption is based on dm-crypy. It is a kernel feature that works on the block device layer. For this reason, encryption works with embedded multi-media cards and flash devices that act as Block devices. In the YAFFS file system, encryption cannot work. It works directly with the nand flash memory chip.
The encryption algorithm is a 128 Advanced Encryption Standard with CBC and ESSIV: SHA256. The primary key is encrypted through the 128-bit AES through the OpenSSL library. You must use a 128-bit or larger-digit key value.
Note: OEMs can encrypt the primary key with 128-bit or higher digits.
There are four encryption statuses in the release of Android5.0:
Default PIN password Mode
At the first startup, the device creates a random 128-bit primary key, and then uses the default password and the stored salt for hashing. The default password is "default_password ". However, the result hashes also need to be signed through TEE, which uses a signature hashes to encrypt the primary key.
You can find the default password in the cryptfs. c file of the Android source code.
When a user configures a PIN or password on the device, only the 128-bit key is reencrypted and stored. (Changing user PIN/password/mode will not cause user data to be re-encrypted ). Note that the managed devices may be subject to PIN, mode, or password restrictions.
Encryption is managed by init and vold. Init calls vold and vold sets the attribute in init to trigger the event. Other parts of the system also work based on these attributes, such as report status, query password, or factory reset in case of fatal errors. To activate encryption features in vold, the system uses the command line tool vdc's cryptfs to run commands: checkpw, restart, enablecrypto, changepw, cryptocomplete, verifypw, setfield, getfield, mountdefaultencrypted, getpwtype, getpw, and clearpw.
To encrypt, decrypt, or clear/data,/data must be mounted. However, to display user interfaces, the framework must run and/data is required for the framework. To solve this problem, a temporary file system is mounted in/data. This allows android to prompt the password, display progress, or erase data as needed. Some restrictions are imposed when converting from a temporary file system to a real/data file system. The system must stop every process that opens files in the temporary file system, restart these processes in the real/data file system. To do this, all services must be in one of the three groups: core, main, and late_start.
Core: Never disable main after startup: Shut down after the disk password is entered. Restart late_restart: Do not start before/data is decrypted and mounted.
To stimulate these behaviors, the vold. decrypt attribute is set to various strings. To kill and restart the service, the init command is:
Class_reset: stop the service and allow the use of class_start to restart. Class_start: restart the service class_stop: Stop a service and add a SVC_DISABLED flag. The stopped service does not respond to class_start.
For an encrypted device, there are four streams. One device only encrypts once and then follows a normal startup stream.
Encrypt an unencrypted device: Use forceencrypt to encrypt a new device: encrypt an existing device forcibly at the first startup (starting with Android L: the user initializes encryption (Android K and earlier) to start an encryption device: Start an encryption device without a password: start an encrypted device without a password (related devices run Android 5.0 or updated) and start a encrypted device with a password: Start an encrypted device with a password.
In addition to these streams, device encryption/data will fail. Each stream is explained in detail below.
Encrypt a new device with/forceencrypt
This is the first normal startup of an Android 5.0 device.
Unencrypted file system with the/forceencrypt flag
/Data is not encrypted, but must be encrypted. Because/Forceencrypt entrusts him to do so. Uninstall/data
Vold. decrypt = "trigger_encryption" triggers init. rc, which will cause vold to encrypt/data with no password. (None is set because this shoshould be a new device .)
Mount a temporary file system/data (from ro. crypto. tmpfs_options) and set the vold attribute. encrypt_progress is 0. vold prepares tmpfs/data for an encrypted system and sets the property vold. decrypt is trigger_restart_min_framework
Propose a framework to display the progress
Because the device has almost no data to encrypt, the progress bar will not be displayed, because the encryption process will be very fast.
After/data is encrypted, remove the framework
Vold sets vold. decrypt to trigger_default_encryption of the ultcrypto service. (This will start the following stream to mount a default encrypted user data ). Trigger_default_encryption check the encryption type to check whether/data is encrypted with a password. Because the Android5.0 device is encrypted when it is started for the first time, there should be no password settings; therefore, we decrypt and mount/data.
Init then mount/data in the RAMDisk of tmpfs using the parameters selected from ro. crypto. tmpfs_options. ro. crypto. tmpfs_options is set in init. rc.
Start the framework
Set vold to trigger_restart_framework to continue the general startup process.
Encrypt a Current Device
This occurs when you encrypt an unencrypted Android k or earlier version of the device until Android L. Note that this is the same as the stream used in K.
This process is initiated by the user and is referenced in the Code as "Local encryption ". When an empty user chooses to encrypt a device, the UI ensures that the power is fully charged and the AC adapter is inserted, so there are enough variables to complete the encryption process.
Warning if the device consumes power and shuts down before encryption is completed, file data will be left in partial encryption. The device must be reset by the factory, and all data will be lost.
To enable local encryption, vold starts a loop to read each slice of the real block device, and then writes it to the encrypted block device. Before reading and writing data, the vold checks whether the slice is in use, which makes encryption on new devices with almost no data very fast.
Device status: Set ro. crypto. state = "unencrypted" and run the on nonencrypted init trigger to continue the startup.
The UI calls the vold with the cryptfs enablecrypto inplace command in the place where passwd is the user's Lock password.
Vold check error. If it cannot be encrypted,-1 is returned and the reason is printed in the log. If encryption is enabled, set vold. decrypt to trigger_shutdown_framework. This causes init. rc to stop services in the late_start and main classes.
Uninstall/mnt/sdcard and then uninstall/data.
Vold then sets the encryption ing. This ing creates a virtual encryption block device that maps to a real block device, but encrypts each sector when writing data, decrypts each slice when reading data. Vold then creates and compiles encrypted metadata.
When encryption is performed, tmpfs is mounted.
Vold mounts a tmpfs/data (from ro. crypto. tmpfs_options) and set the vold attribute. encrypt_progress is 0. vold prepares tmpfs/data for starting an encryption system and sets the property vold. decrypt is trigger_restart_min_framework.
Propose a framework to display the progress
Trigger_restart_min_framework will enable init. rc to start a main class of the service. When the framework shows that vold. encrypt_progress is set to 0, it will display the progress bar UI, which queries the properties every five seconds and then updates the progress bar. Each time a partition is encrypted, the encryption program updates vold. encrypt_progress.
When/data is encrypted, restart
When/data is successfully encrypted, vold clears the identifier ENCRYPTION_IN_PROGRESS in the metadata, and then restarts.
If the restart fails for some reason, vold sets the vold. encrypt_progress attribute to error_reboot_failed, And the UI displays a message asking the user to press the button to restart. This situation is never expected to happen.
Enable an encrypted device with default encryption
This happens when you want to start an encrypted device without a password. Because the Android 5.0 device is encrypted when it is started for the first time, there should be no password, so it should be in the default encryption status.
Checks encrypted/data without a password
Check that the Android device is encrypted because/data cannot be mounted and the flag flagsencryptable or forceencrypt is set. Vold: Set vold. decrypt
Trigger_default_encryption, which is used to start defaultcrypto. Trigger_default_encryption check the encryption type to check whether/data has password encryption.
Create a dm-crypt device in the block device, so the device can be used.
Mount the encrypted/data Partition on vold and prepare a new partition. He sets the property vold. post_fs_data_done to 0 and vold. decrypt to trigger_post_fs_data. This causes init. rc to run his post-fs-data command. They will create necessary directories and links, and then set vold. post_fs_data_done to 1.
Once vold sees 1 in that attribute, it sets vold. decrypt as trigger_restart_framework. This causes init. rc to start the service in the main class again. Then, the Service located in the class late_start is enabled for the first time since the startup.
Now, the framework uses encrypted/data to start all its services, and the system can be used normally.
Enable an encrypted device that is not encrypted by default.
This occurs when you start an encrypted device with a password. The password for this device can be a pin, a mode, or a password.
Detects encrypted devices with passwords
Android devices are encrypted because ro. crypto. state = "encrypted"
Vold sets vold. decrypt to trigger_restart_min_framework, because/data is encrypted with a password.
Init sets the following five attributes to save the initialization mount options, which are used for/data with parameters. They are from init. rc. vold and use these attributes to set encryption ing.
Ro. crypto. Convert (ASCII 8-digit hex number preceded by 0x)
Start the framework to prompt you to enter the password
The framework starts, and then check whether vold. decrypt is set to trigger_restart_min_framework. This tells the framework to be started in the tmpfs/data disk, and he needs to get the user password.
First, determine whether the disk is encrypted correctly. He sends the command cryptfs cryptocomplete to vold. If the encryption is successful, 0 is returned. If an internal error occurs,-1 is returned. Or-2 is returned if the encryption is not successful. Vold determines this by viewing the encryption metadata used for the CRYPTO_ENCRYPTION_IN_PROGRESS flag. If set, the encryption process is interrupted and no data is available on the device. If vold returns an error, the UI should display a message to the user to restart and reset the device in the factory, and give the user a button to do so.
Decrypt data with a password
Once cryptfs cryptocomplete is successful, the Framework displays a UI asking for the disk password. The UI checks the password by sending the cryptfs checkpw command to vold. If the password is correct (this is determined by the encryption/data correctly mounted to the temporary location, and then the tower is unmounted), vold is in the property ro. crypto. in fs_crypto_blkdev, save the name of the decryption block device and return the status 0 to the UI. if the password is incorrect,-1 is returned to the UI.
The UI displays an encrypted startup image, and uses the command cryptfs restart. vold to set the property vold. decrypt to trigger_reset_main to call vold. This will enable init. rc to process class_reset main. This will stop all services in the main class, which allows tmpfs/data to be detached.
Vold, mount the decryption/data Partition, and prepare a new partition (if it is encrypted with a erasable option, it will not be prepared, which is not supported in the first release ). Set vold. post_fs_data_done to 0, and set vold. decrypt to trigger_post_fs_data. This causes init. rc to run his post-fs-data command. They will create any necessary directories or links and then set vold. post_fs_data_done is 1. once vold sees 1 in that property, it will set the property vold. decrypt is trigger_restart_framework. this causes init. rc restarts the service in the class main and starts the service in the class late_start for the first time after startup.
Enable the entire framework
Now, the framework uses the decryption/data file system to start all of its services and the system is ready for use.
A device that fails decryption may be due to the following reasons. The device starts with a conventional series of steps:
Check that the tmpfs enabled framework is mounted to an encrypted device with a password. The system prompts you to enter the password.
However, after the framework is enabled, the device may encounter some errors:
Password matching but cannot decrypt data users enter the wrong password 30 times
If these errors are not resolved, the user is prompted to clear the factory:
If vold detects an error during the encryption process and the data is not decrypted, the framework starts. vold sets the vold. encrypt_progress attribute to error_not_encrypted. The UI prompts the user to restart and warns them that the encryption process has not started. If an error occurs after the framework is detached and the progress bar is enabled, the vold restarts the system. If the restart fails, the vold. encrypt_progress is set to error_shutting_down and-1 is returned. However, no errors will be captured. This is not expected to happen.
If vold detects an error during encryption, it sets vold. encrypt_progress is error_partially_encrypted, and-1 is returned. the UI displays a message box indicating that the encryption fails and a button is provided to indicate that the user can restore the factory reset device.
Storage encryption key
The encrypted key value is stored in the encrypted metadata. Hardware Support is implemented by using a trusted environment signature. Previously, we used to encrypt the primary key by applying scrypt to the user password and storage salt. To make the key resist attacks, we use a stored TEE key to sign a combination key value to inherit its algorithm. The combination signature uses a scrypt application to program a suitable key length. This key is used to encrypt and decrypt the master key. The process for storing this key is as follows:
Generate a random 16-bit disk encryption key (DEK) and 16 is salt. Apply scrypt and salt to the user password to generate a 32-bit intermediate key 1 (IK1 ). Use 0 to fill in the size of the private key (HBK) bound to the hardware by IK1. In particular, we fill in: 00 | IK1 | 00 .. 00; one 0-bit: 32 IK1 bytes, 223 zero bytes. IK1 with HBK signature to generate 256-bit IK2 apply scrypt to IK2 and salt to generate 32-bit IK3 use the first 16-bit IK3 as the KEK, the last 16 bits are encrypted as IV deks with AES_CBS and key KEK, and the initialization vector IV
When the user chooses to modify or remove the password in the settings, the UI sends the cryptfs changepw command to vold, And the vold re-encrypts the disk master key with the new password.
Vold and init communicate with each other by setting properties. The following are some available attributes for encryption.
|Vold. decrypt trigger_encryption
||Encrypt devices without passwords
|Vold. decrypt trigger_default_encryption
||Check whether the device is encrypted without a password. If yes, decrypt and mount it. If not, set vold. decrypt to trigger_restart_min_framework.
|Vold. decrypt trigger_reset_main
||The vold settings disable the UI to ask for the disk Password
|Vold. decrypt trigger_post_fs_data
||Prepare/data with the necessary directory with vold settings
|Vold. decrypt trigger_restart_framework
||The vold settings enable the actual framework and all services.
|Vold. decrypt trigger_shutdown_framework
||Enable Encryption by disabling the overall framework of vold settings
|Vold. decrypt trigger_restart_min_framework
||The start progress bar is set by vold to encrypt or prompt the user to enter the password, depending on the ro. crypto. state value.
||When the framework is started, if this attribute is set, it enters the progress bar mode.
|Vold. encrypt_progress 0 to 100
||The progress bar shows a set of hundreds of values.
|Vold. encrypt_progress error_partially_encrypted
||The progress bar should display a message indicating an encryption failure and give the user an option to reset the device at the factory.
|Vold. encrypt_progress error_reboot_failed
||The progress bar should display a message indicating that the encryption is complete and a button is provided to remind the user to restart the device. We do not expect this error to happen.
|Vold. encrypt_progress error_not_encrypted
||The progress bar should display a message box saying that an error has occurred, no data is encrypted, and a button is provided to remind the user to restart the system.
|Vold. encrypt_progress error_shutting_down
||The progress bar is not running, so it is unclear who will respond to this error. It should not happen.
|Vold. post_fs_data_done 0
||Set vold before setting vold. decrypt to trigger_post_fs_data
|Vold. post_fs_data_done 1
||Set by init. rc after completing the post-fs-data task
|Ro. crypto. fs_crypto_blkdev
||The checkpw setting of the vold command is used later by the vold command restart.
|Ro. crypto. state unencrypted
||According to the init settings, the system is running with unencrypted/data ro. crypto. state encrypted. The system is running encrypted/data according to init settings.
Ro. crypto. fs_type
Ro. crypto. fs_real_blkdev
Ro. crypto. fs_mnt_point
Ro. crypto. fs_options
Ro. crypto. fs_flags
|When he tries to mount/data with parameters from init. rc. vold, the five attributes are set by init to set encryption ing.
|Ro. crypto. tmpfs_options
||When the tmpfs/data file system is mounted, init. rc uses the parameters that init should use to set.
on post-fs-dataon nonencryptedon property:vold.decrypt=trigger_reset_mainon property:vold.decrypt=trigger_post_fs_dataon property:vold.decrypt=trigger_restart_min_frameworkon property:vold.decrypt=trigger_restart_frameworkon property:vold.decrypt=trigger_shutdown_frameworkon property:vold.decrypt=trigger_encryptionon property:vold.decrypt=trigger_default_encryption