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

Unified Diff: scripts/image_signing/make_dev_ssd.sh

Issue 3772013: make_dev_ssd: new script to change SSD image to dev key (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git
Patch Set: Refine shflags dependency Created 10 years, 2 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/make_dev_firmware.sh ('k') | tests/devkeys/firmware_bmpfv.bin » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/image_signing/make_dev_ssd.sh
diff --git a/scripts/image_signing/make_dev_ssd.sh b/scripts/image_signing/make_dev_ssd.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a5a961d69b786c55530f7ac53206e643f4668682
--- /dev/null
+++ b/scripts/image_signing/make_dev_ssd.sh
@@ -0,0 +1,236 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 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.
+#
+# This script can change key (usually developer keys) and kernel config
+# of a kernels on SSD.
+
+SCRIPT_BASE="$(dirname "$0")"
+. "$SCRIPT_BASE/common.sh"
+load_shflags || exit 1
+
+# Constants used by DEFINE_*
+VBOOT_BASE='/usr/share/vboot'
+DEFAULT_KEYS_FOLDER="$VBOOT_BASE/devkeys"
+DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups'
+
+# DEFINE_string name default_value description flag
+DEFINE_string image "/dev/sda" "Path to device or image file" "i"
+DEFINE_string keys "$DEFAULT_KEYS_FOLDER" "Path to folder of dev keys" "k"
+DEFINE_boolean remove_rootfs_verification \
+ $FLAGS_FALSE "Modify kernel boot config to disable rootfs verification" ""
+DEFINE_string backup_dir \
+ "$DEFAULT_BACKUP_FOLDER" "Path of directory to store kernel backups" ""
+DEFINE_boolean debug $FLAGS_FALSE "Provide debug messages" "d"
+
+# Parse command line
+FLAGS "$@" || exit 1
+eval set -- "$FLAGS_ARGV"
+
+# Globals
+# ----------------------------------------------------------------------------
+set -e
+
+# a log file to keep the output results of executed command
+EXEC_LOG="$(make_temp_file)"
+
+# Functions
+# ----------------------------------------------------------------------------
+# Reports error message and exit(1)
+err_die() {
+ echo "ERROR: $*" 1>&2
+ exit 1
+}
+
+# Returns true if we're running in debug mode
+is_debug_mode() {
+ [ "$FLAGS_debug" = $FLAGS_TRUE ]
+}
+
+# Prints messages (in parameters) in debug mode
+debug_msg() {
+ if is_debug_mode; then
+ echo "DEBUG: $*" 1>&2
+ fi
+}
+
+# Removes rootfs verification from kernel boot parameter
+remove_rootfs_verification() {
+ echo "$*" | sed '
+ s|dm_verity[^ ]\+||g
+ s| ro | rw |
+ s|verity /dev/sd%D%P /dev/sd%D%P ||
+ s| root=/dev/dm-0 | root=/dev/sd%D%P |
+ s|dm="[^"]\+" ||'
+}
+
+# Wrapped version of dd
+mydd() {
+ # oflag=sync is safer, but since we need bs=512, syncing every block would be
+ # very slow.
+ dd "$@" >"$EXEC_LOG" 2>&1 ||
+ err_die "Failed in [dd $@], Message: $(cat "$EXEC_LOG")"
+}
+
+# Prints a more friendly name from kernel index number
+cros_kernel_name() {
+ case $1 in
+ 2)
+ echo "Kernel A"
+ ;;
+ 4)
+ echo "Kernel B"
+ ;;
+ *)
+ err_die "unknown kernel index: $1"
+ esac
+}
+
+# Resigns a kernel on SSD or image.
+resign_ssd_kernel() {
+ # bs=512 is the fixed block size for dd and cgpt
+ local bs=512
+ local ssd_device="$1"
+
+ # reasonable size for current kernel partition
+ local min_kernel_size=32000
+ local max_kernel_size=65536
+ local resigned_kernels=0
+
+ for kernel_index in 2 4; do
+ local old_blob="$(make_temp_file)"
+ local new_blob="$(make_temp_file)"
+ local name="$(cros_kernel_name $kernel_index)"
+
+ debug_msg "Probing $name information"
+ local offset size
+ offset="$(partoffset "$ssd_device" "$kernel_index")" ||
+ err_die "Failed to get partition $kernel_index offset from $ssd_device"
+ size="$(partsize "$ssd_device" "$kernel_index")" ||
+ err_die "Failed to get partition $kernel_index size from $ssd_device"
+ if [ ! $size -gt $min_kernel_size ]; then
+ echo "WARNING: $name seems too small ($size), ignored."
+ continue
+ fi
+ if [ ! $size -le $max_kernel_size ]; then
+ echo "WARNING: $name seems too large ($size), ignored."
+ continue
+ fi
+
+ debug_msg "Reading $name from partition $kernel_index"
+ mydd if="$ssd_device" of="$old_blob" bs=$bs skip=$offset count=$size
+
+ debug_msg "Checking if $name is valid"
+ local old_kernel_config
+ if ! old_kernel_config="$(dump_kernel_config "$old_blob" 2>"$EXEC_LOG")"
+ then
+ debug_msg "dump_kernel_config error message: $(cat "$EXEC_LOG")"
+ echo "WARNING: $name: no kernel boot information, ignored."
+ continue
+ fi
+
+ debug_msg "Decide and prepare signing parameters"
+ local resign_command
+ # TODO(hungte) $KERNEL_KEYBLOCK and $new_kernel_config should also be
+ # quoted, but quoting inside would cause extra quote... We should find some
+ # better way to do this, for example using eval.
+ if [ ${FLAGS_remove_rootfs_verification} = $FLAGS_TRUE ]; then
+ local new_kernel_config_file="$(make_temp_file)"
+ remove_rootfs_verification "$old_kernel_config" >"$new_kernel_config_file"
+ resign_command="--config $new_kernel_config_file"
+ debug_msg "New kernel config: $(cat $new_kernel_config_file)"
+ echo "$name: Disabled rootfs verification."
+ else
+ resign_command="--vblockonly --keyblock $KERNEL_KEYBLOCK"
+ fi
+
+ debug_msg "Re-signing $name from $old_blob to $new_blob"
+ debug_msg "Using key: $KERNEL_DATAKEY, command: $resign_command"
+ vbutil_kernel \
+ --repack "$new_blob" \
+ $resign_command \
+ --signprivate "$KERNEL_DATAKEY" \
+ --oldblob "$old_blob" >"$EXEC_LOG" 2>&1 ||
+ err_die "Failed to resign $name. Message: $(cat "$EXEC_LOG")"
+
+ debug_msg "Creating new kernel image (vboot+code+config)"
+ local new_kern="$(make_temp_file)"
+ cp "$old_blob" "$new_kern"
+ mydd if="$new_blob" of="$new_kern" conv=notrunc
+
+ if is_debug_mode; then
+ debug_msg "for debug purposes, check *.dbgbin"
+ cp "$old_blob" old_blob.dbgbin
+ cp "$new_blob" new_blob.dbgbin
+ cp "$new_kern" new_kern.dbgbin
+ fi
+
+ debug_msg "Verifying new kernel and keys"
+ vbutil_kernel \
+ --verify "$new_kern" \
+ --signpubkey "$KERNEL_PUBKEY" --verbose >"$EXEC_LOG" 2>&1 ||
+ err_die "Failed to verify new $name. Message: $(cat "$EXEC_LOG")"
+
+ debug_msg "Backup old kernel blob"
+ local backup_date_time="$(date +'%Y%m%d_%H%M%S')"
+ local backup_name="$(echo "$name" | sed 's/ /_/g; s/^K/k/')"
+ local backup_file_name="${backup_name}_${backup_date_time}.bin"
+ local backup_file_path="$FLAGS_backup_dir/$backup_file_name"
+ if mkdir -p "$FLAGS_backup_dir" &&
+ cp -f "$old_blob" "$backup_file_path"; then
+ echo "Backup of $name is stored in: $backup_file_path"
+ else
+ echo "WARNING: Cannot create file in $FLAGS_backup_dir... Ignore backups."
+ fi
+
+ debug_msg "Writing $name to partition $kernel_index"
+ mydd \
+ if="$new_kern" \
+ of="$ssd_device" \
+ seek=$offset \
+ bs=$bs \
+ count=$size \
+ conv=notrunc
+ resigned_kernels=$(($resigned_kernels + 1))
+
+ # Sometimes doing "dump_kernel_config" or other I/O now (or after return to
+ # shell) will get the data before modification. Not a problem now, but for
+ # safety, let's try to sync more.
+ sync; sync; sync
+
+ echo "$name: Re-signed with developer keys successfully."
+ done
+ return $resigned_kernels
+}
+
+# Main
+# ----------------------------------------------------------------------------
+main() {
+ local num_signed=0
+ # Check parameters
+ KERNEL_KEYBLOCK="$FLAGS_keys/kernel.keyblock"
+ KERNEL_DATAKEY="$FLAGS_keys/kernel_data_key.vbprivk"
+ KERNEL_PUBKEY="$FLAGS_keys/kernel_subkey.vbpubk"
+
+ debug_msg "Prerequisite check"
+ ensure_files_exist \
+ "$KERNEL_KEYBLOCK" \
+ "$KERNEL_DATAKEY" \
+ "$KERNEL_PUBKEY" \
+ "$FLAGS_image" ||
+ exit 1
+
+ resign_ssd_kernel "$FLAGS_image" || num_signed=$?
+
+ debug_msg "Complete."
+ if [ $num_signed -gt 0 -a $num_signed -le 2 ]; then
+ # signed 1 or two kernels
+ echo "Successfully re-signed $num_signed kernel(s) on device $FLAGS_image".
+ else
+ err_die "Failed re-signing kernels."
+ fi
+}
+
+main
« no previous file with comments | « scripts/image_signing/make_dev_firmware.sh ('k') | tests/devkeys/firmware_bmpfv.bin » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698