summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/image_signing/sign_nv_cbootimage.sh239
1 files changed, 210 insertions, 29 deletions
diff --git a/scripts/image_signing/sign_nv_cbootimage.sh b/scripts/image_signing/sign_nv_cbootimage.sh
index 71be794d..da978e84 100755
--- a/scripts/image_signing/sign_nv_cbootimage.sh
+++ b/scripts/image_signing/sign_nv_cbootimage.sh
@@ -26,11 +26,132 @@ EOF
exit 1
}
-main() {
- if [[ $# -ne 4 ]]; then
- usage
- fi
+# 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")"
@@ -39,43 +160,103 @@ main() {
local work_dir=$(make_temp_dir)
local signed_fw=$(make_temp_file)
- if [[ "${type}" == "bootloader" ]]; then
+ pushd "${work_dir}" >/dev/null
- pushd "${work_dir}" >/dev/null
+ cp "${firmware_image}" "${signed_fw}"
- cat >update.cfg <<EOF
-PkcKey = ${pkc_key}, --save;
-ReSignBl;
-EOF
+ # 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
- # 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}"
+ # 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"
- 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}"
+ # Reverse rsa signature to meet tegra soc ordering requirement.
+ objcopy \
+ -I binary \
+ --reverse-bytes=256 \
+ "${signed_fw}.rsa.sig" \
+ "${signed_fw}.rsa.sig.rev"
- elif [[ "${type}" == "lp0_firmware" ]]; then
+ # 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
- pushd "${work_dir}" >/dev/null
+ # Generate public key modulus from key file.
+ openssl \
+ rsa -in "${pkc_key}" \
+ -noout \
+ -modulus \
+ -out "${signed_fw}.key.mod"
- cat >update.cfg <<EOF
-PkcKey = ${pkc_key};
-RsaSign = 0x220,, 288, 16, Complete;
-EOF
+ # Remove prefix.
+ cut \
+ -d= \
+ -f2 "${signed_fw}.key.mod" > "${signed_fw}.key.mod.tmp1"
- cbootimage --sign update.cfg "${firmware_image}" "${signed_fw}"
+ dd \
+ if="${signed_fw}.key.mod.tmp1" \
+ of="${signed_fw}.key.mod.tmp" \
+ count=512 \
+ ibs=1 >/dev/null 2>&1
- popd >/dev/null
- mv "${signed_fw}" "${firmware_image}"
+ # 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"
- else
+ # 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 "$@"