sign_official_build.sh revision 527612e3565be00030a082c262204a0562bc0d4a
137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah#!/bin/bash
237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Use of this source code is governed by a BSD-style license that can be
537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# found in the LICENSE file.
637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Sign the final build image using the "official" keys.
80c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#
90c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Prerequisite tools needed in the system path:
100c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#
110c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#  gbb_utility (from src/platform/vboot_reference)
120c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#  vbutil_kernel (from src/platform/vboot_reference)
130c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#  cgpt (from src/platform/vboot_reference)
140c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#  dump_kernel_config (from src/platform/vboot_reference)
150c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah#  verity (from src/platform/verity)
161cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah#  load_kernel_test (from src/platform/vboot_reference)
171a2e6fc765a13b636d3dd75dc7cae709e9e8d218Gaurav Shah#  dumpe2fs
18d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah#  sha1sum
1937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
2037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Load common constants and variables.
2137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah. "$(dirname "$0")/common.sh"
2237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
231cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Print usage string
241cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahusage() {
2537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  cat <<EOF
261cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahUsage: $PROG <type> input_image /path/to/keys/dir [output_image]
2737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahwhere <type> is one of:
2837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah             ssd  (sign an SSD image)
291cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah             recovery (sign a USB recovery image)
301cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah             install (sign a factory install image)
3164bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson             usb  (sign an image to boot directly from USB)
321cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah             verify (verify an image including rootfs hashes)
331cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
341cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahIf you are signing an image, you must specify an [output_image].
3537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahEOF
361cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah}
371cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
381cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahif [ $# -ne 3 ] && [ $# -ne 4 ]; then
391cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  usage
4037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  exit 1
4137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahfi
4237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
4337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Abort on errors.
4437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahset -e
4537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
460500524edda44c770690bb942e916522f1eca5cdGaurav Shah# Make sure the tools we need are available.
471cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahfor prereqs in gbb_utility vbutil_kernel cgpt dump_kernel_config verity \
485f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  load_kernel_test dumpe2fs sha1sum e2fsck;
491cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahdo
500500524edda44c770690bb942e916522f1eca5cdGaurav Shah  type -P "${prereqs}" &>/dev/null || \
510500524edda44c770690bb942e916522f1eca5cdGaurav Shah    { echo "${prereqs} tool not found."; exit 1; }
520500524edda44c770690bb942e916522f1eca5cdGaurav Shahdone
530500524edda44c770690bb942e916522f1eca5cdGaurav Shah
5437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahTYPE=$1
5537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahINPUT_IMAGE=$2
5637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahKEY_DIR=$3
5737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav ShahOUTPUT_IMAGE=$4
5837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
591cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Get current rootfs hash and kernel command line
60d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah# ARGS: IMAGE KERNELPART
611cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahgrab_kernel_config() {
621cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local image=$1
63d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kernelpart=$2  # Kernel partition number to grab.
641cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # Grab the existing kernel partition and get the kernel config.
650c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  temp_kimage=$(make_temp_file)
66d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  extract_image_partition ${image} ${kernelpart} ${temp_kimage}
671cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  dump_kernel_config ${temp_kimage}
681cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah}
691cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
701cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Get the hash from a kernel config command line
711cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahget_hash_from_config() {
721cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local kernel_config=$1
731cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo ${kernel_config} | sed -e 's/.*dm="\([^"]*\)".*/\1/g' | \
741cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    cut -f2- -d, | cut -f9 -d ' '
751cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah}
761cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
771cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Calculate rootfs hash of an image
781cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Args: ROOTFS_IMAGE KERNEL_CONFIG HASH_IMAGE
791cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah#
801cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# rootfs calculation parameters are grabbed from KERNEL_CONFIG
811cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah#
821cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Returns an updated kernel config command line with the new hash.
831cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# and writes the new hash image to the file HASH_IMAGE
841cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahcalculate_rootfs_hash() {
851cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local rootfs_image=$1
861cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local kernel_config=$2
871cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local hash_image=$3
881cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local dm_config=$(echo ${kernel_config} |
890c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    sed -e 's/.*dm="\([^"]*\)".*/\1/g' |
900c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    cut -f2- -d,)
910c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # We extract dm=... portion of the config command line. Here's an example:
920c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  #
930c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # dm="0 2097152 verity ROOT_DEV HASH_DEV 2097152 1 \
940c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # sha1 63b7ad16cb9db4b70b28593f825aa6b7825fdcf2"
950c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  #
960c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
9733c44fc14f6981601d0f0743d0705587d5f11c56Gaurav Shah  if [ -z "${dm_config}" ]; then
980c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    echo "WARNING: Couldn't grab dm_config. Aborting rootfs hash calculation"
991cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    exit 1
1000c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  fi
1010c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local rootfs_sectors=$(echo ${dm_config} | cut -f2 -d' ')
1020c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local root_dev=$(echo ${dm_config} | cut -f4 -d ' ')
1030c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local hash_dev=$(echo ${dm_config} | cut -f5 -d ' ')
1040c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local verity_depth=$(echo ${dm_config} | cut -f7 -d' ')
1050c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local verity_algorithm=$(echo ${dm_config} | cut -f8 -d' ')
1060c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
1071cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # Run the verity tool on the rootfs partition.
1080c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local table="vroot none ro,"$(sudo verity create \
1090c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${verity_depth} \
1100c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${verity_algorithm} \
1111cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    ${rootfs_image} \
1120c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    $((rootfs_sectors / 8)) \
1130c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${hash_image})
1140c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Reconstruct new kernel config command line and replace placeholders.
1150c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  table="$(echo "$table" |
1160c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")"
1171cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo ${kernel_config} | sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${table}\3#g"
1181cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah}
1191cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
1201cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Re-calculate rootfs hash, update rootfs and kernel command line.
121d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah# Args: IMAGE KEYBLOCK PRIVATEKEY KERNELPART
1221cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahupdate_rootfs_hash() {
1231cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local image=$1  # Input image.
1241cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local keyblock=$2  # Keyblock for re-generating signed kernel partition
1251cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local signprivate=$3  # Private key to use for signing.
126d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kernelpart=$4  # Kernel partition number to update (usually 2 or 4)
127d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah
128d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  echo "Updating rootfs hash and updating config for Kernel partition " \
129d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    "$kernelpart"
1301cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
13104c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  # check and clear need_to_resign tag
13204c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  local rootfs_dir=$(make_temp_dir)
13304c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  mount_image_partition_ro "${image}" 3 "${rootfs_dir}"
13404c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  if has_needs_to_be_resigned_tag "${rootfs_dir}"; then
13504c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin    # remount as RW
13604c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin    sudo umount -d "${rootfs_dir}"
13704c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin    mount_image_partition "${image}" 3 "${rootfs_dir}"
13804c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin    sudo rm -f "${rootfs_dir}/${TAG_NEEDS_TO_BE_SIGNED}"
13904c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  fi
14004c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin  sudo umount -d "${rootfs_dir}"
14104c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin
1421cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local rootfs_image=$(make_temp_file)
1431cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  extract_image_partition ${image} 3 ${rootfs_image}
144d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kernel_config=$(grab_kernel_config "${image}" ${kernelpart})
1451cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local hash_image=$(make_temp_file)
1461cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
147aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry  # Disable rw mount support prior to hashing.
148aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry  disable_rw_mount "${rootfs_image}"
149aaae959412acc95ba2f4a0b5af44d67186c7a3d2Will Drewry
1501cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \
1511cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    "${kernel_config}" "${hash_image}")
152d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  echo "New config for kernel partition $kernelpart is:"
153d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  echo $new_kernel_config
1541cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
1551a2e6fc765a13b636d3dd75dc7cae709e9e8d218Gaurav Shah  local rootfs_blocks=$(sudo dumpe2fs "${rootfs_image}" 2> /dev/null |
1561cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    grep "Block count" |
1571cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    tr -d ' ' |
1581cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    cut -f2 -d:)
1591cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local rootfs_sectors=$((rootfs_blocks * 8))
1600c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
1610c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Overwrite the appended hashes in the rootfs
1620c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local temp_config=$(make_temp_file)
1631cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo ${new_kernel_config} >${temp_config}
1641cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  dd if=${hash_image} of=${rootfs_image} bs=512 \
1650c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    seek=${rootfs_sectors} conv=notrunc
1660c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
1671cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local temp_kimage=$(make_temp_file)
168d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  extract_image_partition ${image} ${kernelpart} ${temp_kimage}
1690c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Re-calculate kernel partition signature and command line.
1700c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local updated_kimage=$(make_temp_file)
1710c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  vbutil_kernel --repack ${updated_kimage} \
1720c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    --keyblock ${keyblock} \
1730c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    --signprivate ${signprivate} \
1740c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    --oldblob ${temp_kimage} \
1750c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    --config ${temp_config}
17633c44fc14f6981601d0f0743d0705587d5f11c56Gaurav Shah
177d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  replace_image_partition ${image} ${kernelpart} ${updated_kimage}
1781cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  replace_image_partition ${image} 3 ${rootfs_image}
1790c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah}
1800c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
1815f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah# Do a sanity check on the image's rootfs
1825f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah# ARGS: Image
1835f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shahverify_image_rootfs() {
1845f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  local image=$1
1855f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  local rootfs_image=$(make_temp_file)
1865f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  extract_image_partition ${image} 3 ${rootfs_image}
1875f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  # This flips the read-only compatibility flag, so that e2fsck does not
1885f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  # complain about unknown file system capabilities.
1895f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  enable_rw_mount ${rootfs_image}
1905f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  echo "Running e2fsck to check root file system for errors"
1915f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  sudo e2fsck -fn "${rootfs_image}" ||
1925f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah    { echo "Root file system has errors!" && exit 1;}
1935f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah}
1945f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  
1950c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Extracts the firmware update binaries from the a firmware update
1960c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# shell ball (generated by src/platform/firmware/pack_firmware.sh)
1970c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Args: INPUT_SCRIPT OUTPUT_DIR
1980c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shahget_firmwarebin_from_shellball() {
1990c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local input=$1
2001cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local output_dir=$2
20171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  if [ -s "${input}" ]; then
20271bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    uudecode -o - ${input} | tar -C ${output_dir} -zxf - 2>/dev/null || \
20371bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      { echo "Extracting firmware autoupdate failed." && exit 1; }
20471bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  else
20571bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    return 1
20671bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  fi
2070c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah}
2080c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
2090c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Re-sign the firmware AU payload inside the image rootfs with a new keys.
2100c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah# Args: IMAGE
2110c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shahresign_firmware_payload() {
2120c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local image=$1
2130c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
214815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah  if [ -n "${NO_FWUPDATE}" ]; then
215815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah    echo "Skipping firmware update."
216815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah    return
217815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah  fi
218815193daeeef8913dce878e36c6608adb1c56bb5Gaurav Shah
2190c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Grab firmware image from the autoupdate shellball.
2200c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local rootfs_dir=$(make_temp_dir)
2210c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  mount_image_partition ${image} 3 ${rootfs_dir}
22214805f555173cf430902ab415cef9d0d83182578Gaurav Shah  # Force unmount of the rootfs on function exit as it is needed later.
22314805f555173cf430902ab415cef9d0d83182578Gaurav Shah  trap "sudo umount -d ${rootfs_dir}" RETURN
22404c00e19c6fd1d9ad09d2bf5e06518c249d62b31Hung-Te Lin
2250c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local shellball_dir=$(make_temp_dir)
226e2baaec4748d5ac89854a8003f75dd48ddd0e557Hung-Te Lin  # get_firmwarebin_from_shellball can fail if the image has no
22771bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  # firmware update.
2280c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  get_firmwarebin_from_shellball \
22971bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate ${shellball_dir} || \
23071bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    { echo "Didn't find a firmware update. Not signing firmware."
23171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    return; }
23271bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  echo "Found a valid firmware update shellball."
2330c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
2340c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  temp_outfd=$(make_temp_file)
2350c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Replace the root key in the GBB
2360c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # TODO(gauravsh): Remove when we lock down the R/O portion of firmware.
23771bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  if [ -e "${KEY_DIR}/hwid" ]; then
23871bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    # Only update the hwid if we see one in the key directory.
23971bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah    gbb_utility -s \
24071bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      --rootkey=${KEY_DIR}/root_key.vbpubk \
24171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      --recoverykey=${KEY_DIR}/recovery_key.vbpubk \
24271bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      --hwid="$(cat ${KEY_DIR}/hwid)" \
24371bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      ${shellball_dir}/bios.bin ${temp_outfd}
24471bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  else
24571bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah        gbb_utility -s \
24671bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      --rootkey=${KEY_DIR}/root_key.vbpubk \
24771bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      --recoverykey=${KEY_DIR}/recovery_key.vbpubk \
24871bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah      ${shellball_dir}/bios.bin ${temp_outfd}
24971bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  fi
2500c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Resign the firmware with new keys
25171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  ${SCRIPT_DIR}/resign_firmwarefd.sh ${temp_outfd} ${shellball_dir}/bios.bin \
2520c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/firmware_data_key.vbprivk \
2530c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/firmware.keyblock \
2540c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/kernel_subkey.vbpubk
2550c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
2560c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Replace MD5 checksum in the firmware update payload
2570c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  newfd_checksum=$(md5sum ${shellball_dir}/bios.bin | cut -f 1 -d ' ')
2580c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  temp_version=$(make_temp_file)
2591cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  cat ${shellball_dir}/VERSION |
2600c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  sed -e "s#\(.*\)\ \(.*bios.bin.*\)#${newfd_checksum}\ \2#" > ${temp_version}
2610c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  sudo cp ${temp_version} ${shellball_dir}/VERSION
2620c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah
2630c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # Re-generate firmware_update.tgz and copy over encoded archive in
2640c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  # the original shell ball.
2650c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  new_fwblob=$(make_temp_file)
2660c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  tar zcf - -C ${shellball_dir} . | \
2670c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    uuencode firmware_package.tgz > ${new_fwblob}
2680c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  new_shellball=$(make_temp_file)
2690c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  cat ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate | \
2700c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    sed -e '/^begin .*firmware_package/,/end/D' | \
2710c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    cat - ${new_fwblob} >${new_shellball}
2720c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  sudo cp ${new_shellball} ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate
2730c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  echo "Re-signed firmware AU payload in $image"
2740c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah}
27537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
2761cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Verify an image including rootfs hash using the specified keys.
2771cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahverify_image() {
278d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kernel_config=$(grab_kernel_config ${INPUT_IMAGE} 2)
2791cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local rootfs_image=$(make_temp_file)
2801cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  extract_image_partition ${INPUT_IMAGE} 3 ${rootfs_image}
2811cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local hash_image=$(make_temp_file)
2821cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local type=""
2831cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
2841cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # First, perform RootFS verification
2851cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo "Verifying RootFS hash..."
2861cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local new_kernel_config=$(calculate_rootfs_hash "${rootfs_image}" \
2871cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    "${kernel_config}" "${hash_image}")
2881cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local expected_hash=$(get_hash_from_config "${new_kernel_config}")
2891cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local got_hash=$(get_hash_from_config "${kernel_config}")
2901cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
2911cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  if [ ! "${got_hash}" = "${expected_hash}" ]; then
2921cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    cat <<EOF
2931cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahFAILED: RootFS hash is incorrect.
2941cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahExpected: ${expected_hash}
2951cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahGot: ${got_hash}
2961cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav ShahEOF
2971cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  else
2981cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    echo "PASS: RootFS hash is correct (${expected_hash})"
2991cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  fi
3001cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
3011cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # Now try and verify kernel partition signature.
3021cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  set +e
3031cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  local try_key=${KEY_DIR}/recovery_key.vbpubk
3041cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo "Testing key verification..."
3051cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # The recovery key is only used in the recovery mode.
3061cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo -n "With Recovery Key (Recovery Mode ON, Dev Mode OFF): " && \
3071cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 2 >/dev/null 2>&1 && \
3081cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    echo "YES"; } || echo "NO"
3091cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo -n "With Recovery Key (Recovery Mode ON, Dev Mode ON): " && \
3101cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 3 >/dev/null 2>&1 && \
3111cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    echo "YES"; } || echo "NO"
3121cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
3131cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  try_key=${KEY_DIR}/kernel_subkey.vbpubk
3141cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # The SSD key is only used in non-recovery mode.
3151cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo -n "With SSD Key (Recovery Mode OFF, Dev Mode OFF): " && \
3161cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 0 >/dev/null 2>&1  && \
3171cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    echo "YES"; } || echo "NO"
3181cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  echo -n "With SSD Key (Recovery Mode OFF, Dev Mode ON): " && \
3191cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  { load_kernel_test "${INPUT_IMAGE}" "${try_key}" -b 1 >/dev/null 2>&1 && \
3201cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah    echo "YES"; } || echo "NO"
3211cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  set -e
3221cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
3235f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah  verify_image_rootfs "${INPUT_IMAGE}"
3245f500b19ba0cdc174a47a68e40f939a4ed69861cGaurav Shah
3251cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  # TODO(gauravsh): Check embedded firmware AU signatures.
3261cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah}
3271cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
32837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the SSD image
32937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_ssd() {
33037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
33137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah    ${KEY_DIR}/kernel_data_key.vbprivk \
33237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah    ${KEY_DIR}/kernel.keyblock
33371bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  echo "Signed SSD image output to ${OUTPUT_IMAGE}"
33437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah}
33537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
33664bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson# Generate the USB image (direct boot)
33764bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardsonsign_for_usb() {
33864bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
33964bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
34064bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson    ${KEY_DIR}/recovery_kernel.keyblock
3414b86514d8581315fafc196d47d4412677f193750Bill Richardson
3424b86514d8581315fafc196d47d4412677f193750Bill Richardson  # Now generate the installer vblock with the SSD keys.
3434b86514d8581315fafc196d47d4412677f193750Bill Richardson  # The installer vblock is for KERN-A on direct boot images.
3444b86514d8581315fafc196d47d4412677f193750Bill Richardson  temp_kimagea=$(make_temp_file)
3454b86514d8581315fafc196d47d4412677f193750Bill Richardson  temp_out_vb=$(make_temp_file)
3464b86514d8581315fafc196d47d4412677f193750Bill Richardson  extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimagea}
3474b86514d8581315fafc196d47d4412677f193750Bill Richardson  ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimagea} ${temp_out_vb} \
3484b86514d8581315fafc196d47d4412677f193750Bill Richardson    ${KEY_DIR}/kernel_data_key.vbprivk \
3494b86514d8581315fafc196d47d4412677f193750Bill Richardson    ${KEY_DIR}/kernel.keyblock
3504b86514d8581315fafc196d47d4412677f193750Bill Richardson
3514b86514d8581315fafc196d47d4412677f193750Bill Richardson  # Copy the installer vblock to the stateful partition.
3524b86514d8581315fafc196d47d4412677f193750Bill Richardson  local stateful_dir=$(make_temp_dir)
3534b86514d8581315fafc196d47d4412677f193750Bill Richardson  mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
3544b86514d8581315fafc196d47d4412677f193750Bill Richardson  sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
3554b86514d8581315fafc196d47d4412677f193750Bill Richardson
35664bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson  echo "Signed USB image output to ${OUTPUT_IMAGE}"
35764bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson}
35864bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson
35937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the USB (recovery + install) image
36037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_recovery() {
361d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # Update the Kernel B hash in Kernel A command line
362d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  temp_kimageb=$(make_temp_file)
363d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  extract_image_partition ${INPUT_IMAGE} 4 ${temp_kimageb}
364d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kern_a_config=$(grab_kernel_config "${INPUT_IMAGE}" 2)
365d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local kern_b_hash=$(sha1sum ${temp_kimageb} | cut -f1 -d' ')
366d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah
367d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  temp_configa=$(make_temp_file)
368d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  echo "$kern_a_config" | 
369d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    sed -e "s#\(kern_b_hash=\)[a-z0-9]*#\1${kern_b_hash}#" > ${temp_configa}
370d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  echo "New config for kernel partition 2 is"
371d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  cat $temp_configa
372d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah
373d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # Make a copy of the input image
374d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  cp "${INPUT_IMAGE}" "${OUTPUT_IMAGE}"
375d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local temp_kimagea=$(make_temp_file)
376d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimagea}
377d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # Re-calculate kernel partition signature and command line.
378d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  local updated_kimagea=$(make_temp_file)
379d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  vbutil_kernel --repack ${updated_kimagea} \
380d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    --keyblock ${KEY_DIR}/recovery_kernel.keyblock \
381d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    --signprivate ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
382d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    --oldblob ${temp_kimagea} \
383d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    --config ${temp_configa}
384d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  
385d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  replace_image_partition ${OUTPUT_IMAGE} 2 ${updated_kimagea}
38637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
38737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  # Now generate the installer vblock with the SSD keys.
388d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # The installer vblock is for KERN-B on recovery images.
3890c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  temp_out_vb=$(make_temp_file)
390d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  extract_image_partition ${OUTPUT_IMAGE} 4 ${temp_kimageb}
391d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimageb} ${temp_out_vb} \
39237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah    ${KEY_DIR}/kernel_data_key.vbprivk \
39337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah    ${KEY_DIR}/kernel.keyblock
39437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
39537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  # Copy the installer vblock to the stateful partition.
3964b86514d8581315fafc196d47d4412677f193750Bill Richardson  # TODO(gauravsh): Remove this if we get rid of the need to overwrite
3974b86514d8581315fafc196d47d4412677f193750Bill Richardson  # the vblock during installs. Kern B could directly be signed by the
398d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # SSD keys.
3990c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah  local stateful_dir=$(make_temp_dir)
40037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
40137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
40237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
40371bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  echo "Signed recovery image output to ${OUTPUT_IMAGE}"
40437522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah}
40537522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
40637522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah# Generate the factory install image.
40737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahsign_for_factory_install() {
40837522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
409baa09de3a426936de697895b95641254ebf2c01fGaurav Shah    ${KEY_DIR}/installer_kernel_data_key.vbprivk \
41037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah    ${KEY_DIR}/installer_kernel.keyblock
41171bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  echo "Signed factory install image output to ${OUTPUT_IMAGE}"
41237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah}
41337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah
4141cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Verification
4151cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahif [ "${TYPE}" == "verify" ]; then
4161cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  verify_image
417527612e3565be00030a082c262204a0562bc0d4aGaurav Shah  exit 0
4181cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahfi
4191cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
4201cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah# Signing requires an output image name
4211cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahif [ -z "${OUTPUT_IMAGE}" ]; then
4221cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  usage
4231cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  exit 1
4241cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shahfi
4251cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah
42671bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah
42737522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahif [ "${TYPE}" == "ssd" ]; then
42871bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  resign_firmware_payload ${INPUT_IMAGE}
4291cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  update_rootfs_hash ${INPUT_IMAGE} \
4300c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/kernel.keyblock \
431d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    ${KEY_DIR}/kernel_data_key.vbprivk \
432d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    2
43337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  sign_for_ssd
43464bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardsonelif [ "${TYPE}" == "usb" ]; then
43564bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson  resign_firmware_payload ${INPUT_IMAGE}
43664bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson  update_rootfs_hash ${INPUT_IMAGE} \
43764bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson    ${KEY_DIR}/recovery_kernel.keyblock \
43864bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
43964bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson    2
44064bd77e1d8b16f6f182184092114a0d8779bdf52Bill Richardson  sign_for_usb
44137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahelif [ "${TYPE}" == "recovery" ]; then
44271bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  resign_firmware_payload ${INPUT_IMAGE}
443d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  # Both kernel command lines must have the correct rootfs hash
444d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah  update_rootfs_hash ${INPUT_IMAGE} \
445d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    ${KEY_DIR}/recovery_kernel.keyblock \
446d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
447d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    4
4481cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  update_rootfs_hash ${INPUT_IMAGE} \
4490c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/recovery_kernel.keyblock \
450d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
451d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    2
45237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  sign_for_recovery
45337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahelif [ "${TYPE}" == "install" ]; then
45471bff41d6f0ff9912b9c56d14ba2ea0dd0331a9cGaurav Shah  resign_firmware_payload ${INPUT_IMAGE}
4551cd4cdbbae7cd51d0c0ab247aab53ebc6a8cc8a9Gaurav Shah  update_rootfs_hash ${INPUT_IMAGE} \
4560c4c9bac3c390445066f08010a753ce76ccb4a5eGaurav Shah    ${KEY_DIR}/installer_kernel.keyblock \
457baa09de3a426936de697895b95641254ebf2c01fGaurav Shah    ${KEY_DIR}/installer_kernel_data_key.vbprivk \
458d7947a197edc905d3f0a14a661de83573dd6c650Gaurav Shah    2
45937522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  sign_for_factory_install
46037522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahelse
46137522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  echo "Invalid type ${TYPE}"
46237522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shah  exit 1
46337522c9c0ccf48e63e0ab6c2b35b50948d15a003Gaurav Shahfi
464