blob: 0cad3ec18c8f9ff6c646c0acee83bf2a6c00bbd8 [file] [log] [blame]
Alex Klyubincf038682015-09-16 12:42:05 -07001page.title=Full Disk Encryption
Robert Ly35f2fda2013-01-29 16:27:05 -08002@jd:body
3
4<!--
Clay Murphy32285dd2014-03-12 12:15:00 -07005 Copyright 2014 The Android Open Source Project
Robert Ly35f2fda2013-01-29 16:27:05 -08006
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-->
Clay Murphy32285dd2014-03-12 12:15:00 -070019
Clay Murphy5e411e62014-10-14 12:44:54 -070020<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
Alex Klyubincf038682015-09-16 12:42:05 -070028<h2 id=what_is_encryption>What is full disk encryption?</h2>
Clay Murphy5e411e62014-10-14 12:44:54 -070029
Alex Klyubincf038682015-09-16 12:42:05 -070030<p>Full disk encryption is the process of encoding all user data on an Android device using an
Clay Murphy5e411e62014-10-14 12:44:54 -070031encrypted key. Once a device is encrypted, all user-created data is
32automatically encrypted before committing it to disk and all reads
33automatically decrypt data before returning it to the calling process.</p>
34
Clay Murphyec58cfb2014-10-22 11:10:53 -070035<h2 id=what_we’ve_added_for_android_l>What we’ve added for Android 5.0</h2>
Clay Murphy5e411e62014-10-14 12:44:54 -070036
37<ul>
38 <li>Created fast encryption, which only encrypts used blocks on the data partition
39to avoid first boot taking a long time. Only ext4 and f2fs filesystems
40currently 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.
Clay Murphy6c2619f2014-11-20 16:49:53 -080043 <li>Added hardware-backed storage of the encryption key using Trusted
44 Execution Environment’s (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.
Clay Murphy5e411e62014-10-14 12:44:54 -070047</ul>
48
Clay Murphyec58cfb2014-10-22 11:10:53 -070049<p class="caution"><strong>Caution:</strong> Devices upgraded to Android 5.0 and then
50encrypted may be returned to an unencrypted state by factory data reset. New Android 5.0
51devices encrypted at first boot cannot be returned to an unencrypted state.</p>
52
Alex Klyubincf038682015-09-16 12:42:05 -070053<h2 id=how_android_encryption_works>How Android full disk encryption works</h2>
Clay Murphy5e411e62014-10-14 12:44:54 -070054
Alex Klyubincf038682015-09-16 12:42:05 -070055<p>Android full disk encryption is based on <code>dm-crypt</code>, which is a kernel
Clay Murphy6c2619f2014-11-20 16:49:53 -080056feature that works at the block device layer. Because of
57this, encryption works with Embedded MultiMediaCard<strong> (</strong>eMMC) and
58similar flash devices that present themselves to the kernel as block
Clay Murphy5e411e62014-10-14 12:44:54 -070059devices. Encryption is not possible with YAFFS, which talks directly to a raw
60NAND flash chip. </p>
61
62<p>The encryption algorithm is 128 Advanced Encryption Standard (AES) with
63cipher-block chaining (CBC) and ESSIV:SHA256. The master key is encrypted with
64128-bit AES via calls to the OpenSSL library. You must use 128 bits or more for
65the 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
Clay Murphyec58cfb2014-10-22 11:10:53 -070069<p>In the Android 5.0 release, there are four kinds of encryption states: </p>
Clay Murphy5e411e62014-10-14 12:44:54 -070070
71<ul>
72 <li>default
73 <li>PIN
74 <li>password
75 <li>pattern
76</ul>
77
Clay Murphy6c2619f2014-11-20 16:49:53 -080078<p>Upon first boot, the device creates a randomly generated 128-bit master key
79and then hashes it with a default password and stored salt. The default password is: "default_password"
80However, the resultant hash is also signed through a TEE (such as TrustZone),
81which 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
84href="https://android.googlesource.com/platform/system/vold/+/master/cryptfs.c">cryptfs.c</a>
85file.</p>
Clay Murphy5e411e62014-10-14 12:44:54 -070086
87<p>When the user sets the PIN/pass or password on the device, only the 128-bit key
88is re-encrypted and stored. (ie. user PIN/pass/pattern changes do NOT cause
Danielle Robertsdc10f932015-11-04 11:36:41 -080089re-encryption of userdata.) Note that
90<a href="http://developer.android.com/guide/topics/admin/device-admin.html">managed device</a>
91may be subject to PIN, pattern, or password restrictions.</p>
Clay Murphy5e411e62014-10-14 12:44:54 -070092
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
94also look at the properties to conduct tasks such as report status, ask for a
95password, or prompt to factory reset in the case of a fatal error. To invoke
96encryption 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
99framework 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
100wipe as needed. It does impose the limitation that in order to switch from the
101temporary filesystem to the true <code>/data</code> filesystem, the system must stop every process with open files on the
102temporary 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
121and 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
Clay Murphyec58cfb2014-10-22 11:10:53 -0700132has no set password (relevant for devices running Android 5.0 and later).
Clay Murphy5e411e62014-10-14 12:44:54 -0700133 <li> Starting an encrypted device with a password: Booting an encrypted device that
134has 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
Clay Murphy92c38f92014-10-30 18:19:30 -0700140<h3 id=encrypt_a_new_device_with_forceencrypt>Encrypt a new device with /forceencrypt</h3>
Clay Murphy5e411e62014-10-14 12:44:54 -0700141
Clay Murphyec58cfb2014-10-22 11:10:53 -0700142<p>This is the normal first boot for an Android 5.0 device. </p>
Clay Murphy5e411e62014-10-14 12:44:54 -0700143
Clay Murphy32285dd2014-03-12 12:15:00 -0700144<ol>
Clay Murphy5e411e62014-10-14 12:44:54 -0700145 <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.
149Unmount <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
162property <code>vold.decrypt</code> to: <code>trigger_restart_min_framework</code>
Paul Lawrence707f7ef2014-05-20 11:00:23 -0700163</p>
Clay Murphy5e411e62014-10-14 12:44:54 -0700164
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
169often 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
Clay Murphyec58cfb2014-10-22 11:10:53 -0700173<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
176default encrypted userdata.) <code>trigger_default_encryption</code> checks the
177encryption type to see if <code>/data</code> is encrypted with or without a
178password. Because Android 5.0 devices are encrypted on first boot, there should
179be no password set; therefore we decrypt and mount <code>/data</code>.</p>
Clay Murphy5e411e62014-10-14 12:44:54 -0700180
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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700188</ol>
Paul Lawrence707f7ef2014-05-20 11:00:23 -0700189
Clay Murphy5e411e62014-10-14 12:44:54 -0700190<h3 id=encrypt_an_existing_device>Encrypt an existing device</h3>
Clay Murphy32285dd2014-03-12 12:15:00 -0700191
Clay Murphy5e411e62014-10-14 12:44:54 -0700192<p>This is what happens when you encrypt an unencrypted Android K or earlier
193device that has been migrated to L. Note that this is the same flow as used in
194K.</p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700195
Clay Murphy5e411e62014-10-14 12:44:54 -0700196<p>This process is user-initiated and is referred to as “inplace encryption” in
197the code. When a user selects to encrypt a device, the UI makes sure the
198battery is fully charged and the AC adapter is plugged in so there is enough
199power to finish the encryption process.</p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700200
Clay Murphy5e411e62014-10-14 12:44:54 -0700201<p class="warning"><strong>Warning:</strong> If the device runs out of power and shuts down before it has finished
202encrypting, file data is left in a partially encrypted state. The device must
203be factory reset and all data is lost.</p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700204
Clay Murphy5e411e62014-10-14 12:44:54 -0700205<p>To enable inplace encryption, <code>vold</code> starts a loop to read each sector of the real block device and then write it
206to the crypto block device. <code>vold</code> checks to see if a sector is in use before reading and writing it, which makes
207encryption much faster on a new device that has little to no data. </p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700208
Clay Murphy5e411e62014-10-14 12:44:54 -0700209<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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700210
Clay Murphy5e411e62014-10-14 12:44:54 -0700211<ol>
212 <li><strong>Check password</strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700213
Clay Murphy5e411e62014-10-14 12:44:54 -0700214<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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700215
Clay Murphy5e411e62014-10-14 12:44:54 -0700216 <li><strong>Take down the framework</strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700217
Clay Murphy5e411e62014-10-14 12:44:54 -0700218<p><code>vold</code> checks for errors, returns -1 if it can't encrypt, and prints a reason in the
219log. 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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700220
Clay Murphy5e411e62014-10-14 12:44:54 -0700221 <li><strong>Unmount <code>/data</code></strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700222
Clay Murphy5e411e62014-10-14 12:44:54 -0700223<p><code>vold</code> unmounts <code>/mnt/sdcard</code> and then <code>/data</code>.</p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700224
Clay Murphy5e411e62014-10-14 12:44:54 -0700225 <li><strong>Start encrypting <code>/data</code></strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700226
Clay Murphy5e411e62014-10-14 12:44:54 -0700227<p><code>vold</code> then sets up the crypto mapping, which creates a virtual crypto block device
228that maps onto the real block device but encrypts each sector as it is written,
229and decrypts each sector as it is read. <code>vold</code> then creates and writes out the crypto metadata.</p>
Clay Murphy32285dd2014-03-12 12:15:00 -0700230
Clay Murphy5e411e62014-10-14 12:44:54 -0700231 <li><strong>While it’s encrypting, mount tmpfs</strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700232
Clay Murphy5e411e62014-10-14 12:44:54 -0700233<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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700234
Clay Murphy5e411e62014-10-14 12:44:54 -0700235 <li><strong>Bring up framework to show progress</strong>
Clay Murphy32285dd2014-03-12 12:15:00 -0700236
Clay Murphy5e411e62014-10-14 12:44:54 -0700237<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
238every 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>
Clay Murphy32285dd2014-03-12 12:15:00 -0700239
Clay Murphy5e411e62014-10-14 12:44:54 -0700240 <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
245reboot. 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.
Clay Murphyec58cfb2014-10-22 11:10:53 -0700251Because Android 5.0 devices are encrypted on first boot, there should be no set
Clay Murphy5e411e62014-10-14 12:44:54 -0700252password 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>
258cannot 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
281password. The device’s 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
307sends 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
309usable data on the device. If <code>vold</code> returns an error, the UI should display a message to the user to reboot and
310factory 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
315UI 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
316decrypted <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
317the 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
326it was encrypted with the wipe option, which is not supported on first
327release). 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
337starts 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
355destroyed 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
356never started. If the error occurs after the framework has been torn down, but
357before 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
358expected 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
361failed 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 Environment’s (TEE) signing capability.
366Previously, 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
367against 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.
Clay Murphy0878fe82014-11-04 16:04:37 -0800371 <li>Apply scrypt to the user password and the salt to produce 32-byte intermediate
Clay Murphy5e411e62014-10-14 12:44:54 -0700372key 1 (IK1).
373 <li>Pad IK1 with zero bytes to the size of the hardware-bound private key (HBK).
374Specifically, we pad as: 00 || IK1 || 00..00; one zero byte, 32 IK1 bytes, 223
375zero bytes.
376 <li>Sign padded IK1 with HBK to produce 256-byte IK2.
Clay Murphy0878fe82014-11-04 16:04:37 -0800377 <li>Apply scrypt to IK2 and salt (same salt as step 2) to produce 32-byte IK3.
Clay Murphy5e411e62014-10-14 12:44:54 -0700378 <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
385the 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
390properties 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.
407If it is, decrypt and mount it,
408else 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
429progress bar UI for encryption or
430prompt for password, depending on
431the 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,
436if this property is set, enter
437the 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
442display 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
447give the user an option to
448factory 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
453display 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
458display a message saying an error
David Pursehouse7b8b01d2015-08-21 18:17:28 +0900459occurred, no data was encrypted or
Clay Murphy5e411e62014-10-14 12:44:54 -0700460lost, 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>
511on post-fs-data
Clay Murphy32285dd2014-03-12 12:15:00 -0700512on nonencrypted
513on property:vold.decrypt=trigger_reset_main
514on property:vold.decrypt=trigger_post_fs_data
515on property:vold.decrypt=trigger_restart_min_framework
516on property:vold.decrypt=trigger_restart_framework
517on property:vold.decrypt=trigger_shutdown_framework
Paul Lawrence707f7ef2014-05-20 11:00:23 -0700518on property:vold.decrypt=trigger_encryption
519on property:vold.decrypt=trigger_default_encryption
Clay Murphy5e411e62014-10-14 12:44:54 -0700520</pre>