sign_firmware: Add nv_pkc_signing step if required

If nv_pkc.pem file is present for a device, use nv_pkc_signing for
adding PKC signature in the firmware image.

BUG=chrome-os-partner:44227
BRANCH=None
TEST=unittests run fine. verified image boots on fused system.

Change-Id: I9b2f48da55137a0e4a75f23d16d3779be1aa94c8
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/296452
Commit-Ready: Furquan Shaikh <furquan@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/image_signing/sign_firmware.sh b/scripts/image_signing/sign_firmware.sh
index 7b9ac94..349988c 100755
--- a/scripts/image_signing/sign_firmware.sh
+++ b/scripts/image_signing/sign_firmware.sh
@@ -123,6 +123,16 @@
     sign_one
     gbb_update "${temp_fw}" "${key_dir}" "${out_firmware}" \
       "${key_dir}/root_key.vbpubk"
+
+    # Additional signing step for nVidia T210 SoC.
+    # Currently, cbootimage is unable to handle path with double slash.
+    if [[ -e ${key_dir}/nv_pkc.pem ]]; then
+      "${SCRIPT_DIR}/sign_nv_cbootimage.sh" \
+        "bootloader" \
+        "${key_dir%/}/nv_pkc.pem" \
+        "${out_firmware}" \
+        tegra210
+    fi
   fi
 }
 main "$@"
diff --git a/scripts/image_signing/sign_nv_cbootimage.sh b/scripts/image_signing/sign_nv_cbootimage.sh
new file mode 100755
index 0000000..890ca6a
--- /dev/null
+++ b/scripts/image_signing/sign_nv_cbootimage.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Wrapper script for signing firmware image using cbootimage.
+
+# Determine script directory.
+SCRIPT_DIR=$(dirname "$0")
+
+# Load common constants and variables.
+. "${SCRIPT_DIR}/common_minimal.sh"
+
+# Abort on error.
+set -e
+
+usage() {
+  cat<<EOF
+Usage: $0 <type> <pkc_key> <firmware_image> <soc>
+
+Signs <firmware_image> of <type> with <pkc_key> using cbootimage for <soc>.
+where type is one of
+      bootloader = sign bootloader image
+EOF
+  exit 1
+}
+
+main() {
+  if [[ $# -ne 4 ]]; then
+    usage
+  fi
+
+  local type=$1
+  local pkc_key="$(readlink -f "$2")"
+  local firmware_image="$(readlink -f "$3")"
+  local soc=$4
+
+  local work_dir=$(make_temp_dir)
+  local signed_fw=$(make_temp_file)
+
+  if [[ "${type}" == "bootloader" ]]; then
+
+    pushd "${work_dir}" >/dev/null
+
+    cat >update.cfg <<EOF
+PkcKey = ${pkc_key}, --save;
+ReSignBl;
+EOF
+
+    # This also generates a file pubkey.sha which contains the hash of public
+    # key required by factory to burn into PKC fuses. Move pubkey.sha into
+    # ${firmware_image}.pubkey.sha.
+    cbootimage -s "${soc}" -u update.cfg "${firmware_image}" \
+      "${signed_fw}"
+
+    popd >/dev/null
+    # Copy signed firmware image and public key hash to current directory.
+    mv "${work_dir}/pubkey.sha" "${firmware_image}.pubkey.sha"
+    mv "${signed_fw}" "${firmware_image}"
+
+  else
+    usage
+  fi
+}
+
+main "$@"