Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1033)

Unified Diff: scripts/image_signing/sign_official_build.sh

Issue 3083025: Make signing script re-sign Firmware AU payload, and update rootfs hash. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git
Patch Set: review fixes Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « scripts/image_signing/resign_image.sh ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/image_signing/sign_official_build.sh
diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh
index 01e581badb54e3775a47d1e39b0749d2cc2e60b3..143d945acdbf61f35550bf61e729e33e98f50a27 100755
--- a/scripts/image_signing/sign_official_build.sh
+++ b/scripts/image_signing/sign_official_build.sh
@@ -5,7 +5,15 @@
# found in the LICENSE file.
# Sign the final build image using the "official" keys.
-
+#
+# Prerequisite tools needed in the system path:
+#
+# gbb_utility (from src/platform/vboot_reference)
+# vbutil_kernel (from src/platform/vboot_reference)
+# cgpt (from src/platform/vboot_reference)
+# dump_kernel_config (from src/platform/vboot_reference)
+# verity (from src/platform/verity)
+#
# Usage: sign_for_ssd.sh <type> input_image /path/to/keys/dir output_image
#
# where <type> is one of:
@@ -35,6 +43,129 @@ INPUT_IMAGE=$2
KEY_DIR=$3
OUTPUT_IMAGE=$4
+# Re-calculate rootfs hash, update rootfs and kernel command line.
+# Args: IMAGE KEYBLOCK PRIVATEKEY
+recalculate_rootfs_hash() {
+ local image=$1 # Input image.
+ local keyblock=$2 # Keyblock for re-generating signed kernel partition
+ local signprivate=$3 # Private key to use for signing.
+
+ # First, grab the existing kernel partition and get the kernel config.
+ temp_kimage=$(make_temp_file)
+ extract_image_partition ${image} 2 ${temp_kimage}
+ local kernel_config=$(sudo dump_kernel_config ${temp_kimage})
+ local dm_config=$(echo $kernel_config |
+ sed -e 's/.*dm="\([^"]*\)".*/\1/g' |
+ cut -f2- -d,)
+ # We extract dm=... portion of the config command line. Here's an example:
+ #
+ # dm="0 2097152 verity ROOT_DEV HASH_DEV 2097152 1 \
+ # sha1 63b7ad16cb9db4b70b28593f825aa6b7825fdcf2"
+ #
+
+ if [ -z ${dm_config} ]; then
+ echo "WARNING: Couldn't grab dm_config. Aborting rootfs hash calculation"
+ return
+ fi
+ local rootfs_sectors=$(echo ${dm_config} | cut -f2 -d' ')
+ local root_dev=$(echo ${dm_config} | cut -f4 -d ' ')
+ local hash_dev=$(echo ${dm_config} | cut -f5 -d ' ')
+ local verity_depth=$(echo ${dm_config} | cut -f7 -d' ')
+ local verity_algorithm=$(echo ${dm_config} | cut -f8 -d' ')
+
+ # Mount the rootfs and run the verity tool on it.
+ local hash_image=$(make_temp_file)
+ local rootfs_img=$(make_temp_file)
+ extract_image_partition ${image} 3 ${rootfs_img}
+ local table="vroot none ro,"$(sudo verity create \
+ ${verity_depth} \
+ ${verity_algorithm} \
+ ${rootfs_img} \
+ $((rootfs_sectors / 8)) \
+ ${hash_image})
+ # Reconstruct new kernel config command line and replace placeholders.
+ table="$(echo "$table" |
+ sed -s "s|ROOT_DEV|${root_dev}|g;s|HASH_DEV|${hash_dev}|")"
+ kernel_config=$(echo ${kernel_config} |
+ sed -e 's#\(.*dm="\)\([^"]*\)\(".*\)'"#\1${table}\3#g")
+
+ # Overwrite the appended hashes in the rootfs
+ local temp_config=$(make_temp_file)
+ echo ${kernel_config} >${temp_config}
+ dd if=${hash_image} of=${rootfs_img} bs=512 \
+ seek=${rootfs_sectors} conv=notrunc
+
+ # Re-calculate kernel partition signature and command line.
+ local updated_kimage=$(make_temp_file)
+ vbutil_kernel --repack ${updated_kimage} \
+ --keyblock ${keyblock} \
+ --signprivate ${signprivate} \
+ --oldblob ${temp_kimage} \
+ --config ${temp_config}
+
+ replace_image_partition ${image} 2 ${updated_kimage}
+ replace_image_partition ${image} 3 ${rootfs_img}
+}
+
+# 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
+get_firmwarebin_from_shellball() {
+ local input=$1
+ local output_dir=$2
+ uudecode -o - ${input} | tar -C ${output_dir} -zxf - 2>/dev/null || \
+ echo "Extracting firmware autoupdate failed.
+Try re-running with FW_NOUPDATE=1." && exit 1
+}
+
+# Re-sign the firmware AU payload inside the image rootfs with a new keys.
+# Args: IMAGE
+resign_firmware_payload() {
+ local image=$1
+
+ # Grab firmware image from the autoupdate shellball.
+ local rootfs_dir=$(make_temp_dir)
+ mount_image_partition ${image} 3 ${rootfs_dir}
+
+ local shellball_dir=$(make_temp_dir)
+ get_firmwarebin_from_shellball \
+ ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate ${shellball_dir}
+
+ temp_outfd=$(make_temp_file)
+ # Replace the root key in the GBB
+ # TODO(gauravsh): Remove when we lock down the R/O portion of firmware.
+ gbb_utility -s \
+ --rootkey=${KEY_DIR}/root_key.vbpubk \
+ --recoverykey=${KEY_DIR}/recovery_key.vbpubk \
+ ${shellball_dir}/bios.bin ${temp_outfd}
+
+ # Resign the firmware with new keys
+ ${SCRIPT_DIR}/resign_firmwarefd.sh ${temp_outfd} ${temp_dir}/bios.bin \
+ ${KEY_DIR}/firmware_data_key.vbprivk \
+ ${KEY_DIR}/firmware.keyblock \
+ ${KEY_DIR}/kernel_subkey.vbpubk
+
+ # Replace MD5 checksum in the firmware update payload
+ newfd_checksum=$(md5sum ${shellball_dir}/bios.bin | cut -f 1 -d ' ')
+ temp_version=$(make_temp_file)
+ cat ${shellball_dir}/VERSION |
+ sed -e "s#\(.*\)\ \(.*bios.bin.*\)#${newfd_checksum}\ \2#" > ${temp_version}
+ sudo cp ${temp_version} ${shellball_dir}/VERSION
+
+ # Re-generate firmware_update.tgz and copy over encoded archive in
+ # the original shell ball.
+ new_fwblob=$(make_temp_file)
+ tar zcf - -C ${shellball_dir} . | \
+ uuencode firmware_package.tgz > ${new_fwblob}
+ new_shellball=$(make_temp_file)
+ cat ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate | \
+ sed -e '/^begin .*firmware_package/,/end/D' | \
+ cat - ${new_fwblob} >${new_shellball}
+ sudo cp ${new_shellball} ${rootfs_dir}/usr/sbin/chromeos-firmwareupdate
+ # Force unmount of the image as it is needed later.
+ sudo umount -d ${rootfs_dir}
+ echo "Re-signed firmware AU payload in $image"
+}
# Generate the SSD image
sign_for_ssd() {
@@ -51,18 +182,15 @@ sign_for_recovery() {
${KEY_DIR}/recovery_kernel.keyblock
# Now generate the installer vblock with the SSD keys.
- temp_kimage=$(mktemp)
- trap "rm -f ${temp_kimage}" EXIT
- temp_out_vb=$(mktemp)
- trap "rm -f ${temp_out_vb}" EXIT
+ temp_kimage=$(make_temp_file)
+ temp_out_vb=$(make_temp_file)
extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimage}
${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimage} ${temp_out_vb} \
${KEY_DIR}/kernel_data_key.vbprivk \
${KEY_DIR}/kernel.keyblock
# Copy the installer vblock to the stateful partition.
- local stateful_dir=$(mktemp -d)
- trap "sudo umount -d $stateful_dir; rm -rf $stateful_dir" EXIT
+ local stateful_dir=$(make_temp_dir)
mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
@@ -77,15 +205,26 @@ sign_for_factory_install() {
echo "Output signed factory install image to ${OUTPUT_IMAGE}"
}
+if [ ! "${FW_NOUPDATE}" == "1" ]; then
+ resign_firmware_payload ${INPUT_IMAGE}
+fi
+
if [ "${TYPE}" == "ssd" ]; then
+ recalculate_rootfs_hash ${INPUT_IMAGE} \
+ ${KEY_DIR}/kernel.keyblock \
+ ${KEY_DIR}/kernel_data_key.vbprivk
sign_for_ssd
elif [ "${TYPE}" == "recovery" ]; then
+ recalculate_rootfs_hash ${INPUT_IMAGE} \
+ ${KEY_DIR}/recovery_kernel.keyblock \
+ ${KEY_DIR}/recovery_kernel_data_key.vbprivk
sign_for_recovery
elif [ "${TYPE}" == "install" ]; then
+ recalculate_rootfs_hash ${INPUT_IMAGE} \
+ ${KEY_DIR}/installer_kernel.keyblock \
+ ${KEY_DIR}/recovery_kernel_data_key.vbprivk
sign_for_factory_install
else
echo "Invalid type ${TYPE}"
exit 1
fi
-
-
« no previous file with comments | « scripts/image_signing/resign_image.sh ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698