Rework how versioning work. am: e3cadcacd7
am: a467bedf7e
Change-Id: Icaf914c19e0aa6a45b60f380c8dc6471af719453
diff --git a/Android.mk b/Android.mk
index b6ce49f..1ac7e63 100644
--- a/Android.mk
+++ b/Android.mk
@@ -74,7 +74,8 @@
libavb/avb_slot_verify.c \
libavb/avb_sysdeps_posix.c \
libavb/avb_util.c \
- libavb/avb_vbmeta_image.c
+ libavb/avb_vbmeta_image.c \
+ libavb/avb_version.c
include $(BUILD_STATIC_LIBRARY)
# Build libavb for the host (for unit tests).
@@ -101,7 +102,8 @@
libavb/avb_sha512.c \
libavb/avb_slot_verify.c \
libavb/avb_util.c \
- libavb/avb_vbmeta_image.c
+ libavb/avb_vbmeta_image.c \
+ libavb/avb_version.c
include $(BUILD_HOST_STATIC_LIBRARY)
# Build libavb_ab for the host (for unit tests).
diff --git a/README b/README
index 4ff6bf5..e9ffbe1 100644
--- a/README
+++ b/README
@@ -153,41 +153,59 @@
Applications using the compiled libavb_ab library must only include
the libavb_ab/libavb_ab.h file for similar reasons.
--- COMPATIBILITY NOTES
+-- VERSIONING AND COMPATIBILITY
-The VBMeta structure (as defined in libavb/avb_vbmeta_header.h)
-guarantees forwards- and backwards-compatibility provided the major
-version does not change.
+AVB uses a version number with three fields - the major, minor, and
+sub version. Here's an example version number
-When backwards-compatible changes are made - for example, when a new
-field is added to AvbVBMetaImageHeader - the minor version will be
-bumped. At the same time, libavb will also be modified to test for the
-appropriate minor version before attempting to access the newly added
-field. This ensures that version 1.N of the library is able to read an
-old vbmeta image header produced with version 1.M where N > M.
+ 1.4.3
+ ^ ^ ^
+ | | |
+ the major version ---+ | |
+ the minor version -----+ |
+ the sub version -------+
-The usual scenario is that the code parsing the AvbVBMetaImageHeader
-rarely changes (it's usually in the firmware of a device and this
-firmware is rarely updated if ever), let's say it's fixed at version
-1.N. At the same time, the version of the avbtool used to produce the
-vbmeta image is rolling forward and is at version 1.M where M > N. The
-problem with this scenario is that version 1.M may easily and
-inadvertently introduce a seemingly compatible change that isn't. For
-example, consider if a new verification algorithm is added - in this
-case version 1.N of the reference implementation will fail at
-verification time when validating the |algorithm_field| of a 1.M image
-if it's set to the new algorithm.
+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 best approach for dealing with this problem is to always used a
-pinned version of avbtool (say, use version 1.N to generate images
-targeted for devices running version 1.N) for generating and signing
-images but sometimes this is not always possible nor
-desirable. Therefore, to avoid this compatibility problem, avbtool is
-designed to always take such input as a command-line argument so it
-can be kept constant by the caller. In other words, as long as you
-keep your command-line options passed to the avb tool the same, images
-produced by newer versions of avb will continue to work on the same
-version of the reference implementation.
+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
@@ -200,7 +218,8 @@
[--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]
+ [--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:
@@ -214,7 +233,8 @@
[--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]
+ [--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
@@ -230,7 +250,8 @@
[--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]
+ [--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.
diff --git a/avbtool b/avbtool
index 78b87c1..9850634 100755
--- a/avbtool
+++ b/avbtool
@@ -37,11 +37,14 @@
import Crypto.PublicKey.RSA
-# Keep in sync with avb_vbmeta_header.h.
+# Keep in sync with libavb/avb_version.h.
AVB_VERSION_MAJOR = 1
AVB_VERSION_MINOR = 0
+AVB_VERSION_SUB = 0
+
AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = 1
+
class AvbError(Exception):
"""Application-specific errors.
@@ -173,6 +176,14 @@
}
+def get_release_string():
+ """Calculates the release string to use in the VBMeta struct."""
+ # Keep in sync with libavb/avb_version.c:avb_version_string().
+ return 'avbtool {}.{}.{}'.format(AVB_VERSION_MAJOR,
+ AVB_VERSION_MINOR,
+ AVB_VERSION_SUB)
+
+
def round_to_multiple(number, size):
"""Rounds a number up to nearest multiple of another number.
@@ -391,17 +402,17 @@
"""
p = None
if signing_helper is not None:
- p = subprocess.Popen(
- [signing_helper, algorithm_name, key_path],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ p = subprocess.Popen(
+ [signing_helper, algorithm_name, key_path],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
else:
- p = subprocess.Popen(
- ['openssl', 'rsautl', '-sign', '-inkey', key_path, '-raw'],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ p = subprocess.Popen(
+ ['openssl', 'rsautl', '-sign', '-inkey', key_path, '-raw'],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
(pout, perr) = p.communicate(str(raw_data_to_sign))
retcode = p.wait()
if retcode != 0:
@@ -1454,6 +1465,8 @@
MAGIC = 'AVBf'
SIZE = 64
RESERVED = 28
+ FOOTER_VERSION_MAJOR = 1
+ FOOTER_VERSION_MINOR = 0
FORMAT_STRING = ('!4s2L' # magic, 2 x version.
'Q' # Original image size.
'Q' # Offset of VBMeta blob.
@@ -1480,8 +1493,8 @@
raise LookupError('Given data does not look like a AVB footer.')
else:
self.magic = self.MAGIC
- self.version_major = AVB_VERSION_MAJOR
- self.version_minor = AVB_VERSION_MINOR
+ self.version_major = self.FOOTER_VERSION_MAJOR
+ self.version_minor = self.FOOTER_VERSION_MINOR
self.original_image_size = 0
self.vbmeta_offset = 0
self.vbmeta_size = 0
@@ -1507,8 +1520,10 @@
SIZE = 256
- # Keep in sync with |reserved| field of |AvbVBMetaImageHeader|.
- RESERVED = 132
+ # Keep in sync with |reserved0| and |reserved| field of
+ # |AvbVBMetaImageHeader|.
+ RESERVED0 = 4
+ RESERVED = 80
# Keep in sync with |AvbVBMetaImageHeader|.
FORMAT_STRING = ('!4s2L' # magic, 2 x version
@@ -1521,6 +1536,8 @@
'2Q' # offset, size (descriptors)
'Q' # rollback_index
'L' + # flags
+ str(RESERVED0) + 'x' + # padding for reserved bytes
+ '47sx' + # NUL-terminated release string
str(RESERVED) + 'x') # padding for reserved bytes
def __init__(self, data=None):
@@ -1535,7 +1552,8 @@
assert struct.calcsize(self.FORMAT_STRING) == self.SIZE
if data:
- (self.magic, self.header_version_major, self.header_version_minor,
+ (self.magic, self.required_libavb_version_major,
+ self.required_libavb_version_minor,
self.authentication_data_block_size, self.auxiliary_data_block_size,
self.algorithm_type, self.hash_offset, self.hash_size,
self.signature_offset, self.signature_size, self.public_key_offset,
@@ -1543,14 +1561,18 @@
self.public_key_metadata_size, self.descriptors_offset,
self.descriptors_size,
self.rollback_index,
- self.flags) = struct.unpack(self.FORMAT_STRING, data)
+ self.flags,
+ self.release_string) = struct.unpack(self.FORMAT_STRING, data)
# Nuke NUL-bytes at the end of the string.
if self.magic != 'AVB0':
raise AvbError('Given image does not look like a vbmeta image.')
else:
self.magic = 'AVB0'
- self.header_version_major = AVB_VERSION_MAJOR
- self.header_version_minor = AVB_VERSION_MINOR
+ # Start by just requiring version 1.0. Code that adds features
+ # in a future version can use bump_required_libavb_version_minor() to
+ # bump the minor.
+ self.required_libavb_version_major = AVB_VERSION_MAJOR
+ self.required_libavb_version_minor = 0
self.authentication_data_block_size = 0
self.auxiliary_data_block_size = 0
self.algorithm_type = 0
@@ -1566,6 +1588,19 @@
self.descriptors_size = 0
self.rollback_index = 0
self.flags = 0
+ self.release_string = get_release_string()
+
+ def bump_required_libavb_version_minor(self, minor):
+ """Function to bump required_libavb_version_minor.
+
+ Call this when writing data that requires a specific libavb
+ version to parse it.
+
+ Arguments:
+ minor: The minor version of libavb that has support for the feature.
+ """
+ self.required_libavb_version_minor = (
+ min(self.required_libavb_version_minor, minor))
def save(self, output):
"""Serializes the header (256 bytes) to disk.
@@ -1574,14 +1609,14 @@
output: The object to write the output to.
"""
output.write(struct.pack(
- self.FORMAT_STRING, self.magic, self.header_version_major,
- self.header_version_minor, self.authentication_data_block_size,
+ self.FORMAT_STRING, self.magic, self.required_libavb_version_major,
+ self.required_libavb_version_minor, self.authentication_data_block_size,
self.auxiliary_data_block_size, self.algorithm_type, self.hash_offset,
self.hash_size, self.signature_offset, self.signature_size,
self.public_key_offset, self.public_key_size,
self.public_key_metadata_offset, self.public_key_metadata_size,
self.descriptors_offset, self.descriptors_size, self.rollback_index,
- self.flags))
+ self.flags, self.release_string))
def encode(self):
"""Serializes the header (256) to a bytearray().
@@ -1590,14 +1625,16 @@
A bytearray() with the encoded header.
"""
return struct.pack(self.FORMAT_STRING, self.magic,
- self.header_version_major, self.header_version_minor,
+ self.required_libavb_version_major,
+ self.required_libavb_version_minor,
self.authentication_data_block_size,
self.auxiliary_data_block_size, self.algorithm_type,
self.hash_offset, self.hash_size, self.signature_offset,
self.signature_size, self.public_key_offset,
self.public_key_size, self.public_key_metadata_offset,
self.public_key_metadata_size, self.descriptors_offset,
- self.descriptors_size, self.rollback_index, self.flags)
+ self.descriptors_size, self.rollback_index, self.flags,
+ self.release_string)
class Avb(object):
@@ -1719,8 +1756,9 @@
(alg_name, _) = lookup_algorithm_by_type(header.algorithm_type)
- o.write('VBMeta image version: {}.{}{}\n'.format(
- header.header_version_major, header.header_version_minor,
+ o.write('Minimum libavb version: {}.{}{}\n'.format(
+ header.required_libavb_version_major,
+ header.required_libavb_version_minor,
' (Sparse)' if image.is_sparse else ''))
o.write('Header Block: {} bytes\n'.format(AvbVBMetaHeader.SIZE))
o.write('Authentication Block: {} bytes\n'.format(
@@ -1730,6 +1768,8 @@
o.write('Algorithm: {}\n'.format(alg_name))
o.write('Rollback Index: {}\n'.format(header.rollback_index))
o.write('Flags: {}\n'.format(header.flags))
+ o.write('Release String: \'{}\'\n'.format(
+ header.release_string.rstrip('\0')))
# Print descriptors.
num_printed = 0
@@ -1855,7 +1895,9 @@
key_path, public_key_metadata_path, rollback_index,
flags, props, props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper):
+ include_descriptors_from_image, signing_helper,
+ release_string,
+ append_to_release_string):
"""Implements the 'make_vbmeta_image' command.
Arguments:
@@ -1872,6 +1914,8 @@
setup_rootfs_from_kernel: None or file to generate from.
include_descriptors_from_image: List of file objects with descriptors.
signing_helper: Program which signs a hash and return signature.
+ release_string: None or avbtool release string to use instead of default.
+ append_to_release_string: None or string to append.
Raises:
AvbError: If a chained partition is malformed.
@@ -1898,7 +1942,8 @@
algorithm_name, key_path, public_key_metadata_path, descriptors,
rollback_index, flags, props, props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper)
+ include_descriptors_from_image, signing_helper, release_string,
+ append_to_release_string)
# Write entire vbmeta blob (header, authentication, auxiliary).
output.seek(0)
@@ -1909,7 +1954,8 @@
rollback_index, flags, props, props_from_file,
kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper):
+ include_descriptors_from_image, signing_helper,
+ release_string, append_to_release_string):
"""Generates a VBMeta blob.
This blob contains the header (struct AvbVBMetaHeader), the
@@ -1935,6 +1981,8 @@
include_descriptors_from_image: List of file objects for which
to insert descriptors from.
signing_helper: Program which signs a hash and return signature.
+ release_string: None or avbtool release string.
+ append_to_release_string: None or string to append.
Returns:
A bytearray() with the VBMeta blob.
@@ -2021,6 +2069,14 @@
h = AvbVBMetaHeader()
+ # Override release string, if requested.
+ if isinstance(release_string, (str, unicode)):
+ h.release_string = release_string
+
+ # Append to release string, if requested. Also insert a space before.
+ if isinstance(append_to_release_string, (str, unicode)):
+ h.release_string += ' ' + append_to_release_string
+
# For the Auxiliary data block, descriptors are stored at offset 0,
# followed by the public key, followed by the public key metadata blob.
h.auxiliary_data_block_size = round_to_multiple(
@@ -2102,6 +2158,7 @@
props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
include_descriptors_from_image, signing_helper,
+ release_string, append_to_release_string,
output_vbmeta_image, do_not_append_vbmeta_image):
"""Implementation of the add_hash_footer on unsparse images.
@@ -2123,6 +2180,8 @@
include_descriptors_from_image: List of file objects for which
to insert descriptors from.
signing_helper: Program which signs a hash and return signature.
+ release_string: None or avbtool release string.
+ append_to_release_string: None or string to append.
output_vbmeta_image: If not None, also write vbmeta struct to this file.
do_not_append_vbmeta_image: If True, don't append vbmeta struct.
@@ -2199,7 +2258,8 @@
algorithm_name, key_path, public_key_metadata_path, [h_desc],
rollback_index, flags, props, props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper)
+ include_descriptors_from_image, signing_helper, release_string,
+ append_to_release_string)
# If the image isn't sparse, its size might not be a multiple of
# the block size. This will screw up padding later so just grow it.
@@ -2256,6 +2316,7 @@
setup_rootfs_from_kernel,
include_descriptors_from_image,
calc_max_image_size, signing_helper,
+ release_string, append_to_release_string,
output_vbmeta_image, do_not_append_vbmeta_image):
"""Implements the 'add_hashtree_footer' command.
@@ -2286,6 +2347,8 @@
calculate the maximum image size leaving enough room for hashtree
and metadata with the given |partition_size|.
signing_helper: Program which signs a hash and return signature.
+ release_string: None or avbtool release string.
+ append_to_release_string: None or string to append.
output_vbmeta_image: If not None, also write vbmeta struct to this file.
do_not_append_vbmeta_image: If True, don't append vbmeta struct.
@@ -2424,7 +2487,8 @@
algorithm_name, key_path, public_key_metadata_path, [ht_desc],
rollback_index, flags, props, props_from_file, kernel_cmdlines,
setup_rootfs_from_kernel,
- include_descriptors_from_image, signing_helper)
+ include_descriptors_from_image, signing_helper, release_string,
+ append_to_release_string)
padding_needed = (round_to_multiple(len(vbmeta_blob), image.block_size) -
len(vbmeta_blob))
vbmeta_blob_with_padding = vbmeta_blob + '\0'*padding_needed
@@ -2764,6 +2828,12 @@
help='Rollback Index',
type=parse_number,
default=0)
+ # This is used internally for unit tests. Do not include in --help output.
+ sub_parser.add_argument('--internal_release_string',
+ help=argparse.SUPPRESS)
+ sub_parser.add_argument('--append_to_release_string',
+ help='Text to append to release string',
+ metavar='STR')
sub_parser.add_argument('--prop',
help='Add property',
metavar='KEY:VALUE',
@@ -3026,7 +3096,7 @@
def version(self, _):
"""Implements the 'version' sub-command."""
- print '{}.{}'.format(AVB_VERSION_MAJOR, AVB_VERSION_MINOR)
+ print get_release_string()
def extract_public_key(self, args):
"""Implements the 'extract_public_key' sub-command."""
@@ -3043,7 +3113,9 @@
args.kernel_cmdline,
args.setup_rootfs_from_kernel,
args.include_descriptors_from_image,
- args.signing_helper)
+ args.signing_helper,
+ args.internal_release_string,
+ args.append_to_release_string)
def add_hash_footer(self, args):
"""Implements the 'add_hash_footer' sub-command."""
@@ -3056,6 +3128,8 @@
args.setup_rootfs_from_kernel,
args.include_descriptors_from_image,
args.signing_helper,
+ args.internal_release_string,
+ args.append_to_release_string,
args.output_vbmeta_image,
args.do_not_append_vbmeta_image)
@@ -3074,10 +3148,11 @@
args.setup_rootfs_from_kernel,
args.include_descriptors_from_image,
args.calc_max_image_size, args.signing_helper,
+ args.internal_release_string,
+ args.append_to_release_string,
args.output_vbmeta_image,
args.do_not_append_vbmeta_image)
-
def erase_footer(self, args):
"""Implements the 'erase_footer' sub-command."""
self.avb.erase_footer(args.image.name, args.keep_hashtree)
diff --git a/examples/uefi/Makefile b/examples/uefi/Makefile
index eae589f..6349057 100644
--- a/examples/uefi/Makefile
+++ b/examples/uefi/Makefile
@@ -54,6 +54,7 @@
$(AVB)/libavb/avb_slot_verify.c \
$(AVB)/libavb/avb_util.c \
$(AVB)/libavb/avb_vbmeta_image.c \
+ $(AVB)/libavb/avb_version.c \
$(AVB)/libavb_ab/avb_ab_flow.c
EFI_OBJ_FILES = $(notdir $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(EFI_SRC_FILES))))
diff --git a/examples/uefi/main.c b/examples/uefi/main.c
index c5a0030..8342196 100644
--- a/examples/uefi/main.c
+++ b/examples/uefi/main.c
@@ -42,7 +42,10 @@
InitializeLib(ImageHandle, SystemTable);
- avb_print("UEFI AVB-based bootloader\n");
+ avb_printv("UEFI AVB-based bootloader using libavb version ",
+ avb_version_string(),
+ "\n",
+ NULL);
ops = uefi_avb_ops_new(ImageHandle);
if (ops == NULL) {
@@ -68,8 +71,15 @@
switch (ab_result) {
case AVB_AB_FLOW_RESULT_OK:
case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
- avb_printv("slot_suffix: ", slot_data->ab_suffix, "\n", NULL);
- avb_printv("cmdline: ", slot_data->cmdline, "\n", NULL);
+ avb_printv("slot_suffix: ", slot_data->ab_suffix, "\n", NULL);
+ avb_printv("cmdline: ", slot_data->cmdline, "\n", NULL);
+ avb_printv(
+ "release string: ",
+ (const char*)((((AvbVBMetaImageHeader*)(slot_data->vbmeta_images[0]
+ .vbmeta_data)))
+ ->release_string),
+ "\n",
+ NULL);
/* Pass 'skip_initramfs' since we're not booting into recovery
* mode. Also pass the selected slot in androidboot.slot_suffix.
*/
diff --git a/libavb/avb_footer.c b/libavb/avb_footer.c
index 5f6ed71..b8b8211 100644
--- a/libavb/avb_footer.c
+++ b/libavb/avb_footer.c
@@ -45,7 +45,7 @@
/* Ensure we don't attempt to access any fields if the footer major
* version is not supported.
*/
- if (dest->version_major > AVB_FOOTER_MAJOR_VERSION) {
+ if (dest->version_major > AVB_FOOTER_VERSION_MAJOR) {
avb_error("No support for footer version.\n");
return false;
}
diff --git a/libavb/avb_footer.h b/libavb/avb_footer.h
index 6607c75..e84826f 100644
--- a/libavb/avb_footer.h
+++ b/libavb/avb_footer.h
@@ -42,9 +42,9 @@
/* Size of the footer. */
#define AVB_FOOTER_SIZE 64
-/* The current MAJOR and MINOR versions used - keep in sync with avbtool. */
-#define AVB_FOOTER_MAJOR_VERSION 1
-#define AVB_FOOTER_MINOR_VERSION 0
+/* The current footer version used - keep in sync with avbtool. */
+#define AVB_FOOTER_VERSION_MAJOR 1
+#define AVB_FOOTER_VERSION_MINOR 0
/* The struct used as a footer used on partitions, used to find the
* AvbVBMetaImageHeader struct. This struct is always stored at the
diff --git a/libavb/avb_slot_verify.c b/libavb/avb_slot_verify.c
index f3527c7..3423adc 100644
--- a/libavb/avb_slot_verify.c
+++ b/libavb/avb_slot_verify.c
@@ -30,6 +30,7 @@
#include "avb_sha.h"
#include "avb_util.h"
#include "avb_vbmeta_image.h"
+#include "avb_version.h"
/* Maximum allow length (in bytes) of a partition name, including
* ab_suffix.
@@ -54,6 +55,7 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
+ case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
return false;
case AVB_SLOT_VERIFY_RESULT_OK:
@@ -367,6 +369,14 @@
": Error verifying vbmeta image: invalid vbmeta header\n",
NULL);
goto out;
+
+ case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
+ /* No way to continue this case. */
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION;
+ avb_errorv(full_partition_name,
+ ": Error verifying vbmeta image: unsupported AVB version\n",
+ NULL);
+ goto out;
}
/* Byteswap the header. */
@@ -928,11 +938,11 @@
goto fail;
}
- /* Add androidboot.vbmeta.version option. */
+ /* Add androidboot.vbmeta.avb_version option. */
if (!cmdline_append_version(slot_data,
- "androidboot.vbmeta.version",
- AVB_MAJOR_VERSION,
- AVB_MINOR_VERSION)) {
+ "androidboot.vbmeta.avb_version",
+ AVB_VERSION_MAJOR,
+ AVB_VERSION_MINOR)) {
ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
goto fail;
}
@@ -1107,6 +1117,9 @@
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
ret = "ERROR_INVALID_METADATA";
break;
+ case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+ ret = "ERROR_UNSUPPORTED_VERSION";
+ break;
/* Do not add a 'default:' case here because of -Wswitch. */
}
diff --git a/libavb/avb_slot_verify.h b/libavb/avb_slot_verify.h
index 89cfec7..c50b847 100644
--- a/libavb/avb_slot_verify.h
+++ b/libavb/avb_slot_verify.h
@@ -49,7 +49,8 @@
AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION,
AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX,
AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED,
- AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA
+ AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA,
+ AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION
} AvbSlotVerifyResult;
/* Get a textual representation of |result|. */
@@ -146,13 +147,13 @@
* will end up pointing to the vbmeta partition for the verified
* slot.
*
- * androidboot.vbmeta.version: This is set to the decimal value of
- * AVB_MAJOR_VERSION followed by a dot followed by the decimal value
- * of AVB_MINOR_VERSION, for example "1.0". This version number
- * represents the vbmeta file format version supported by libavb
- * copy used in the boot loader. This is not necessarily the same
- * version number of the on-disk metadata for the slot that was
- * verified.
+ * androidboot.vbmeta.avb_version: This is set to the decimal value
+ * of AVB_VERSION_MAJOR followed by a dot followed by the decimal
+ * value of AVB_VERSION_MINOR, for example "1.0" or "1.4". This
+ * version number represents the vbmeta file format version
+ * supported by libavb copy used in the boot loader. This is not
+ * necessarily the same version number of the on-disk metadata for
+ * the slot that was verified.
*
* Note that androidboot.slot_suffix is not set in |cmdline| - you
* will have to pass this command-line option yourself.
@@ -235,6 +236,10 @@
*
* AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA is returned if some
* of the metadata is invalid or inconsistent.
+ *
+ * AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION is returned if
+ * some of the metadata requires a newer version of libavb than what
+ * is in use.
*/
AvbSlotVerifyResult avb_slot_verify(AvbOps* ops,
const char* const* requested_partitions,
diff --git a/libavb/avb_vbmeta_image.c b/libavb/avb_vbmeta_image.c
index 61b1eda..21bbf92 100644
--- a/libavb/avb_vbmeta_image.c
+++ b/libavb/avb_vbmeta_image.c
@@ -27,6 +27,7 @@
#include "avb_rsa.h"
#include "avb_sha.h"
#include "avb_util.h"
+#include "avb_version.h"
AvbVBMetaVerifyResult avb_vbmeta_image_verify(
const uint8_t* data,
@@ -67,11 +68,19 @@
avb_vbmeta_image_header_to_host_byte_order((const AvbVBMetaImageHeader*)data,
&h);
- /* Ensure we don't attempt to access any fields if the major version
- * is not supported.
+ /* Ensure we don't attempt to access any fields if we do not meet
+ * the specified minimum version of libavb.
*/
- if (h.header_version_major > AVB_MAJOR_VERSION) {
- avb_error("No support for given major version.\n");
+ if ((h.required_libavb_version_major != AVB_VERSION_MAJOR) ||
+ (h.required_libavb_version_minor > AVB_VERSION_MINOR)) {
+ avb_error("Mismatch between image version and libavb version.\n");
+ ret = AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION;
+ goto out;
+ }
+
+ /* Ensure |release_string| ends with a NUL byte. */
+ if (h.release_string[AVB_RELEASE_STRING_SIZE - 1] != '\0') {
+ avb_error("Release string does not end with a NUL byte.\n");
goto out;
}
@@ -233,8 +242,10 @@
AvbVBMetaImageHeader* dest) {
avb_memcpy(dest, src, sizeof(AvbVBMetaImageHeader));
- dest->header_version_major = avb_be32toh(dest->header_version_major);
- dest->header_version_minor = avb_be32toh(dest->header_version_minor);
+ dest->required_libavb_version_major =
+ avb_be32toh(dest->required_libavb_version_major);
+ dest->required_libavb_version_minor =
+ avb_be32toh(dest->required_libavb_version_minor);
dest->authentication_data_block_size =
avb_be64toh(dest->authentication_data_block_size);
@@ -276,6 +287,9 @@
case AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER:
ret = "INVALID_VBMETA_HEADER";
break;
+ case AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION:
+ ret = "UNSUPPORTED_VERSION";
+ break;
case AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH:
ret = "HASH_MISMATCH";
break;
diff --git a/libavb/avb_vbmeta_image.h b/libavb/avb_vbmeta_image.h
index 832773a..0df7126 100644
--- a/libavb/avb_vbmeta_image.h
+++ b/libavb/avb_vbmeta_image.h
@@ -45,9 +45,8 @@
#define AVB_MAGIC "AVB0"
#define AVB_MAGIC_LEN 4
-/* The current MAJOR and MINOR versions used - keep in sync with avbtool. */
-#define AVB_MAJOR_VERSION 1
-#define AVB_MINOR_VERSION 0
+/* Maximum size of the release string including the terminating NUL byte. */
+#define AVB_RELEASE_STRING_SIZE 48
/* Flags for the vbmeta image.
*
@@ -103,9 +102,13 @@
* descriptors. See avb_descriptor_foreach() for a convenience
* function to iterate over descriptors.
*
- * This struct is versioned, see the |header_version_major| and
- * |header_version_minor| fields. Compatibility is guaranteed only
- * within the same major version.
+ * This struct is versioned, see the |required_libavb_version_major|
+ * and |required_libavb_version_minor| fields. This represents the
+ * minimum version of libavb required to verify the header and depends
+ * on the features (e.g. algorithms, descriptors) used. Note that this
+ * may be 1.0 even if generated by an avbtool from 1.4 but where no
+ * features introduced after 1.0 has been used. See the VERSIONING AND
+ * COMPATIBILITY section in the README file for more details.
*
* All fields are stored in network byte order when serialized. To
* generate a copy with fields swapped to native byte order, use the
@@ -118,10 +121,11 @@
typedef struct AvbVBMetaImageHeader {
/* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */
uint8_t magic[AVB_MAGIC_LEN];
- /* 4: The major version of the vbmeta image header. */
- uint32_t header_version_major;
- /* 8: The minor version of the vbmeta image header. */
- uint32_t header_version_minor;
+
+ /* 4: The major version of libavb required for this header. */
+ uint32_t required_libavb_version_major;
+ /* 8: The minor version of libavb required for this header. */
+ uint32_t required_libavb_version_minor;
/* 12: The size of the signature block. */
uint64_t authentication_data_block_size;
@@ -168,10 +172,22 @@
*/
uint32_t flags;
- /* 124: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
+ /* 124: Reserved to ensure |release_string| start on a 16-byte
+ * boundary. Must be set to zeroes.
+ */
+ uint8_t reserved0[4];
+
+ /* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or
+ * "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL
+ * terminated. Applications must not make assumptions about how this
+ * string is formatted.
+ */
+ uint8_t release_string[AVB_RELEASE_STRING_SIZE];
+
+ /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
* bytes. This must be set to zeroes.
*/
- uint8_t reserved[132];
+ uint8_t reserved[80];
} AVB_ATTR_PACKED AvbVBMetaImageHeader;
/* Copies |src| to |dest|, byte-swapping fields in the process.
@@ -192,21 +208,28 @@
* AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED is returned if the vbmeta
* image header is valid but there is no signature or hash.
*
- * AVB_VERIFY_INVALID_VBMETA_HEADER is returned if the header of
- * the vbmeta image is invalid, for example, invalid magic or
- * inconsistent data.
+ * AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER is returned if the
+ * header of the vbmeta image is invalid, for example, invalid magic
+ * or inconsistent data.
*
- * AVB_VERIFY_HASH_MISMATCH is returned if the hash stored in the
- * "Authentication data" block does not match the calculated hash.
+ * AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION is returned if a) the
+ * vbmeta image requires a minimum version of libavb which exceeds the
+ * version of libavb used; or b) the vbmeta image major version
+ * differs from the major version of libavb in use.
*
- * AVB_VERIFY_SIGNATURE_MISMATCH is returned if the signature stored
- * in the "Authentication data" block is invalid or doesn't match the
- * public key stored in the vbmeta image.
+ * AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH is returned if the hash
+ * stored in the "Authentication data" block does not match the
+ * calculated hash.
+ *
+ * AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH is returned if the
+ * signature stored in the "Authentication data" block is invalid or
+ * doesn't match the public key stored in the vbmeta image.
*/
typedef enum {
AVB_VBMETA_VERIFY_RESULT_OK,
AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED,
AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
+ AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION,
AVB_VBMETA_VERIFY_RESULT_HASH_MISMATCH,
AVB_VBMETA_VERIFY_RESULT_SIGNATURE_MISMATCH,
} AvbVBMetaVerifyResult;
diff --git a/libavb/avb_version.c b/libavb/avb_version.c
new file mode 100644
index 0000000..31f5fa6
--- /dev/null
+++ b/libavb/avb_version.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "avb_version.h"
+
+#define AVB_QUOTE(str) #str
+#define AVB_EXPAND_AND_QUOTE(str) AVB_QUOTE(str)
+
+/* Keep in sync with get_release_string() in avbtool. */
+const char* avb_version_string(void) {
+ return AVB_EXPAND_AND_QUOTE(AVB_VERSION_MAJOR) "." AVB_EXPAND_AND_QUOTE(
+ AVB_VERSION_MINOR) "." AVB_EXPAND_AND_QUOTE(AVB_VERSION_SUB);
+}
diff --git a/libavb/avb_version.h b/libavb/avb_version.h
new file mode 100644
index 0000000..7757d09
--- /dev/null
+++ b/libavb/avb_version.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
+#error "Never include this file directly, include libavb.h instead."
+#endif
+
+#ifndef AVB_VERSION_H_
+#define AVB_VERSION_H_
+
+#include "avb_sysdeps.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The version number of AVB - keep in sync with avbtool. */
+#define AVB_VERSION_MAJOR 1
+#define AVB_VERSION_MINOR 0
+#define AVB_VERSION_SUB 0
+
+/* Returns a NUL-terminated string for the libavb version in use. The
+ * returned string usually looks like "%d.%d.%d". Applications must
+ * not make assumptions about the content of this string.
+ *
+ * Boot loaders should display this string in debug/diagnostics output
+ * to aid with debugging.
+ *
+ * This is similar to the string put in the |release_string| string
+ * field in the VBMeta struct by avbtool.
+ */
+const char* avb_version_string(void);
+
+/* TODO: remove when there are no more users of AVB_{MAJOR,MINOR}_VERSION. */
+#define AVB_MAJOR_VERSION AVB_VERSION_MAJOR
+#define AVB_MINOR_VERSION AVB_VERSION_MINOR
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AVB_VERSION_H_ */
diff --git a/libavb/libavb.h b/libavb/libavb.h
index b74307c..d511584 100644
--- a/libavb/libavb.h
+++ b/libavb/libavb.h
@@ -44,6 +44,7 @@
#include "avb_sysdeps.h"
#include "avb_util.h"
#include "avb_vbmeta_image.h"
+#include "avb_version.h"
#undef AVB_INSIDE_LIBAVB_H
#endif /* LIBAVB_H_ */
diff --git a/libavb_ab/avb_ab_flow.c b/libavb_ab/avb_ab_flow.c
index 006e617..3adb927 100644
--- a/libavb_ab/avb_ab_flow.c
+++ b/libavb_ab/avb_ab_flow.c
@@ -248,7 +248,8 @@
break;
case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
- /* Even with |allow_verification_error| this is game over. */
+ case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
+ /* Even with |allow_verification_error| these mean game over. */
set_slot_unbootable = true;
break;
diff --git a/test/avb_slot_verify_unittest.cc b/test/avb_slot_verify_unittest.cc
index 8bc6b6e..c9398a2 100644
--- a/test/avb_slot_verify_unittest.cc
+++ b/test/avb_slot_verify_unittest.cc
@@ -53,7 +53,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -69,7 +70,8 @@
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
"4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
@@ -81,7 +83,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA512_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -97,7 +100,8 @@
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha512 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
"cb913d2f1a884f4e04c1db5bb181f3133fd16ac02fb367a20ef0776c0b07b3656ad1f081"
@@ -110,7 +114,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -128,7 +133,8 @@
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=unlocked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=unlocked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1152 "
"androidboot.vbmeta.digest="
"4161a7e655eabe16c3fe714de5d43736e7c0a190cf08d36c946d2509ce071e4d",
@@ -140,7 +146,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -161,7 +168,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
AvbSlotVerifyData* slot_data = NULL;
const char* requested_partitions[] = {"boot", NULL};
@@ -195,7 +203,11 @@
}
TEST_F(AvbSlotVerifyTest, UnsignedVBMeta) {
- GenerateVBMetaImage("vbmeta_a.img", "", 0, base::FilePath(""));
+ GenerateVBMetaImage("vbmeta_a.img",
+ "",
+ 0,
+ base::FilePath(""),
+ "--internal_release_string \"\"");
AvbSlotVerifyData* slot_data = NULL;
const char* requested_partitions[] = {"boot", NULL};
@@ -220,7 +232,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
// Corrupt four bytes of data in the end of the image. Since the aux
// data is at the end and this data is signed, this will change the
@@ -256,7 +269,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
// Corrupt four bytes of data in the beginning of the image. Unlike
// the CorruptedImage test-case above (which is valid metadata) this
@@ -286,7 +300,8 @@
GenerateVBMetaImage("vbmeta_a.img",
"SHA256_RSA2048",
42,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -339,7 +354,8 @@
" --partition_name boot"
" --partition_size %zd"
" --kernel_cmdline 'cmdline in hash footer $(ANDROID_SYSTEM_PARTUUID)'"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -350,17 +366,19 @@
base::FilePath("test/data/testkey_rsa2048.pem"),
base::StringPrintf(
"--include_descriptors_from_image %s"
- " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'",
+ " --kernel_cmdline 'cmdline in vbmeta $(ANDROID_BOOT_PARTUUID)'"
+ " --internal_release_string \"\"",
boot_path.value().c_str()));
EXPECT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 896 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 4\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Kernel Cmdline descriptor:\n"
" Flags: 0\n"
@@ -428,7 +446,8 @@
"cmdline in vbmeta 1234-fake-guid-for:boot_a cmdline in hash footer "
"1234-fake-guid-for:system_a "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
"androidboot.vbmeta.digest="
"34cdb59b955aa35d4da97701f304fabf7392eecca8c50ff1a0b7b6e1c9aaa1b8",
@@ -451,7 +470,8 @@
" --rollback_index 0"
" --partition_name boot"
" --partition_size %zd"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -459,7 +479,8 @@
"SHA256_RSA2048",
0,
base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--include_descriptors_from_image %s",
+ base::StringPrintf("--include_descriptors_from_image %s"
+ " --internal_release_string \"\"",
boot_path.value().c_str()));
EXPECT_COMMAND(0,
@@ -522,7 +543,8 @@
" --partition_size %zd"
" --algorithm SHA256_RSA4096"
" --key test/data/testkey_rsa4096.pem"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -539,17 +561,19 @@
11,
base::FilePath("test/data/testkey_rsa2048.pem"),
base::StringPrintf("--chain_partition boot:1:%s"
- " --kernel_cmdline 'cmdline2 in vbmeta'",
+ " --kernel_cmdline 'cmdline2 in vbmeta'"
+ " --internal_release_string \"\"",
pk_path.value().c_str()));
EXPECT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 1728 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 11\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Chain Partition descriptor:\n"
" Partition Name: boot\n"
@@ -568,13 +592,14 @@
"VBMeta offset: 5242880\n"
"VBMeta size: 2112 bytes\n"
"--\n"
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 576 bytes\n"
"Auxiliary Block: 1280 bytes\n"
"Algorithm: SHA256_RSA4096\n"
"Rollback Index: 12\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hash descriptor:\n"
" Image Size: 5242880 bytes\n"
@@ -658,7 +683,8 @@
EXPECT_EQ(
"cmdline2 in hash footer cmdline2 in vbmeta "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
"androidboot.vbmeta.digest="
"4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
@@ -684,7 +710,8 @@
" --partition_size %zd"
" --algorithm SHA256_RSA4096"
" --key test/data/testkey_rsa4096.pem"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -699,7 +726,8 @@
"SHA256_RSA2048",
0,
base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--chain_partition boot:1:%s",
+ base::StringPrintf("--chain_partition boot:1:%s"
+ " --internal_release_string \"\"",
pk_path.value().c_str()));
ops_.set_expected_public_key(
@@ -759,7 +787,8 @@
" --partition_size %zd"
" --algorithm SHA256_RSA8192"
" --key test/data/testkey_rsa8192.pem"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -774,7 +803,8 @@
"SHA256_RSA2048",
0,
base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--chain_partition boot:1:%s",
+ base::StringPrintf("--chain_partition boot:1:%s"
+ " --internal_release_string \"\"",
pk_path.value().c_str()));
ops_.set_expected_public_key(
@@ -811,7 +841,8 @@
" --partition_size %zd"
" --algorithm SHA256_RSA4096"
" --key test/data/testkey_rsa4096.pem"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -826,7 +857,8 @@
"SHA256_RSA2048",
110,
base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--chain_partition boot:1:%s",
+ base::StringPrintf("--chain_partition boot:1:%s"
+ " --internal_release_string \"\"",
pk_path.value().c_str()));
ops_.set_expected_public_key(
@@ -894,7 +926,8 @@
" --partition_size %zd"
" --algorithm SHA256_RSA4096"
" --key test/data/testkey_rsa4096.pem"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
boot_path.value().c_str(),
boot_partition_size);
@@ -911,17 +944,19 @@
11,
base::FilePath("test/data/testkey_rsa2048.pem"),
base::StringPrintf("--chain_partition boot:1:%s"
- " --kernel_cmdline 'cmdline2 in vbmeta'",
+ " --kernel_cmdline 'cmdline2 in vbmeta'"
+ " --internal_release_string \"\"",
pk_path.value().c_str()));
EXPECT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 1728 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 11\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Chain Partition descriptor:\n"
" Partition Name: boot\n"
@@ -972,7 +1007,8 @@
EXPECT_EQ(
"cmdline2 in hash footer cmdline2 in vbmeta "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=4416 "
"androidboot.vbmeta.digest="
"4a45faa9adfeb94e9154fe682c11fef1a1a3d829b67cbf1a12ac7f0aa4f8e2e4",
@@ -998,7 +1034,8 @@
" --image %s"
" --partition_name foo"
" --partition_size %zd"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
foo_path.value().c_str(),
foo_partition_size);
@@ -1007,7 +1044,8 @@
" --image %s"
" --partition_name bar"
" --partition_size %zd"
- " --salt deadbeef",
+ " --salt deadbeef"
+ " --internal_release_string \"\"",
bar_path.value().c_str(),
bar_partition_size);
@@ -1016,18 +1054,20 @@
4,
base::FilePath("test/data/testkey_rsa2048.pem"),
base::StringPrintf("--include_descriptors_from_image %s"
- " --include_descriptors_from_image %s",
+ " --include_descriptors_from_image %s"
+ " --internal_release_string \"\"",
foo_path.value().c_str(),
bar_path.value().c_str()));
EXPECT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 896 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 4\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hash descriptor:\n"
" Image Size: 5242880 bytes\n"
@@ -1088,12 +1128,13 @@
TEST_F(AvbSlotVerifyTest, PublicKeyMetadata) {
base::FilePath md_path = GenerateImage("md.bin", 1536);
- GenerateVBMetaImage(
- "vbmeta_a.img",
- "SHA256_RSA2048",
- 0,
- base::FilePath("test/data/testkey_rsa2048.pem"),
- base::StringPrintf("--public_key_metadata %s", md_path.value().c_str()));
+ GenerateVBMetaImage("vbmeta_a.img",
+ "SHA256_RSA2048",
+ 0,
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ base::StringPrintf("--public_key_metadata %s"
+ " --internal_release_string \"\"",
+ md_path.value().c_str()));
ops_.set_expected_public_key(
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem")));
@@ -1113,7 +1154,8 @@
EXPECT_NE(nullptr, slot_data);
EXPECT_EQ(
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=2688 "
"androidboot.vbmeta.digest="
"5edcaa54f40382ee6a2fc3b86cdf383348b35ed07955e83ea32d84b69a97eaa0",
@@ -1142,7 +1184,8 @@
"./avbtool add_hashtree_footer --salt d00df00d --image %s "
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size);
@@ -1156,7 +1199,8 @@
base::StringPrintf("--setup_rootfs_from_kernel %s "
"--kernel_cmdline should_be_in_both=1 "
"--algorithm SHA256_RSA2048 "
- "--flags %d ",
+ "--flags %d "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
hashtree_verification_on
? 0
@@ -1164,13 +1208,14 @@
EXPECT_EQ(
base::StringPrintf(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 896 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 4\n"
"Flags: %d\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Kernel Cmdline descriptor:\n"
" Flags: 1\n"
@@ -1213,7 +1258,8 @@
"restart_on_corruption ignore_zero_blocks\" root=0xfd00 "
"should_be_in_both=1 "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
"androidboot.vbmeta.digest="
"32572f7a89fb44cc76e9e3adbc0cb5272d0604578b2179729aa52d2bba4061c3",
@@ -1222,7 +1268,8 @@
EXPECT_EQ(
"root=PARTUUID=1234-fake-guid-for:system_a should_be_in_both=1 "
"androidboot.vbmeta.device=PARTUUID=1234-fake-guid-for:vbmeta_a "
- "androidboot.vbmeta.version=1.0 androidboot.vbmeta.device_state=locked "
+ "androidboot.vbmeta.avb_version=1.0 "
+ "androidboot.vbmeta.device_state=locked "
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=1472 "
"androidboot.vbmeta.digest="
"bb630c27d09e10117092d4444ea57a99bf44101c46cf5424cfb86928a0873249",
diff --git a/test/avb_util_unittest.cc b/test/avb_util_unittest.cc
index 4ee155d..aeeb425 100644
--- a/test/avb_util_unittest.cc
+++ b/test/avb_util_unittest.cc
@@ -63,8 +63,8 @@
n64 = 0x1122334455667788;
memcpy(h.magic, AVB_FOOTER_MAGIC, AVB_FOOTER_MAGIC_LEN);
- h.version_major = htobe32(AVB_FOOTER_MAJOR_VERSION);
- h.version_minor = htobe32(AVB_FOOTER_MINOR_VERSION);
+ h.version_major = htobe32(AVB_FOOTER_VERSION_MAJOR);
+ h.version_minor = htobe32(AVB_FOOTER_VERSION_MINOR);
h.original_image_size = htobe64(n64);
n64++;
h.vbmeta_offset = htobe64(n64);
@@ -76,8 +76,8 @@
n64 = 0x1122334455667788;
- EXPECT_EQ((uint32_t)AVB_FOOTER_MAJOR_VERSION, s.version_major);
- EXPECT_EQ((uint32_t)AVB_FOOTER_MINOR_VERSION, s.version_minor);
+ EXPECT_EQ((uint32_t)AVB_FOOTER_VERSION_MAJOR, s.version_major);
+ EXPECT_EQ((uint32_t)AVB_FOOTER_VERSION_MINOR, s.version_minor);
EXPECT_EQ(n64, s.original_image_size);
n64++;
EXPECT_EQ(n64, s.vbmeta_offset);
@@ -88,7 +88,7 @@
// Check that the struct still validates if minor is bigger than
// what we expect.
other = h;
- h.version_minor = htobe32(AVB_FOOTER_MINOR_VERSION + 1);
+ h.version_minor = htobe32(AVB_FOOTER_VERSION_MINOR + 1);
EXPECT_NE(0, avb_footer_validate_and_byteswap(&other, &s));
// Check for bad magic.
@@ -98,7 +98,7 @@
// Check for bad major version.
bad = h;
- bad.version_major = htobe32(AVB_FOOTER_MAJOR_VERSION + 1);
+ bad.version_major = htobe32(AVB_FOOTER_VERSION_MAJOR + 1);
EXPECT_EQ(0, avb_footer_validate_and_byteswap(&bad, &s));
}
diff --git a/test/avb_vbmeta_image_unittest.cc b/test/avb_vbmeta_image_unittest.cc
index 560dd01..5403cd2 100644
--- a/test/avb_vbmeta_image_unittest.cc
+++ b/test/avb_vbmeta_image_unittest.cc
@@ -152,10 +152,11 @@
0,
base::FilePath("test/data/testkey_rsa2048.pem"));
+ // Bail if it's a different major version.
AvbVBMetaImageHeader* h =
reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data());
- h->header_version_major = htobe32(1 + be32toh(h->header_version_major));
- EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
+ h->required_libavb_version_major = htobe32(1 + AVB_VERSION_MAJOR);
+ EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION,
avb_vbmeta_image_verify(
vbmeta_image_.data(), vbmeta_image_.size(), NULL, NULL));
}
@@ -163,10 +164,25 @@
TEST_F(VerifyTest, MinorVersionCheck) {
GenerateVBMetaImage("vbmeta.img", "", 0, base::FilePath(""));
+ // Bail if required_libavb_version_minor exceeds our libavb version.
AvbVBMetaImageHeader* h =
reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data());
- h->header_version_minor = htobe32(1 + be32toh(h->header_version_minor));
- EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK_NOT_SIGNED,
+ h->required_libavb_version_minor = htobe32(1 + AVB_VERSION_MINOR);
+ EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_UNSUPPORTED_VERSION,
+ avb_vbmeta_image_verify(
+ vbmeta_image_.data(), vbmeta_image_.size(), NULL, NULL));
+}
+
+TEST_F(VerifyTest, NulTerminatedReleaseString) {
+ GenerateVBMetaImage("vbmeta.img", "", 0, base::FilePath(""));
+
+ // Bail if |release_string| isn't NUL-terminated.
+ AvbVBMetaImageHeader* h =
+ reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data());
+ for (size_t n = 0; n < AVB_RELEASE_STRING_SIZE; n++) {
+ h->release_string[n] = 'a';
+ }
+ EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_INVALID_VBMETA_HEADER,
avb_vbmeta_image_verify(
vbmeta_image_.data(), vbmeta_image_.size(), NULL, NULL));
}
@@ -482,9 +498,9 @@
n32 = 0x11223344;
n64 = 0x1122334455667788;
- h.header_version_major = htobe32(n32);
+ h.required_libavb_version_major = htobe32(n32);
n32++;
- h.header_version_minor = htobe32(n32);
+ h.required_libavb_version_minor = htobe32(n32);
n32++;
h.authentication_data_block_size = htobe64(n64);
n64++;
@@ -522,9 +538,9 @@
n32 = 0x11223344;
n64 = 0x1122334455667788;
- EXPECT_EQ(n32, s.header_version_major);
+ EXPECT_EQ(n32, s.required_libavb_version_major);
n32++;
- EXPECT_EQ(n32, s.header_version_minor);
+ EXPECT_EQ(n32, s.required_libavb_version_minor);
n32++;
EXPECT_EQ(n64, s.authentication_data_block_size);
n64++;
@@ -560,7 +576,7 @@
// If new fields are added, the following will fail. This is to
// remind that byteswapping code (in avb_util.c) and unittests for
// this should be updated.
- static_assert(offsetof(AvbVBMetaImageHeader, reserved) == 124,
+ static_assert(offsetof(AvbVBMetaImageHeader, reserved) == 176,
"Remember to unittest byteswapping of newly added fields");
}
diff --git a/test/avbtool_unittest.cc b/test/avbtool_unittest.cc
index a14bc0f..924dfbb 100644
--- a/test/avbtool_unittest.cc
+++ b/test/avbtool_unittest.cc
@@ -57,16 +57,77 @@
std::string printed_version;
ASSERT_TRUE(base::ReadFileToString(path, &printed_version));
base::TrimWhitespaceASCII(printed_version, base::TRIM_ALL, &printed_version);
- std::string expected_version =
- base::StringPrintf("%d.%d", AVB_MAJOR_VERSION, AVB_MINOR_VERSION);
- EXPECT_EQ(printed_version, expected_version);
+ // See comments in libavb/avb_version.c and avbtool's get_release_string()
+ // about being in sync.
+ EXPECT_EQ(printed_version,
+ std::string("avbtool ") + std::string(avb_version_string()));
+}
+
+TEST_F(AvbToolTest, DefaultReleaseString) {
+ GenerateVBMetaImage("vbmeta.img",
+ "SHA256_RSA2048",
+ 0,
+ base::FilePath("test/data/testkey_rsa2048.pem"));
+
+ // Default release string is "avbtool " + avb_version_string().
+ AvbVBMetaImageHeader h;
+ avb_vbmeta_image_header_to_host_byte_order(
+ reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
+ EXPECT_EQ(std::string("avbtool ") + std::string(avb_version_string()),
+ std::string((const char*)h.release_string));
+}
+
+TEST_F(AvbToolTest, ReleaseStringAppend) {
+ GenerateVBMetaImage("vbmeta.img",
+ "SHA256_RSA2048",
+ 0,
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--append_to_release_string \"Woot XYZ\"");
+
+ // Note that avbtool inserts the space by itself.
+ std::string expected_str =
+ std::string("avbtool ") + std::string(avb_version_string()) + " Woot XYZ";
+
+ AvbVBMetaImageHeader h;
+ avb_vbmeta_image_header_to_host_byte_order(
+ reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
+ EXPECT_EQ(expected_str, std::string((const char*)h.release_string));
+}
+
+TEST_F(AvbToolTest, ReleaseStringAppendTruncated) {
+ // Append enough text that truncation is sure to happen.
+ std::string append_str = "0123456789abcdef0123456789abcdef0123456789abcdef";
+ std::string expected_str = std::string("avbtool ") +
+ std::string(avb_version_string()) + " " +
+ append_str;
+ EXPECT_GT(expected_str.size(), (size_t)(AVB_RELEASE_STRING_SIZE - 1));
+ expected_str.resize(AVB_RELEASE_STRING_SIZE - 1);
+
+ GenerateVBMetaImage(
+ "vbmeta.img",
+ "SHA256_RSA2048",
+ 0,
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ std::string("--append_to_release_string \"") + append_str + "\"");
+
+ // This checks that it ends with a NUL byte.
+ EXPECT_EQ(AVB_VBMETA_VERIFY_RESULT_OK,
+ avb_vbmeta_image_verify(
+ vbmeta_image_.data(), vbmeta_image_.size(), nullptr, nullptr));
+
+ // For good measure we also check here.
+ AvbVBMetaImageHeader h;
+ avb_vbmeta_image_header_to_host_byte_order(
+ reinterpret_cast<AvbVBMetaImageHeader*>(vbmeta_image_.data()), &h);
+ EXPECT_EQ(expected_str, std::string((const char*)h.release_string));
}
TEST_F(AvbToolTest, ExtractPublicKey) {
GenerateVBMetaImage("vbmeta.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
std::string key_data =
PublicKeyAVB(base::FilePath("test/data/testkey_rsa2048.pem"));
@@ -97,7 +158,8 @@
"--prop large_hexnumber:0xfedcba9876543210 "
"--prop larger_than_uint64:0xfedcba98765432101 "
"--prop almost_a_number:423x "
- "--prop_from_file blob:test/data/small_blob.bin ");
+ "--prop_from_file blob:test/data/small_blob.bin "
+ "--internal_release_string \"\"");
AvbVBMetaImageHeader h;
avb_vbmeta_image_header_to_host_byte_order(
@@ -194,7 +256,8 @@
GenerateVBMetaImage("vbmeta.img",
"SHA256_RSA2048",
rollback_index,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
AvbVBMetaImageHeader h;
avb_vbmeta_image_header_to_host_byte_order(
@@ -207,7 +270,8 @@
GenerateVBMetaImage("vbmeta.img",
"SHA256_RSA2048",
0,
- base::FilePath("test/data/testkey_rsa2048.pem"));
+ base::FilePath("test/data/testkey_rsa2048.pem"),
+ "--internal_release_string \"\"");
const uint8_t* pubkey = NULL;
size_t pubkey_length = 0;
@@ -243,16 +307,18 @@
"--prop larger_than_uint64:0xfedcba98765432101 "
"--prop almost_a_number:423x "
"--prop_from_file blob:test/data/small_blob.bin "
- "--prop_from_file large_blob:test/data/large_blob.bin");
+ "--prop_from_file large_blob:test/data/large_blob.bin "
+ "--internal_release_string \"\"");
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 3200 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Prop: foo -> 'brillo'\n"
" Prop: bar -> 'chromeos'\n"
@@ -321,7 +387,8 @@
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
"--key test/data/testkey_rsa2048.pem "
- "--output_vbmeta %s",
+ "--output_vbmeta %s "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size,
ext_vbmeta_path.value().c_str());
@@ -332,13 +399,14 @@
"VBMeta offset: 1052672\n"
"VBMeta size: 1280 bytes\n"
"--\n"
- "VBMeta image version: 1.0%s\n"
+ "Minimum libavb version: 1.0%s\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 704 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hash descriptor:\n"
" Image Size: 1052672 bytes\n"
@@ -352,13 +420,14 @@
InfoImage(rootfs_path));
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 704 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hash descriptor:\n"
" Image Size: 1052672 bytes\n"
@@ -407,8 +476,8 @@
EXPECT_EQ(
std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
AVB_FOOTER_MAGIC);
- EXPECT_EQ(AVB_FOOTER_MAJOR_VERSION, (int)f.version_major);
- EXPECT_EQ(AVB_FOOTER_MINOR_VERSION, (int)f.version_minor);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
EXPECT_EQ(1052672UL, f.original_image_size);
EXPECT_EQ(1052672UL, f.vbmeta_offset);
EXPECT_EQ(1280UL, f.vbmeta_size);
@@ -463,7 +532,8 @@
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
"--key test/data/testkey_rsa2048.pem "
- "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image",
+ "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size,
ext_vbmeta_path.value().c_str());
@@ -520,7 +590,8 @@
"--hash_algorithm sha256 --image %s "
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
partition_path.value().c_str(),
(int)partition_size);
@@ -537,13 +608,14 @@
"VBMeta offset: 10354688\n"
"VBMeta size: 1280 bytes\n"
"--\n"
- "VBMeta image version: 1.0 (Sparse)\n"
+ "Minimum libavb version: 1.0 (Sparse)\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 704 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hash descriptor:\n"
" Image Size: 10354688 bytes\n"
@@ -599,7 +671,8 @@
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
"--key test/data/testkey_rsa2048.pem "
- "--output_vbmeta_image %s",
+ "--output_vbmeta_image %s "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size,
ext_vbmeta_path.value().c_str());
@@ -610,13 +683,14 @@
"VBMeta offset: 1069056\n"
"VBMeta size: 1344 bytes\n"
"--\n"
- "VBMeta image version: 1.0%s\n"
+ "Minimum libavb version: 1.0%s\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 768 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hashtree descriptor:\n"
" Version of dm-verity: 1\n"
@@ -637,13 +711,14 @@
InfoImage(rootfs_path));
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 768 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hashtree descriptor:\n"
" Version of dm-verity: 1\n"
@@ -708,8 +783,8 @@
EXPECT_EQ(
std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
AVB_FOOTER_MAGIC);
- EXPECT_EQ(AVB_FOOTER_MAJOR_VERSION, (int)f.version_major);
- EXPECT_EQ(AVB_FOOTER_MINOR_VERSION, (int)f.version_minor);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
EXPECT_EQ(1052672UL, f.original_image_size);
EXPECT_EQ(1069056UL, f.vbmeta_offset);
EXPECT_EQ(1344UL, f.vbmeta_size);
@@ -763,18 +838,20 @@
"--output %s "
"--setup_rootfs_from_kernel %s "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
vbmeta_dmv_path.value().c_str(),
rootfs_path.value().c_str());
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 896 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Kernel Cmdline descriptor:\n"
" Flags: 1\n"
@@ -808,7 +885,8 @@
"--partition_size %d --partition_name foobar "
"--algorithm SHA256_RSA2048 "
"--key test/data/testkey_rsa2048.pem "
- "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image",
+ "--output_vbmeta %s_2nd_run --do_not_append_vbmeta_image "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size,
ext_vbmeta_path.value().c_str());
@@ -864,7 +942,8 @@
"--partition_size %d --partition_name foobar "
"--generate_fec "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
rootfs_path.value().c_str(),
(int)partition_size);
@@ -874,13 +953,14 @@
"VBMeta offset: 1085440\n"
"VBMeta size: 1344 bytes\n"
"--\n"
- "VBMeta image version: 1.0%s\n"
+ "Minimum libavb version: 1.0%s\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 768 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Hashtree descriptor:\n"
" Version of dm-verity: 1\n"
@@ -929,8 +1009,8 @@
EXPECT_EQ(
std::string(reinterpret_cast<const char*>(f.magic), AVB_FOOTER_MAGIC_LEN),
AVB_FOOTER_MAGIC);
- EXPECT_EQ(AVB_FOOTER_MAJOR_VERSION, (int)f.version_major);
- EXPECT_EQ(AVB_FOOTER_MINOR_VERSION, (int)f.version_minor);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MAJOR, (int)f.version_major);
+ EXPECT_EQ(AVB_FOOTER_VERSION_MINOR, (int)f.version_minor);
EXPECT_EQ(1052672UL, f.original_image_size);
EXPECT_EQ(1085440UL, f.vbmeta_offset);
EXPECT_EQ(1344UL, f.vbmeta_size);
@@ -986,18 +1066,20 @@
"--output %s "
"--setup_rootfs_from_kernel %s "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
vbmeta_dmv_path.value().c_str(),
rootfs_path.value().c_str());
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 960 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Kernel Cmdline descriptor:\n"
" Flags: 1\n"
@@ -1061,7 +1143,8 @@
" --partition_size %zd"
" --salt deadbeef"
" --algorithm SHA512_RSA4096 "
- " --key test/data/testkey_rsa4096.pem",
+ " --key test/data/testkey_rsa4096.pem"
+ " --internal_release_string \"\"",
system_path.value().c_str(),
partition_size);
}
@@ -1096,7 +1179,8 @@
" --salt deadbeef"
" --generate_fec "
" --algorithm SHA512_RSA4096 "
- " --key test/data/testkey_rsa4096.pem",
+ " --key test/data/testkey_rsa4096.pem"
+ " --internal_release_string \"\"",
system_path.value().c_str(),
partition_size);
}
@@ -1111,17 +1195,19 @@
"--kernel_cmdline 'foo bar baz' "
"--kernel_cmdline 'second cmdline' "
"--algorithm SHA256_RSA2048 "
- "--key test/data/testkey_rsa2048.pem",
+ "--key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
vbmeta_path.value().c_str());
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 640 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Kernel Cmdline descriptor:\n"
" Flags: 0\n"
@@ -1182,14 +1268,16 @@
"./avbtool make_vbmeta_image "
"--output %s "
"--kernel_cmdline 'something' "
- "--prop name:value ",
+ "--prop name:value "
+ "--internal_release_string \"\"",
vbmeta1_path.value().c_str());
EXPECT_COMMAND(0,
"./avbtool make_vbmeta_image "
"--output %s "
"--prop name2:value2 "
- "--prop name3:value3 ",
+ "--prop name3:value3 "
+ "--internal_release_string \"\"",
vbmeta2_path.value().c_str());
EXPECT_COMMAND(0,
@@ -1197,19 +1285,21 @@
"--output %s "
"--prop name4:value4 "
"--include_descriptors_from_image %s "
- "--include_descriptors_from_image %s ",
+ "--include_descriptors_from_image %s "
+ "--internal_release_string \"\"",
vbmeta3_path.value().c_str(),
vbmeta1_path.value().c_str(),
vbmeta2_path.value().c_str());
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 0 bytes\n"
"Auxiliary Block: 256 bytes\n"
"Algorithm: NONE\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Prop: name4 -> 'value4'\n"
" Prop: name -> 'value'\n"
@@ -1237,18 +1327,20 @@
"./avbtool make_vbmeta_image "
"--output %s "
"--chain_partition system:1:%s "
- "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem",
+ "--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
+ "--internal_release_string \"\"",
vbmeta_path.value().c_str(),
pk_path.value().c_str());
ASSERT_EQ(
- "VBMeta image version: 1.0\n"
+ "Minimum libavb version: 1.0\n"
"Header Block: 256 bytes\n"
"Authentication Block: 320 bytes\n"
"Auxiliary Block: 1152 bytes\n"
"Algorithm: SHA256_RSA2048\n"
"Rollback Index: 0\n"
"Flags: 0\n"
+ "Release String: ''\n"
"Descriptors:\n"
" Chain Partition descriptor:\n"
" Partition Name: system\n"
@@ -1308,7 +1400,8 @@
"SIGNING_HELPER_TEST=\"%s\" ./avbtool make_vbmeta_image "
"--output %s "
"--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
- "--signing_helper test/avbtool_signing_helper_test.py",
+ "--signing_helper test/avbtool_signing_helper_test.py "
+ "--internal_release_string \"\"",
signing_helper_test_path.value().c_str(),
vbmeta_path.value().c_str());
@@ -1325,7 +1418,8 @@
"./avbtool make_vbmeta_image "
"--output %s "
"--algorithm SHA256_RSA2048 --key test/data/testkey_rsa2048.pem "
- "--signing_helper test/avbtool_signing_helper_test.py",
+ "--signing_helper test/avbtool_signing_helper_test.py "
+ "--internal_release_string \"\"",
vbmeta_path.value().c_str());
}