mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-26 19:25:02 +00:00
make_dev_ssd: new script to change SSD image to dev key
The make_dev_ssd.sh is made for devinstall shim to
change SSD kernels to be signed by dev keys.
- Kernel A, B will be resigned with dev keys (ignore if A/B seems not bootable)
- Adding param --remove_rootfs_verification can even disable rootfs hash check
This CL also includes some shared refine/fix to make_dev_firmware.sh
BUG=chrome-os-partner:1276
TEST=sudo ./make_dev_ssd.sh; (seeing Kernel A is resigned and B is ignored)
then reboot without developer mode (OK),
rootdev shows /dev/dm-0, rootdev -s shows /dev/sda3
sudo ./make_dev_ssd.sh --remove_rootfs_verification;
then reboot without developer mode (OK), rootdev shows /dev/sda3
Change-Id: Ic20f734b2af42e50a43c19a565a166a39d57a7fd
Review URL: http://codereview.chromium.org/3772013
This commit is contained in:
@@ -12,12 +12,20 @@ GPT=cgpt
|
|||||||
# The tag when the rootfs is changed.
|
# The tag when the rootfs is changed.
|
||||||
TAG_NEEDS_TO_BE_SIGNED="/root/.need_to_be_signed"
|
TAG_NEEDS_TO_BE_SIGNED="/root/.need_to_be_signed"
|
||||||
|
|
||||||
# Load shflags
|
# Finds and loads the 'shflags' library, or return as failed.
|
||||||
if [ -f /usr/lib/shflags ]; then
|
load_shflags() {
|
||||||
. /usr/lib/shflags
|
# Load shflags
|
||||||
else
|
if [ -f /usr/lib/shflags ]; then
|
||||||
. "${SCRIPT_DIR}/lib/shflags/shflags"
|
. /usr/lib/shflags
|
||||||
fi
|
elif [ -f "${SCRIPT_DIR}/shflags" ]; then
|
||||||
|
. "${SCRIPT_DIR}/shflags"
|
||||||
|
elif [ -f "${SCRIPT_DIR}/lib/shflags/shflags" ]; then
|
||||||
|
. "${SCRIPT_DIR}/lib/shflags/shflags"
|
||||||
|
else
|
||||||
|
echo "ERROR: Cannot find the required shflags library."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# List of Temporary files and mount points.
|
# List of Temporary files and mount points.
|
||||||
TEMP_FILE_LIST=$(mktemp)
|
TEMP_FILE_LIST=$(mktemp)
|
||||||
@@ -46,27 +54,18 @@ tag_as_needs_to_be_resigned() {
|
|||||||
|
|
||||||
# Determines if the target file system has the tag for resign
|
# Determines if the target file system has the tag for resign
|
||||||
# Args: MOUNTDIRECTORY
|
# Args: MOUNTDIRECTORY
|
||||||
# Returns: $FLAGS_TRUE if the tag is there, otherwise $FLAGS_FALSE
|
# Returns: true if the tag is there otherwise false
|
||||||
has_needs_to_be_resigned_tag() {
|
has_needs_to_be_resigned_tag() {
|
||||||
local mount_dir="$1"
|
local mount_dir="$1"
|
||||||
if [ -f "$mount_dir/$TAG_NEEDS_TO_BE_SIGNED" ]; then
|
[ -f "$mount_dir/$TAG_NEEDS_TO_BE_SIGNED" ]
|
||||||
return ${FLAGS_TRUE}
|
|
||||||
else
|
|
||||||
return ${FLAGS_FALSE}
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determines if the target file system is a Chrome OS root fs
|
# Determines if the target file system is a Chrome OS root fs
|
||||||
# Args: MOUNTDIRECTORY
|
# Args: MOUNTDIRECTORY
|
||||||
# Returns: $FLAGS_TRUE if MOUNTDIRECTORY looks like root fs,
|
# Returns: true if MOUNTDIRECTORY looks like root fs, otherwise false
|
||||||
# otherwise $FLAGS_FALSE
|
|
||||||
is_rootfs_partition() {
|
is_rootfs_partition() {
|
||||||
local mount_dir="$1"
|
local mount_dir="$1"
|
||||||
if [ -f "$mount_dir/$(dirname "$TAG_NEEDS_TO_BE_SIGNED")" ]; then
|
[ -f "$mount_dir/$(dirname "$TAG_NEEDS_TO_BE_SIGNED")" ]
|
||||||
return ${FLAGS_TRUE}
|
|
||||||
else
|
|
||||||
return ${FLAGS_FALSE}
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Mount a partition read-only from an image into a local directory
|
# Mount a partition read-only from an image into a local directory
|
||||||
@@ -149,5 +148,18 @@ cleanup_temps_and_mounts() {
|
|||||||
rm -rf $TEMP_DIR_LIST $TEMP_FILE_LIST
|
rm -rf $TEMP_DIR_LIST $TEMP_FILE_LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns true if all files in parameters exist.
|
||||||
|
ensure_files_exist() {
|
||||||
|
local filename return_value=0
|
||||||
|
for filename in "$@"; do
|
||||||
|
if [ ! -f "$filename" -a ! -b "$filename" ]; then
|
||||||
|
echo "ERROR: Cannot find required file: $filename"
|
||||||
|
return_value=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return $return_value
|
||||||
|
}
|
||||||
|
|
||||||
trap "cleanup_temps_and_mounts" EXIT
|
trap "cleanup_temps_and_mounts" EXIT
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,23 @@
|
|||||||
# found in the LICENSE file.
|
# found in the LICENSE file.
|
||||||
#
|
#
|
||||||
# This script can change key (usually developer keys) in a firmware binary
|
# This script can change key (usually developer keys) in a firmware binary
|
||||||
# image or system live firmware, and assign proper HWID, BMPFV as well.
|
# image or system live firmware (EEPROM), and assign proper HWID, BMPFV as well.
|
||||||
|
|
||||||
SCRIPT_BASE="$(dirname "$0")"
|
SCRIPT_BASE="$(dirname "$0")"
|
||||||
. "$SCRIPT_BASE/common.sh"
|
. "$SCRIPT_BASE/common.sh"
|
||||||
|
load_shflags || exit 1
|
||||||
|
|
||||||
# Constants used by DEFINE_*
|
# Constants used by DEFINE_*
|
||||||
|
VBOOT_BASE='/usr/share/vboot'
|
||||||
|
DEFAULT_KEYS_FOLDER="$VBOOT_BASE/devkeys"
|
||||||
|
DEFAULT_BMPFV_FILE="$DEFAULT_KEYS_FOLDER/firmware_bmpfv.bin"
|
||||||
DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups'
|
DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups'
|
||||||
|
|
||||||
# DEFINE_string name default_value description flag
|
# DEFINE_string name default_value description flag
|
||||||
DEFINE_string from "" "Path of input file (empty for system live firmware)" "f"
|
DEFINE_string from "" "Path of input file (empty for system live firmware)" "f"
|
||||||
DEFINE_string to "" "Path of output file (empty for system live firmware)" "t"
|
DEFINE_string to "" "Path of output file (empty for system live firmware)" "t"
|
||||||
DEFINE_string keys "$SCRIPT_BASE/keys" "Path of folder of dev keys" "k"
|
DEFINE_string keys "$DEFAULT_KEYS_FOLDER" "Path to folder of dev keys" "k"
|
||||||
DEFINE_string bmpfv "$SCRIPT_BASE/rsrc/bmpfv.bin" "Path to the new bitmap FV" ""
|
DEFINE_string bmpfv "$DEFAULT_BMPFV_FILE" "Path to the new bitmap FV" ""
|
||||||
DEFINE_boolean force_backup \
|
DEFINE_boolean force_backup \
|
||||||
$FLAGS_TRUE "Create backup even if source is not live" ""
|
$FLAGS_TRUE "Create backup even if source is not live" ""
|
||||||
DEFINE_string backup_dir \
|
DEFINE_string backup_dir \
|
||||||
@@ -33,10 +37,10 @@ eval set -- "$FLAGS_ARGV"
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
# the image we are (temporary) working with
|
# the image we are (temporary) working with
|
||||||
IMAGE=$(make_temp_file)
|
IMAGE="$(make_temp_file)"
|
||||||
|
|
||||||
# a log file to keep the output results of executed command
|
# a log file to keep the output results of executed command
|
||||||
EXEC_LOG=$(make_temp_file)
|
EXEC_LOG="$(make_temp_file)"
|
||||||
|
|
||||||
# Functions
|
# Functions
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
@@ -77,6 +81,7 @@ read_image() {
|
|||||||
write_image() {
|
write_image() {
|
||||||
if [ -z "$FLAGS_to" ]; then
|
if [ -z "$FLAGS_to" ]; then
|
||||||
echo "Writing system live firmware..."
|
echo "Writing system live firmware..."
|
||||||
|
# TODO(hungte) we can enable partial write to make this faster
|
||||||
if is_debug_mode; then
|
if is_debug_mode; then
|
||||||
flashrom -V -w "$IMAGE"
|
flashrom -V -w "$IMAGE"
|
||||||
else
|
else
|
||||||
@@ -96,6 +101,8 @@ echo_dev_hwid() {
|
|||||||
|
|
||||||
# NOTE: Some DEV firmware image files may put GUID in HWID.
|
# NOTE: Some DEV firmware image files may put GUID in HWID.
|
||||||
# These are not officially supported and they will see "{GUID} DEV".
|
# These are not officially supported and they will see "{GUID} DEV".
|
||||||
|
# Also there's some length limitation in chromeos_acpi/HWID, so
|
||||||
|
# a "{GUID} DEV" will become "{GUID} " in that case.
|
||||||
|
|
||||||
if [ "$hwid" != "$hwid_no_dev" ]; then
|
if [ "$hwid" != "$hwid_no_dev" ]; then
|
||||||
hwid="$hwid_no_dev"
|
hwid="$hwid_no_dev"
|
||||||
@@ -105,21 +112,6 @@ echo_dev_hwid() {
|
|||||||
echo "$hwid_dev"
|
echo "$hwid_dev"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Checks if the files given by parameters all exist.
|
|
||||||
check_exist_or_die() {
|
|
||||||
local file is_success=$FLAGS_TRUE
|
|
||||||
for file in "$@"; do
|
|
||||||
if [ ! -s "$file" ]; then
|
|
||||||
echo "ERROR: Cannot find required file: $file"
|
|
||||||
is_success=$FLAGS_FALSE
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$is_success" = $FLAGS_FALSE ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main
|
# Main
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
main() {
|
main() {
|
||||||
@@ -133,19 +125,20 @@ main() {
|
|||||||
local is_from_live=0
|
local is_from_live=0
|
||||||
local backup_image=
|
local backup_image=
|
||||||
|
|
||||||
debug_msg "Pre-requisition check"
|
debug_msg "Prerequisite check"
|
||||||
check_exist_or_die \
|
ensure_files_exist \
|
||||||
"$root_pubkey" \
|
"$root_pubkey" \
|
||||||
"$recovery_pubkey" \
|
"$recovery_pubkey" \
|
||||||
"$firmware_keyblock" \
|
"$firmware_keyblock" \
|
||||||
"$firmware_prvkey" \
|
"$firmware_prvkey" \
|
||||||
"$kernel_sub_pubkey" \
|
"$kernel_sub_pubkey" \
|
||||||
"$new_bmpfv"
|
"$new_bmpfv" ||
|
||||||
|
exit 1
|
||||||
|
|
||||||
if [ -z "$FLAGS_from" ]; then
|
if [ -z "$FLAGS_from" ]; then
|
||||||
is_from_live=1
|
is_from_live=1
|
||||||
else
|
else
|
||||||
check_exist_or_die "$FLAGS_from"
|
ensure_files_exist "$FLAGS_from"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# TODO(hungte) check if GPIO.3 (WP) is enabled
|
# TODO(hungte) check if GPIO.3 (WP) is enabled
|
||||||
@@ -156,27 +149,26 @@ main() {
|
|||||||
|
|
||||||
debug_msg "Prepare to backup the file"
|
debug_msg "Prepare to backup the file"
|
||||||
if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then
|
if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then
|
||||||
backup_image=$(make_temp_file)
|
backup_image="$(make_temp_file)"
|
||||||
debug_msg "Creating backup file to $backup_image..."
|
debug_msg "Creating backup file to $backup_image..."
|
||||||
cp -f "$IMAGE" "$backup_image"
|
cp -f "$IMAGE" "$backup_image"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# TODO(hungte) We can use vbutil_firmware to check if the current firmware is
|
# TODO(hungte) We can use vbutil_firmware to check if the current firmware is
|
||||||
# valid, so that we can know both they key, vbutil_firmware are working fine.
|
# valid so that we know keys and vbutil_firmware are all working fine.
|
||||||
|
|
||||||
echo "Preparing new firmware image..."
|
echo "Preparing new firmware image..."
|
||||||
|
|
||||||
debug_msg "Extract current HWID and rootkey"
|
debug_msg "Extract current HWID and rootkey"
|
||||||
local old_hwid
|
local old_hwid
|
||||||
old_hwid=$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" |
|
old_hwid="$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" |
|
||||||
grep '^hardware_id:' |
|
grep '^hardware_id:' |
|
||||||
sed 's/^hardware_id: //')
|
sed 's/^hardware_id: //')"
|
||||||
|
|
||||||
debug_msg "Decide new HWID"
|
debug_msg "Decide new HWID"
|
||||||
if [ -z "$old_hwid" ]; then
|
if [ -z "$old_hwid" ]; then
|
||||||
err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))"
|
err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))"
|
||||||
fi
|
fi
|
||||||
local new_hwid=$(echo_dev_hwid "$old_hwid")
|
local new_hwid="$(echo_dev_hwid "$old_hwid")"
|
||||||
|
|
||||||
debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)"
|
debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)"
|
||||||
gbb_utility --set \
|
gbb_utility --set \
|
||||||
@@ -188,7 +180,7 @@ main() {
|
|||||||
err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))"
|
err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))"
|
||||||
|
|
||||||
debug_msg "Resign the firmware code (A/B) with new keys"
|
debug_msg "Resign the firmware code (A/B) with new keys"
|
||||||
local unsigned_image=$(make_temp_file)
|
local unsigned_image="$(make_temp_file)"
|
||||||
cp -f "$IMAGE" "$unsigned_image"
|
cp -f "$IMAGE" "$unsigned_image"
|
||||||
"$SCRIPT_BASE/resign_firmwarefd.sh" \
|
"$SCRIPT_BASE/resign_firmwarefd.sh" \
|
||||||
"$unsigned_image" \
|
"$unsigned_image" \
|
||||||
@@ -200,21 +192,22 @@ main() {
|
|||||||
|
|
||||||
# TODO(hungte) compare if the image really needs to be changed.
|
# TODO(hungte) compare if the image really needs to be changed.
|
||||||
|
|
||||||
debug_msg "Backup files when reading from system live image."
|
debug_msg "Check if we need to make backup file(s)"
|
||||||
if [ -n "$backup_image" ]; then
|
if [ -n "$backup_image" ]; then
|
||||||
local backup_hwid_name=$(echo "$old_hwid" | sed 's/ /_/g')
|
local backup_hwid_name="$(echo "$old_hwid" | sed 's/ /_/g')"
|
||||||
local backup_date_time=$(date +'%Y%m%d_%H%M%S')
|
local backup_date_time="$(date +'%Y%m%d_%H%M%S')"
|
||||||
local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd"
|
local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd"
|
||||||
local backup_file_path="$FLAGS_backup_dir/$backup_file_name"
|
local backup_file_path="$FLAGS_backup_dir/$backup_file_name"
|
||||||
if mkdir -p "$FLAGS_backup_dir" &&
|
if mkdir -p "$FLAGS_backup_dir" &&
|
||||||
cp -f "$backup_image" "$backup_file_path"; then
|
cp -f "$backup_image" "$backup_file_path"; then
|
||||||
echo "Backup of current firmware image is stored in: $backup_file_path"
|
echo "Backup of current firmware image is stored in: $backup_file_path"
|
||||||
else
|
else
|
||||||
echo "Cannot create file in $FLAGS_backup_dir... Ignore backups."
|
echo "WARNING: Cannot create file in $FLAGS_backup_dir... Ignore backups."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# TODO(hungte) use vbutil_firmware to check if the new firmware is valid.
|
# TODO(hungte) use vbutil_firmware to check if the new firmware is valid.
|
||||||
|
# Or, do verification in resign_firmwarefd.sh and trust it.
|
||||||
|
|
||||||
debug_msg "Write the image"
|
debug_msg "Write the image"
|
||||||
write_image ||
|
write_image ||
|
||||||
@@ -224,7 +217,7 @@ main() {
|
|||||||
if [ -z "$FLAGS_to" ]; then
|
if [ -z "$FLAGS_to" ]; then
|
||||||
echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid"
|
echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid"
|
||||||
else
|
else
|
||||||
echo "Firmware image '$FLAGS_to' now uses Developer Keys. HWID: $new_hwid"
|
echo "Firmware '$FLAGS_to' now uses Developer Keys. New HWID: $new_hwid"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
236
scripts/image_signing/make_dev_ssd.sh
Executable file
236
scripts/image_signing/make_dev_ssd.sh
Executable file
@@ -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
|
||||||
BIN
tests/devkeys/firmware_bmpfv.bin
Normal file
BIN
tests/devkeys/firmware_bmpfv.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user