| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # Build arguments used in the context of verified boot. |
| # See [this document](https://android.googlesource.com/platform/external/avb/+/HEAD/README.md) |
| # for more information. |
| |
| import("//build/testing/verify_files_match.gni") |
| import("//build/zircon/tools.gni") |
| import("//src/developer/ffx/build/ffx_action.gni") |
| |
| declare_args() { |
| # If true, then a vbmeta image will be generated for provided ZBI |
| # and the paving script will pave vbmeta images to the target device. |
| use_vbmeta = false |
| |
| # If true, /config/devmgr config will be included into a vbmeta image |
| # instead of bootfs. |
| include_devmgr_config_in_vbmeta = false |
| |
| # a key which will be used to sign VBMETA and images for AVB |
| avb_key = "" |
| |
| # AVB metadata which will be used to validate public key |
| avb_atx_metadata = "" |
| |
| # AVB algorithm type.Supported options: |
| # SHA256_RSA2048 |
| # SHA256_RSA4096 |
| # SHA256_RSA8192 |
| # SHA512_RSA2048 |
| # SHA512_RSA4096 |
| # SHA512_RSA8192 |
| avb_algorithm = "SHA512_RSA4096" |
| |
| # Partition name from where image will be verified |
| zvb_partition_name = "zircon" |
| |
| # Board level extra vbmeta images to be combined into the top-level vbmeta |
| # struct. |
| board_extra_vbmeta_images = [] |
| } |
| |
| # Template for producing VBMETA image for AVB |
| # |
| # Parameters |
| # |
| # output_name (optional, default: target_name) |
| # |
| # zbi (required) |
| # [list-of-strings] path to a ZBI image to be included in AVB chain. |
| # Must only contain a single entry. |
| # |
| # prop_from_file (required) |
| # [list of type/file] a list of pairs |type| and |file|. |
| # |type| is one of ZBI item types (w/o ZBI_TYPE_ prefix); |
| # |file| is a path to file to be stored in a vbmeta image |
| # as ZBI_TYPE_|type| items in 'zbi' property. |
| # |
| # deps (usually required) |
| # testonly, metadata |
| # Usual GN meaning. |
| template("vbmeta") { |
| if (defined(invoker.output_name)) { |
| output_file = invoker.output_name |
| } else { |
| output_file = target_name |
| } |
| |
| output_file += ".vbmeta" |
| |
| zbi = invoker.zbi |
| assert([ zbi[0] ] == zbi, "zbi parameter must contain a single entry") |
| assert(avb_key != "", "avb_key must be specified") |
| assert(avb_atx_metadata != "", "avb metadata must be specified") |
| output_file = "$root_out_dir/$output_file" |
| output_vbmeta_desc_file = "${output_file}.desc" |
| if (defined(invoker.prop_from_file)) { |
| output_vbmeta_props_zbi_file = "${output_file}.props.zbi" |
| } |
| |
| if (defined(invoker.prop_from_file)) { |
| action("${target_name}__zbi_props") { |
| script = zbi_tool_path |
| |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "deps", |
| ]) |
| |
| outputs = [ output_vbmeta_props_zbi_file ] |
| args = [ |
| "--output", |
| rebase_path(outputs[0], root_build_dir), |
| ] |
| sources = [] |
| foreach(entry, invoker.prop_from_file) { |
| file = rebase_path(entry.file, root_build_dir) |
| sources += [ entry.file ] |
| args += [ |
| "-T", |
| "${entry.type}", |
| "${file}", |
| ] |
| } |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ zbi_tool_target ] |
| } |
| } |
| |
| target_name_avbtool = "${target_name}.avbtool" |
| output_file_avbtool = "${output_file}.avbtool" |
| |
| target_name_ffx = "${target_name}.ffx" |
| output_file_ffx = "${output_file}.ffx" |
| |
| salt_action = target_name_ffx |
| salt_file = "$target_out_dir/$salt_action.salt" |
| |
| action("${target_name_avbtool}__vb_desc") { |
| # TODO(fxbug.dev/69047): This is a "stamping" action, figure out how to |
| # handle this class of actions. |
| hermetic_deps = false |
| script = "//third_party/android/platform/external/avb/avbtool.py" |
| |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "deps", |
| ]) |
| |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ ":$salt_action" ] |
| |
| inputs = [ |
| zbi[0], |
| salt_file, |
| ] |
| outputs = [ output_vbmeta_desc_file ] |
| args = [ |
| "add_hash_footer", |
| "--salt", |
| "@" + rebase_path(salt_file, root_build_dir), |
| "--image", |
| rebase_path(inputs[0], root_build_dir), |
| "--partition_name", |
| zvb_partition_name, |
| "--do_not_append_vbmeta_image", |
| "--output_vbmeta_image", |
| rebase_path(outputs[0], root_build_dir), |
| "--partition_size", |
| |
| # we are not going to add footer into image, |
| # so, we do not care about a partition size checking. |
| # `partition_size' is a mandatory option, thus let |
| # use obviously big number for the partition size to pass |
| # verification. 200M should be good enough. |
| # TODO (dmitryya@) fix avbtool to do not check partition |
| # size if --do_not_append_vbmeta_image is specified. |
| "209715200", |
| ] |
| } |
| |
| action(target_name_avbtool) { |
| script = "//third_party/android/platform/external/avb/avbtool.py" |
| |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "deps", |
| ]) |
| |
| deps += [ ":${target_name}__vb_desc" ] |
| if (defined(invoker.prop_from_file)) { |
| deps += [ ":${target_name}__zbi_props" ] |
| } |
| |
| inputs = [ |
| avb_key, |
| avb_atx_metadata, |
| output_vbmeta_desc_file, |
| ] |
| outputs = [ output_file_avbtool ] |
| args = [ |
| "make_vbmeta_image", |
| "--output", # output of VBMETA image |
| rebase_path(outputs[0], root_build_dir), |
| "--key", # a key for signing |
| rebase_path(avb_key, root_build_dir), |
| "--algorithm", # an algorithm for signing |
| avb_algorithm, |
| "--public_key_metadata", # avb metadata |
| rebase_path(avb_atx_metadata, root_build_dir), |
| "--include_descriptors_from_image", |
| rebase_path(output_vbmeta_desc_file, root_build_dir), |
| ] |
| foreach(entry, board_extra_vbmeta_images) { |
| file = rebase_path(entry, root_build_dir) |
| args += [ |
| "--include_descriptors_from_image", |
| file, |
| ] |
| } |
| if (defined(invoker.prop_from_file)) { |
| inputs += [ output_vbmeta_props_zbi_file ] |
| args += [ |
| "--prop_from_file", |
| "zbi:" + rebase_path(output_vbmeta_props_zbi_file, root_build_dir), |
| ] |
| } |
| } |
| |
| additional_descriptor_labels = [] |
| foreach(entry, board_extra_vbmeta_images) { |
| extra_vbmeta_filename = get_path_info(entry, "file") |
| descriptor_output_filename = |
| "$target_name_ffx.additional_descriptor.$extra_vbmeta_filename.json" |
| descriptor_output_file = "$target_out_dir/$descriptor_output_filename" |
| additional_descriptor_labels += [ ":$descriptor_output_filename" ] |
| |
| action(descriptor_output_filename) { |
| script = "//build/images/assembly/extract_descriptor_fields.py" |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| avbtool = "//third_party/android/platform/external/avb/avbtool.py" |
| args = [ |
| "--avbtool", |
| rebase_path(avbtool, root_build_dir), |
| "--vbmeta", |
| rebase_path(entry, root_build_dir), |
| "--output", |
| rebase_path(descriptor_output_file, root_build_dir), |
| ] |
| inputs = [ |
| avbtool, |
| entry, |
| ] |
| outputs = [ descriptor_output_file ] |
| } |
| } |
| |
| # TODO(fxbug.dev/75889): Remove these build_args in a separate cleanup pass |
| assert(include_devmgr_config_in_vbmeta == false, |
| "placing the devmgr config in vbmeta is not supported at this time") |
| assert(avb_algorithm == "SHA512_RSA4096", |
| "setting 'avb_algorithm' is not supported at this time") |
| |
| ffx_action(target_name_ffx) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "deps", |
| ]) |
| |
| args = [ |
| "--config", |
| "assembly_enabled=true", |
| "assembly", |
| "vbmeta", |
| "sign", |
| "--key", |
| rebase_path(avb_key, root_build_dir), |
| "--key-metadata", |
| rebase_path(avb_atx_metadata, root_build_dir), |
| "--name", |
| zvb_partition_name, |
| "--image-path", |
| rebase_path(zbi[0], root_build_dir), |
| "--output", |
| rebase_path(output_file_ffx, root_build_dir), |
| "--salt-outfile", |
| rebase_path(salt_file, root_build_dir), |
| ] |
| inputs = [ |
| avb_key, |
| avb_atx_metadata, |
| zbi[0], |
| ] |
| |
| foreach(descriptor_target, additional_descriptor_labels) { |
| descriptor_outputs = get_target_outputs(descriptor_target) |
| descriptor_file = descriptor_outputs[0] |
| args += [ |
| "--additional-descriptor", |
| rebase_path(descriptor_file, root_build_dir), |
| ] |
| inputs += [ descriptor_file ] |
| deps += [ descriptor_target ] |
| } |
| |
| outputs = [ |
| output_file_ffx, |
| salt_file, |
| ] |
| } |
| |
| verify_files_match("$target_name.avbtool.matches") { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [ |
| ":$target_name_avbtool", |
| ":$target_name_ffx", |
| ] |
| |
| first = output_file_avbtool |
| second = output_file_ffx |
| } |
| |
| # the final copy action |
| copy(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| "deps", |
| "metadata", |
| ]) |
| deps += [ |
| ":$target_name.avbtool.matches", |
| ":$target_name_ffx", |
| ] |
| sources = [ output_file_ffx ] |
| outputs = [ output_file ] |
| } |
| } |