• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Android Verified Boot 2.0
2---
3
4This repository contains tools and libraries for working with Android
5Verified Boot 2.0. Usually AVB is used to refer to this codebase.
6
7# Table of Contents
8
9* [What is it?](#What-is-it)
10    + [The VBMeta struct](#The-VBMeta-struct)
11    + [Rollback Protection](#Rollback-Protection)
12    + [A/B Support](#A_B-Support)
13* [Tools and Libraries](#Tools-and-Libraries)
14    + [avbtool and libavb](#avbtool-and-libavb)
15    + [Files and Directories](#Files-and-Directories)
16    + [Portability](#Portability)
17    + [Versioning and Compatibility](#Versioning-and-Compatibility)
18    + [Adding New Features](#Adding-New-Features)
19    + [Using avbtool](#Using-avbtool)
20    + [Build System Integration](#Build-System-Integration)
21* [Device Integration](#Device-Integration)
22    + [System Dependencies](#System-Dependencies)
23    + [Locked and Unlocked mode](#Locked-and-Unlocked-mode)
24    + [Tamper-evident Storage](#Tamper_evident-Storage)
25    + [Updating Stored Rollback Indexes](#Updating-Stored-Rollback-Indexes)
26    + [Recommended Bootflow](#Recommended-Bootflow)
27    + [Handling dm-verity Errors](#Handling-dm_verity-Errors)
28    + [Android Specific Integration](#Android-Specific-Integration)
29
30# What is it?
31
32Verified boot is the process of assuring the end user of the integrity
33of the software running on a device. It typically starts with a
34read-only portion of the device firmware which loads code and executes
35it only after cryptographically verifying that the code is authentic
36and doesn't have any known security flaws. AVB is one implementation
37of verified boot.
38
39## The VBMeta struct
40
41The central data structure used in AVB is the VBMeta struct. This data
42structure contains a number of descriptors (and other metadata) and
43all of this data is cryptographically signed. Descriptors are used for
44image hashes, image hashtree metadata, and so-called *chained
45partitions*. A simple example is the following:
46
47![AVB with boot, system, and vendor](docs/avb-integrity-data-in-vbmeta.png)
48
49where the `vbmeta` partition holds the hash for the `boot` partition
50in a hash descriptor. For the `system` and `vendor` partitions a
51hashtree follows the filesystem data and the `vbmeta` partition holds
52the root hash, salt, and offset of the hashtree in hashtree
53descriptors. Because the VBMeta struct in the `vbmeta` partition is
54cryptographically signed, the boot loader can check the signature and
55verify it was made by the owner of `key0` (by e.g. embedding the
56public part of `key0`) and thereby trust the hashes used for `boot`,
57`system`, and `vendor`.
58
59A chained partition descriptor is used to delegate authority - it
60contains the name of the partition where authority is delegated as
61well as the public key that is trusted for signatures on this
62particular partition. As an example, consider the following setup:
63
64![AVB with a chained partition](docs/avb-chained-partition.png)
65
66In this setup the `xyz` partition has a hashtree for
67integrity-checking. Following the hashtree is a VBMeta struct which
68contains the hashtree descriptor with hashtree metadata (root hash,
69salt, offset, etc.) and this struct is signed with `key1`. Finally, at
70the end of the partition is a footer which has the offset of the
71VBMeta struct.
72
73This setup allows the bootloader to use the chain partition descriptor
74to find the footer at the end of the partition (using the name in the
75chain partition descriptor) which in turns helps locate the VBMeta
76struct and verify that it was signed by `key1` (using `key1_pub` stored in the
77chain partition descriptor). Crucially, because there's a footer with
78the offset, the `xyz` partition can be updated without the `vbmeta`
79partition needing any changes.
80
81The VBMeta struct is flexible enough to allow hash descriptors and
82hashtree descriptors for any partition to live in either the `vbmeta`
83partition or - via a chain partition descriptor - in the partition
84that they are used to integrity check. This allows for a wide range of
85organizational and trust relationships.
86
87## Rollback Protection
88
89AVB includes Rollback Protection which is used to protect against
90known security flaws. Each VBMeta struct has a *rollback index* baked
91into it like the following:
92
93![AVB rollback indexes](docs/avb-rollback-indexes.png)
94
95These numbers are referred to as `rollback_index[n]` and are increased
96for each image as security flaws are discovered and
97fixed. Additionally the device stores the last seen rollback index in
98tamper-evident storage:
99
100![AVB stored rollback indexes](docs/avb-stored-rollback-indexes.png)
101
102and these are referred to as `stored_rollback_index[n]`.
103
104Rollback protection is having the device reject an image unless
105`rollback_index[n]` >= `stored_rollback_index[n]` for all `n`, and
106having the device increase `stored_rollback_index[n]` over
107time. Exactly how this is done is discussed in
108the
109[Updating Stored Rollback Indexes](#Updating-Stored-Rollback-Indexes)
110section.
111
112## A/B Support
113
114AVB has been designed to work with A/B by requiring that the A/B
115suffix is never used in any partition names stored in
116descriptors. Here's an example with two slots:
117
118![AVB with A/B partitions](docs/avb-ab-partitions.png)
119
120Note how the rollback indexes differ between slots - for slot A the
121rollback indexes are `[42, 101]` and for slot B they are `[43, 103]`.
122
123# Tools and Libraries
124
125This section contains information about the tools and libraries
126included in AVB.
127
128## avbtool and libavb
129
130The main job of `avbtool` is to create `vbmeta.img` which is the
131top-level object for verified boot. This image is designed to go into
132the `vbmeta` partition (or, if using A/B, the slot in question
133e.g. `vbmeta_a` or `vbmeta_b`) and be of minimal size (for out-of-band
134updates). The vbmeta image is cryptographically signed and contains
135verification data (e.g. cryptographic digests) for verifying
136`boot.img`, `system.img`, and other partitions/images.
137
138The vbmeta image can also contain references to other partitions where
139verification data is stored as well as a public key indicating who
140should sign the verification data. This indirection provides
141delegation, that is, it allows a 3rd party to control content on a
142given partition by including their public key in `vbmeta.img`. By
143design, this authority can be easily revoked by simply updating
144`vbmeta.img` with new descriptors for the partition in question.
145
146Storing signed verification data on other images - for example
147`boot.img` and `system.img` - is also done with `avbtool`.
148
149In addition to `avbtool`, a library - `libavb` - is provided. This
150library performs all verification on the device side e.g. it starts by
151loading the `vbmeta` partition, checks the signature, and then goes on
152to load the `boot` partition for verification. This library is
153intended to be used in both boot loaders and inside Android. It has a
154simple abstraction for system dependencies (see `avb_sysdeps.h`) as
155well as operations that the boot loader or OS is expected to implement
156(see `avb_ops.h`). The main entry point for verification is
157`avb_slot_verify()`.
158
159Android Things has specific requirements and validation logic for the
160vbmeta public key. An extension is provided in `libavb_atx` which
161performs this validation as an implementation of `libavb`'s public key
162validation operation (see `avb_validate_vbmeta_public_key()` in
163`avb_ops.h`).
164
165## Files and Directories
166
167* `libavb/`
168    + An implementation of image verification. This code is designed
169      to be highly portable so it can be used in as many contexts as
170      possible. This code requires a C99-compliant C compiler. Part of
171      this code is considered internal to the implementation and
172      should not be used outside it. For example, this applies to the
173      `avb_rsa.[ch]` and `avb_sha.[ch]` files. System dependencies
174      expected to be provided by the platform is defined in
175      `avb_sysdeps.h`. If the platform provides the standard C runtime
176      `avb_sysdeps_posix.c` can be used.
177* `libavb_ab/`
178    + An experimental A/B implementation for use in boot loaders
179      and AVB examples.
180* `libavb_atx/`
181    + An Android Things Extension for validating public key metadata.
182* `libavb_user/`
183    + Contains an `AvbOps` implementation suitable for use in Android
184      userspace. This is used in `boot_control.avb` and `avbctl`.
185* `boot_control/`
186    + An implementation of the Android `boot_control` HAL for use with
187      boot loaders using the experimental `libavb_ab` A/B stack.
188* `Android.bp`
189    + Build instructions for building `libavb` (a static library for use
190      on the device), host-side libraries (for unit tests), and unit
191      tests.
192* `avbtool`
193    + A tool written in Python for working with images related to
194      verified boot.
195* `test/`
196    + Unit tests for `abvtool`, `libavb`, `libavb_ab`, and
197      `libavb_atx`.
198* `tools/avbctl/`
199    + Contains the source-code for a tool that can be used to control
200      AVB at runtime in Android.
201* `examples/uefi/`
202    + Contains the source-code for a UEFI-based boot-loader utilizing
203      `libavb/` and `libavb_ab/`.
204* `README.md`
205    + This file.
206* `docs/`
207    + Contains documentation files.
208
209## Portability
210
211The `libavb` code is intended to be used in bootloaders in devices
212that will load Android or other operating systems. The suggested
213approach is to copy the appropriate header and C files mentioned in
214the previous section into the boot loader and integrate as
215appropriate.
216
217As the `libavb/` codebase will evolve over time integration should be
218as non-invasive as possible. The intention is to keep the API of the
219library stable however it will be broken if necessary. As for
220portability, the library is intended to be highly portable, work on
221both little- and big-endian architectures and 32- and 64-bit. It's
222also intended to work in non-standard environments without the
223standard C library and runtime.
224
225If the `AVB_ENABLE_DEBUG` preprocessor symbol is set, the code will
226include useful debug information and run-time checks. Production
227builds should not use this. The preprocessor symbol `AVB_COMPILATION`
228should be set only when compiling the libraries. The code must be
229compiled into a separate library.
230
231Applications using the compiled `libavb` library must only include the
232`libavb/libavb.h` file (which will include all public interfaces) and
233must not have the `AVB_COMPILATION` preprocessor symbol set. This is
234to ensure that internal code that may be change in the future (for
235example `avb_sha.[ch]` and `avb_rsa.[ch]`) will not be visible to
236application code.
237
238## Versioning and Compatibility
239
240AVB uses a version number with three fields - the major, minor, and
241sub version. Here's an example version number
242
243                         1.4.3
244                         ^ ^ ^
245                         | | |
246    the major version ---+ | |
247    the minor version -----+ |
248      the sub version -------+
249
250The major version number is bumped only if compatibility is broken,
251e.g. a struct field has been removed or changed. The minor version
252number is bumped only if a new feature is introduced, for example a
253new algorithm or descriptor has been added. The sub version number is
254bumped when bugs are fixed or other changes not affecting
255compatibility are made.
256
257The `AvbVBMetaImageHeader` struct (as defined in the
258`avb_vbmeta_image.h`) carries the major and minor version number of
259`libavb` required to verify the struct in question. This is stored in
260the `required_libavb_version_major` and
261`required_libavb_version_minor` fields. Additionally this struct
262contains a textual field with the version of `avbtool` used to create
263the struct, for example "avbtool 1.4.3" or "avbtool 1.4.3 some_board
264Git-4589fbec".
265
266Note that it's entirely possible to have a `AvbVBMetaImageHeader`
267struct with
268
269    required_libavb_version_major = 1
270    required_libavb_version_minor = 0
271    avbtool_release_string = "avbtool 1.4.3"
272
273if, for example, creating an image that does not use any features
274added after AVB version 1.0.
275
276## Adding New Features
277
278If adding a new feature for example a new algorithm or a new
279descriptor then `AVB_VERSION_MINOR` in `avb_version.h` and `avbtool`
280must be bumped and `AVB_VERSION_SUB` should be set to zero.
281
282Unit tests **MUST** be added to check that
283
284* The feature is used if - and only if - suitable commands/options are
285  passed to `avbtool`.
286* The `required_version_minor` field is set to the bumped value if -
287  and only if - the feature is used. Also add tests to check that the
288  correct value is output when `--print_required_libavb_version` is
289  used.
290
291If `AVB_VERSION_MINOR` has already been bumped since the last release
292there is obviously no need to bump it again.
293
294## Using avbtool
295
296The content for the vbmeta partition can be generated as follows:
297
298    $ avbtool make_vbmeta_image                                                    \
299        [--output OUTPUT]                                                          \
300        [--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key]   \
301        [--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER]        \
302        [--include_descriptors_from_image /path/to/image.bin]                      \
303        [--setup_rootfs_from_kernel /path/to/image.bin]                            \
304        [--chain_partition part_name:rollback_index_location:/path/to/key1.bin]    \
305        [--signing_helper /path/to/external/signer]                                \
306        [--signing_helper_with_files /path/to/external/signer_with_files]          \
307        [--print_required_libavb_version]                                          \
308        [--append_to_release_string STR]
309
310An integrity footer containing the hash for an entire partition can be
311added to an existing image as follows:
312
313    $ avbtool add_hash_footer                                                      \
314        --partition_name PARTNAME --partition_size SIZE                            \
315        [--image IMAGE]                                                            \
316        [--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key]   \
317        [--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER]        \
318        [--hash_algorithm HASH_ALG] [--salt HEX]                                   \
319        [--include_descriptors_from_image /path/to/image.bin]                      \
320        [--setup_rootfs_from_kernel /path/to/image.bin]                            \
321        [--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image]        \
322        [--signing_helper /path/to/external/signer]                                \
323        [--signing_helper_with_files /path/to/external/signer_with_files]          \
324        [--print_required_libavb_version]                                          \
325        [--append_to_release_string STR]                                           \
326        [--calc_max_image_size]
327
328An integrity footer containing the root digest and salt for a hashtree
329for a partition can be added to an existing image as follows. The
330hashtree is also appended to the image.
331
332    $ avbtool add_hashtree_footer                                                  \
333        --partition_name PARTNAME --partition_size SIZE                            \
334        [--image IMAGE]                                                            \
335        [--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key]   \
336        [--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER]        \
337        [--hash_algorithm HASH_ALG] [--salt HEX] [--block_size SIZE]               \
338        [--include_descriptors_from_image /path/to/image.bin]                      \
339        [--setup_rootfs_from_kernel /path/to/image.bin]                            \
340        [--setup_as_rootfs_from_kernel]                                            \
341        [--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image]        \
342        [--do_not_generate_fec] [--fec_num_roots FEC_NUM_ROOTS]                    \
343        [--signing_helper /path/to/external/signer]                                \
344        [--signing_helper_with_files /path/to/external/signer_with_files]          \
345        [--print_required_libavb_version]                                          \
346        [--append_to_release_string STR]                                           \
347        [--calc_max_image_size]
348
349The size of an image with integrity footers can be changed using the
350`resize_image` command:
351
352    $ avbtool resize_image                                                         \
353        --image IMAGE                                                              \
354        --partition_size SIZE
355
356The integrity footer on an image can be removed from an image. The
357hashtree can optionally be kept in place.
358
359    $ avbtool erase_footer --image IMAGE [--keep_hashtree]
360
361For hash- and hashtree-images the vbmeta struct can also be written to
362an external file via the `--output_vbmeta_image` option and one can
363also specify that the vbmeta struct and footer not be added to the
364image being operated on.
365
366To calculate the maximum size of an image that will fit in a partition
367of a given size after having used the `avbtool add_hash_footer` or
368`avbtool add_hashtree_footer` commands on it, use the
369`--calc_max_image_size` option:
370
371    $ avbtool add_hash_footer --partition_size $((10*1024*1024)) \
372        --calc_max_image_size
373    10416128
374
375    $ avbtool add_hashtree_footer --partition_size $((10*1024*1024)) \
376        --calc_max_image_size
377    10330112
378
379To calculate the required libavb version that would be put in the
380vbmeta struct when using `make_vbmeta_image`, `add_hash_footer`, and
381`add_hashtree_footer` commands use the
382`--print_required_libavb_version` option:
383
384    $ avbtool make_vbmeta_image \
385        --algorithm SHA256_RSA2048 --key /path/to/key.pem \
386        --include_descriptors_from_image /path/to/boot.img \
387        --include_descriptors_from_image /path/to/system.img \
388        --print_required_libavb_version
389    1.0
390
391The `--signing_helper` option can be used in `make_vbmeta_image`,
392`add_hash_footer` and `add_hashtree_footer` commands to specify any
393external program for signing hashes. The data to sign (including
394padding e.g. PKCS1-v1.5) is fed via `STDIN` and the signed data is
395returned via `STDOUT`. If `--signing_helper` is present in a command
396line, the `--key` option need only contain a public key. Arguments for
397a signing helper are `algorithm` and `public key`. If the signing
398helper exits with a non-zero exit code, it means failure.
399
400Here's an example invocation:
401
402    /path/to/my_signing_program SHA256_RSA2048 /path/to/publickey.pem
403
404The `--signing_helper_with_files` is similar to `--signing_helper`
405except that a temporary file is used to communicate with the helper
406instead of `STDIN` and `STDOUT`. This is useful in situations where
407the signing helper is using code which is outputting diagnostics on
408`STDOUT` instead of `STDERR`. Here's an example invocation
409
410    /path/to/my_signing_program_with_files SHA256_RSA2048 \
411      /path/to/publickey.pem /tmp/path/to/communication_file
412
413where the last positional argument is a file that contains the data to
414sign. The helper should write the signature in this file.
415
416The `append_vbmeta_image` command can be used to append an entire
417vbmeta blob to the end of another image. This is useful for cases when
418not using any vbmeta partitions, for example:
419
420    $ cp boot.img boot-with-vbmeta-appended.img
421    $ avbtool append_vbmeta_image                       \
422        --image boot-with-vbmeta-appended.img           \
423        --partition_size SIZE_OF_BOOT_PARTITION         \
424        --vbmeta_image vbmeta.img
425    $ fastboot flash boot boot-with-vbmeta-appended.img
426
427The `verify_image` command can be used to verify the contents of
428several image files at the same time. When invoked on an image the
429following checks are performed:
430
431* If the image has a VBMeta struct the signature is checked against
432  the embedded public key. If the image doesn't look like `vbmeta.img`
433  then a footer is looked for and used if present.
434
435* If the option `--key` is passed then a `.pem` file is expected and
436  it's checked that the embedded public key in said VBMeta struct
437  matches the given key.
438
439* All descriptors in the VBMeta struct are checked in the following
440  way:
441    + For a hash descriptor the image file corresponding to the
442      partition name is loaded and its digest is checked against that
443      in the descriptor.
444    + For a hashtree descriptor the image file corresponding to the
445      partition name is loaded and the hashtree is calculated and its
446      root digest compared to that in the descriptor.
447    + For a chained partition descriptor its contents is compared
448      against content that needs to be passed in via the
449      `--expected_chain_partition` options. The format for this option
450      is similar to that of the `--chain_partition` option. If there
451      is no `--expected_chain_partition` descriptor for the chain
452      partition descriptor the check fails.
453
454Here's an example for a setup where the digests for `boot.img` and
455`system.img` are stored in `vbmeta.img` which is signed with
456`my_key.pem`. It also checks that the chain partition for partition
457`foobar` uses rollback index 8 and that the public key in AVB format
458matches that of the file `foobar_vendor_key.avbpubkey`:
459
460    $ avbtool verify_image \
461         --image /path/to/vbmeta.img \
462         --key my_key.pem \
463         --expect_chained_partition foobar:8:foobar_vendor_key.avbpubkey
464
465    Verifying image /path/to/vbmeta.img using key at my_key.pem
466    vbmeta: Successfully verified SHA256_RSA4096 vbmeta struct in /path_to/vbmeta.img
467    boot: Successfully verified sha256 hash of /path/to/boot.img for image of 10543104 bytes
468    system: Successfully verified sha1 hashtree of /path/to/system.img for image of 1065213952 bytes
469    foobar: Successfully verified chain partition descriptor matches expected data
470
471In this example the `verify_image` command verifies the files
472`vbmeta.img`, `boot.img`, and `system.img` in the directory
473`/path/to`. The directory and file extension of the given image
474(e.g. `/path/to/vbmeta.img`) is used together with the partition name
475in the descriptor to calculate the filenames of the images holding
476hash and hashtree images.
477
478The `verify_image` command can also be used to check that a custom
479signing helper works as intended.
480
481## Build System Integration
482
483In Android, AVB is enabled by the `BOARD_AVB_ENABLE` variable
484
485    BOARD_AVB_ENABLE := true
486
487This will make the build system create `vbmeta.img` which will contain
488a hash descriptor for `boot.img`, a hashtree descriptor for
489`system.img`, a kernel-cmdline descriptor for setting up `dm-verity`
490for `system.img` and append a hash-tree to `system.img`. If the build
491system is set up such that `vendor.img` is being built, a hash-tree
492will also be appended to this image and its hash-tree descriptor will
493be included in `vbmeta.img`.
494
495By default, the algorithm `SHA256_RSA4096` is used with a test key
496from the `external/avb/test/data` directory. This can be overriden by
497the `BOARD_AVB_ALGORITHM` and `BOARD_AVB_KEY_PATH` variables to use
498e.g. a 4096-bit RSA key and SHA-512:
499
500    BOARD_AVB_ALGORITHM := SHA512_RSA4096
501    BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
502
503Remember that the public part of this key needs to be available to the
504bootloader of the device expected to verify resulting images. Use
505`avbtool extract_public_key` to extract the key in the expected format
506(`AVB_pk` in the following). If the device is using a different root
507of trust than `AVB_pk` the `--public_key_metadata` option can be used
508to embed a blob (`AVB_pkmd` in the following) that can be used to
509e.g. derive `AVB_pk`. Both `AVB_pk` and `AVB_pkmd` are passed to the
510`validate_vbmeta_public_key()` operation when verifying a slot.
511
512To prevent rollback attacks, the rollback index should be increased on
513a regular basis. The rollback index can be set with the
514`BOARD_AVB_ROLLBACK_INDEX` variable:
515
516     BOARD_AVB_ROLLBACK_INDEX := 5
517
518If this is not set, the rollback index defaults to 0.
519
520The variable `BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS` can be used to specify
521additional options passed to `avbtool make_vbmeta_image`. Typical
522options to be used here include `--prop`, `--prop_from_file`,
523`--chain_partition`, `--public_key_metadata`, and `--signing_helper`.
524
525The variable `BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS` can be used to
526specify additional options passed to `avbtool add_hash_footer` for
527`boot.img`. Typical options to be used here include `--hash_algorithm`
528and `--salt`.
529
530The variable `BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS` can be used
531to specify additional options passed to `avbtool add_hashtree_footer`
532for `system.img`. Typical options to be used here include
533`--hash_algorithm`, `--salt`, `--block_size`, and
534`--do_not_generate_fec`.
535
536The variable `BOARD_AVB_VENDOR_ADD_HASHTREE_FOOTER_ARGS` can be used
537to specify additional options passed to `avbtool add_hashtree_footer`
538for `vendor.img`. Typical options to be used here include
539`--hash_algorithm`, `--salt`, `--block_size`, and
540`--do_not_generate_fec`.
541
542The variable `BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS` can be used to
543specify additional options passed to `avbtool add_hash_footer` for
544`dtbo.img`. Typical options to be used here include `--hash_algorithm`
545and `--salt`.
546
547Build system variables (such as `PRODUCT_SUPPORTS_VERITY_FEC`) used
548for previous version of Verified Boot in Android are not used in AVB.
549
550# Device Integration
551
552This section discusses recommendations and best practices for
553integrating `libavb` with a device boot loader. It's important to
554emphasize that these are just recommendations so the use of the word
555`must` should be taken lightly.
556
557Additionally term *HLOS* is used in this chapter to refer to the *High
558Level Operating System*. This obviously includes Android (including
559other form-factors than phones) but could also be other operating
560systems.
561
562## System Dependencies
563
564The `libavb` library is written in a way so it's portable to any
565system with a C99 compiler. It does not require the standard C library
566however the boot loader must implement a simple set of system
567primitives required by `libavb` such as `avb_malloc()`, `avb_free()`,
568and `avb_print()`.
569
570In addition to the system primitives, `libavb` interfaces with the boot
571loader through the supplied `AvbOps` struct. This includes operations
572to read and write data from partitions, read and write rollback
573indexes, check if the public key used to make a signature should be
574accepted, and so on.
575
576## Locked and Unlocked mode
577
578AVB has been designed to support the notion of the device being either
579LOCKED state or UNLOCKED state as used in Android.
580
581In the context of AVB, the LOCKED state means that verification errors
582are fatal whereas in UNLOCKED state they are not. If the device is
583UNLOCKED pass `AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR` flag in
584the `flags` parameter of `avb_slot_verify()` and treat verification
585errors including
586
587* `AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED`
588* `AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION`
589* `AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX`
590
591as non-fatal. If the device is in the LOCKED state, don't pass the
592`AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR` flag in the `flags`
593parameter of `avb_slot_verify()` and only treat
594`AVB_SLOT_VERIFY_RESULT_OK` as non-fatal.
595
596On Android, device state may be altered through the fastboot interface
597using, e.g. `fastboot flashing lock` (to transition to the LOCKED
598state) and `fastboot flashing unlock` (to transition to the UNLOCKED
599state).
600
601The device must only allow state transitions (e.g. from LOCKED to
602UNLOCKED or UNLOCKED to LOCKED) after asserting physical presence of
603the user. If the device has a display and buttons this is typically
604done by showing a dialog and requiring the user to confirm or cancel
605using physical buttons.
606
607All user data must be cleared when transitioning from the LOCKED to
608the UNLOCKED state (including the `userdata` partition and any NVRAM
609spaces). Additionally all `stored_rollback_index[n]` locations must be
610cleared (all elements must be set to zero). Similar action (erasing
611`userdata`, NVRAM spaces, and `stored_rollback_index[n]` locations)
612shall also happening when transitioning from UNLOCKED to LOCKED. If
613the device is required to use full disk encryption, then a less
614intensive wipe is required for UNLOCKED to LOCKED. Depending on the
615device form-factor and intended use, the user should be prompted to
616confirm before any data is erased.
617
618## Tamper-evident Storage
619
620In this document, *tamper-evident* means that it's possible to detect
621if the HLOS has tampered with the data, e.g. if it has been
622overwritten.
623
624Tamper-evident storage must be used for stored rollback indexes, keys
625used for verification, and device state (whether the device is LOCKED
626or UNLOCKED). If tampering has been detected the corresponding
627`AvbOps` operation should fail by e.g. returning
628`AVB_IO_RESULT_ERROR_IO`. It is especially important that verification
629keys cannot be tampered with since they represent the root-of-trust.
630
631If verification keys are mutable they must only be set by the end
632user, e.g. it must never be set at the factory or store or any
633intermediate point before the end user. Additionally, it must only be
634possible to set or clear a key while the device is in the UNLOCKED
635state.
636
637## Updating Stored Rollback Indexes
638
639In order for Rollback Protection to work the bootloader will need to
640update the `stored_rollback_indexes[n]` array on the device prior to
641transferring control to the HLOS. If not using A/B this is
642straightforward - just update it to what's in the AVB metadata for the
643slot before booting. In pseudo-code it would look like this:
644
645```c++
646// The |slot_data| parameter should be the AvbSlotVerifyData returned
647// by avb_slot_verify() for the slot we're about to boot.
648//
649bool update_stored_rollback_indexes_for_slot(AvbOps* ops,
650                                             AvbSlotVerifyData* slot_data) {
651    for (int n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
652        uint64_t rollback_index = slot_data->rollback_indexes[n];
653        if (rollback_index > 0) {
654            AvbIOResult io_ret;
655            uint64_t current_stored_rollback_index;
656
657            io_ret = ops->read_rollback_index(ops, n, &current_stored_rollback_index);
658            if (io_ret != AVB_IO_RESULT_OK) {
659                return false;
660            }
661
662            if (rollback_index > current_stored_rollback_index) {
663                io_ret = ops->write_rollback_index(ops, n, rollback_index);
664                if (io_ret != AVB_IO_RESULT_OK) {
665                    return false;
666                }
667            }
668        }
669    }
670    return true;
671}
672```
673
674However if using A/B more care must be taken to still allow the device
675to fall back to the old slot if the update didn't work.
676
677For an HLOS like Android where rollback is only supported if the
678updated OS version is found to not work, `stored_rollback_index[n]`
679should only be updated from slots that are marked as SUCCESSFUL in the
680A/B metadata. The pseudo-code for that is as follows where
681`is_slot_is_marked_as_successful()` comes from the A/B stack in use:
682
683```c++
684if (is_slot_is_marked_as_successful(slot->ab_suffix)) {
685    if (!update_stored_rollback_indexes_for_slot(ops, slot)) {
686        // TODO: handle error.
687    }
688}
689```
690
691For an HLOS where it's possible to roll back to a previous version,
692`stored_rollback_index[n]` should be set to the largest possible value
693allowing all bootable slots to boot. This approach is implemented in
694AVB's experimental A/B stack `libavb_ab`, see the `avb_ab_flow()`
695implementation. Note that this requires verifying *all* bootable slots
696at every boot and this may impact boot time.
697
698## Recommended Bootflow
699
700The recommended boot flow for a device using AVB is as follows:
701
702![Recommended AVB boot flow](docs/avb-recommended-boot-flow.png)
703
704Notes:
705
706* The device is expected to search through all A/B slots until it
707  finds a valid OS to boot. Slots that are rejected in the LOCKED
708  state might not be rejected in the UNLOCKED state, (e.g. when
709  UNLOCKED any key can be used and rollback index failures are
710  allowed), so the algorithm used for selecting a slot varies
711  depending on what state the device is in.
712
713* If no valid OS (that is, no bootable A/B slot) can be found, the
714  device cannot boot and has to enter repair mode. It is
715  device-dependent what this looks like.  If the device has a screen
716  it must convey this state to the user.
717
718* If the device is LOCKED, only an OS signed by an embedded
719  verification key (see the previous section) shall be
720  accepted. Additionally, `rollback_index[n]` as stored in the
721  verified image must be greater or equal than what's in
722  `stored_rollback_index[n]` on the device (for all `n`) and the
723  `stored_rollback_index[n]` array is expected to be updated as
724  specified in the previous section.
725    + If the key used for verification was set by the end user, and
726      the device has a screen, it must show a warning with the key
727      fingerprint to convey that the device is booting a custom
728      OS. The warning must be shown for at least 10 seconds before the
729      boot process continues. If the device does not have a screen,
730      other ways must be used to convey that the device is booting a
731      custom OS (lightbars, LEDs, etc.).
732
733* If the device is UNLOCKED, there is no requirement to check the key
734  used to sign the OS nor is there any requirement to check or update
735  rollback `stored_rollback_index[n]` on the device. Because of this
736  the user must always be shown a warning about verification not
737  occurring.
738    + It is device-dependent how this is implemented since it depends
739      on the device form-factor and intended usage. If the device has
740      a screen and buttons (for example if it's a phone) the warning
741      is to be shown for at least 10 seconds before the boot process
742      continues. If the device does not have a screen, other ways must
743      be used to convey that the device is UNLOCKED (lightbars, LEDs,
744      etc.).
745
746## Handling dm-verity Errors
747
748By design, hashtree verification errors are detected by the HLOS and
749not the bootloader. AVB provides a way to specify how the error should
750be handled through the `hashtree_error_mode` parameter in the
751`avb_slot_verify()` function. Possible values include
752
753* `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE` means that the HLOS
754  will invalidate the current slot and restart. On devices with A/B
755  this would lead to attempting to boot the other slot (if it's marked
756  as bootable) or it could lead to a mode where no OS can be booted
757  (e.g. some form of repair mode).
758
759* `AVB_HASHTREE_ERROR_MODE_RESTART` means that the OS will restart
760  without the current slot being invalidated. Be careful using this
761  mode unconditionally as it may introduce boot loops if the same
762  hashtree verification error is hit on every boot.
763
764* `AVB_HASHTREE_ERROR_MODE_EIO` means that an `EIO` error will be
765  returned to the application.
766
767* `AVB_HASHTREE_ERROR_MODE_LOGGING` means that errors will be logged
768   and corrupt data may be returned to applications. This mode should
769   be used for **ONLY** diagnostics and debugging. It cannot be used
770   unless verification errors are allowed.
771
772The value passed in `hashtree_error_mode` is essentially just passed
773on through to the HLOS through the the `androidboot.veritymode` and
774`androidboot.vbmeta.invalidate_on_error` kernel command-line
775parameters. The HLOS - including the Linux kernel when using
776`CONFIG_DM_VERITY_AVB` - will then act upon hashtree verification
777errors as specified.
778
779### Which mode should I use for my device?
780
781This depends entirely on the device, how the device is intended to be
782used, and the desired user experience.
783
784For example, consider
785the
786[EIO mode in an earlier version of Android Verified Boot](https://source.android.com/security/verifiedboot/verified-boot) (see
787the "Recovering from dm-verity errors" section). In a nutshell this
788mode uses `AVB_HASHTREE_ERROR_MODE_RESTART` mode until an error is
789encounted and then it switches to `AVB_HASHTREE_ERROR_MODE_EIO` mode
790on the reboot. Additionally when in `AVB_HASHTREE_ERROR_MODE_EIO` mode
791the user is informed that the device experienced corruption and then
792asked to click through a screen to continue.
793
794To implement this mode in a boot loader, a combination of the
795`AVB_HASHTREE_ERROR_MODE_RESTART` mode and
796`AVB_HASHTREE_ERROR_MODE_EIO` mode could be used along with persistent
797storage recording what mode the bootloader is currently in. This would
798need to include transition rules e.g. if the kernel indicates that it
799rebooted because of a `dm-verity` error the bootloader would need to
800transition from the `AVB_HASHTREE_ERROR_MODE_RESTART` mode to the
801`AVB_HASHTREE_ERROR_MODE_EIO` mode. Ditto, when the slot is updated
802the bootloader needs to transition from the
803`AVB_HASHTREE_ERROR_MODE_EIO` mode back to the
804`AVB_HASHTREE_ERROR_MODE_RESTART` mode so the user doesn't have to
805click through a screen on every boot.
806
807On the other hand, if the device doesn't have a screen or if the HLOS
808supports multiple bootable slots simultaneously it may make more sense
809to just use `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE`.
810
811## Android Specific Integration
812
813On Android, the boot loader must set the
814`androidboot.verifiedbootstate` parameter on the kernel command-line
815to indicate the boot state. It shall use the following values:
816
817* **green**: If in LOCKED state and the key used for verification was not set by the end user.
818* **yellow**: If in LOCKED state and the key used for verification was set by the end user.
819* **orange**: If in the UNLOCKED state.
820