{"id":30666,"date":"2015-09-07T12:40:26","date_gmt":"2015-09-07T16:40:26","guid":{"rendered":"http:\/\/www.opensource.im\/uncategorized\/encryption-android-open-source-project.php"},"modified":"2015-09-07T12:40:26","modified_gmt":"2015-09-07T16:40:26","slug":"encryption-android-open-source-project","status":"publish","type":"post","link":"https:\/\/euvolution.com\/open-source-convergence\/encryption\/encryption-android-open-source-project.php","title":{"rendered":"Encryption | Android Open Source Project"},"content":{"rendered":"<p><p>What is encryption?    <\/p>\n<p>    Encryption is the process of encoding user data on an Android    device using an encrypted key. Once a device is encrypted, all    user-created data is automatically encrypted before committing    it to disk and all reads automatically decrypt data before    returning it to the calling process.  <\/p>\n<p>    Caution: Devices upgraded to Android 5.0 and    then encrypted may be returned to an unencrypted state by    factory data reset. New Android 5.0 devices encrypted at first    boot cannot be returned to an unencrypted state.  <\/p>\n<p>    Android disk encryption is based on dm-crypt,    which is a kernel feature that works at the block device layer.    Because of this, encryption works with Embedded MultiMediaCard    (eMMC) and similar flash devices that present    themselves to the kernel as block devices. Encryption is not    possible with YAFFS, which talks directly to a raw NAND flash    chip.  <\/p>\n<p>    The encryption algorithm is 128 Advanced Encryption Standard    (AES) with cipher-block chaining (CBC) and ESSIV:SHA256. The    master key is encrypted with 128-bit AES via calls to the    OpenSSL library. You must use 128 bits or more for the key    (with 256 being optional).  <\/p>\n<p>    Note: OEMs can use 128-bit or higher to    encrypt the master key.  <\/p>\n<p>    In the Android 5.0 release, there are four kinds of encryption    states:  <\/p>\n<p>    Upon first boot, the device creates a randomly generated    128-bit master key and then hashes it with a default password    and stored salt. The default password is: \"default_password\"    However, the resultant hash is also signed through a TEE (such    as TrustZone), which uses a hash of the signature to encrypt    the master key.  <\/p>\n<p>    You can find the default password defined in the Android Open    Source Project     cryptfs.c file.  <\/p>\n<p>    When the user sets the PIN\/pass or password on the device, only    the 128-bit key is re-encrypted and stored. (ie. user    PIN\/pass\/pattern changes do NOT cause re-encryption of    userdata.)  <\/p>\n<p>    Encryption is managed by init and    vold. init calls vold,    and vold sets properties to trigger events in init. Other parts    of the system also look at the properties to conduct tasks such    as report status, ask for a password, or prompt to factory    reset in the case of a fatal error. To invoke encryption    features in vold, the system uses the command line    tool vdcs cryptfs commands:    checkpw, restart,    enablecrypto, changepw,    cryptocomplete, verifypw,    setfield, getfield,    mountdefaultencrypted, getpwtype,    getpw, and clearpw.  <\/p>\n<p>    In order to encrypt, decrypt or wipe \/data,    \/data must not be mounted. However, in order to    show any user interface (UI), the framework must start and the    framework requires \/data to run. To resolve this    conundrum, a temporary filesystem is mounted on    \/data. This allows Android to prompt for    passwords, show progress, or suggest a data wipe as needed. It    does impose the limitation that in order to switch from the    temporary filesystem to the true \/data filesystem,    the system must stop every process with open files on the    temporary filesystem and restart those processes on the real    \/data filesystem. To do this, all services must be    in one of three groups: core, main,    and late_start.  <\/p>\n<p>    To trigger these actions, the vold.decrypt    property is set to     various strings. To kill and restart services, the    init commands are:  <\/p>\n<p>    There are four flows for an encrypted device. A device is    encrypted just once and then follows a normal boot flow.  <\/p>\n<p>    In addition to these flows, the device can also fail to encrypt    \/data. Each of the flows are explained in detail    below.  <\/p>\n<p>    This is the normal first boot for an Android 5.0 device.  <\/p>\n<p>        \/data is not encrypted but needs to be because        \/forceencrypt mandates it. Unmount        \/data.      <\/p>\n<p>        vold.decrypt = \"trigger_encryption\" triggers        init.rc, which will cause vold to        encrypt \/data with no password. (None is set        because this should be a new device.)      <\/p>\n<p>        vold mounts a tmpfs \/data (using        the tmpfs options from        ro.crypto.tmpfs_options) and sets the property        vold.encrypt_progress to 0. vold        prepepares the tmpfs \/data for booting an        encrypted system and sets the property        vold.decrypt to:        trigger_restart_min_framework      <\/p>\n<p>        Because the device has virtually no data to encrypt, the        progress bar will often not actually appear because        encryption happens so quickly. See Encrypt an existing        device for more details about the progress UI.      <\/p>\n<p>        vold sets vold.decrypt to        trigger_default_encryption which starts the        defaultcrypto service. (This starts the flow        below for mounting a default encrypted userdata.)        trigger_default_encryption checks the        encryption type to see if \/data is encrypted        with or without a password. Because Android 5.0 devices are        encrypted on first boot, there should be no password set;        therefore we decrypt and mount \/data.      <\/p>\n<p>        init then mounts \/data on a tmpfs        RAMDisk using parameters it picks up from        ro.crypto.tmpfs_options, which is set in        init.rc.      <\/p>\n<p>        Set vold to        trigger_restart_framework, which continues the        usual boot process.      <\/p>\n<p>    This is what happens when you encrypt an unencrypted Android K    or earlier device that has been migrated to L. Note that this    is the same flow as used in K.  <\/p>\n<p>    This process is user-initiated and is referred to as inplace    encryption in the code. When a user selects to encrypt a    device, the UI makes sure the battery is fully charged and the    AC adapter is plugged in so there is enough power to finish the    encryption process.  <\/p>\n<p>    Warning: If the device runs out of power and    shuts down before it has finished encrypting, file data is left    in a partially encrypted state. The device must be factory    reset and all data is lost.  <\/p>\n<p>    To enable inplace encryption, vold starts a loop    to read each sector of the real block device and then write it    to the crypto block device. vold checks to see if    a sector is in use before reading and writing it, which makes    encryption much faster on a new device that has little to no    data.  <\/p>\n<p>    State of device: Set ro.crypto.state =    \"unencrypted\" and execute the on    nonencrypted init trigger to continue    booting.  <\/p>\n<p>        The UI calls vold with the command        cryptfs enablecrypto inplace where        passwd is the user's lock screen password.      <\/p>\n<p>        vold checks for errors, returns -1 if it can't        encrypt, and prints a reason in the log. If it can encrypt,        it sets the property vold.decrypt to        trigger_shutdown_framework. This causes        init.rc to stop services in the classes        late_start and main.      <\/p>\n<p>        vold unmounts \/mnt\/sdcard and        then \/data.      <\/p>\n<p>        vold then sets up the crypto mapping, which        creates a virtual crypto block device that maps onto the        real block device but encrypts each sector as it is        written, and decrypts each sector as it is read.        vold then creates and writes out the crypto        metadata.      <\/p>\n<p>        vold mounts a tmpfs \/data (using        the tmpfs options from        ro.crypto.tmpfs_options) and sets the property        vold.encrypt_progress to 0. vold        prepares the tmpfs \/data for booting an        encrypted system and sets the property        vold.decrypt to:        trigger_restart_min_framework      <\/p>\n<p>        trigger_restart_min_framework causes        init.rc to start the main class        of services. When the framework sees that        vold.encrypt_progress is set to 0, it brings        up the progress bar UI, which queries that property every        five seconds and updates a progress bar. The encryption        loop updates vold.encrypt_progress every time        it encrypts another percent of the partition.      <\/p>\n<p>        When \/data is successfully encrypted,        vold clears the flag        ENCRYPTION_IN_PROGRESS in the metadata and        reboots the system.      <\/p>\n<p>        If the reboot fails for some reason, vold sets        the property vold.encrypt_progress to        error_reboot_failed and the UI should display        a message asking the user to press a button to reboot. This        is not expected to ever occur.      <\/p>\n<p>    This is what happens when you boot up an encrypted device with    no password. Because Android 5.0 devices are encrypted on first    boot, there should be no set password and therefore this is the    default encryption state.  <\/p>\n<p>        Detect that the Android device is encrypted because        \/data cannot be mounted and one of the flags        encryptable or forceencrypt is        set.      <\/p>\n<p>        vold sets vold.decrypt to        trigger_default_encryption, which starts the        defaultcrypto service.        trigger_default_encryption checks the        encryption type to see if \/data is encrypted        with or without a password.      <\/p>\n<p>        Creates the dm-crypt device over the block        device so the device is ready for use.      <\/p>\n<p>        vold then mounts the decrypted real        \/data partition and then prepares the new        partition. It sets the property        vold.post_fs_data_done to 0 and then sets        vold.decrypt to        trigger_post_fs_data. This causes        init.rc to run its post-fs-data        commands. They will create any necessary directories or        links and then set vold.post_fs_data_done to        1.      <\/p>\n<p>        Once vold sees the 1 in that property, it sets        the property vold.decrypt to:        trigger_restart_framework. This causes        init.rc to start services in class        main again and also start services in class        late_start for the first time since boot.      <\/p>\n<p>        Now the framework boots all its services using the        decrypted \/data, and the system is ready for        use.      <\/p>\n<p>    This is what happens when you boot up an encrypted device that    has a set password. The devices password can be a pin,    pattern, or password.  <\/p>\n<p>        Detect that the Android device is encrypted because the        flag ro.crypto.state = \"encrypted\"      <\/p>\n<p>        vold sets vold.decrypt to        trigger_restart_min_framework because        \/data is encrypted with a password.      <\/p>\n<p>        init sets five properties to save the initial        mount options given for \/data with parameters        passed from init.rc. vold uses        these properties to set up the crypto mapping:      <\/p>\n<p>        The framework starts up and sees that        vold.decrypt is set to        trigger_restart_min_framework. This tells the        framework that it is booting on a tmpfs \/data        disk and it needs to get the user password.      <\/p>\n<p>        First, however, it needs to make sure that the disk was        properly encrypted. It sends the command cryptfs        cryptocomplete to vold.        vold returns 0 if encryption was completed        successfully, -1 on internal error, or -2 if encryption was        not completed successfully. vold determines        this by looking in the crypto metadata for the        CRYPTO_ENCRYPTION_IN_PROGRESS flag. If it's        set, the encryption process was interrupted, and there is        no usable data on the device. If vold returns        an error, the UI should display a message to the user to        reboot and factory reset the device, and give the user a        button to press to do so.      <\/p>\n<p>        Once cryptfs cryptocomplete is successful, the        framework displays a UI asking for the disk password. The        UI checks the password by sending the command cryptfs        checkpw to vold. If the password is        correct (which is determined by successfully mounting the        decrypted \/data at a temporary location, then        unmounting it), vold saves the name of the        decrypted block device in the property        ro.crypto.fs_crypto_blkdev and returns status        0 to the UI. If the password is incorrect, it returns -1 to        the UI.      <\/p>\n<p>        The UI puts up a crypto boot graphic and then calls        vold with the command cryptfs        restart. vold sets the property        vold.decrypt to        trigger_reset_main, which causes        init.rc to do class_reset main.        This stops all services in the main class, which allows the        tmpfs \/data to be unmounted.      <\/p>\n<p>        vold then mounts the decrypted real        \/data partition and prepares the new partition        (which may never have been prepared if it was encrypted        with the wipe option, which is not supported on first        release). It sets the property        vold.post_fs_data_done to 0 and then sets        vold.decrypt to        trigger_post_fs_data. This causes        init.rc to run its post-fs-data        commands. They will create any necessary directories or        links and then set vold.post_fs_data_done to        1. Once vold sees the 1 in that property, it        sets the property vold.decrypt to        trigger_restart_framework. This causes        init.rc to start services in class        main again and also start services in class        late_start for the first time since boot.      <\/p>\n<p>        Now the framework boots all its services using the        decrypted \/data filesystem, and the system is        ready for use.      <\/p>\n<p>    A device that fails to decrypt might be awry for a few reasons.    The device starts with the normal series of steps to boot:  <\/p>\n<p>    But after the framework opens, the device can encounter some    errors:  <\/p>\n<p>    If these errors are not resolved, prompt user to    factory wipe:  <\/p>\n<p>    If vold detects an error during the encryption    process, and if no data has been destroyed yet and the    framework is up, vold sets the property    vold.encrypt_progress to    error_not_encrypted. The UI prompts the user to    reboot and alerts them the encryption process never started. If    the error occurs after the framework has been torn down, but    before the progress bar UI is up, vold will reboot    the system. If the reboot fails, it sets    vold.encrypt_progress to    error_shutting_down and returns -1; but there will    not be anything to catch the error. This is not expected to    happen.  <\/p>\n<p>    If vold detects an error during the encryption    process, it sets vold.encrypt_progress to    error_partially_encrypted and returns -1. The UI    should then display a message saying the encryption failed and    provide a button for the user to factory reset the device.  <\/p>\n<p>    The encrypted key is stored in the crypto metadata. Hardware    backing is implemented by using Trusted Execution Environments    (TEE) signing capability. Previously, we encrypted the master    key with a key generated by applying scrypt to the user's    password and the stored salt. In order to make the key    resilient against off-box attacks, we extend this algorithm by    signing the resultant key with a stored TEE key. The resultant    signature is then turned into an appropriate length key by one    more application of scrypt. This key is then used to encrypt    and decrypt the master key. To store this key:  <\/p>\n<p>    When a user elects to change or remove their password in    settings, the UI sends the command cryptfs    changepw to vold, and vold    re-encrypts the disk master key with the new password.  <\/p>\n<p>    vold and init communicate with each    other by setting properties. Here is a list of available    properties for encryption.  <\/p>\n<p>          ro.crypto.fs_type          ro.crypto.fs_real_blkdev          ro.crypto.fs_mnt_point          ro.crypto.fs_options          ro.crypto.fs_flags<\/p>\n<p><!-- Auto Generated --><\/p>\n<p>See original here:<br \/>\n<a target=\"_blank\" href=\"http:\/\/source.android.com\/devices\/tech\/security\/encryption\/\" title=\"Encryption | Android Open Source Project\">Encryption | Android Open Source Project<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p> What is encryption? Encryption is the process of encoding user data on an Android device using an encrypted key<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45],"tags":[],"class_list":["post-30666","post","type-post","status-publish","format-standard","hentry","category-encryption"],"_links":{"self":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts\/30666"}],"collection":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/comments?post=30666"}],"version-history":[{"count":0,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts\/30666\/revisions"}],"wp:attachment":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/media?parent=30666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/categories?post=30666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/tags?post=30666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}