diff options
author | Gaurav Shah <gauravsh@chromium.org> | 2011-02-06 15:44:39 -0800 |
---|---|---|
committer | Gaurav Shah <gauravsh@chromium.org> | 2011-02-06 15:44:39 -0800 |
commit | 8ae7b0e41a1252f98e6662a298efb97624431c44 (patch) | |
tree | 2aecfe178ec4b7157ca276db40a5fb97e9de8ba7 | |
parent | d55085da49da8b7981494ea53ad23a6038fbb5c9 (diff) | |
download | vboot-8ae7b0e41a1252f98e6662a298efb97624431c44.tar.gz |
Allow signing scripts to (optionally) set the firmware and kernel versions
Versions are (optionally) read from a file with the format
firmware_version=<firmware version>
kernel_version=<kernel version>
The new scripts and arguments are compatible with older versions of the script.
Change-Id: I502df69d6c02caee75cdf010e61812be408a64e0
BUG=chromium-os:8016
TEST=manually tested all invocations of sign_official_build {verify|usb|ssd|install|recovery} with and without versions.
Review URL: http://codereview.chromium.org/6368064
-rwxr-xr-x | scripts/image_signing/resign_firmwarefd.sh | 48 | ||||
-rwxr-xr-x | scripts/image_signing/resign_image.sh | 62 | ||||
-rwxr-xr-x | scripts/image_signing/resign_kernel_partition.sh | 32 | ||||
-rwxr-xr-x | scripts/image_signing/sign_official_build.sh | 53 | ||||
-rw-r--r-- | scripts/image_signing/versions.default | 7 |
5 files changed, 120 insertions, 82 deletions
diff --git a/scripts/image_signing/resign_firmwarefd.sh b/scripts/image_signing/resign_firmwarefd.sh index 98903422..36334718 100755 --- a/scripts/image_signing/resign_firmwarefd.sh +++ b/scripts/image_signing/resign_firmwarefd.sh @@ -54,9 +54,9 @@ set -e # Check arguments -if [ $# -ne 5 ] ; then - echo \ - "Usage: $0 src_fd dst_fd firmware_datakey firmware_keyblock kernel_subkey" +if [ $# -lt 5 ] || [ $# -gt 6 ]; then + echo "Usage: $PROG src_fd dst_fd firmware_datakey firmware_keyblock"\ + "kernel_subkey [version]" exit 1 fi @@ -66,15 +66,17 @@ for prog in mosys vbutil_firmware; do { echo "${prog} tool not found."; exit 1; } done -src_fd=$1 -dst_fd=$2 -firmware_datakey=$3 -firmware_keyblock=$4 -kernel_subkey=$5 +SRC_FD=$1 +DST_FD=$2 +FIRMWARE_DATAKEY=$3 +FIRMWARE_KEYBLOCK=$4 +KERNEL_SUBKEY=$5 +VERSION=$6 -# TODO(gauravsh): Figure out where the version comes from. -# Do we rev it manually? -VERSION=1 +if [ -z $VERSION ]; then + VERSION=1 +fi +echo "Using firmware version: $VERSION" # Parse offsets and size of firmware data and vblocks for i in "A" "B" @@ -98,37 +100,37 @@ temp_fwimage=$(make_temp_file) temp_out_vb=$(make_temp_file) # Extract out Firmware A data and generate signature using the right keys -dd if="${src_fd}" of="${temp_fwimage}" skip="${fwA_offset}" bs=1 \ +dd if="${SRC_FD}" of="${temp_fwimage}" skip="${fwA_offset}" bs=1 \ count="${fwA_size}" echo "Re-calculating Firmware A vblock" vbutil_firmware \ --vblock "${temp_out_vb}" \ - --keyblock "${firmware_keyblock}" \ - --signprivate "${firmware_datakey}" \ + --keyblock "${FIRMWARE_KEYBLOCK}" \ + --signprivate "${FIRMWARE_DATAKEY}" \ --version "${VERSION}" \ --fv "${temp_fwimage}" \ - --kernelkey "${kernel_subkey}" + --kernelkey "${KERNEL_SUBKEY}" # Create a copy of the input image and put in the new vblock for firmware A -cp "${src_fd}" "${dst_fd}" -dd if="${temp_out_vb}" of="${dst_fd}" seek="${fwA_vblock_offset}" bs=1 \ +cp "${SRC_FD}" "${DST_FD}" +dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwA_vblock_offset}" bs=1 \ count="${fwA_vblock_size}" conv=notrunc # Repeat for firmware B -dd if="${src_fd}" of="${temp_fwimage}" skip="${fwB_offset}" bs=1 \ +dd if="${SRC_FD}" of="${temp_fwimage}" skip="${fwB_offset}" bs=1 \ count="${fwB_size}" echo "Re-calculating Firmware B vblock" vbutil_firmware \ --vblock "${temp_out_vb}" \ - --keyblock "${firmware_keyblock}" \ - --signprivate "${firmware_datakey}" \ + --keyblock "${FIRMWARE_KEYBLOCK}" \ + --signprivate "${FIRMWARE_DATAKEY}" \ --version "${VERSION}" \ --fv "${temp_fwimage}" \ - --kernelkey "${kernel_subkey}" + --kernelkey "${KERNEL_SUBKEY}" # Destination image has already been created. -dd if="${temp_out_vb}" of="${dst_fd}" seek="${fwB_vblock_offset}" bs=1 \ +dd if="${temp_out_vb}" of="${DST_FD}" seek="${fwB_vblock_offset}" bs=1 \ count="${fwB_vblock_size}" conv=notrunc -echo "New signed image was output to ${dst_fd}" +echo "New signed image was output to ${DST_FD}" diff --git a/scripts/image_signing/resign_image.sh b/scripts/image_signing/resign_image.sh index 5098f7d4..9cdc1def 100755 --- a/scripts/image_signing/resign_image.sh +++ b/scripts/image_signing/resign_image.sh @@ -16,45 +16,41 @@ set -e # Check arguments -if [ $# -ne 4 ] ; then - echo "usage: $0 src_bin dst_bin kernel_datakey kernel_keyblock" +if [ $# -lt 4 ] || [ $# -gt 5 ] ; then + echo "usage: $PROG src_bin dst_bin kernel_datakey kernel_keyblock [version]" exit 1 fi # Make sure the tools we need are available. -type -P cgpt &>/dev/null || \ - { echo "cgpt tool not found."; exit 1; } -type -P vbutil_kernel &>/dev/null || \ - { echo "vbutil_kernel tool not found."; exit 1; } - -sector_size=512 # sector size in bytes -num_sectors_vb=128 # number of sectors in kernel verification blob -src_bin=$1 -dst_bin=$2 -kernel_datakey=$3 -kernel_keyblock=$4 - -koffset="$(cgpt show -b -i 2 $1)" -ksize="$(cgpt show -s -i 2 $1)" - -echo "Re-signing image ${src_bin} and outputting ${dst_bin}" +for prereqs in vbutil_kernel cgpt; +do + type -P "${prereqs}" &>/dev/null || \ + { echo "${prereqs} tool not found."; exit 1; } +done + +SRC_BIN=$1 +DST_BIN=$2 +KERNEL_DATAKEY=$3 +KERNEL_KEYBLOCK=$4 +VERSION=$5 + +if [ -z $VERSION ]; then + VERSION=1 +fi +echo "Using kernel version: $VERSION" + temp_kimage=$(make_temp_file) -temp_out_vb=$(make_temp_file) - -# Grab the kernel image in preparation for resigning -dd if="${src_bin}" of="${temp_kimage}" skip=$koffset bs=$sector_size \ - count=$ksize -vbutil_kernel \ - --repack "${temp_out_vb}" \ - --vblockonly \ - --keyblock "${kernel_keyblock}" \ - --signprivate "${kernel_datakey}" \ +extract_image_partition ${SRC_BIN} 2 ${temp_kimage} +updated_kimage=$(make_temp_file) + +vbutil_kernel --repack "${updated_kimage}" \ + --keyblock "${KERNEL_KEYBLOCK}" \ + --signprivate "${KERNEL_DATAKEY}" \ + --version "${VERSION}" \ --oldblob "${temp_kimage}" # Create a copy of the input image and put in the new vblock -cp "${src_bin}" "${dst_bin}" -dd if="${temp_out_vb}" of="${dst_bin}" seek=$koffset bs=$sector_size \ - count=$num_sectors_vb conv=notrunc - -echo "New signed image was output to ${dst_bin}" +cp "${SRC_BIN}" "${DST_BIN}" +replace_image_partition ${DST_BIN} 2 ${updated_kimage} +echo "New signed image was output to ${DST_BIN}" diff --git a/scripts/image_signing/resign_kernel_partition.sh b/scripts/image_signing/resign_kernel_partition.sh index 1b88cb2b..fd7cfd39 100755 --- a/scripts/image_signing/resign_kernel_partition.sh +++ b/scripts/image_signing/resign_kernel_partition.sh @@ -9,12 +9,14 @@ # vbutil_kernel must be in the system path. +SCRIPT_DIR=$(dirname $0) + # Abort on error set -e # Check arguments -if [ $# -ne 4 ] ; then - echo "usage: $0 src_kpart dst_vblock kernel_datakey kernel_keyblock" +if [ $# -lt 4 ] || [ $# -gt 5 ]; then + echo "usage: $0 src_kpart dst_vblock kernel_datakey kernel_keyblock [version]" exit 1 fi @@ -22,17 +24,23 @@ fi type -P vbutil_kernel &>/dev/null || \ ( echo "vbutil_kernel tool not found."; exit 1; ) -src_kpart=$1 -dst_vblock=$2 -kernel_datakey=$3 -kernel_keyblock=$4 +SRC_KPART=$1 +DST_VBLOCK=$2 +KERNEL_DATAKEY=$3 +KERNEL_KEYBLOCK=$4 +VERSION=$5 + +if [ -z $VERSION ]; then + VERSION=1 +fi +echo "Using kernel version: $VERSION" -vbutil_kernel \ - --repack "${dst_vblock}" \ +vbutil_kernel --repack "${DST_VBLOCK}" \ --vblockonly \ - --keyblock "${kernel_keyblock}" \ - --signprivate "${kernel_datakey}" \ - --oldblob "${src_kpart}" + --keyblock "${KERNEL_KEYBLOCK}" \ + --signprivate "${KERNEL_DATAKEY}" \ + --version "${VERSION}" \ + --oldblob "${SRC_KPART}" -echo "New kernel vblock was output to ${dst_vblock}" +echo "New kernel vblock was output to ${DST_VBLOCK}" diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh index 85d315fe..3737d943 100755 --- a/scripts/image_signing/sign_official_build.sh +++ b/scripts/image_signing/sign_official_build.sh @@ -23,7 +23,7 @@ # Print usage string usage() { cat <<EOF -Usage: $PROG <type> input_image /path/to/keys/dir [output_image] +Usage: $PROG <type> input_image /path/to/keys/dir [output_image] [version_file] where <type> is one of: ssd (sign an SSD image) recovery (sign a USB recovery image) @@ -31,11 +31,16 @@ where <type> is one of: usb (sign an image to boot directly from USB) verify (verify an image including rootfs hashes) -If you are signing an image, you must specify an [output_image]. +output_image: File name of the signed output image +version_file: File name of where to read the kernel and firmware versions. + +If you are signing an image, you must specify an [output_image] and +optionally, a [version_file]. + EOF } -if [ $# -ne 3 ] && [ $# -ne 4 ]; then +if [ $# -lt 3 ] || [ $# -gt 5 ]; then usage exit 1 fi @@ -55,6 +60,10 @@ TYPE=$1 INPUT_IMAGE=$2 KEY_DIR=$3 OUTPUT_IMAGE=$4 +VERSION_FILE=$5 + +FIRMWARE_VERSION=1 +KERNEL_VERSION=1 # Get current rootfs hash and kernel command line # ARGS: IMAGE KERNELPART @@ -125,7 +134,7 @@ update_rootfs_hash() { local signprivate=$3 # Private key to use for signing. local kernelpart=$4 # Kernel partition number to update (usually 2 or 4) - echo "Updating rootfs hash and updating config for Kernel partition " \ + echo "Updating rootfs hash and updating config for Kernel partition" \ "$kernelpart" # check and clear need_to_resign tag @@ -171,6 +180,7 @@ update_rootfs_hash() { vbutil_kernel --repack ${updated_kimage} \ --keyblock ${keyblock} \ --signprivate ${signprivate} \ + --version "${KERNEL_VERSION}" \ --oldblob ${temp_kimage} \ --config ${temp_config} @@ -191,7 +201,7 @@ verify_image_rootfs() { sudo e2fsck -fn "${rootfs_image}" || { echo "Root file system has errors!" && exit 1;} } - + # Extracts the firmware update binaries from the a firmware update # shell ball (generated by src/platform/firmware/pack_firmware.sh) # Args: INPUT_SCRIPT OUTPUT_DIR @@ -242,7 +252,7 @@ resign_firmware_payload() { --hwid="$(cat ${KEY_DIR}/hwid)" \ ${shellball_dir}/bios.bin ${temp_outfd} else - gbb_utility -s \ + gbb_utility -s \ --rootkey=${KEY_DIR}/root_key.vbpubk \ --recoverykey=${KEY_DIR}/recovery_key.vbpubk \ ${shellball_dir}/bios.bin ${temp_outfd} @@ -251,7 +261,8 @@ resign_firmware_payload() { ${SCRIPT_DIR}/resign_firmwarefd.sh ${temp_outfd} ${shellball_dir}/bios.bin \ ${KEY_DIR}/firmware_data_key.vbprivk \ ${KEY_DIR}/firmware.keyblock \ - ${KEY_DIR}/kernel_subkey.vbpubk + ${KEY_DIR}/kernel_subkey.vbpubk \ + ${FIRMWARE_VERSION} # Replace MD5 checksum in the firmware update payload newfd_checksum=$(md5sum ${shellball_dir}/bios.bin | cut -f 1 -d ' ') @@ -329,7 +340,8 @@ EOF sign_for_ssd() { ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ ${KEY_DIR}/kernel_data_key.vbprivk \ - ${KEY_DIR}/kernel.keyblock + ${KEY_DIR}/kernel.keyblock \ + "${KERNEL_VERSION}" echo "Signed SSD image output to ${OUTPUT_IMAGE}" } @@ -337,7 +349,8 @@ sign_for_ssd() { sign_for_usb() { ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ - ${KEY_DIR}/recovery_kernel.keyblock + ${KEY_DIR}/recovery_kernel.keyblock \ + "${KERNEL_VERSION}" # Now generate the installer vblock with the SSD keys. # The installer vblock is for KERN-A on direct boot images. @@ -346,7 +359,8 @@ sign_for_usb() { extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimagea} ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimagea} ${temp_out_vb} \ ${KEY_DIR}/kernel_data_key.vbprivk \ - ${KEY_DIR}/kernel.keyblock + ${KEY_DIR}/kernel.keyblock \ + "${KERNEL_VERSION}" # Copy the installer vblock to the stateful partition. local stateful_dir=$(make_temp_dir) @@ -365,7 +379,7 @@ sign_for_recovery() { local kern_b_hash=$(sha1sum ${temp_kimageb} | cut -f1 -d' ') temp_configa=$(make_temp_file) - echo "$kern_a_config" | + echo "$kern_a_config" | sed -e "s#\(kern_b_hash=\)[a-z0-9]*#\1${kern_b_hash}#" > ${temp_configa} echo "New config for kernel partition 2 is" cat $temp_configa @@ -379,9 +393,10 @@ sign_for_recovery() { vbutil_kernel --repack ${updated_kimagea} \ --keyblock ${KEY_DIR}/recovery_kernel.keyblock \ --signprivate ${KEY_DIR}/recovery_kernel_data_key.vbprivk \ + --version "${KERNEL_VERSION}" \ --oldblob ${temp_kimagea} \ --config ${temp_configa} - + replace_image_partition ${OUTPUT_IMAGE} 2 ${updated_kimagea} # Now generate the installer vblock with the SSD keys. @@ -390,7 +405,8 @@ sign_for_recovery() { extract_image_partition ${OUTPUT_IMAGE} 4 ${temp_kimageb} ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimageb} ${temp_out_vb} \ ${KEY_DIR}/kernel_data_key.vbprivk \ - ${KEY_DIR}/kernel.keyblock + ${KEY_DIR}/kernel.keyblock \ + "${KERNEL_VERSION}" # Copy the installer vblock to the stateful partition. # TODO(gauravsh): Remove this if we get rid of the need to overwrite @@ -407,7 +423,8 @@ sign_for_recovery() { sign_for_factory_install() { ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \ ${KEY_DIR}/installer_kernel_data_key.vbprivk \ - ${KEY_DIR}/installer_kernel.keyblock + ${KEY_DIR}/installer_kernel.keyblock \ + "${KERNEL_VERSION}" echo "Signed factory install image output to ${OUTPUT_IMAGE}" } @@ -423,6 +440,14 @@ if [ -z "${OUTPUT_IMAGE}" ]; then exit 1 fi +# If a version file was specified, read the firmware and kernel +# versions from there. +if [ -n "${VERSION_FILE}" ]; then + FIRMWARE_VERSION=$(sed -n 's#^firmware_version=\(.*\)#\1#pg' ${VERSION_FILE}) + KERNEL_VERSION=$(sed -n 's#^kernel_version=\(.*\)#\1#pg' ${VERSION_FILE}) +fi +echo "Using firmware version: ${FIRMWARE_VERSION}" +echo "Using kernel version: ${KERNEL_VERSION}" if [ "${TYPE}" == "ssd" ]; then resign_firmware_payload ${INPUT_IMAGE} diff --git a/scripts/image_signing/versions.default b/scripts/image_signing/versions.default new file mode 100644 index 00000000..1fefcb38 --- /dev/null +++ b/scripts/image_signing/versions.default @@ -0,0 +1,7 @@ +# sign_official_build.sh can (optionally) take a file name from which to read +# firmware and kernel versions to set during the signing process. + +# This is a sample version file template. + +firmware_version=1 +kernel_version=1 |