blob: e9ffbe179b327a8d7d5f5e668912d82a4262ddd6 [file] [log] [blame]
This directory contains avbtool, libavb, and libavb_ab.
The main job of avbtool is to create vbmeta.img which is the
top-level object for verified boot. This image is designed to go into
the vbmeta partition (or, if using A/B, the slot in question
e.g. vbmeta_a or vbmeta_b) and be of minimal size (for out-of-band
updates). The vbmeta image is cryptographically signed and contains
verification data (e.g. cryptographic digests) for verifying boot.img,
system.img, and other partitions/images.
The vbmeta image can also contain references to other partitions where
verification data is stored as well as a public key indicating who
should sign the verification data. This indirection provides
delegation, that is, it allows a 3rd party to control content on a given
partition by including the public key said 3rd party is using to sign
the data with, in vbmeta.img. By design, this authority can be easily
revoked by simply updating vbmeta.img with new descriptors for the
partition in question.
Storing signed verification data on other images - for example
boot.img and system.img - is also done with avbtool.
In addition to avbtool, a library - libavb - is provided. This library
performs all verification on the device side e.g. it starts by loading
the vbmeta partition, checks the signature, and then goes on to load
the boot partition for verification.
The libavb library is intended to be used in both boot loaders and
inside Android. It has a simple abstraction for system dependencies
(see libavb/avb_sysdeps.h) as well as operations that the boot loader
or OS is expected to implement (see libavb/avb_ops.h). The main entry
point for verification is avb_slot_verify().
It is expected that most devices will use A/B (e.g. multiple copies of
the OS in separate so-called 'slots') in addition to AVB. While
managing A/B metadata and associated metadata (e.g. managing
stored_rollback_index[n] locations) is outside the scope of libavb,
enough interfaces are exposed so the boot loader can integrate its A/B
stack with libavb. In particular avb_slot_verify() takes a
|slot_suffix| parameter and its result struct |AvbSlotVerifyData|
convey the rollback indexes in the image that was verified.
AVB also includes an A/B implementation that boot loaders may
optionally use. This implementation is in the libavb_ab library and
integrates with image verification including updating the
stored_rollback_index[n] locations on the device as needed. The
bootloader can use this through the avb_ab_flow() function. This
library is built on top of libavb.
In libavb_ab, A/B metadata is stored in the 'misc' partition using a
format private to libavb_ab in the location on 'misc' reserved for
this. For more information about the misc.img file format see the
bootable/recovery/bootloader.h file. A/B metadata can be written to
misc.img using the set_ab_metadata sub-command of avbtool. A/B
metadata is comprised of (for each slot) a priority field (0 to 15),
number of tries remaining for attempting to boot the slot (0 to 7),
and a flag to indicate whether the slot has successfully booted.
A/B metadata integrity is provided by a simple magic marker and a
CRC-32 checksum. If invalid A/B metadata is detected, the behavior is
to reset the A/B metadata to a known state where both slots are given
seven boot tries.
An implementation of a boot_control HAL using AVB-specific A/B
metadata is also provided.
Android Things has specific requirements and validation logic for the
vbmeta public key. An extension is provided in libavb_atx which performs
this validation as an implementatio of libavb's public key validation
operation (see avb_validate_vbmeta_public_key in avb_ops.h).
-- FILES AND DIRECTORIES
libavb/
An implementation of image verification. This code is designed to
be highly portable so it can be used in as many contexts as
possible. This code requires a C99-compliant C compiler.
Part of this code is considered internal to the implementation and
should not be used outside it. For example, this applies to the
avb_rsa.[ch] and avb_sha.[ch] files.
System dependencies expected to be provided by the platform is
defined in avb_sysdeps.h. If the platform provides the standard C
runtime avb_sysdeps_posix.c can be used.
libavb_ab/
An A/B implementation for use in boot loaders. This is built on top
of libavb.
libavb_atx/
An Android Things Extension for validating public key metadata.
boot_control/
An implemementation of the Android boot_control HAL for use with
boot loaders using libavb_ab.
Android.mk
Build instructions for building libavb (a static library for use on
the device), host-side libraries (for unit tests), and unit tests.
avbtool
A tool written in Python for working with images related to
verified boot.
test/
Contains unit tests for abvtool, libavb, libavb_ab, and libavb_atx.
examples/uefi/
Contains the source-code for a UEFI-based boot-loader utilizing
libavb/ and libavb_ab/.
-- AUDIENCE AND PORTABILITY NOTES
This code is intended to be used in bootloaders in devices running
Android. The suggested approach is to copy the appropriate header and
C files mentioned in the previous section into the boot loader and
integrate as appropriate.
The libavb/ and libavb_ab/ codebase will evolve over time so
integration should be as non-invasive as possible. The intention is to
keep the API of the library stable however it will be broken if
necessary.
As for portability, the library is intended to be highly portable,
work on both little- and big-endian architectures and 32- and
64-bit. It's also intended to work in non-standard environments
without the standard C library and runtime.
If the AVB_ENABLE_DEBUG preprocessor symbol is set, the code will
include useful debug information and run-time checks. Production
builds should not use this.
The preprocessor symbol AVB_COMPILATION should be set only when
compiling the libraries. The code must be compiled into a separate
libraries.
Applications using the compiled libavb library must only include the
libavb/libavb.h file (which will include all public interfaces) and
must not have the AVB_COMPILATION preprocessor symbol set. This is to
ensure that internal code that may be change in the future (for
example avb_sha.[ch] and avb_rsa.[ch]) will not be visible to
application code.
Applications using the compiled libavb_ab library must only include
the libavb_ab/libavb_ab.h file for similar reasons.
-- VERSIONING AND COMPATIBILITY
AVB uses a version number with three fields - the major, minor, and
sub version. Here's an example version number
1.4.3
^ ^ ^
| | |
the major version ---+ | |
the minor version -----+ |
the sub version -------+
The major version number is bumped only if compatibility is broken,
e.g. a struct field has been removed or changed. The minor version
number is bumped only if a new feature is introduced, for example a
new algorithm or descriptor has been added. The sub version number is
bumped when bugs are fixed or other changes not affecting
compatibility are made.
The VBMeta struct (as defined in libavb/avb_vbmeta_header.h) carries
the major and minor version number of libavb required to verify the
struct in question. This is stored in the |required_libavb_version_major|
and |required_libavb_version_minor| fields.
Additionally the VBMeta structure contains a textual field with the
version of avbtool used to create the struct, for example "avbtool
1.4.3" or "avbtool 1.4.3 some_board Git-4589fbec".
Note that it's entirely possible to have a VBMeta struct with
required_libavb_version_major = 1
required_libavb_version_minor = 0
avbtool_release_string = "avbtool 1.4.3"
if, for example, creating an image that do not use any features added
after AVB version 1.0.
-- ADDING NEW FEATURES
If adding a new feature for example a new algorithm or a new
descriptor then AVB_VERSION_MINOR in libavb/avb_version.h and avbtool
must be bumped and AVB_VERSION_SUB should be set to zero.
Unit tests MUST be added to check that
- The feature is used if - and only if - suitable commands/options
are passed to avbtool.
- The |required_version_minor| field is set to the bumped value if -
and only if - the feature is used.
If AVB_VERSION_MINOR has already been bumped since the last release
there is obviously no need to bump it again.
-- USAGE
The content for the vbmeta partition can be generated as follows:
$ avbtool make_vbmeta_image \
--output OUTPUT \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--include_descriptors_from_footer /path/to/image.bin] \
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--chain_partition part_name:rollback_index_location:/path/to/key1.bin] \
[--signing_helper /path/to/external/signer] \
[--append_to_release_string STR]
An integrity footer containing the hash for an entire partition can be
added to an existing image as follows:
$ avbtool add_hash_footer \
--image IMAGE \
--partition_name PARTNAME --partition_size SIZE \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--hash_algorithm HASH_ALG] [--salt HEX] \
[--include_descriptors_from_footer /path/to/image.bin] \
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image] \
[--signing_helper /path/to/external/signer] \
[--append_to_release_string STR]
An integrity footer containing the root digest and salt for a hashtree
for a partition can be added to an existing image as follows. The
hashtree is also appended to the image.
$ avbtool add_hashtree_footer \
--image IMAGE \
--partition_name PARTNAME --partition_size SIZE \
[--algorithm ALGORITHM] [--key /path/to/key_used_for_signing_or_pub_key] \
[--public_key_metadata /path/to/pkmd.bin] [--rollback_index NUMBER] \
[--hash_algorithm HASH_ALG] [--salt HEX] [--block_size SIZE] \
[--include_descriptors_from_footer /path/to/image.bin] \
[--setup_rootfs_from_kernel /path/to/image.bin] \
[--output_vbmeta_image OUTPUT_IMAGE] [--do_not_append_vbmeta_image] \
[--generate_fec] [--fec_num_roots FEC_NUM_ROOTS] \
[--signing_helper /path/to/external/signer] \
[--append_to_release_string STR]
The integrity footer on an image can be removed from an image. The
hashtree can optionally be kept in place.
$ avbtool erase_footer --image IMAGE [--keep_hashtree]
For hash- and hashtree-images the vbmeta struct can also be written to
an external file via the --output_vbmeta_image option and one can also
specify that the vbmeta struct and footer not be added to the image
being operated on.
To calculate the maximum size of an image that will fit in a partition
of a given size after having used the 'avbtool add_hashtree_footer'
command on it, use the --calc_max_image_size option:
$ avbtool add_hashtree_footer --partition_size $((10*1024*1024)) \
--calc_max_image_size
10330112
The --signing_helper option can be used in 'make_vbmeta_image', 'add_hash_footer'
and 'add_hashtree_footer' commands to specify any external program for signing
hashes. The data to sign (including padding e.g. PKCS1-v1.5) is fed via STDIN
and the signed data is returned via STDOUT. If --signing_helper is present in
a command line, the --key option need only contain a public key. Arguments for
a signing helper are 'algorithm' and 'public key'. If the signing helper exits
with a non-zero exit code, it means failure.
Here's an example invocation:
/path/to/my_signing_program SHA256_RSA2048 /path/to/publickey.pem
-- BUILD SYSTEM INTEGRATION NOTES
Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable
BOARD_AVB_ENABLE := true
This will make the build system create vbmeta.img which will contain a
hash descriptor for boot.img, a hashtree descriptor for system.img, a
kernel-cmdline descriptor for setting up dm-verity for system.img and
append a hash-tree to system.img.
By default, the algorithm SHA256_RSA4096 is used with a test key from
this directory. This can be overriden by the BOARD_AVB_ALGORITHM and
BOARD_AVB_KEY_PATH variables to use e.g. a 4096-bit RSA key and
SHA-512:
BOARD_AVB_ALGORITHM := SHA512_RSA4096
BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
Remember that the public part of this key needs to be available to the
bootloader of the device expected to verify resulting images. Use
'avbtool extract_public_key' to extract the key in the expected format
("AVB_pk" in the following). If the device is using a different root
of trust than AVB_pk the --public_key_metadata option can be used to
embed a blob ("AVB_pkmd" in the following) that can be used to
e.g. derive AVB_pk. Both AVB_pk and AVB_pkmd is passed to the
bootloader for validation as part of verifying a slot.
To prevent rollback attacks, the rollback index should be increased on
a regular basis. The rollback index can be set with the
BOARD_AVB_ROLLBACK_INDEX variable:
BOARD_AVB_ROLLBACK_INDEX := 5
If this is not set, the rollback index defaults to 0.
The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify
additional options passed to 'avbtool make_vbmeta_image'. Typical
options to be used here include '--prop', '--prop_from_file', and
'--chain_partition'.
The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to
specify additional options passed to 'avbtool add_hash_footer' for
boot.img. Typical options to be used here include '--hash_algorithm'
and '--salt'.
The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used
to specify additional options passed to 'avbtool add_hashtree_footer'
for systems.img. Typical options to be used here include
'--hash_algorithm', '--salt', and '--block_size'.