blob: 3c8bb9d1e883a709f533b491fc41da8f49162b6a [file] [log] [blame]
<html devsite>
<head>
<title>Device State</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2018 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
//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.
-->
<p>
The device state indicates how freely software can be flashed to a device and
whether verification is enforced. Device states are <code>LOCKED</code> and
<code>UNLOCKED</code>. <code>LOCKED</code> devices prevent you from flashing new
software to the device, whereas <code>UNLOCKED</code> devices allow
modification.
</p>
<p>
When a device powers on, the bootloader first checks if a device is
<code>LOCKED</code> or <code>UNLOCKED</code>. If a device is
<code>UNLOCKED</code>, the bootloader shows the user a warning and then proceeds
to boot even if the loaded OS isn't signed by the root of trust.
</p>
<p>
If the device is <code>LOCKED</code>, the bootloader goes through the steps in
<a href="/security/verifiedboot/verified-boot">Verifying Boot</a> to verify
the device's software. <code>LOCKED</code> devices boot <em>only</em> if the
loaded OS is properly signed by the root of trust. For more details, see
<a href="/security/verifiedboot/boot-flow">The boot flow</a>.
</p>
<h2 id="changing-device-state">Changing device state</h2>
<p>
To <a href="/devices/bootloader/unlock-trusty">change a device's state</a>, use
the <code>fastboot flashing [unlock | lock]</code> command. To protect user
data, <em>all</em> state transitions wipe the data partitions and ask for user
confirmation before data is deleted.
</p>
<p>
The <code>UNLOCKED</code> to <code>LOCKED</code> transition is anticipated when
a user buys a used development device. As a result of locking the device, the
user should have confidence that it is in a state produced by the device
manufacturer, as long as there is no warning. The <code>LOCKED</code> to
<code>UNLOCKED</code> transition is expected when a developer wishes to disable
verification on the device for development purposes.
</p>
<h2 id="root-of-trust">Root of Trust</h2>
<p>
<em>Root of trust</em> is the cryptographic key used to sign the copy of Android
stored on the device. The private part of the root of trust is known only to the
device manufacturer and is used to sign every version of Android intended for
distribution. The public part of the root of trust is embedded in the device and
is stored in a place so it cannot be tampered with (typically read-only
storage).
</p>
<p>
When it loads Android, the bootloader uses the root of trust to verify
authenticity. For more details on this process, see
<a href="/security/verifiedboot/verified-boot">Verifying Boot</a>. Devices may have
multiple boot loaders and as such multiple cryptographic keys may be in play.
</p>
<h3 id="user-settable-root-of-trust">User-settable root of trust</h3>
<p>
Devices can optionally allow the user to configure the root of trust (for
example, a public key). Devices can use this user-settable root of trust for
Verified Boot instead of the built-in root of trust. This allows the user to
install and use custom versions of Android without sacrificing the security
improvements of Verified Boot.
</p>
<p>
If user-settable root of trust is implemented, it should be done in a way such
that:
</p>
<ul>
<li>Physical confirmation is required to set/clear the user-settable root of
trust.</li>
<li>The user-settable root of trust can only be set by the end user. It cannot
be set at the factory or any intermediate point before the end user gets the
device.</li>
<li>The user-settable root of trust is stored in tamper-evident storage.
<em>Tamper-evident</em> means that it's possible to detect if Android has
tampered with the data, for example, if it has been overwritten or changed.
</li>
<li>If an user-settable root of trust is set, the device should allow a version
of Android signed with either the built-in root of trust or the user-settable
root of trust to boot.</li>
<li>Every time the device boots using the user-settable root of trust, the user
should be notified that the device is loading a custom version of Android. For
example waring screens, see
<a href="/security/verifiedboot/boot-flow#locked-devices-with-custom-key-set"><code>LOCKED</code>
devices with custom key set</a>.</li>
</ul>
<p>
One way of implementing user-settable root of trust is to have a virtual
partition that can only be flashed or cleared when the device is in the
<code>UNLOCKED</code> state. The Google Pixel 2 devices use this approach and
the virtual partition is called <code>avb_custom_key</code>. The format of the
data in this partition is the output of the
<code>avbtool extract_public_key</code> command. Here's an example of how to set
the user-settable root of trust:
</p>
<pre
class="prettyprint"><code class="devsite-terminal">avbtool extract_public_key --key key.pem --output pkmd.bin</code>
<code class="devsite-terminal">fastboot flash avb_custom_key pkmd.bin</code>
</pre>
<p>
The user-settable root of trust can be cleared by issuing:
</p>
<pre
class="devsite-terminal devsite-click-to-copy">fastboot erase avb_custom_key
</pre>
</body>
</html>