# Copyright 2021 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.

import("//build/dev.gni")

# Check the kernel cmdline extracted from ZBI against a golden file.
#
# Parameters
#
#   zbi
#     Required: Path to the ZBI image to extract kernel cmdline from.
#   zbi_target
#     Required: The target to build the 'zbi'.
#   goldens
#     Required: Path to a list of golden files that contain golden kernel
#       cmdline in the format of one cmdline entry per line. The actual cmdline
#       must match either one of the goldens. There should be only one golden
#       file in this list for normal case and two golden files, one for the
#       old golden file, one for the new golden file during a soft transition.
#   deps, public_deps, data_deps (optional)
#     Usual GN meaning.

template("verify_kernel_cmdline") {
  assert(defined(invoker.zbi), "verify_kernel_cmdline() must specify zbi")
  assert(defined(invoker.zbi_target),
         "verify_kernel_cmdline() must specify zbi_target")
  assert(defined(invoker.goldens),
         "verify_kernel_cmdline() must specify goldens")

  action("${target_name}") {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "deps",
                             "public_deps",
                             "data_deps",
                             "visibility",
                           ])

    script = "//build/security/verify_build/verify_build.py"
    stamp_file = "$target_gen_dir/$target_name.verified"
    scrutiny_target = "//src/security/scrutiny/bin($host_toolchain)"
    scrutiny_tool =
        get_label_info(scrutiny_target, "root_out_dir") + "/scrutiny"

    inputs = [
      scrutiny_tool,
      invoker.zbi,
    ]
    inputs += invoker.goldens

    outputs = [ stamp_file ]

    args = [
             "--type",
             "kernel_cmdline",
             "--zbi-file",
             rebase_path(invoker.zbi, root_build_dir),
             "--scrutiny",
             rebase_path(scrutiny_tool, root_build_dir),
             "--stamp",
             rebase_path(stamp_file, root_build_dir),
             "--golden-files",
           ] + rebase_path(invoker.goldens, root_build_dir)
    if (!defined(invoker.deps)) {
      deps = []
    }

    deps += [
      invoker.zbi_target,
      scrutiny_target,
    ]
  }
}

# Check the bootfs filelist extracted from ZBI against a golden file.
#
# Parameters
#
#   zbi
#     Required: Path to the ZBI image to extract bootfs from.
#   zbi_target
#     Required: The target to build the 'zbi'.
#   goldens
#     Required: Path to a list of golden files that contain golden bootFS
#       file list in the format of one file name per line. The actual bootFS
#       filelist must match either one of the goldens. There should be only one
#       golden file in this list for normal case and two golden files, one for
#       the old golden file, one for the new golden file during a soft
#       transition.
#   deps, public_deps, data_deps (optional)
#     Usual GN meaning.

template("verify_bootfs_filelist") {
  assert(defined(invoker.zbi), "verify_bootfs_filelist() must specify zbi")
  assert(defined(invoker.zbi_target),
         "verify_bootfs_filelist() must specify zbi_target")
  assert(defined(invoker.goldens),
         "verify_kernel_cmdline() must specify goldens")

  action("${target_name}") {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "deps",
                             "public_deps",
                             "data_deps",
                             "visibility",
                           ])

    script = "//build/security/verify_build/verify_build.py"
    stamp_file = "$target_gen_dir/$target_name.verified"
    scrutiny_target = "//src/security/scrutiny/bin($host_toolchain)"
    scrutiny_tool =
        get_label_info(scrutiny_target, "root_out_dir") + "/scrutiny"

    inputs = [
      scrutiny_tool,
      invoker.zbi,
    ]
    inputs += invoker.goldens

    outputs = [ stamp_file ]

    args = [
             "--type",
             "bootfs_filelist",
             "--zbi-file",
             rebase_path(invoker.zbi, root_build_dir),
             "--scrutiny",
             rebase_path(scrutiny_tool, root_build_dir),
             "--stamp",
             rebase_path(stamp_file, root_build_dir),
             "--golden-files",
           ] + rebase_path(invoker.goldens, root_build_dir)

    if (!defined(invoker.deps)) {
      deps = []
    }

    deps += [
      invoker.zbi_target,
      scrutiny_target,
    ]
  }
}

# Check the static pkgs list against a golden file.
#
# The target that generates 'zbi' needs to be added to deps.
#
# Parameters
#
#   zbi
#     Required: Path to the ZBI image.
#   zbi_target
#     Required: The target to build the 'zbi'.
#   blobfs_manifest
#     Required: Path to the blobfs manifest file.
#   blobfs_manifest_target:
#     Required: The target to build the 'blobfs_manifest'.
#   goldens
#     Required: Path to a list of golden files that contain golden static pkgs
#       list in the format of one static pkg name per line. The actual static
#       pkgs list must match either one of the goldens. There should be only one
#       golden file in this list for normal case and two golden files, one for
#       the old golden file, one for the new golden file during a soft
#       transition.
#   deps, public_deps, data_deps (optional)
#     Usual GN meaning.

template("verify_static_pkgs") {
  assert(defined(invoker.zbi), "verify_static_pkgs() must specify zbi")
  assert(defined(invoker.zbi_target),
         "verify_static_pkgs() must specify zbi_target")
  assert(defined(invoker.blobfs_manifest),
         "verify_static_pkgs() must specify blobfs_manifest")
  assert(defined(invoker.blobfs_manifest_target),
         "verify_static_pkgs() must specify blobfs_manifest_target")
  assert(defined(invoker.goldens),
         "verify_kernel_cmdline() must specify goldens")

  action("${target_name}") {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "deps",
                             "public_deps",
                             "data_deps",
                             "visibility",
                           ])

    script = "//build/security/verify_build/verify_build.py"
    stamp_file = "$target_gen_dir/$target_name.verified"
    depfile = "$target_gen_dir/$target_name.d"
    scrutiny_target = "//src/security/scrutiny/bin($host_toolchain)"
    scrutiny_tool =
        get_label_info(scrutiny_target, "root_out_dir") + "/scrutiny"
    far_target = "//src/sys/pkg/bin/far:bin($host_toolchain)"
    far_tool = get_label_info(far_target, "root_out_dir") + "/far"

    inputs = [
               scrutiny_tool,
               far_tool,
               invoker.zbi,
               invoker.blobfs_manifest,
             ] + invoker.goldens

    outputs = [ stamp_file ]

    args = [
             "--type",
             "static_pkgs",
             "--zbi-file",
             rebase_path(invoker.zbi, root_build_dir),
             "--blobfs-manifest",
             rebase_path(invoker.blobfs_manifest, root_build_dir),
             "--scrutiny",
             rebase_path(scrutiny_tool, root_build_dir),
             "--far",
             rebase_path(far_tool, root_build_dir),
             "--stamp",
             rebase_path(stamp_file, root_build_dir),
             "--depfile",
             rebase_path(depfile, root_build_dir),
             "--golden-files",
           ] + rebase_path(invoker.goldens, root_build_dir)

    if (!defined(invoker.deps)) {
      deps = []
    }

    deps += [
      far_target,
      invoker.zbi_target,
      invoker.blobfs_manifest_target,
      scrutiny_target,
    ]
  }
}
