# 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/standalone: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/standalone: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/standalone: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,
    ]
  }
}
