diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | scripts/image_signing/nv_pkc_signing.sh | 22 | ||||
-rwxr-xr-x | scripts/image_signing/sign_nv_cbootimage.sh | 262 |
3 files changed, 263 insertions, 23 deletions
@@ -590,7 +590,7 @@ SIGNING_SCRIPTS_DEV = \ scripts/image_signing/make_dev_firmware.sh \ scripts/image_signing/make_dev_ssd.sh \ scripts/image_signing/set_gbb_flags.sh \ - scripts/image_signing/nv_pkc_signing.sh + scripts/image_signing/sign_nv_cbootimage.sh # Installed, but not made executable. SIGNING_COMMON = scripts/image_signing/common_minimal.sh diff --git a/scripts/image_signing/nv_pkc_signing.sh b/scripts/image_signing/nv_pkc_signing.sh deleted file mode 100755 index 34951734..00000000 --- a/scripts/image_signing/nv_pkc_signing.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2012 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. - -set +e - -# If tools are not present, do not continue signing -if [ ! type nv_bct_dump ] || [ ! type nv_cbootimage ]; then - exit 0 -fi - -cat >update.cfg <<EOF -PkcKey = $1/nv_pkc.pem; -ReSignBl; -EOF - -nv_cbootimage -s tegra210 -u update.cfg $2 $2-final -cp $2-final $2 - -exit 0 diff --git a/scripts/image_signing/sign_nv_cbootimage.sh b/scripts/image_signing/sign_nv_cbootimage.sh new file mode 100755 index 00000000..da978e84 --- /dev/null +++ b/scripts/image_signing/sign_nv_cbootimage.sh @@ -0,0 +1,262 @@ +#!/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 + lp0_firmware = sign lp0 firmware +EOF + exit 1 +} + +# Signs bootloader image using pkc_key provided for given soc +# Args: TYPE=bootloader PKC_KEY FIRMWARE_IMAGE SOC +sign_bootloader() { + 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 config_file=$(make_temp_file) + local signed_fw=$(make_temp_file) + + pushd "${work_dir}" >/dev/null + + # Get bootloader length. + # + # Example: + # $ bct_dump image.fastboot.bin + # Version = 0x00210001; + # BlockSize = 0x00008000; + # ... + # ... + # # Bootloader[0].Length = 69324; + # ... + # ... + # + # then, bl_length=69324 (size of bootloader that needs to be signed) + local bl_length=$(bct_dump "${firmware_image}" | \ + sed -n '/Bootloader\[0\].Length/{ s/.*=\s*//; s/;//; p; q}') + + # Extract bootloader to sign. + dd \ + if="${firmware_image}" \ + of="${signed_fw}.bl.tosig" \ + count="${bl_length}" \ + ibs=1 \ + skip=32768 >/dev/null 2>&1 + + # Calculate rsa signature for bootloader. + openssl \ + dgst -sha256 \ + -sigopt rsa_padding_mode:pss \ + -sigopt rsa_pss_saltlen:-1 \ + -sign "${pkc_key}" \ + -out "${signed_fw}.bl.sig" \ + "${signed_fw}.bl.tosig" + + # Update bootloader's rsa signature, aes hash and bct's aes hash. + echo "RsaPssSigBlFile = ${signed_fw}.bl.sig;" > "${config_file}" + echo "RehashBl;" >> "${config_file}" + cbootimage \ + -s "${soc}" \ + -u "${config_file}" \ + "${firmware_image}" \ + "${signed_fw}.tmp" >/dev/null + + # Extract the part of bct which needs to be rsa signed. + dd \ + if="${signed_fw}.tmp" \ + of="${signed_fw}.bct.tosig" \ + count=8944 \ + ibs=1 \ + skip=1296 >/dev/null 2>&1 + + # Calculate rsa signature for bct. + openssl \ + dgst -sha256 \ + -sigopt rsa_padding_mode:pss \ + -sigopt rsa_pss_saltlen:-1 \ + -sign "${pkc_key}" \ + -out "${signed_fw}.bct.sig" \ + "${signed_fw}.bct.tosig" + + # Create public key modulus from key file. + openssl \ + rsa -in "${pkc_key}" \ + -noout \ + -modulus \ + -out "${signed_fw}.key.mod" + + # Remove prefix. + cut \ + -d= \ + -f2 "${signed_fw}.key.mod" > "${signed_fw}.key.mod.tmp1" + dd \ + if="${signed_fw}.key.mod.tmp1" \ + of="${signed_fw}.key.mod.tmp" \ + count=512 \ + ibs=1 >/dev/null 2>&1 + + # Convert from hexdecimal to binary. + perl -pe 's/([0-9a-f]{2})/chr hex $1/gie' \ + < "${signed_fw}.key.mod.tmp" \ + > "${signed_fw}.key.mod.bin" + + # Update bct's rsa signature and modulus. + echo "RsaPssSigBctFile = ${signed_fw}.bct.sig;" > "${config_file}" + echo "RsaKeyModulusFile = ${signed_fw}.key.mod.bin;" >> "${config_file}" + cbootimage \ + -s "${soc}" \ + -u "${config_file}" \ + "${signed_fw}.tmp" \ + "${signed_fw}" >/dev/null + + # Calculate hash of public key modulus. + objcopy \ + -I binary \ + --reverse-bytes=256 \ + "${signed_fw}.key.mod.bin" \ + "${signed_fw}.key.mod.bin.rev" + openssl \ + dgst -sha256 \ + -binary \ + -out "${signed_fw}.key.sha" \ + "${signed_fw}.key.mod.bin.rev" + + popd >/dev/null + + # Copy signed firmware image and public key hash to current directory.. + mv "${signed_fw}" "${firmware_image}" + mv "${signed_fw}.key.sha" "${firmware_image}.pubkey.sha" +} + +# Signs lp0 firmware image using pkc_key provided for given soc +# Args: TYPE=lp0_firmware PKC_KEY FIRMWARE_IMAGE SOC +sign_lp0_firmware() { + 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) + + pushd "${work_dir}" >/dev/null + + cp "${firmware_image}" "${signed_fw}" + + # Extract the part of the binary which needs to be signed. + dd \ + if="${firmware_image}" \ + of="${signed_fw}.tosig" \ + ibs=1 \ + skip=544 >/dev/null 2>&1 + + # Calculate rsa-pss signature. + openssl \ + dgst -sha256 \ + -sigopt rsa_padding_mode:pss \ + -sigopt rsa_pss_saltlen:-1 \ + -sign "${pkc_key}" \ + -out "${signed_fw}.rsa.sig" \ + "${signed_fw}.tosig" + + # Reverse rsa signature to meet tegra soc ordering requirement. + objcopy \ + -I binary \ + --reverse-bytes=256 \ + "${signed_fw}.rsa.sig" \ + "${signed_fw}.rsa.sig.rev" + + # Inject rsa-pss signature into the binary image's header. + dd \ + if="${signed_fw}.rsa.sig.rev" \ + of="${signed_fw}" \ + count=256 \ + obs=1 \ + seek=288 \ + conv=notrunc >/dev/null 2>&1 + + # Generate public key modulus from key file. + openssl \ + rsa -in "${pkc_key}" \ + -noout \ + -modulus \ + -out "${signed_fw}.key.mod" + + # Remove prefix. + cut \ + -d= \ + -f2 "${signed_fw}.key.mod" > "${signed_fw}.key.mod.tmp1" + + dd \ + if="${signed_fw}.key.mod.tmp1" \ + of="${signed_fw}.key.mod.tmp" \ + count=512 \ + ibs=1 >/dev/null 2>&1 + + # Convert from hexdecimal to binary. + perl -pe 's/([0-9a-f]{2})/chr hex $1/gie' \ + < "${signed_fw}.key.mod.tmp" \ + > "${signed_fw}.key.mod.bin" + + # Reverse byte order. + objcopy \ + -I binary \ + --reverse-bytes=256 \ + "${signed_fw}.key.mod.bin" \ + "${signed_fw}.key.mod.bin.rev" + + # Inject public key modulus into the binary image's header. + dd \ + if="${signed_fw}.key.mod.bin.rev" \ + of="${signed_fw}" \ + count=256 \ + obs=1 \ + seek=16 \ + conv=notrunc >/dev/null 2>&1 + + popd >/dev/null + mv "${signed_fw}" "${firmware_image}" +} + +main() { + if [[ $# -ne 4 ]]; then + usage + fi + + local type=$1 + + case ${type} in + bootloader) + sign_bootloader "$@" + ;; + lp0_firmware) + sign_lp0_firmware "$@" + ;; + *) + usage + ;; + esac +} + +main "$@" |