Home | History | Annotate | Download | only in encryption
      1 page.title=Full Disk Encryption
      2 @jd:body
      3 
      4 <!--
      5     Copyright 2014 The Android Open Source Project
      6 
      7     Licensed under the Apache License, Version 2.0 (the "License");
      8     you may not use this file except in compliance with the License.
      9     You may obtain a copy of the License at
     10 
     11         http://www.apache.org/licenses/LICENSE-2.0
     12 
     13     Unless required by applicable law or agreed to in writing, software
     14     distributed under the License is distributed on an "AS IS" BASIS,
     15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16     See the License for the specific language governing permissions and
     17     limitations under the License.
     18 -->
     19 
     20 <div id="qv-wrapper">
     21   <div id="qv">
     22     <h2>In this document</h2>
     23     <ol id="auto-toc">
     24     </ol>
     25   </div>
     26 </div>
     27 
     28 <h2 id=what_is_encryption>What is full disk encryption?</h2>
     29 
     30 <p>Full disk encryption is the process of encoding all user data on an Android device using an
     31 encrypted key. Once a device is encrypted, all user-created data is
     32 automatically encrypted before committing it to disk and all reads
     33 automatically decrypt data before returning it to the calling process.</p>
     34 
     35 <h2 id=what_weve_added_for_android_l>What weve added for Android 5.0</h2>
     36 
     37 <ul>
     38   <li>Created fast encryption, which only encrypts used blocks on the data partition
     39 to avoid first boot taking a long time. Only ext4 and f2fs filesystems
     40 currently support fast encryption.
     41   <li>Added the <code>forceencrypt</code> flag to encrypt on first boot.
     42   <li>Added support for patterns and encryption without a password.
     43   <li>Added hardware-backed storage of the encryption key using Trusted
     44     Execution Environments (TEE) signing capability (such as in a TrustZone).
     45     See <a href="#storing_the_encrypted_key">Storing the encrypted key</a> for more
     46     details.
     47 </ul>
     48 
     49 <p class="caution"><strong>Caution:</strong> Devices upgraded to Android 5.0 and then
     50 encrypted may be returned to an unencrypted state by factory data reset. New Android 5.0
     51 devices encrypted at first boot cannot be returned to an unencrypted state.</p>
     52 
     53 <h2 id=how_android_encryption_works>How Android full disk encryption works</h2>
     54 
     55 <p>Android full disk encryption is based on <code>dm-crypt</code>, which is a kernel
     56 feature that works at the block device layer. Because of
     57 this, encryption works with Embedded MultiMediaCard<strong> (</strong>eMMC) and
     58 similar flash devices that present themselves to the kernel as block
     59 devices. Encryption is not possible with YAFFS, which talks directly to a raw
     60 NAND flash chip. </p>
     61 
     62 <p>The encryption algorithm is 128 Advanced Encryption Standard (AES) with
     63 cipher-block chaining (CBC) and ESSIV:SHA256. The master key is encrypted with
     64 128-bit AES via calls to the OpenSSL library. You must use 128 bits or more for
     65 the key (with 256 being optional). </p>
     66 
     67 <p class="note"><strong>Note:</strong> OEMs can use 128-bit or higher to encrypt the master key.</p>
     68 
     69 <p>In the Android 5.0 release, there are four kinds of encryption states: </p>
     70 
     71 <ul>
     72   <li>default
     73   <li>PIN
     74   <li>password
     75   <li>pattern
     76 </ul>
     77 
     78 <p>Upon first boot, the device creates a randomly generated 128-bit master key
     79 and then hashes it with a default password and stored salt. The default password is: "default_password"
     80 However, the resultant hash is also signed through a TEE (such as TrustZone),
     81 which uses a hash of the signature to encrypt the master key.</p>
     82 
     83 <p>You can find the default password defined in the Android Open Source Project <a
     84 href="https://android.googlesource.com/platform/system/vold/+/master/cryptfs.c">cryptfs.c</a>
     85 file.</p>
     86 
     87 <p>When the user sets the PIN/pass or password on the device, only the 128-bit key
     88 is re-encrypted and stored. (ie. user PIN/pass/pattern changes do NOT cause
     89 re-encryption of userdata.) Note that
     90 <a href="http://developer.android.com/guide/topics/admin/device-admin.html">managed device</a>
     91 may be subject to PIN, pattern, or password restrictions.</p>
     92 
     93 <p>Encryption is managed by <code>init</code> and <code>vold</code>. <code>init</code> calls <code>vold</code>, and vold sets properties to trigger events in init. Other parts of the system
     94 also look at the properties to conduct tasks such as report status, ask for a
     95 password, or prompt to factory reset in the case of a fatal error. To invoke
     96 encryption features in <code>vold</code>, the system uses the command line tool <code>vdc</code>s <code>cryptfs</code> commands: <code>checkpw</code>, <code>restart</code>, <code>enablecrypto</code>, <code>changepw</code>, <code>cryptocomplete</code>, <code>verifypw</code>, <code>setfield</code>, <code>getfield</code>, <code>mountdefaultencrypted</code>, <code>getpwtype</code>, <code>getpw</code>, and <code>clearpw</code>.</p>
     97 
     98 <p>In order to encrypt, decrypt or wipe <code>/data</code>, <code>/data</code> must not be mounted. However, in order to show any user interface (UI), the
     99 framework must start and the framework requires <code>/data</code> to run. To resolve this conundrum, a temporary filesystem is mounted on <code>/data</code>. This allows Android to prompt for passwords, show progress, or suggest a data
    100 wipe as needed. It does impose the limitation that in order to switch from the
    101 temporary filesystem to the true <code>/data</code> filesystem, the system must stop every process with open files on the
    102 temporary filesystem and restart those processes on the real <code>/data</code> filesystem. To do this, all services must be in one of three groups: <code>core</code>, <code>main</code>, and <code>late_start</code>.</p>
    103 
    104 <ul>
    105   <li><code>core</code>: Never shut down after starting.
    106   <li><code>main</code>: Shut down and then restart after the disk password is entered.
    107   <li><code>late_start</code>: Does not start until after <code>/data</code> has been decrypted and mounted.
    108 </ul>
    109 
    110 <p>To trigger these actions, the  <code>vold.decrypt</code> property is set to <a href="https://android.googlesource.com/platform/system/vold/+/master/cryptfs.c">various strings</a>. To kill and restart services, the <code>init</code> commands are:</p>
    111 
    112 <ul>
    113   <li><code>class_reset</code>: Stops a service but allows it to be restarted with class_start.
    114   <li><code>class_start</code>: Restarts a service.
    115   <li><code>class_stop</code>: Stops a service and adds a <code>SVC_DISABLED</code> flag. Stopped services do not respond to <code>class_start</code>.
    116 </ul>
    117 
    118 <h2 id=flows>Flows</h2>
    119 
    120 <p>There are four flows for an encrypted device. A device is encrypted just once
    121 and then follows a normal boot flow.  </p>
    122 
    123 <ul>
    124   <li>Encrypt a previously unencrypted device:
    125   <ul>
    126     <li>Encrypt a new device with <code>forceencrypt</code>: Mandatory encryption at first boot (starting in Android L).
    127     <li>Encrypt an existing device: User-initiated encryption (Android K and earlier).
    128   </ul>
    129   <li>Boot an encrypted device:
    130   <ul>
    131     <li>Starting an encrypted device with no password: Booting an encrypted device that
    132 has no set password (relevant for devices running Android 5.0 and later).
    133     <li> Starting an encrypted device with a password: Booting an encrypted device that
    134 has a set password.
    135   </ul>
    136 </ul>
    137 
    138 <p>In addition to these flows, the device can also fail to encrypt <code>/data</code>. Each of the flows are explained in detail below.</p>
    139 
    140 <h3 id=encrypt_a_new_device_with_forceencrypt>Encrypt a new device with /forceencrypt</h3>
    141 
    142 <p>This is the normal first boot for an Android 5.0 device. </p>
    143 
    144 <ol>
    145   <li><strong>Detect unencrypted filesystem with <code>/forceencrypt</code> flag</strong>
    146 
    147 <p>
    148 <code>/data</code> is not encrypted but needs to be because <code>/forceencrypt</code> mandates it.
    149 Unmount <code>/data</code>.</p>
    150 
    151   <li><strong>Start encrypting <code>/data</code></strong>
    152 
    153 <p><code>vold.decrypt = "trigger_encryption"</code> triggers <code>init.rc</code>, which will cause <code>vold</code> to encrypt <code>/data</code> with no password. (None is set because this should be a new device.)</p>
    154 
    155 
    156   <li><strong>Mount tmpfs</strong>
    157 
    158 
    159 <p><code>vold</code> mounts a tmpfs <code>/data</code> (using the tmpfs options from
    160 <code>ro.crypto.tmpfs_options</code>) and sets the property <code>vold.encrypt_progress</code> to 0.
    161 <code>vold</code> prepepares the tmpfs <code>/data</code> for booting an encrypted system and sets the
    162 property <code>vold.decrypt</code> to: <code>trigger_restart_min_framework</code>
    163 </p>
    164 
    165   <li><strong>Bring up framework to show progress</strong>
    166 
    167 
    168 <p>Because the device has virtually no data to encrypt, the progress bar will
    169 often not actually appear because encryption happens so quickly. See <a href="#encrypt_an_existing_device">Encrypt an existing device</a> for more details about the progress UI. </p>
    170 
    171   <li><strong>When <code>/data</code> is encrypted, take down the framework</strong>
    172 
    173 <p><code>vold</code>  sets <code>vold.decrypt</code> to
    174 <code>trigger_default_encryption</code> which starts the
    175 <code>defaultcrypto</code> service. (This starts the flow below for mounting a
    176 default encrypted userdata.) <code>trigger_default_encryption</code> checks the
    177 encryption type to see if <code>/data</code> is  encrypted with or without a
    178 password. Because Android 5.0 devices are encrypted on first boot, there should
    179 be no password set; therefore we decrypt and mount <code>/data</code>.</p>
    180 
    181   <li><strong>Mount <code>/data</code></strong>
    182 
    183 <p><code>init</code> then mounts <code>/data</code> on a tmpfs RAMDisk using parameters it picks up from <code>ro.crypto.tmpfs_options</code>, which is set in <code>init.rc</code>.</p>
    184 
    185   <li><strong>Start framework</strong>
    186 
    187 <p>Set <code>vold</code> to <code>trigger_restart_framework</code>, which continues the usual boot process.</p>
    188 </ol>
    189 
    190 <h3 id=encrypt_an_existing_device>Encrypt an existing device</h3>
    191 
    192 <p>This is what happens when you encrypt an unencrypted Android K or earlier
    193 device that has been migrated to L. Note that this is the same flow as used in
    194 K.</p>
    195 
    196 <p>This process is user-initiated and is referred to as inplace encryption in
    197 the code. When a user selects to encrypt a device, the UI makes sure the
    198 battery is fully charged and the AC adapter is plugged in so there is enough
    199 power to finish the encryption process.</p>
    200 
    201 <p class="warning"><strong>Warning:</strong> If the device runs out of power and shuts down before it has finished
    202 encrypting, file data is left in a partially encrypted state. The device must
    203 be factory reset and all data is lost.</p>
    204 
    205 <p>To enable inplace encryption, <code>vold</code> starts a loop to read each sector of the real block device and then write it
    206 to the crypto block device. <code>vold</code> checks to see if a sector is in use before reading and writing it, which makes
    207 encryption much faster on a new device that has little to no data. </p>
    208 
    209 <p><strong>State of device</strong>: Set <code>ro.crypto.state = "unencrypted"</code> and execute the <code>on nonencrypted</code> <code>init</code> trigger to continue booting.</p>
    210 
    211 <ol>
    212   <li><strong>Check password</strong>
    213 
    214 <p>The UI calls <code>vold</code> with the command <code>cryptfs enablecrypto inplace</code> where <code>passwd</code> is the user's lock screen password.</p>
    215 
    216   <li><strong>Take down the framework</strong>
    217 
    218 <p><code>vold</code> checks for errors, returns -1 if it can't encrypt, and prints a reason in the
    219 log. If it can encrypt, it sets the property <code>vold.decrypt</code> to <code>trigger_shutdown_framework</code>. This causes <code>init.rc</code> to stop services in the classes <code>late_start</code> and <code>main</code>. </p>
    220 
    221   <li><strong>Unmount <code>/data</code></strong>
    222 
    223 <p><code>vold</code> unmounts <code>/mnt/sdcard</code> and then <code>/data</code>.</p>
    224 
    225   <li><strong>Start encrypting <code>/data</code></strong>
    226 
    227 <p><code>vold</code> then sets up the crypto mapping, which creates a virtual crypto block device
    228 that maps onto the real block device but encrypts each sector as it is written,
    229 and decrypts each sector as it is read. <code>vold</code> then creates and writes out the crypto metadata.</p>
    230 
    231   <li><strong>While its encrypting, mount tmpfs</strong>
    232 
    233 <p><code>vold</code> mounts a tmpfs <code>/data</code> (using the tmpfs options from <code>ro.crypto.tmpfs_options</code>) and sets the property <code>vold.encrypt_progress</code> to 0. <code>vold</code> prepares the tmpfs <code>/data</code> for booting an encrypted system and sets the property <code>vold.decrypt</code> to: <code>trigger_restart_min_framework</code> </p>
    234 
    235   <li><strong>Bring up framework to show progress</strong>
    236 
    237 <p><code>trigger_restart_min_framework </code>causes <code>init.rc</code> to start the <code>main</code> class of services. When the framework sees that <code>vold.encrypt_progress</code> is set to 0, it brings up the progress bar UI, which queries that property
    238 every five seconds and updates a progress bar. The encryption loop updates <code>vold.encrypt_progress</code> every time it encrypts another percent of the partition. </p>
    239 
    240   <li><strong>When<code> /data</code> is encrypted, reboot</strong>
    241 
    242 <p>When <code>/data</code> is successfully encrypted, <code>vold</code> clears the flag <code>ENCRYPTION_IN_PROGRESS</code> in the metadata and reboots the system. </p>
    243 
    244 <p> If the reboot fails for some reason, <code>vold</code> sets the property <code>vold.encrypt_progress</code> to <code>error_reboot_failed</code> and the UI should display a message asking the user to press a button to
    245 reboot. This is not expected to ever occur.</p>
    246 </ol>
    247 
    248 <h3 id=starting_an_encrypted_device_with_default_encryption>Starting an encrypted device with default encryption</h3>
    249 
    250 <p>This is what happens when you boot up an encrypted device with no password.
    251 Because Android 5.0 devices are encrypted on first boot, there should be no set
    252 password and therefore this is the <em>default encryption</em> state.</p>
    253 
    254 <ol>
    255   <li><strong>Detect encrypted <code>/data</code> with no password</strong>
    256 
    257 <p>Detect that the Android device is encrypted because <code>/data</code>
    258 cannot be mounted and one of the flags <code>encryptable</code> or
    259 <code>forceencrypt</code> is set.</p>
    260 
    261 <p><code>vold</code> sets <code>vold.decrypt</code> to <code>trigger_default_encryption</code>, which starts the <code>defaultcrypto</code> service. <code>trigger_default_encryption</code> checks the encryption type to see if <code>/data</code> is  encrypted with or without a  password. </p>
    262 
    263   <li><strong>Decrypt /data</strong>
    264 
    265 <p>Creates the <code>dm-crypt</code> device over the block device so the device is ready for use.</p>
    266 
    267   <li><strong>Mount /data</strong>
    268 
    269 <p><code>vold</code> then mounts the decrypted real <code>/data </code>partition and then prepares the new partition. It sets the property <code>vold.post_fs_data_done</code> to 0 and then sets <code>vold.decrypt</code> to <code>trigger_post_fs_data</code>. This causes <code>init.rc</code> to run its <code>post-fs-data</code> commands. They will create any necessary directories or links and then set <code>vold.post_fs_data_done</code> to 1.</p>
    270 
    271 <p>Once <code>vold</code> sees the 1 in that property, it sets the property <code>vold.decrypt</code> to: <code>trigger_restart_framework.</code> This causes <code>init.rc</code> to start services in class <code>main</code> again and also start services in class <code>late_start</code> for the first time since boot.</p>
    272 
    273   <li><strong>Start framework</strong>
    274 
    275 <p>Now the framework boots all its services using the decrypted <code>/data</code>, and the system is ready for use.</p>
    276 </ol>
    277 
    278 <h3 id=starting_an_encrypted_device_without_default_encryption>Starting an encrypted device without default encryption</h3>
    279 
    280 <p>This is what happens when you boot up an encrypted device that has a set
    281 password. The devices password can be a pin, pattern, or password. </p>
    282 
    283 <ol>
    284   <li><strong>Detect encrypted device with a password</strong>
    285 
    286 <p>Detect that the Android device is encrypted because the flag <code>ro.crypto.state = "encrypted"</code></p>
    287 
    288 <p><code>vold</code> sets <code>vold.decrypt</code> to <code>trigger_restart_min_framework</code> because <code>/data</code> is  encrypted with a password.</p>
    289 
    290   <li><strong>Mount tmpfs</strong>
    291 
    292 <p><code>init</code> sets five properties to save the initial mount options given for <code>/data</code> with parameters passed from <code>init.rc</code>.  <code>vold</code> uses these properties to set up the crypto mapping:</p>
    293 
    294 <ol>
    295   <li><code>ro.crypto.fs_type</code>
    296   <li><code>ro.crypto.fs_real_blkdev</code>
    297   <li><code>ro.crypto.fs_mnt_point</code>
    298   <li><code>ro.crypto.fs_options</code>
    299   <li><code>ro.crypto.fs_flags </code>(ASCII 8-digit hex number preceded by 0x)
    300   </ol>
    301 
    302   <li><strong>Start framework to prompt for password</strong>
    303 
    304 <p>The framework starts up and sees that <code>vold.decrypt</code> is set to <code>trigger_restart_min_framework</code>. This tells the framework that it is booting on a tmpfs <code>/data</code> disk and it needs to get the user password.</p>
    305 
    306 <p>First, however, it needs to make sure that the disk was properly encrypted. It
    307 sends the command <code>cryptfs cryptocomplete</code> to <code>vold</code>. <code>vold</code> returns 0 if encryption was completed successfully, -1 on internal error, or
    308 -2 if encryption was not completed successfully. <code>vold</code> determines this by looking in the crypto metadata for the <code>CRYPTO_ENCRYPTION_IN_PROGRESS</code> flag. If it's set, the encryption process was interrupted, and there is no
    309 usable data on the device. If <code>vold</code> returns an error, the UI should display a message to the user to reboot and
    310 factory reset the device, and give the user a button to press to do so.</p>
    311 
    312   <li><strong>Decrypt data with password</strong>
    313 
    314 <p>Once <code>cryptfs cryptocomplete</code> is successful, the framework displays a UI asking for the disk password. The
    315 UI checks the password by sending the command <code>cryptfs checkpw</code> to <code>vold</code>. If the password is correct (which is determined by successfully mounting the
    316 decrypted <code>/data</code> at a temporary location, then unmounting it), <code>vold</code> saves the name of the decrypted block device in the property <code>ro.crypto.fs_crypto_blkdev</code> and returns status 0 to the UI. If the password is incorrect, it returns -1 to
    317 the UI.</p>
    318 
    319   <li><strong>Stop framework</strong>
    320 
    321 <p>The UI puts up a crypto boot graphic and then calls <code>vold</code> with the command <code>cryptfs restart</code>. <code>vold</code> sets the property <code>vold.decrypt</code> to <code>trigger_reset_main</code>, which causes <code>init.rc</code> to do <code>class_reset main</code>. This stops all services in the main class, which allows the tmpfs <code>/data</code> to be unmounted. </p>
    322 
    323   <li><strong>Mount <code>/data</code></strong>
    324 
    325 <p><code>vold</code> then mounts the decrypted real <code>/data </code>partition and prepares the new partition (which may never have been prepared if
    326 it was encrypted with the wipe option, which is not supported on first
    327 release). It sets the property <code>vold.post_fs_data_done</code> to 0 and then sets <code>vold.decrypt</code> to <code>trigger_post_fs_data</code>. This causes <code>init.rc</code> to run its <code>post-fs-data</code> commands. They will create any necessary directories or links and then set <code>vold.post_fs_data_done</code> to 1. Once <code>vold</code> sees the 1 in that property, it sets the property <code>vold.decrypt</code> to <code>trigger_restart_framework</code>. This causes <code>init.rc</code> to start services in class <code>main</code> again and also start services in class <code>late_start</code> for the first time since boot.</p>
    328 
    329   <li><strong>Start full framework</strong>
    330 
    331 <p>Now the framework boots all its services using the decrypted <code>/data</code> filesystem, and the system is ready for use.</p>
    332 </ol>
    333 
    334 <h3 id=failure>Failure</h3>
    335 
    336 <p>A device that fails to decrypt might be awry for a few reasons. The device
    337 starts with the normal series of steps to boot:</p>
    338 
    339 <ol>
    340   <li>Detect encrypted device with a password
    341   <li>Mount tmpfs
    342   <li>Start framework to prompt for password
    343 </ol>
    344 
    345 <p>But after the framework opens, the device can encounter some errors:</p>
    346 
    347 <ul>
    348   <li>Password matches but cannot decrypt data
    349   <li>User enters wrong password 30 times
    350 </ul>
    351 
    352 <p>If these errors are not resolved, <strong>prompt user to factory wipe</strong>:</p>
    353 
    354 <p>If <code>vold</code> detects an error during the encryption process, and if no data has been
    355 destroyed yet and the framework is up, <code>vold</code> sets the property <code>vold.encrypt_progress </code>to <code>error_not_encrypted</code>. The UI prompts the user to reboot and alerts them the encryption process
    356 never started. If the error occurs after the framework has been torn down, but
    357 before the progress bar UI is up, <code>vold</code> will reboot the system. If the reboot fails, it sets <code>vold.encrypt_progress</code> to <code>error_shutting_down</code> and returns -1; but there will not be anything to catch the error. This is not
    358 expected to happen.</p>
    359 
    360 <p>If <code>vold</code> detects an error during the encryption process, it sets <code>vold.encrypt_progress</code> to <code>error_partially_encrypted</code> and returns -1. The UI should then display a message saying the encryption
    361 failed and provide a button for the user to factory reset the device. </p>
    362 
    363 <h2 id=storing_the_encrypted_key>Storing the encrypted key</h2>
    364 
    365 <p>The encrypted key is stored in the crypto metadata. Hardware backing is implemented by using Trusted Execution Environments (TEE) signing capability.
    366 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
    367 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>
    368 
    369 <ol>
    370   <li>Generate random 16-byte disk encryption key (DEK) and 16-byte salt.
    371   <li>Apply scrypt to the user password and the salt to produce 32-byte intermediate
    372 key 1 (IK1).
    373   <li>Pad IK1 with zero bytes to the size of the hardware-bound private key (HBK).
    374 Specifically, we pad as: 00 || IK1 || 00..00; one zero byte, 32 IK1 bytes, 223
    375 zero bytes.
    376   <li>Sign padded IK1 with HBK to produce 256-byte IK2.
    377   <li>Apply scrypt to IK2 and salt (same salt as step 2) to produce 32-byte IK3.
    378   <li>Use the first 16 bytes of IK3 as KEK and the last 16 bytes as IV.
    379   <li>Encrypt DEK with AES_CBC, with key KEK, and initialization vector IV.
    380 </ol>
    381 
    382 <h2 id=changing_the_password>Changing the password</h2>
    383 
    384 <p>When a user elects to change or remove their password in settings, the UI sends
    385 the command <code>cryptfs changepw</code>  to <code>vold</code>, and <code>vold</code> re-encrypts the disk master key with the new password.</p>
    386 
    387 <h2 id=encryption_properties>Encryption properties</h2>
    388 
    389 <p><code>vold</code> and <code>init</code> communicate with each other by setting properties. Here is a list of available
    390 properties for encryption.</p>
    391 
    392 <h3 id=vold_properties>Vold properties </h3>
    393 
    394 <table>
    395   <tr>
    396     <th>Property</th>
    397     <th>Description</th>
    398   </tr>
    399   <tr>
    400     <td><code>vold.decrypt  trigger_encryption</code></td>
    401     <td>Encrypt the drive with no
    402     password.</td>
    403   </tr>
    404   <tr>
    405     <td><code>vold.decrypt  trigger_default_encryption</code></td>
    406     <td>Check the drive to see if it is encrypted with no password.
    407 If it is, decrypt and mount it,
    408 else set <code>vold.decrypt</code> to trigger_restart_min_framework.</td>
    409   </tr>
    410   <tr>
    411     <td><code>vold.decrypt  trigger_reset_main</code></td>
    412     <td>Set by vold to shutdown the UI asking for the disk password.</td>
    413   </tr>
    414   <tr>
    415     <td><code>vold.decrypt  trigger_post_fs_data</code></td>
    416     <td> Set by vold to prep /data with necessary directories, et al.</td>
    417   </tr>
    418   <tr>
    419     <td><code>vold.decrypt  trigger_restart_framework</code></td>
    420     <td>Set by vold to start the real framework and all services.</td>
    421   </tr>
    422   <tr>
    423     <td><code>vold.decrypt  trigger_shutdown_framework</code></td>
    424     <td>Set by vold to shutdown the full framework to start encryption.</td>
    425   </tr>
    426   <tr>
    427     <td><code>vold.decrypt  trigger_restart_min_framework</code></td>
    428     <td>Set by vold to start the
    429 progress bar UI for encryption or
    430 prompt for password, depending on
    431 the value of <code>ro.crypto.state</code>.</td>
    432   </tr>
    433   <tr>
    434     <td><code>vold.encrypt_progress</code></td>
    435     <td>When the framework starts up,
    436 if this property is set, enter
    437 the progress bar UI mode.</td>
    438   </tr>
    439   <tr>
    440     <td><code>vold.encrypt_progress  0 to 100</code></td>
    441     <td>The progress bar UI should
    442 display the percentage value set.</td>
    443   </tr>
    444   <tr>
    445     <td><code>vold.encrypt_progress  error_partially_encrypted</code></td>
    446     <td>The progress bar UI should display a message that the encryption failed, and
    447 give the user an option to
    448 factory reset the device.</td>
    449   </tr>
    450   <tr>
    451     <td><code>vold.encrypt_progress  error_reboot_failed</code></td>
    452     <td>The progress bar UI should
    453 display a message saying encryption completed, and give the user a button to reboot the device. This error is not expected to happen.</td>
    454   </tr>
    455   <tr>
    456     <td><code>vold.encrypt_progress  error_not_encrypted</code></td>
    457     <td>The progress bar UI should
    458 display a message saying an error
    459 occurred,  no data was encrypted or
    460 lost, and give the user a button to reboot the system.</td>
    461   </tr>
    462   <tr>
    463     <td><code>vold.encrypt_progress  error_shutting_down</code></td>
    464     <td>The progress bar UI is not running, so it is unclear who will respond to this error. And it should never happen anyway.</td>
    465   </tr>
    466   <tr>
    467     <td><code>vold.post_fs_data_done  0</code></td>
    468     <td>Set by <code>vold</code> just before setting <code>vold.decrypt</code> to <code>trigger_post_fs_data</code>.</td>
    469   </tr>
    470   <tr>
    471     <td><code>vold.post_fs_data_done  1</code></td>
    472     <td>Set by <code>init.rc</code> or
    473     <code>init.rc</code> just after finishing the task <code>post-fs-data</code>.</td>
    474   </tr>
    475 </table>
    476 <h3 id=init_properties>init properties</h3>
    477 
    478 <table>
    479   <tr>
    480     <th>Property</th>
    481     <th>Description</th>
    482   </tr>
    483   <tr>
    484     <td><code>ro.crypto.fs_crypto_blkdev</code></td>
    485     <td>Set by the <code>vold</code> command <code>checkpw</code> for later use by the <code>vold</code> command <code>restart</code>.</td>
    486   </tr>
    487   <tr>
    488     <td><code>ro.crypto.state unencrypted</code></td>
    489     <td>Set by <code>init</code> to say this system is running with an unencrypted
    490     <code>/data ro.crypto.state encrypted</code>. Set by <code>init</code> to say this system is running with an encrypted <code>/data</code>.</td>
    491   </tr>
    492   <tr>
    493     <td><p><code>ro.crypto.fs_type<br>
    494       ro.crypto.fs_real_blkdev      <br>
    495       ro.crypto.fs_mnt_point<br>
    496       ro.crypto.fs_options<br>
    497       ro.crypto.fs_flags      <br>
    498     </code></p></td>
    499     <td> These five properties are set by
    500       <code>init</code> when it tries to mount <code>/data</code> with parameters passed in from
    501     <code>init.rc</code>. <code>vold</code> uses these to setup the crypto mapping.</td>
    502   </tr>
    503   <tr>
    504     <td><code>ro.crypto.tmpfs_options</code></td>
    505     <td>Set by <code>init.rc</code> with the options init should use when mounting the tmpfs /data filesystem.</td>
    506   </tr>
    507 </table>
    508 <h2 id=init_actions>Init actions</h2>
    509 
    510 <pre>
    511 on post-fs-data
    512 on nonencrypted
    513 on property:vold.decrypt=trigger_reset_main
    514 on property:vold.decrypt=trigger_post_fs_data
    515 on property:vold.decrypt=trigger_restart_min_framework
    516 on property:vold.decrypt=trigger_restart_framework
    517 on property:vold.decrypt=trigger_shutdown_framework
    518 on property:vold.decrypt=trigger_encryption
    519 on property:vold.decrypt=trigger_default_encryption
    520 </pre>
    521