aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielle Roberts <daroberts@google.com>2016-07-26 21:47:57 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-07-26 21:47:57 +0000
commit7138dcf8da9893bae490b6ab03a4a29d43b35ee5 (patch)
treecebbc1fd933346058f7db0b78dfd0bc5d0d3108c
parente23ae52e282c73f6b77b31bb8219ec5114fbf913 (diff)
parenta136b014bdf92d606ea87b5d66bac947532bd0bb (diff)
downloadsource.android.com-7138dcf8da9893bae490b6ab03a4a29d43b35ee5.tar.gz
Docs: Add file-based encryption docs
am: a136b014bd Change-Id: I468318759367907bf8274e1cfabe9ce873cc8de3
-rw-r--r--src/security/encryption/file-based.jd500
-rw-r--r--src/security/encryption/full-disk.jd630
-rw-r--r--src/security/encryption/index.jd535
-rw-r--r--src/security/security_toc.cs6
4 files changed, 1178 insertions, 493 deletions
diff --git a/src/security/encryption/file-based.jd b/src/security/encryption/file-based.jd
new file mode 100644
index 00000000..e21a8e41
--- /dev/null
+++ b/src/security/encryption/file-based.jd
@@ -0,0 +1,500 @@
+page.title=File-Based Encryption
+@jd:body
+
+<!--
+ Copyright 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>
+Android 7.0 and above supports file-based encryption (FBE). File-based
+encryption allows different files to be encrypted with different keys that can
+be unlocked independently.
+</p>
+<p>
+This article describes how to enable file-based encryption on new devices
+and how system applications can be updated to take full advantage of the new
+Direct Boot APIs and offer users the best, most secure experience possible.
+</p>
+<h2 id="direct-boot">Direct Boot</h2>
+<p>
+File-based encryption enables a new feature introduced in Android 7.0 called <a
+href="https://developer.android.com/preview/features/direct-boot.html">Direct
+Boot</a>. Direct Boot allows encrypted devices to boot straight to the lock
+screen. Previously, on encrypted devices using <a href="full-disk.html">full disk
+encryption</a> (FDE), users needed to provided credentials before any data could
+be accessed, preventing the phone from performing all but the most basic of
+operations. For example, alarms could not operate, accessibility services were
+unavailable, and phones could not receive calls but were limited to only basic
+emergency dialer operations.
+</p>
+<p>
+With the introduction of file-based encryption (FBE) and new APIs to make
+applications aware of encryption, it is possible for these apps to operate
+within a limited context. This can happen before users have provided their
+credentials while still protecting private user information.
+</p>
+<p>
+On an FBE-enabled device, each user of the device has two storage locations
+available to applications:
+</p><ul>
+<li>Credential Encrypted (CE) storage, which is the default storage location and
+only available after the user has unlocked the device.
+<li>Device Encrypted (DE) storage, which is a storage location available both
+during Direct Boot mode and after the user has unlocked the device.</li></ul>
+<p>
+This separation makes work profiles more secure because it allows more than one
+user to be protected at a time as the encryption is no longer based solely on a
+boot time password.
+</p>
+<p>
+The Direct Boot API allows encryption-aware applications to access each of these
+areas. There are changes to the application lifecycle to accommodate the need to
+notify applications when a user’s CE storage is <em>unlocked</em> in response to
+first entering credentials at the lock screen, or in the case of work profile
+providing a <a
+href="https://developer.android.com/preview/api-overview.html#android_for_work">work
+challenge</a>. Devices running Android 7.0 must support these new APIs and
+lifecycles regardless of whether or not they implement FBE. Although, without
+FBE, DE and CE storage will always be in the unlocked state.
+</p>
+<p>
+A complete implementation of file based encryption on an Ext4 file system is
+provided in the Android Open Source Project (AOSP) and needs only be enabled on
+devices that meet the requirements. Manufacturers electing to use FBE may wish
+to explore ways of optimizing the feature based on the system on chip (SoC)
+used.
+</p>
+<p>
+All the necessary packages in AOSP have been updated to be direct-boot aware.
+However, where device manufacturers use customized versions of these apps, they
+will want to ensure at a minimum there are direct-boot aware packages providing
+the following services:
+</p>
+
+<ul>
+<li>Telephony Services and Dialer
+<li>Input method for entering passwords into the lock screen
+</ul>
+
+<h2 id="examples-and-source">Examples and source</h2>
+
+<p>
+Android provides a reference implementation of file-based encryption, in which
+vold (system/vold) provides the functionality for managing storage devices and
+volumes on Android. The addition of FBE provides vold with several new commands
+to support key management for the CE and DE keys of multiple users. In addition
+to the core changes to use the <a href="#kernel-support">ext4 Encryption</a>
+capabilities in kernel many system packages including the lockscreen and the
+SystemUI have been modified to support the FBE and Direct Boot features. These
+include:
+</p>
+
+<ul>
+<li>AOSP Dialer (packages/apps/Dialer)
+<li>Desk Clock (packages/apps/DeskClock)
+<li>LatinIME (packages/inputmethods/LatinIME)*
+<li>Settings App (packages/apps/Settings)*
+<li>SystemUI (frameworks/base/packages/SystemUI)*</li></ul>
+<p>
+<em>* System applications that use the <code><a
+href="#supporting-direct-boot-in-system-applications">defaultToDeviceProtectedStorage</a></code>
+manifest attribute</em>
+</p>
+<p>
+More examples of applications and services that are encryption aware can be
+found by running the command <code>mangrep directBootAware</code> in the
+frameworks or packages directory of the AOSP
+source tree.
+</p>
+<h2 id="dependencies">Dependencies</h2>
+<p>
+To use the AOSP implementation of FBE securely, a device needs to meet the
+following dependencies:
+</p>
+
+<ul>
+<li><strong>Kernel Support</strong> for ext4 encryption (Kernel config option:
+EXT4_FS_ENCRYPTION)
+<li><strong><a
+href="{@docRoot}security/keystore/index.html">Keymaster
+Support</a></strong> with a HAL version 1.0 or 2.0. There is no support for
+Keymaster 0.3 as that does not provide that necessary capabilities or assure
+sufficient protection for encryption keys.
+<li><strong>Keymaster/<a
+href="{@docRoot}security/keystore/index.html">Keystore</a> and
+Gatekeeper</strong> must be implemented in a <a
+href="{@docRoot}security/trusty/index.html">Trusted Execution
+Environment</a> (TEE) to provide protection for the DE keys so that an
+unauthorized OS (custom OS flashed onto the device) cannot simply request the
+DE keys.
+<li><strong>Encryption performance</strong> in the kernel of at least 50MB/s
+using AES XTS to ensure a good user experience.
+<li><strong>Hardware Root of Trust</strong> and <strong>Verified Boot</strong>
+bound to the keymaster initialisation is required to ensure that Device
+Encryption credentials are not accessible by an unauthorized operating
+system.</li>
+</ul>
+
+<p class="note">
+<strong>Note</strong>: Storage policies are applied to a folder and all of its
+subfolders. Manufacturers should limit the contents that go unencrypted to the
+OTA folder and the folder that holds the key that decrypts the system. Most
+contents should reside in credential-encrypted storage rather than
+device-encrypted storage.
+</p>
+
+<h2 id="implementation">Implementation</h2>
+<p>
+First and foremost, apps such as alarm clocks, phone, accessibility features
+should be made android:directBootAware according to <a
+href="https://developer.android.com/preview/features/direct-boot.html">Direct
+Boot</a> developer documentation.
+</p>
+<h3 id="kernel-support">Kernel Support</h3>
+<p>
+The AOSP implementation of file-based encryption uses the ext4 encryption
+features in the Linux 4.4 kernel. The recommended solution is to use a kernel
+based on 4.4 or later. Ext4 encryption has also been backported to a 3.10 kernel
+in the Android common repositories and for the supported Nexus kernels.
+</p>
+<p>
+The android-3.10.y branch in the AOSP kernel/common git repository may
+provide a good starting point for device manufacturers that want to import this
+capability into their own device kernels. However, it is necessary to apply
+the most recent patches from the latest stable Linux kernel (currently <a
+href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/?id=refs/tags/v4.6">linux-4.6</a>)
+of the ext4 and jbd2 projects. The Nexus device kernels already include many of
+these patches.
+</p>
+<table>
+ <tr>
+ <th>Device</th>
+ <th>Kernel</th>
+ </tr>
+ <tr>
+ <td>Android Common
+ </td>
+ <td><strong>kernel/common</strong> android-3.10.y (<a
+href="https://android.googlesource.com/kernel/common/+/android-3.10.y">git</a>)
+ </td>
+ </tr>
+ <tr>
+ <td>Nexus 5X (bullhead)
+ </td>
+ <td><strong>kernel/msm</strong> android-msm-bullhead-3.10-n-preview-2 (<a
+href="https://android.googlesource.com/kernel/msm/+/android-msm-bullhead-3.10-n-preview-2">git</a>)
+ </td>
+ </tr>
+ <tr>
+ <td>Nexus 6P (angler)
+ </td>
+ <td><strong>kernel/msm</strong> android-msm-angler-3.10-n-preview-2 (<a
+href="https://android.googlesource.com/kernel/msm/+/android-msm-angler-3.10-n-preview-2">git</a>
+ )
+ </td>
+ </tr>
+</table>
+<p>
+Note that each of these kernels uses a backport to 3.10. The ext4
+and jbd2 drivers from linux 3.18 were transplanted into existing kernels based
+on 3.10. Due to interdependencies between parts of the kernel, this backport
+breaks support for a number of features that are not used by Nexus devices.
+These include:
+</p>
+
+<ul>
+<li>The ext3 driver, although ext4 can still mount and use ext3 filesystems
+<li>Global File Sytem (GFS) Support
+<li>ACL support in ext4</li>
+</ul>
+
+<p>
+In addition to functional support for ext4 encryption, device manufacturers may
+also consider implementing cryptographic acceleration to speed up file-based
+encryption and improve the user experience.
+</p>
+<h3 id="enabling-file-based-encryption">Enabling file-based encryption</h3>
+<p>
+FBE is enabled by adding the flag <code>fileencryption</code> with no parameters
+to the <code>fstab</code> line in the final column for the <code>userdata</code>
+partition. You can see an example at:
+<a href="https://android.googlesource.com/device/lge/bullhead/+/nougat-release/fstab_fbe.bullhead">
+https://android.googlesource.com/device/lge/bullhead/+/nougat-release/fstab_fbe.bullhead</a>
+</p>
+<p>
+Whilst testing the FBE implementation on a device, it is possible to specify the
+following flag:
+<code>forcefdeorfbe="&lt;path/to/metadata/partition&gt;"</code>
+</p>
+<p>
+This sets the device up with FDE but allows conversion to FBE for developers. By
+default, this behaves like <code>forceencrypt</code>, putting the device into
+FDE mode. However, it will expose a debug option allowing a device to be put
+into FBE mode as is the case in the developer preview. It is also possible to
+enable FBE from fastboot using this command:
+</p>
+<p>
+<code>$ fastboot --wipe-and-use-fbe</code>
+</p>
+<p>
+This is intended solely for development purposes as a platform for demonstrating
+the feature before actual FBE devices are released. This flag may be deprecated
+in the future.
+</p>
+<h3 id="integrating-with-keymaster">Integrating with Keymaster</h3>
+<p>
+The generation of keys and management of the kernel keyring is handled by
+<code>vold</code>. The AOSP implementation of FBE requires that the device
+support Keymaster HAL version 1.0 or later. There is no support for earlier
+versions of the Keymaster HAL.
+</p>
+<p>
+On first boot, user 0’s keys are generated and installed early in the boot
+process. By the time the <code>on-post-fs</code> phase of <code>init</code>
+completes, the Keymaster must be ready to handle requests. On Nexus devices,
+this is handled by having a script block:
+</p>
+
+<ul>
+<li>Ensure Keymaster is started before <code>/data</code> is mounted
+<li>Specify the file encryption cipher suite: AOSP implementation of file-based
+encryption uses AES-256 in XTS mode
+<p class="note">
+<strong>Note</strong>: All encryption is based on AES-256 in
+XTS mode. Due to the way XTS is defined, it needs two 256-bit keys; so in
+effect, both CE and DE keys are 512-bit keys.i
+</p>
+</li>
+</ul>
+
+<h3 id="encryption-policy">Encryption policy</h3>
+<p>
+Ext4 encryption applies the encryption policy at the directory level. When a
+device’s <code>userdata</code> partition is first created, the basic structures
+and policies are applied by the <code>init</code> scripts. These scripts will
+trigger the creation of the first user’s (user 0’s) CE and DE keys as well as
+define which directories are to be encrypted with these keys. When additional
+users and profiles are created, the necessary additional keys are generated and
+stored in the keystore; their credential and devices storage locations are
+created and the encryption policy links these keys to those directories.
+</p>
+<p>
+In the current AOSP implementation, the encryption policy is hardcoded into this
+location:
+</p>
+<p>
+<code>/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp</code>
+</p>
+<p>
+It is possible to add exceptions in this file to prevent certain directories
+from being encrypted at all, by adding to the <code>directories_to_exclude</code>
+list. If modifications of this sort are made then the device
+manufacturer should include <a href="{@docRoot}security/selinux/device-policy.html">
+SELinux policies</a> that only grant access to the
+applications that need to use the unencrypted directory. This should exclude all
+untrusted applications.
+</p>
+<p>
+The only known acceptable use case for this is in support of legacy OTA
+capabilities.
+</p>
+<h3 id="supporting-direct-boot-in-system-applications">
+Supporting Direct Boot in system applications</h3>
+
+<h4 id="making-applications-direct-boot-aware">
+Making applications Direct Boot aware</h4>
+<p>
+To facilitate rapid migration of system apps, there are two new attributes that
+can be set at the application level. The
+<code>defaultToDeviceProtectedStorage</code> attribute is available only to
+system apps. The <code>directBootAware</code> attribute is available to all.
+</p>
+
+<pre>
+&lt;application
+ android:directBootAware="true"
+ android:defaultToDeviceProtectedStorage="true"&gt;
+</pre>
+
+<p>
+The <code>directBootAware</code> attribute at the application level is shorthand for marking
+all components in the app as being encryption aware.
+</p>
+<p>
+The <code>defaultToDeviceProtectedStorage</code> attribute redirects the default
+app storage location to point at DE storage instead of pointing at CE storage.
+System apps using this flag must carefully audit all data stored in the default
+location, and change the paths of sensitive data to use CE storage. Device
+manufactures using this option should carefully inspect the data that they are
+storing to ensure that it contains no personal information.
+</p>
+<p>
+When running in this mode, the following System APIs are
+available to explicitly manage a Context backed by CE storage when needed, which
+are equivalent to their Device Protected counterparts.
+</p>
+
+<ul>
+<li><code>Context.createCredentialProtectedStorageContext()</code>
+<li><code>Context.isCredentialProtectedStorage()</code></li>
+</ul>
+<h4 id="supporting-multiple-users">Supporting multiple users</h4>
+<p>
+Each user in a multi-user environment gets a separate encryption key. Every user
+gets two keys: a DE and a CE key. User 0 must log into the device first as it is
+a special user. This is pertinent for <a
+href="{@docRoot}devices/tech/admin/index.html">Device
+Administration</a> uses.
+</p>
+<p>
+Crypto-aware applications interact across users in this manner:
+<code>INTERACT_ACROSS_USERS</code> and <code>INTERACT_ACROSS_USERS_FULL</code>
+allow an application to act across all the users on the device. However, those
+apps will be able to access only CE-encrypted directories for users that are
+already unlocked.
+</p>
+<p>
+An application may be able to interact freely across the DE areas, but one user
+unlocked does not mean that all the users on the device are unlocked. The
+application should check this status before trying to access these areas.
+</p>
+<p>
+Each work profile user ID also gets two keys: DE and CE. When the work challenge
+is met, the profile user is unlocked and the Keymaster (in TEE) can provide the
+profile’s TEE key.
+</p>
+<h3 id="handling-updates">Handling updates</h3>
+<p>
+The recovery partition is unable to access the DE protected storage on the
+userdata partition. Devices implementing FBE are strongly recommended to support
+OTA using the upcoming A/B system updates. As the OTA can be applied during
+normal operation there is no need for recovery to access data on the encrypted drive.
+</p>
+<p>
+If a legacy OTA solution is used, which requires recovery to access the OTA file
+on the userdata partition then:
+</p>
+
+<ul>
+<li>Create a top level directory (for example “misc_ne”) in the userdata
+partition.
+<li>Add this top level directory to the encryption policy exception (see <a
+href="#encryption-policy">Encryption policy</a> above).
+<li>Create a directory with this to hold OTA packages.
+<li>Add an SELinux rule and file contexts to control access to this folder and
+it contents. Only the process or applications receiving OTA updates should be be
+able to read and write to this folder.
+<li>No other application or process should have access to this folder.</li>
+</ul>
+
+<p>
+Within this folder create a directory to contain the OTA packages.
+</p>
+<h2 id="validation">Validation</h2>
+<p>
+To ensure the implemented version of the feature works as intended, employ the
+many <a href="://android.googlesource.com/platform/cts/+/nougat-cts-release/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java">
+CTS encryption tests</a>.
+</p>
+<p>
+Once the kernel builds for your board, it should be tested by building an x86
+kernel that can be tested using QEMU. This will allow the implementation to be
+tested using
+<a hre="https://git.kernel.org/cgit/fs/ext2/xfstests-bld.git/plain/quick-start?h=META">
+xfstest</a>. Test the crypto support using:
+</p>
+<pre>
+$ kvm-xfstests -c encrypt -g auto
+</pre>
+<p>
+In addition, device manufacturers may perform these manual tests. On a device
+with FBE enabled:
+</p>
+
+<ul>
+ <li>Check that <code>ro.crypto.state</code> exists
+ <ul>
+ <li>Ensure <code>ro.crypto.state</code> is encrypted</li>
+ </ul>
+ </li>
+ <li>Check that <code>ro.crypto.type</code> exists
+ <ul>
+ <li>Ensure <code>ro.crypto.type</code> is set to <code>file</code></li>
+ </ul>
+ </li>
+</ul>
+
+<p>
+Additionally, testers can boot a <code>userdebug</code> instance with a lockscreen set on the
+primary user. Then <code>adb</code> shell into the device and use
+<code>su</code> to become root. Make sure <code>/data/data</code> contains
+encrypted filenames; if it does not, something is wrong.
+</p>
+<h2 id="aosp-implementation-details">AOSP implementation details</h2>
+<p>
+This section provides details on the AOSP implementation and describes how
+file-based encryption works. It should not be necessary for device manufacturers
+to make any changes here to use FBE and Direct Boot on their devices.
+</p>
+<h3 id="ext4-encryption">ext4 encryption</h3>
+<p>
+The AOSP implementation uses ext4 encryption in kernel and is configured to:
+</p><ul>
+<li>Encrypt file contents with AES-256 in XTS mode
+<li>Encrypt file names with AES-256 in CBC-CTS mode</li></ul>
+<h3 id="key-derivation">Key derivation</h3>
+<p>
+Disk encryption keys, which are 512-bit AES-XTS keys, are stored encrypted
+by another key (a 256-bit AES-GCM key) held in the TEE. To use this TEE key,
+three requirements must be met:
+</p><ul>
+<li>The auth token
+<li>The stretched credential
+<li>The “secdiscardable hash”</li></ul>
+<p>
+The <em>auth token</em> is a cryptographically authenticated token generated by
+<a
+href="{@docRoot}security/authentication/gatekeeper.html">Gatekeeper</a>
+when a user successfully logs in. The TEE will refuse to use the key unless the
+correct auth token is supplied. If the user has no credential, then no auth
+token is used nor needed.
+</p>
+<p>
+The <em>stretched credential</em> is the user credential after salting and
+stretching with the <code>scrypt</code> algorithm. The credential is actually
+hashed once in the lock settings service before being passed to
+<code>vold</code> for passing to <code>scrypt</code>. This is cryptographically
+bound to the key in the TEE with all the guarantees that apply to
+<code>KM_TAG_APPLICATION_ID</code>. If the user has no credential, then no
+stretched credential is used nor needed.
+</p>
+<p>
+The <code>secdiscardable hash</code> is a 512-bit hash of a random 16 KB file
+stored alongside other information used to reconstruct the key, such as the
+seed. This file is securely deleted when the key is deleted, or it is encrypted
+in a new way; this added protection ensures an attacker must recover every bit
+of this securely deleted file to recover the key. This is cryptographically
+bound to the key in the TEE with all the guarantees that apply to
+<code>KM_TAG_APPLICATION_ID</code>. See the <a
+href="{@docRoot}security/keystore/implementer-ref.html">Keystore
+Implementer's Reference</a>.
diff --git a/src/security/encryption/full-disk.jd b/src/security/encryption/full-disk.jd
new file mode 100644
index 00000000..8a598258
--- /dev/null
+++ b/src/security/encryption/full-disk.jd
@@ -0,0 +1,630 @@
+page.title=Full-Disk Encryption
+@jd:body
+
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol id="auto-toc">
+ </ol>
+ </div>
+</div>
+
+<p>Full-disk encryption is the process of encoding all 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>
+
+<p>
+Full-disk encryption was introduced to Android in 4.4, but Android 5.0 introduced
+these new features:</p>
+<ul>
+ <li>Created fast encryption, which only encrypts used blocks on the data partition
+to avoid first boot taking a long time. Only ext4 and f2fs filesystems
+currently support fast encryption.
+ <li>Added the <a href="{@docRoot}devices/storage/config.html"><code>forceencrypt</code>
+ fstab flag</a> to encrypt on first boot.
+ <li>Added support for patterns and encryption without a password.
+ <li>Added hardware-backed storage of the encryption key using Trusted
+ Execution Environment’s (TEE) signing capability (such as in a TrustZone).
+ See <a href="#storing_the_encrypted_key">Storing the encrypted key</a> for more
+ details.
+</ul>
+
+<p class="caution"><strong>Caution:</strong> 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>
+
+<h2 id=how_android_encryption_works>How Android full-disk encryption works</h2>
+
+<p>Android full-disk encryption is based on <code>dm-crypt</code>, which is a kernel
+feature that works at the block device layer. Because of
+this, encryption works with Embedded MultiMediaCard<strong> (</strong>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>
+
+<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>
+
+<p class="note"><strong>Note:</strong> OEMs can use 128-bit or higher to encrypt the master key.</p>
+
+<p>In the Android 5.0 release, there are four kinds of encryption states: </p>
+
+<ul>
+ <li>default
+ <li>PIN
+ <li>password
+ <li>pattern
+</ul>
+
+<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>
+
+<p>You can find the default password defined in the Android Open Source Project <a
+href="https://android.googlesource.com/platform/system/vold/+/master/cryptfs.c">cryptfs.c</a>
+file.</p>
+
+<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.) Note that
+<a href="http://developer.android.com/guide/topics/admin/device-admin.html">managed device</a>
+may be subject to PIN, pattern, or password restrictions.</p>
+
+<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
+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 <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>
+
+<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
+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
+wipe as needed. It does impose the limitation that in order to switch from the
+temporary filesystem to the true <code>/data</code> filesystem, the system must
+stop every process with open files on the 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>
+
+<ul>
+ <li><code>core</code>: Never shut down after starting.
+ <li><code>main</code>: Shut down and then restart after the disk password is entered.
+ <li><code>late_start</code>: Does not start until after <code>/data</code> has been decrypted and mounted.
+</ul>
+
+<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>
+
+<ul>
+ <li><code>class_reset</code>: Stops a service but allows it to be restarted with class_start.
+ <li><code>class_start</code>: Restarts a service.
+ <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>.
+</ul>
+
+<h2 id=flows>Flows</h2>
+
+<p>There are four flows for an encrypted device. A device is encrypted just once
+and then follows a normal boot flow. </p>
+
+<ul>
+ <li>Encrypt a previously unencrypted device:
+ <ul>
+ <li>Encrypt a new device with <code>forceencrypt</code>: Mandatory encryption
+ at first boot (starting in Android L).
+ <li>Encrypt an existing device: User-initiated encryption (Android K and earlier).
+ </ul>
+ <li>Boot an encrypted device:
+ <ul>
+ <li>Starting an encrypted device with no password: Booting an encrypted device that
+ has no set password (relevant for devices running Android 5.0 and later).
+ <li>Starting an encrypted device with a password: Booting an encrypted device that
+ has a set password.
+ </ul>
+</ul>
+
+<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>
+
+
+<h3 id=encrypt_a_new_device_with_forceencrypt>Encrypt a new device with forceencrypt</h3>
+
+<p>This is the normal first boot for an Android 5.0 device.</p>
+
+<ol>
+ <li><strong>Detect unencrypted filesystem with <code>forceencrypt</code> flag</strong>
+
+<p>
+<code>/data</code> is not encrypted but needs to be because <code>forceencrypt</code> mandates it.
+Unmount <code>/data</code>.</p>
+
+ <li><strong>Start encrypting <code>/data</code></strong>
+
+<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>
+
+
+ <li><strong>Mount tmpfs</strong>
+
+
+<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> prepepares 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>
+
+ <li><strong>Bring up framework to show progress</strong>
+
+
+<p>Because the device has virtually no data to encrypt, the progress bar will
+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>
+
+ <li><strong>When <code>/data</code> is encrypted, take down the framework</strong>
+
+<p><code>vold</code> sets <code>vold.decrypt</code> to
+<code>trigger_default_encryption</code> which starts the
+<code>defaultcrypto</code> service. (This starts the flow below for mounting a
+default encrypted userdata.) <code>trigger_default_encryption</code> checks the
+encryption type to see if <code>/data</code> 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 <code>/data</code>.</p>
+
+ <li><strong>Mount <code>/data</code></strong>
+
+<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>
+
+ <li><strong>Start framework</strong>
+
+<p>Set <code>vold</code> to <code>trigger_restart_framework</code>, which
+continues the usual boot process.</p>
+</ol>
+
+<h3 id=encrypt_an_existing_device>Encrypt an existing device</h3>
+
+<p>This is what happens when you encrypt an unencrypted Android K or earlier
+device that has been migrated to L.</p>
+
+<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>
+
+<p class="warning"><strong>Warning:</strong> 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>
+
+<p>To enable inplace encryption, <code>vold</code> starts a loop to read each
+sector of the real block device and then write it
+to the crypto block device. <code>vold</code> 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>
+
+<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>
+
+<ol>
+ <li><strong>Check password</strong>
+
+<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>
+
+ <li><strong>Take down the framework</strong>
+
+<p><code>vold</code> 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 <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>
+
+ <li><strong>Create a crypto footer</strong></li>
+ <li><strong>Create a breadcrumb file</strong></li>
+ <li><strong>Reboot</strong></li>
+ <li><strong>Detect breadcrumb file</strong></li>
+ <li><strong>Start encrypting <code>/data</code></strong>
+
+<p><code>vold</code> 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. <code>vold</code> then creates and writes
+out the crypto metadata.</p>
+
+ <li><strong>While it’s encrypting, mount tmpfs</strong>
+
+<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>
+
+ <li><strong>Bring up framework to show progress</strong>
+
+<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 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>
+
+ <li><strong>When<code> /data</code> is encrypted, update the crypto footer</strong>
+
+<p>When <code>/data</code> is successfully encrypted, <code>vold</code> clears
+the flag <code>ENCRYPTION_IN_PROGRESS</code> in the metadata.</p>
+
+<p>When the device is successfully unlocked, the password is then used to
+encrypt the master key and the crypto footer is updated.</p>
+
+<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
+reboot. This is not expected to ever occur.</p>
+</ol>
+
+<h3 id=starting_an_encrypted_device_with_default_encryption>
+Starting an encrypted device with default encryption</h3>
+
+<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 <em>default encryption</em> state.</p>
+
+<ol>
+ <li><strong>Detect encrypted <code>/data</code> with no password</strong>
+
+<p>Detect that the Android device is encrypted because <code>/data</code>
+cannot be mounted and one of the flags <code>encryptable</code> or
+<code>forceencrypt</code> is set.</p>
+
+<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>
+
+ <li><strong>Decrypt /data</strong>
+
+<p>Creates the <code>dm-crypt</code> device over the block device so the device
+is ready for use.</p>
+
+ <li><strong>Mount /data</strong>
+
+<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>
+
+<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>
+
+ <li><strong>Start framework</strong>
+
+<p>Now the framework boots all its services using the decrypted <code>/data</code>,
+and the system is ready for use.</p>
+</ol>
+
+<h3 id=starting_an_encrypted_device_without_default_encryption>
+Starting an encrypted device without default encryption</h3>
+
+<p>This is what happens when you boot up an encrypted device that has a set
+password. The device’s password can be a pin, pattern, or password. </p>
+
+<ol>
+ <li><strong>Detect encrypted device with a password</strong>
+
+<p>Detect that the Android device is encrypted because the flag
+<code>ro.crypto.state = "encrypted"</code></p>
+
+<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>
+
+ <li><strong>Mount tmpfs</strong>
+
+<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>
+
+<ol>
+ <li><code>ro.crypto.fs_type</code>
+ <li><code>ro.crypto.fs_real_blkdev</code>
+ <li><code>ro.crypto.fs_mnt_point</code>
+ <li><code>ro.crypto.fs_options</code>
+ <li><code>ro.crypto.fs_flags </code>(ASCII 8-digit hex number preceded by 0x)
+ </ol>
+
+ <li><strong>Start framework to prompt for password</strong>
+
+<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>
+
+<p>First, however, it needs to make sure that the disk was properly encrypted. It
+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
+-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
+usable data on the device. If <code>vold</code> 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>
+
+ <li><strong>Decrypt data with password</strong>
+
+<p>Once <code>cryptfs cryptocomplete</code> is successful, the framework
+displays a UI asking for the disk password. The 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
+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 the UI.</p>
+
+ <li><strong>Stop framework</strong>
+
+<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>
+
+ <li><strong>Mount <code>/data</code></strong>
+
+<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
+it was encrypted with the wipe option, which is not supported on first
+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>
+
+ <li><strong>Start full framework</strong>
+
+<p>Now the framework boots all its services using the decrypted <code>/data</code>
+filesystem, and the system is ready for use.</p>
+</ol>
+
+<h3 id=failure>Failure</h3>
+
+<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>
+
+<ol>
+ <li>Detect encrypted device with a password
+ <li>Mount tmpfs
+ <li>Start framework to prompt for password
+</ol>
+
+<p>But after the framework opens, the device can encounter some errors:</p>
+
+<ul>
+ <li>Password matches but cannot decrypt data
+ <li>User enters wrong password 30 times
+</ul>
+
+<p>If these errors are not resolved, <strong>prompt user to factory wipe</strong>:</p>
+
+<p>If <code>vold</code> detects an error during the encryption process, and if
+no data has been 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
+never started. If the error occurs after the framework has been torn down, but
+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 expected to happen.</p>
+
+<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
+failed and provide a button for the user to factory reset the device. </p>
+
+<h2 id=storing_the_encrypted_key>Storing the encrypted key</h2>
+
+<p>The encrypted key is stored in the crypto metadata. Hardware backing is
+implemented by using Trusted Execution Environment’s (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>
+
+<ol>
+ <li>Generate random 16-byte disk encryption key (DEK) and 16-byte salt.
+ <li>Apply scrypt to the user password and the salt to produce 32-byte intermediate
+key 1 (IK1).
+ <li>Pad IK1 with zero bytes to the size of the hardware-bound private key (HBK).
+Specifically, we pad as: 00 || IK1 || 00..00; one zero byte, 32 IK1 bytes, 223
+zero bytes.
+ <li>Sign padded IK1 with HBK to produce 256-byte IK2.
+ <li>Apply scrypt to IK2 and salt (same salt as step 2) to produce 32-byte IK3.
+ <li>Use the first 16 bytes of IK3 as KEK and the last 16 bytes as IV.
+ <li>Encrypt DEK with AES_CBC, with key KEK, and initialization vector IV.
+</ol>
+
+<h2 id=changing_the_password>Changing the password</h2>
+
+<p>When a user elects to change or remove their password in settings, the UI sends
+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>
+
+<h2 id=encryption_properties>Encryption properties</h2>
+
+<p><code>vold</code> and <code>init</code> communicate with each other by
+setting properties. Here is a list of available properties for encryption.</p>
+
+<h3 id=vold_properties>Vold properties</h3>
+
+<table>
+ <tr>
+ <th>Property</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_encryption</code></td>
+ <td>Encrypt the drive with no
+ password.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_default_encryption</code></td>
+ <td>Check the drive to see if it is encrypted with no password.
+If it is, decrypt and mount it,
+else set <code>vold.decrypt</code> to trigger_restart_min_framework.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_reset_main</code></td>
+ <td>Set by vold to shutdown the UI asking for the disk password.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_post_fs_data</code></td>
+ <td> Set by vold to prep /data with necessary directories, et al.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_restart_framework</code></td>
+ <td>Set by vold to start the real framework and all services.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_shutdown_framework</code></td>
+ <td>Set by vold to shutdown the full framework to start encryption.</td>
+ </tr>
+ <tr>
+ <td><code>vold.decrypt trigger_restart_min_framework</code></td>
+ <td>Set by vold to start the
+progress bar UI for encryption or
+prompt for password, depending on
+the value of <code>ro.crypto.state</code>.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress</code></td>
+ <td>When the framework starts up,
+if this property is set, enter
+the progress bar UI mode.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress 0 to 100</code></td>
+ <td>The progress bar UI should
+display the percentage value set.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress error_partially_encrypted</code></td>
+ <td>The progress bar UI should display a message that the encryption failed, and
+give the user an option to
+factory reset the device.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress error_reboot_failed</code></td>
+ <td>The progress bar UI should display a message saying encryption
+ completed, and give the user a button to reboot the device. This error
+ is not expected to happen.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress error_not_encrypted</code></td>
+ <td>The progress bar UI should
+display a message saying an error
+occurred, no data was encrypted or
+lost, and give the user a button to reboot the system.</td>
+ </tr>
+ <tr>
+ <td><code>vold.encrypt_progress error_shutting_down</code></td>
+ <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>
+ </tr>
+ <tr>
+ <td><code>vold.post_fs_data_done 0</code></td>
+ <td>Set by <code>vold</code> just before setting <code>vold.decrypt</code>
+ to <code>trigger_post_fs_data</code>.</td>
+ </tr>
+ <tr>
+ <td><code>vold.post_fs_data_done 1</code></td>
+ <td>Set by <code>init.rc</code> or
+ <code>init.rc</code> just after finishing the task <code>post-fs-data</code>.</td>
+ </tr>
+</table>
+<h3 id=init_properties>init properties</h3>
+
+<table>
+ <tr>
+ <th>Property</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>ro.crypto.fs_crypto_blkdev</code></td>
+ <td>Set by the <code>vold</code> command <code>checkpw</code> for later use
+ by the <code>vold</code> command <code>restart</code>.</td>
+ </tr>
+ <tr>
+ <td><code>ro.crypto.state unencrypted</code></td>
+ <td>Set by <code>init</code> to say this system is running with an unencrypted
+ <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>
+ </tr>
+ <tr>
+ <td><p><code>ro.crypto.fs_type<br>
+ ro.crypto.fs_real_blkdev <br>
+ ro.crypto.fs_mnt_point<br>
+ ro.crypto.fs_options<br>
+ ro.crypto.fs_flags <br>
+ </code></p></td>
+ <td> These five properties are set by
+ <code>init</code> when it tries to mount <code>/data</code> with parameters passed in from
+ <code>init.rc</code>. <code>vold</code> uses these to setup the crypto mapping.</td>
+ </tr>
+ <tr>
+ <td><code>ro.crypto.tmpfs_options</code></td>
+ <td>Set by <code>init.rc</code> with the options init should use when
+ mounting the tmpfs /data filesystem.</td>
+ </tr>
+</table>
+<h2 id=init_actions>Init actions</h2>
+
+<pre>
+on post-fs-data
+on nonencrypted
+on property:vold.decrypt=trigger_reset_main
+on property:vold.decrypt=trigger_post_fs_data
+on property:vold.decrypt=trigger_restart_min_framework
+on property:vold.decrypt=trigger_restart_framework
+on property:vold.decrypt=trigger_shutdown_framework
+on property:vold.decrypt=trigger_encryption
+on property:vold.decrypt=trigger_default_encryption
+</pre>
diff --git a/src/security/encryption/index.jd b/src/security/encryption/index.jd
index 0cad3ec1..4e154954 100644
--- a/src/security/encryption/index.jd
+++ b/src/security/encryption/index.jd
@@ -1,4 +1,4 @@
-page.title=Full Disk Encryption
+page.title=Encryption
@jd:body
<!--
@@ -25,496 +25,47 @@ page.title=Full Disk Encryption
</div>
</div>
-<h2 id=what_is_encryption>What is full disk encryption?</h2>
-
-<p>Full disk encryption is the process of encoding all 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>
-
-<h2 id=what_we’ve_added_for_android_l>What we’ve added for Android 5.0</h2>
-
-<ul>
- <li>Created fast encryption, which only encrypts used blocks on the data partition
-to avoid first boot taking a long time. Only ext4 and f2fs filesystems
-currently support fast encryption.
- <li>Added the <code>forceencrypt</code> flag to encrypt on first boot.
- <li>Added support for patterns and encryption without a password.
- <li>Added hardware-backed storage of the encryption key using Trusted
- Execution Environment’s (TEE) signing capability (such as in a TrustZone).
- See <a href="#storing_the_encrypted_key">Storing the encrypted key</a> for more
- details.
-</ul>
-
-<p class="caution"><strong>Caution:</strong> 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>
-
-<h2 id=how_android_encryption_works>How Android full disk encryption works</h2>
-
-<p>Android full disk encryption is based on <code>dm-crypt</code>, which is a kernel
-feature that works at the block device layer. Because of
-this, encryption works with Embedded MultiMediaCard<strong> (</strong>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>
-
-<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>
-
-<p class="note"><strong>Note:</strong> OEMs can use 128-bit or higher to encrypt the master key.</p>
-
-<p>In the Android 5.0 release, there are four kinds of encryption states: </p>
-
-<ul>
- <li>default
- <li>PIN
- <li>password
- <li>pattern
-</ul>
-
-<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>
-
-<p>You can find the default password defined in the Android Open Source Project <a
-href="https://android.googlesource.com/platform/system/vold/+/master/cryptfs.c">cryptfs.c</a>
-file.</p>
-
-<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.) Note that
-<a href="http://developer.android.com/guide/topics/admin/device-admin.html">managed device</a>
-may be subject to PIN, pattern, or password restrictions.</p>
-
-<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
-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 <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>
-
-<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
-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
-wipe as needed. It does impose the limitation that in order to switch from the
-temporary filesystem to the true <code>/data</code> filesystem, the system must stop every process with open files on the
-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>
-
-<ul>
- <li><code>core</code>: Never shut down after starting.
- <li><code>main</code>: Shut down and then restart after the disk password is entered.
- <li><code>late_start</code>: Does not start until after <code>/data</code> has been decrypted and mounted.
-</ul>
-
-<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>
-
-<ul>
- <li><code>class_reset</code>: Stops a service but allows it to be restarted with class_start.
- <li><code>class_start</code>: Restarts a service.
- <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>.
-</ul>
-
-<h2 id=flows>Flows</h2>
-
-<p>There are four flows for an encrypted device. A device is encrypted just once
-and then follows a normal boot flow. </p>
-
-<ul>
- <li>Encrypt a previously unencrypted device:
- <ul>
- <li>Encrypt a new device with <code>forceencrypt</code>: Mandatory encryption at first boot (starting in Android L).
- <li>Encrypt an existing device: User-initiated encryption (Android K and earlier).
- </ul>
- <li>Boot an encrypted device:
- <ul>
- <li>Starting an encrypted device with no password: Booting an encrypted device that
-has no set password (relevant for devices running Android 5.0 and later).
- <li> Starting an encrypted device with a password: Booting an encrypted device that
-has a set password.
- </ul>
-</ul>
-
-<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>
-
-<h3 id=encrypt_a_new_device_with_forceencrypt>Encrypt a new device with /forceencrypt</h3>
-
-<p>This is the normal first boot for an Android 5.0 device. </p>
-
-<ol>
- <li><strong>Detect unencrypted filesystem with <code>/forceencrypt</code> flag</strong>
-
<p>
-<code>/data</code> is not encrypted but needs to be because <code>/forceencrypt</code> mandates it.
-Unmount <code>/data</code>.</p>
-
- <li><strong>Start encrypting <code>/data</code></strong>
-
-<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>
-
-
- <li><strong>Mount tmpfs</strong>
-
-
-<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> prepepares 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>
+Encryption is the process of encoding all user data on an Android device using
+symmetric encryption keys. 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. Encryption ensures that
+even if an unauthorized party tries to access the data, they won’t be able to
+read it.
+</p>
+<p>
+Android has two methods for device encryption: full-disk encryption and
+file-based encryption.
+</p>
+<h2 id=full-disk>Full-disk encryption</h2>
+<p>
+Android 5.0 and above supports <a href="full-disk.html">full-disk encryption</a>.
+Full-disk encryption uses a single key—protected with the user’s device password—to
+protect the whole of a device’s userdata partition. Upon boot, the user must
+provide their credentials before any part of the disk is accessible.
+</p>
+<p>
+While this is great for security, it means that most of the core functionality
+of the phone in not immediately available when users reboot their device.
+Because access to their data is protected behind their single user credential,
+features like alarms could not operate, accessibility services were unavailable,
+and phones could not receive calls.
+</p>
+<h2 id=file-based>File-based encryption</h2>
+<p>
+Android 7.0 and above supports <a href="file-based.html">file-based encryption</a>.
+File-based encryption
+allows different files to be encrypted with different keys that can be unlocked
+independently. Devices that support file-based encryption can also support a new
+feature called <a
+href="https://developer.android.com/preview/features/direct-boot.html">Direct
+Boot</a> that allows encrypted devices to boot straight to the lock screen, thus
+enabling quick access to important device features like accessibility services
+and alarms.
+</p>
+<p>
+With the introduction of file-based encryption and new APIs to make
+applications aware of encryption, it is possible for these apps to operate
+within a limited context. This can happen before users have provided their
+credentials while still protecting private user information.
</p>
-
- <li><strong>Bring up framework to show progress</strong>
-
-
-<p>Because the device has virtually no data to encrypt, the progress bar will
-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>
-
- <li><strong>When <code>/data</code> is encrypted, take down the framework</strong>
-
-<p><code>vold</code> sets <code>vold.decrypt</code> to
-<code>trigger_default_encryption</code> which starts the
-<code>defaultcrypto</code> service. (This starts the flow below for mounting a
-default encrypted userdata.) <code>trigger_default_encryption</code> checks the
-encryption type to see if <code>/data</code> 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 <code>/data</code>.</p>
-
- <li><strong>Mount <code>/data</code></strong>
-
-<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>
-
- <li><strong>Start framework</strong>
-
-<p>Set <code>vold</code> to <code>trigger_restart_framework</code>, which continues the usual boot process.</p>
-</ol>
-
-<h3 id=encrypt_an_existing_device>Encrypt an existing device</h3>
-
-<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>
-
-<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>
-
-<p class="warning"><strong>Warning:</strong> 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>
-
-<p>To enable inplace encryption, <code>vold</code> starts a loop to read each sector of the real block device and then write it
-to the crypto block device. <code>vold</code> 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>
-
-<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>
-
-<ol>
- <li><strong>Check password</strong>
-
-<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>
-
- <li><strong>Take down the framework</strong>
-
-<p><code>vold</code> 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 <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>
-
- <li><strong>Unmount <code>/data</code></strong>
-
-<p><code>vold</code> unmounts <code>/mnt/sdcard</code> and then <code>/data</code>.</p>
-
- <li><strong>Start encrypting <code>/data</code></strong>
-
-<p><code>vold</code> 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. <code>vold</code> then creates and writes out the crypto metadata.</p>
-
- <li><strong>While it’s encrypting, mount tmpfs</strong>
-
-<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>
-
- <li><strong>Bring up framework to show progress</strong>
-
-<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
-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>
-
- <li><strong>When<code> /data</code> is encrypted, reboot</strong>
-
-<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>
-
-<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
-reboot. This is not expected to ever occur.</p>
-</ol>
-
-<h3 id=starting_an_encrypted_device_with_default_encryption>Starting an encrypted device with default encryption</h3>
-
-<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 <em>default encryption</em> state.</p>
-
-<ol>
- <li><strong>Detect encrypted <code>/data</code> with no password</strong>
-
-<p>Detect that the Android device is encrypted because <code>/data</code>
-cannot be mounted and one of the flags <code>encryptable</code> or
-<code>forceencrypt</code> is set.</p>
-
-<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>
-
- <li><strong>Decrypt /data</strong>
-
-<p>Creates the <code>dm-crypt</code> device over the block device so the device is ready for use.</p>
-
- <li><strong>Mount /data</strong>
-
-<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>
-
-<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>
-
- <li><strong>Start framework</strong>
-
-<p>Now the framework boots all its services using the decrypted <code>/data</code>, and the system is ready for use.</p>
-</ol>
-
-<h3 id=starting_an_encrypted_device_without_default_encryption>Starting an encrypted device without default encryption</h3>
-
-<p>This is what happens when you boot up an encrypted device that has a set
-password. The device’s password can be a pin, pattern, or password. </p>
-
-<ol>
- <li><strong>Detect encrypted device with a password</strong>
-
-<p>Detect that the Android device is encrypted because the flag <code>ro.crypto.state = "encrypted"</code></p>
-
-<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>
-
- <li><strong>Mount tmpfs</strong>
-
-<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>
-
-<ol>
- <li><code>ro.crypto.fs_type</code>
- <li><code>ro.crypto.fs_real_blkdev</code>
- <li><code>ro.crypto.fs_mnt_point</code>
- <li><code>ro.crypto.fs_options</code>
- <li><code>ro.crypto.fs_flags </code>(ASCII 8-digit hex number preceded by 0x)
- </ol>
-
- <li><strong>Start framework to prompt for password</strong>
-
-<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>
-
-<p>First, however, it needs to make sure that the disk was properly encrypted. It
-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
--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
-usable data on the device. If <code>vold</code> 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>
-
- <li><strong>Decrypt data with password</strong>
-
-<p>Once <code>cryptfs cryptocomplete</code> is successful, the framework displays a UI asking for the disk password. The
-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
-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
-the UI.</p>
-
- <li><strong>Stop framework</strong>
-
-<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>
-
- <li><strong>Mount <code>/data</code></strong>
-
-<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
-it was encrypted with the wipe option, which is not supported on first
-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>
-
- <li><strong>Start full framework</strong>
-
-<p>Now the framework boots all its services using the decrypted <code>/data</code> filesystem, and the system is ready for use.</p>
-</ol>
-
-<h3 id=failure>Failure</h3>
-
-<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>
-
-<ol>
- <li>Detect encrypted device with a password
- <li>Mount tmpfs
- <li>Start framework to prompt for password
-</ol>
-
-<p>But after the framework opens, the device can encounter some errors:</p>
-
-<ul>
- <li>Password matches but cannot decrypt data
- <li>User enters wrong password 30 times
-</ul>
-
-<p>If these errors are not resolved, <strong>prompt user to factory wipe</strong>:</p>
-
-<p>If <code>vold</code> detects an error during the encryption process, and if no data has been
-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
-never started. If the error occurs after the framework has been torn down, but
-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
-expected to happen.</p>
-
-<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
-failed and provide a button for the user to factory reset the device. </p>
-
-<h2 id=storing_the_encrypted_key>Storing the encrypted key</h2>
-
-<p>The encrypted key is stored in the crypto metadata. Hardware backing is implemented by using Trusted Execution Environment’s (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>
-
-<ol>
- <li>Generate random 16-byte disk encryption key (DEK) and 16-byte salt.
- <li>Apply scrypt to the user password and the salt to produce 32-byte intermediate
-key 1 (IK1).
- <li>Pad IK1 with zero bytes to the size of the hardware-bound private key (HBK).
-Specifically, we pad as: 00 || IK1 || 00..00; one zero byte, 32 IK1 bytes, 223
-zero bytes.
- <li>Sign padded IK1 with HBK to produce 256-byte IK2.
- <li>Apply scrypt to IK2 and salt (same salt as step 2) to produce 32-byte IK3.
- <li>Use the first 16 bytes of IK3 as KEK and the last 16 bytes as IV.
- <li>Encrypt DEK with AES_CBC, with key KEK, and initialization vector IV.
-</ol>
-
-<h2 id=changing_the_password>Changing the password</h2>
-
-<p>When a user elects to change or remove their password in settings, the UI sends
-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>
-
-<h2 id=encryption_properties>Encryption properties</h2>
-
-<p><code>vold</code> and <code>init</code> communicate with each other by setting properties. Here is a list of available
-properties for encryption.</p>
-
-<h3 id=vold_properties>Vold properties </h3>
-
-<table>
- <tr>
- <th>Property</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_encryption</code></td>
- <td>Encrypt the drive with no
- password.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_default_encryption</code></td>
- <td>Check the drive to see if it is encrypted with no password.
-If it is, decrypt and mount it,
-else set <code>vold.decrypt</code> to trigger_restart_min_framework.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_reset_main</code></td>
- <td>Set by vold to shutdown the UI asking for the disk password.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_post_fs_data</code></td>
- <td> Set by vold to prep /data with necessary directories, et al.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_restart_framework</code></td>
- <td>Set by vold to start the real framework and all services.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_shutdown_framework</code></td>
- <td>Set by vold to shutdown the full framework to start encryption.</td>
- </tr>
- <tr>
- <td><code>vold.decrypt trigger_restart_min_framework</code></td>
- <td>Set by vold to start the
-progress bar UI for encryption or
-prompt for password, depending on
-the value of <code>ro.crypto.state</code>.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress</code></td>
- <td>When the framework starts up,
-if this property is set, enter
-the progress bar UI mode.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress 0 to 100</code></td>
- <td>The progress bar UI should
-display the percentage value set.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress error_partially_encrypted</code></td>
- <td>The progress bar UI should display a message that the encryption failed, and
-give the user an option to
-factory reset the device.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress error_reboot_failed</code></td>
- <td>The progress bar UI should
-display a message saying encryption completed, and give the user a button to reboot the device. This error is not expected to happen.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress error_not_encrypted</code></td>
- <td>The progress bar UI should
-display a message saying an error
-occurred, no data was encrypted or
-lost, and give the user a button to reboot the system.</td>
- </tr>
- <tr>
- <td><code>vold.encrypt_progress error_shutting_down</code></td>
- <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>
- </tr>
- <tr>
- <td><code>vold.post_fs_data_done 0</code></td>
- <td>Set by <code>vold</code> just before setting <code>vold.decrypt</code> to <code>trigger_post_fs_data</code>.</td>
- </tr>
- <tr>
- <td><code>vold.post_fs_data_done 1</code></td>
- <td>Set by <code>init.rc</code> or
- <code>init.rc</code> just after finishing the task <code>post-fs-data</code>.</td>
- </tr>
-</table>
-<h3 id=init_properties>init properties</h3>
-
-<table>
- <tr>
- <th>Property</th>
- <th>Description</th>
- </tr>
- <tr>
- <td><code>ro.crypto.fs_crypto_blkdev</code></td>
- <td>Set by the <code>vold</code> command <code>checkpw</code> for later use by the <code>vold</code> command <code>restart</code>.</td>
- </tr>
- <tr>
- <td><code>ro.crypto.state unencrypted</code></td>
- <td>Set by <code>init</code> to say this system is running with an unencrypted
- <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>
- </tr>
- <tr>
- <td><p><code>ro.crypto.fs_type<br>
- ro.crypto.fs_real_blkdev <br>
- ro.crypto.fs_mnt_point<br>
- ro.crypto.fs_options<br>
- ro.crypto.fs_flags <br>
- </code></p></td>
- <td> These five properties are set by
- <code>init</code> when it tries to mount <code>/data</code> with parameters passed in from
- <code>init.rc</code>. <code>vold</code> uses these to setup the crypto mapping.</td>
- </tr>
- <tr>
- <td><code>ro.crypto.tmpfs_options</code></td>
- <td>Set by <code>init.rc</code> with the options init should use when mounting the tmpfs /data filesystem.</td>
- </tr>
-</table>
-<h2 id=init_actions>Init actions</h2>
-
-<pre>
-on post-fs-data
-on nonencrypted
-on property:vold.decrypt=trigger_reset_main
-on property:vold.decrypt=trigger_post_fs_data
-on property:vold.decrypt=trigger_restart_min_framework
-on property:vold.decrypt=trigger_restart_framework
-on property:vold.decrypt=trigger_shutdown_framework
-on property:vold.decrypt=trigger_encryption
-on property:vold.decrypt=trigger_default_encryption
-</pre>
diff --git a/src/security/security_toc.cs b/src/security/security_toc.cs
index 805905c6..aa8f0da8 100644
--- a/src/security/security_toc.cs
+++ b/src/security/security_toc.cs
@@ -84,9 +84,13 @@
<li class="nav-section">
<div class="nav-section-header">
<a href="<?cs var:toroot ?>security/encryption/index.html">
- <span class="en">Full Disk Encryption</span>
+ <span class="en">Encryption</span>
</a>
</div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>security/encryption/file-based.html">File-Based Encryption</a></li>
+ <li><a href="<?cs var:toroot ?>security/encryption/full-disk.html">Full-Disk Encryption</a></li>
+ </ul>
</li>
<li class="nav-section">
<div class="nav-section-header">