| 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'. |