| OLD | NEW |
| 1 #!/bin/sh | 1 #!/bin/sh |
| 2 # | 2 # |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 # | 6 # |
| 7 # This script can change key (usually developer keys) in a firmware binary | 7 # This script can change key (usually developer keys) in a firmware binary |
| 8 # image or system live firmware, and assign proper HWID, BMPFV as well. | 8 # image or system live firmware (EEPROM), and assign proper HWID, BMPFV as well. |
| 9 | 9 |
| 10 SCRIPT_BASE="$(dirname "$0")" | 10 SCRIPT_BASE="$(dirname "$0")" |
| 11 . "$SCRIPT_BASE/common.sh" | 11 . "$SCRIPT_BASE/common.sh" |
| 12 load_shflags || exit 1 |
| 12 | 13 |
| 13 # Constants used by DEFINE_* | 14 # Constants used by DEFINE_* |
| 15 VBOOT_BASE='/usr/share/vboot' |
| 16 DEFAULT_KEYS_FOLDER="$VBOOT_BASE/devkeys" |
| 17 DEFAULT_BMPFV_FILE="$DEFAULT_KEYS_FOLDER/firmware_bmpfv.bin" |
| 14 DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups' | 18 DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups' |
| 15 | 19 |
| 16 # DEFINE_string name default_value description flag | 20 # DEFINE_string name default_value description flag |
| 17 DEFINE_string from "" "Path of input file (empty for system live firmware)" "f" | 21 DEFINE_string from "" "Path of input file (empty for system live firmware)" "f" |
| 18 DEFINE_string to "" "Path of output file (empty for system live firmware)" "t" | 22 DEFINE_string to "" "Path of output file (empty for system live firmware)" "t" |
| 19 DEFINE_string keys "$SCRIPT_BASE/keys" "Path of folder of dev keys" "k" | 23 DEFINE_string keys "$DEFAULT_KEYS_FOLDER" "Path to folder of dev keys" "k" |
| 20 DEFINE_string bmpfv "$SCRIPT_BASE/rsrc/bmpfv.bin" "Path to the new bitmap FV" "" | 24 DEFINE_string bmpfv "$DEFAULT_BMPFV_FILE" "Path to the new bitmap FV" "" |
| 21 DEFINE_boolean force_backup \ | 25 DEFINE_boolean force_backup \ |
| 22 $FLAGS_TRUE "Create backup even if source is not live" "" | 26 $FLAGS_TRUE "Create backup even if source is not live" "" |
| 23 DEFINE_string backup_dir \ | 27 DEFINE_string backup_dir \ |
| 24 "$DEFAULT_BACKUP_FOLDER" "Path of directory to store firmware backups" "" | 28 "$DEFAULT_BACKUP_FOLDER" "Path of directory to store firmware backups" "" |
| 25 DEFINE_boolean debug $FLAGS_FALSE "Provide debug messages" "d" | 29 DEFINE_boolean debug $FLAGS_FALSE "Provide debug messages" "d" |
| 26 | 30 |
| 27 # Parse command line | 31 # Parse command line |
| 28 FLAGS "$@" || exit 1 | 32 FLAGS "$@" || exit 1 |
| 29 eval set -- "$FLAGS_ARGV" | 33 eval set -- "$FLAGS_ARGV" |
| 30 | 34 |
| 31 # Globals | 35 # Globals |
| 32 # ---------------------------------------------------------------------------- | 36 # ---------------------------------------------------------------------------- |
| 33 set -e | 37 set -e |
| 34 | 38 |
| 35 # the image we are (temporary) working with | 39 # the image we are (temporary) working with |
| 36 IMAGE=$(make_temp_file) | 40 IMAGE="$(make_temp_file)" |
| 37 | 41 |
| 38 # a log file to keep the output results of executed command | 42 # a log file to keep the output results of executed command |
| 39 EXEC_LOG=$(make_temp_file) | 43 EXEC_LOG="$(make_temp_file)" |
| 40 | 44 |
| 41 # Functions | 45 # Functions |
| 42 # ---------------------------------------------------------------------------- | 46 # ---------------------------------------------------------------------------- |
| 43 # Reports error message and exit(1) | 47 # Reports error message and exit(1) |
| 44 err_die() { | 48 err_die() { |
| 45 echo "ERROR: $*" 1>&2 | 49 echo "ERROR: $*" 1>&2 |
| 46 exit 1 | 50 exit 1 |
| 47 } | 51 } |
| 48 | 52 |
| 49 # Returns true if we're running in debug mode | 53 # Returns true if we're running in debug mode |
| (...skipping 20 matching lines...) Expand all Loading... |
| 70 else | 74 else |
| 71 debug_msg "reading from file: $FLAGS_from" | 75 debug_msg "reading from file: $FLAGS_from" |
| 72 cp -f "$FLAGS_from" "$IMAGE" | 76 cp -f "$FLAGS_from" "$IMAGE" |
| 73 fi | 77 fi |
| 74 } | 78 } |
| 75 | 79 |
| 76 # Writes $IMAGE to $FLAGS_to | 80 # Writes $IMAGE to $FLAGS_to |
| 77 write_image() { | 81 write_image() { |
| 78 if [ -z "$FLAGS_to" ]; then | 82 if [ -z "$FLAGS_to" ]; then |
| 79 echo "Writing system live firmware..." | 83 echo "Writing system live firmware..." |
| 84 # TODO(hungte) we can enable partial write to make this faster |
| 80 if is_debug_mode; then | 85 if is_debug_mode; then |
| 81 flashrom -V -w "$IMAGE" | 86 flashrom -V -w "$IMAGE" |
| 82 else | 87 else |
| 83 flashrom -w "$IMAGE" >"$EXEC_LOG" 2>&1 | 88 flashrom -w "$IMAGE" >"$EXEC_LOG" 2>&1 |
| 84 fi | 89 fi |
| 85 else | 90 else |
| 86 debug_msg "writing to file: $FLAGS_to" | 91 debug_msg "writing to file: $FLAGS_to" |
| 87 cp -f "$IMAGE" "$FLAGS_to" | 92 cp -f "$IMAGE" "$FLAGS_to" |
| 88 chmod a+r "$FLAGS_to" | 93 chmod a+r "$FLAGS_to" |
| 89 fi | 94 fi |
| 90 } | 95 } |
| 91 | 96 |
| 92 # Converts HWID from $1 to proper format with "DEV" extension | 97 # Converts HWID from $1 to proper format with "DEV" extension |
| 93 echo_dev_hwid() { | 98 echo_dev_hwid() { |
| 94 local hwid="$1" | 99 local hwid="$1" |
| 95 local hwid_no_dev="${hwid% DEV}" | 100 local hwid_no_dev="${hwid% DEV}" |
| 96 | 101 |
| 97 # NOTE: Some DEV firmware image files may put GUID in HWID. | 102 # NOTE: Some DEV firmware image files may put GUID in HWID. |
| 98 # These are not officially supported and they will see "{GUID} DEV". | 103 # These are not officially supported and they will see "{GUID} DEV". |
| 104 # Also there's some length limitation in chromeos_acpi/HWID, so |
| 105 # a "{GUID} DEV" will become "{GUID} " in that case. |
| 99 | 106 |
| 100 if [ "$hwid" != "$hwid_no_dev" ]; then | 107 if [ "$hwid" != "$hwid_no_dev" ]; then |
| 101 hwid="$hwid_no_dev" | 108 hwid="$hwid_no_dev" |
| 102 fi | 109 fi |
| 103 local hwid_dev="$hwid DEV" | 110 local hwid_dev="$hwid DEV" |
| 104 debug_msg "echo_dev_hwid: [$1] -> [$hwid_dev]" | 111 debug_msg "echo_dev_hwid: [$1] -> [$hwid_dev]" |
| 105 echo "$hwid_dev" | 112 echo "$hwid_dev" |
| 106 } | 113 } |
| 107 | 114 |
| 108 # Checks if the files given by parameters all exist. | |
| 109 check_exist_or_die() { | |
| 110 local file is_success=$FLAGS_TRUE | |
| 111 for file in "$@"; do | |
| 112 if [ ! -s "$file" ]; then | |
| 113 echo "ERROR: Cannot find required file: $file" | |
| 114 is_success=$FLAGS_FALSE | |
| 115 fi | |
| 116 done | |
| 117 | |
| 118 if [ "$is_success" = $FLAGS_FALSE ]; then | |
| 119 exit 1 | |
| 120 fi | |
| 121 } | |
| 122 | |
| 123 # Main | 115 # Main |
| 124 # ---------------------------------------------------------------------------- | 116 # ---------------------------------------------------------------------------- |
| 125 main() { | 117 main() { |
| 126 # Check parameters | 118 # Check parameters |
| 127 local root_pubkey="$FLAGS_keys/root_key.vbpubk" | 119 local root_pubkey="$FLAGS_keys/root_key.vbpubk" |
| 128 local recovery_pubkey="$FLAGS_keys/recovery_key.vbpubk" | 120 local recovery_pubkey="$FLAGS_keys/recovery_key.vbpubk" |
| 129 local firmware_keyblock="$FLAGS_keys/firmware.keyblock" | 121 local firmware_keyblock="$FLAGS_keys/firmware.keyblock" |
| 130 local firmware_prvkey="$FLAGS_keys/firmware_data_key.vbprivk" | 122 local firmware_prvkey="$FLAGS_keys/firmware_data_key.vbprivk" |
| 131 local kernel_sub_pubkey="$FLAGS_keys/kernel_subkey.vbpubk" | 123 local kernel_sub_pubkey="$FLAGS_keys/kernel_subkey.vbpubk" |
| 132 local new_bmpfv="$FLAGS_bmpfv" | 124 local new_bmpfv="$FLAGS_bmpfv" |
| 133 local is_from_live=0 | 125 local is_from_live=0 |
| 134 local backup_image= | 126 local backup_image= |
| 135 | 127 |
| 136 debug_msg "Pre-requisition check" | 128 debug_msg "Prerequisite check" |
| 137 check_exist_or_die \ | 129 ensure_files_exist \ |
| 138 "$root_pubkey" \ | 130 "$root_pubkey" \ |
| 139 "$recovery_pubkey" \ | 131 "$recovery_pubkey" \ |
| 140 "$firmware_keyblock" \ | 132 "$firmware_keyblock" \ |
| 141 "$firmware_prvkey" \ | 133 "$firmware_prvkey" \ |
| 142 "$kernel_sub_pubkey" \ | 134 "$kernel_sub_pubkey" \ |
| 143 "$new_bmpfv" | 135 "$new_bmpfv" || |
| 136 exit 1 |
| 144 | 137 |
| 145 if [ -z "$FLAGS_from" ]; then | 138 if [ -z "$FLAGS_from" ]; then |
| 146 is_from_live=1 | 139 is_from_live=1 |
| 147 else | 140 else |
| 148 check_exist_or_die "$FLAGS_from" | 141 ensure_files_exist "$FLAGS_from" |
| 149 fi | 142 fi |
| 150 | 143 |
| 151 # TODO(hungte) check if GPIO.3 (WP) is enabled | 144 # TODO(hungte) check if GPIO.3 (WP) is enabled |
| 152 | 145 |
| 153 debug_msg "Pulling image to $IMAGE" | 146 debug_msg "Pulling image to $IMAGE" |
| 154 (read_image && [ -s "$IMAGE" ]) || | 147 (read_image && [ -s "$IMAGE" ]) || |
| 155 err_die "Failed to read image. Error message: $(cat "$EXEC_LOG")" | 148 err_die "Failed to read image. Error message: $(cat "$EXEC_LOG")" |
| 156 | 149 |
| 157 debug_msg "Prepare to backup the file" | 150 debug_msg "Prepare to backup the file" |
| 158 if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then | 151 if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then |
| 159 backup_image=$(make_temp_file) | 152 backup_image="$(make_temp_file)" |
| 160 debug_msg "Creating backup file to $backup_image..." | 153 debug_msg "Creating backup file to $backup_image..." |
| 161 cp -f "$IMAGE" "$backup_image" | 154 cp -f "$IMAGE" "$backup_image" |
| 162 fi | 155 fi |
| 163 | 156 |
| 164 # TODO(hungte) We can use vbutil_firmware to check if the current firmware is | 157 # TODO(hungte) We can use vbutil_firmware to check if the current firmware is |
| 165 # valid, so that we can know both they key, vbutil_firmware are working fine. | 158 # valid so that we know keys and vbutil_firmware are all working fine. |
| 166 | 159 |
| 167 echo "Preparing new firmware image..." | 160 echo "Preparing new firmware image..." |
| 168 | |
| 169 debug_msg "Extract current HWID and rootkey" | 161 debug_msg "Extract current HWID and rootkey" |
| 170 local old_hwid | 162 local old_hwid |
| 171 old_hwid=$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" | | 163 old_hwid="$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" | |
| 172 grep '^hardware_id:' | | 164 grep '^hardware_id:' | |
| 173 sed 's/^hardware_id: //') | 165 sed 's/^hardware_id: //')" |
| 174 | 166 |
| 175 debug_msg "Decide new HWID" | 167 debug_msg "Decide new HWID" |
| 176 if [ -z "$old_hwid" ]; then | 168 if [ -z "$old_hwid" ]; then |
| 177 err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))" | 169 err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))" |
| 178 fi | 170 fi |
| 179 local new_hwid=$(echo_dev_hwid "$old_hwid") | 171 local new_hwid="$(echo_dev_hwid "$old_hwid")" |
| 180 | 172 |
| 181 debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)" | 173 debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)" |
| 182 gbb_utility --set \ | 174 gbb_utility --set \ |
| 183 --hwid="$new_hwid" \ | 175 --hwid="$new_hwid" \ |
| 184 --bmpfv="$new_bmpfv" \ | 176 --bmpfv="$new_bmpfv" \ |
| 185 --rootkey="$root_pubkey" \ | 177 --rootkey="$root_pubkey" \ |
| 186 --recoverykey="$recovery_pubkey" \ | 178 --recoverykey="$recovery_pubkey" \ |
| 187 "$IMAGE" >"$EXEC_LOG" 2>&1 || | 179 "$IMAGE" >"$EXEC_LOG" 2>&1 || |
| 188 err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))" | 180 err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))" |
| 189 | 181 |
| 190 debug_msg "Resign the firmware code (A/B) with new keys" | 182 debug_msg "Resign the firmware code (A/B) with new keys" |
| 191 local unsigned_image=$(make_temp_file) | 183 local unsigned_image="$(make_temp_file)" |
| 192 cp -f "$IMAGE" "$unsigned_image" | 184 cp -f "$IMAGE" "$unsigned_image" |
| 193 "$SCRIPT_BASE/resign_firmwarefd.sh" \ | 185 "$SCRIPT_BASE/resign_firmwarefd.sh" \ |
| 194 "$unsigned_image" \ | 186 "$unsigned_image" \ |
| 195 "$IMAGE" \ | 187 "$IMAGE" \ |
| 196 "$firmware_prvkey" \ | 188 "$firmware_prvkey" \ |
| 197 "$firmware_keyblock" \ | 189 "$firmware_keyblock" \ |
| 198 "$kernel_sub_pubkey" >"$EXEC_LOG" 2>&1 || | 190 "$kernel_sub_pubkey" >"$EXEC_LOG" 2>&1 || |
| 199 err_die "Failed to re-sign firmware. (message: $(cat "$EXEC_LOG"))" | 191 err_die "Failed to re-sign firmware. (message: $(cat "$EXEC_LOG"))" |
| 200 | 192 |
| 201 # TODO(hungte) compare if the image really needs to be changed. | 193 # TODO(hungte) compare if the image really needs to be changed. |
| 202 | 194 |
| 203 debug_msg "Backup files when reading from system live image." | 195 debug_msg "Check if we need to make backup file(s)" |
| 204 if [ -n "$backup_image" ]; then | 196 if [ -n "$backup_image" ]; then |
| 205 local backup_hwid_name=$(echo "$old_hwid" | sed 's/ /_/g') | 197 local backup_hwid_name="$(echo "$old_hwid" | sed 's/ /_/g')" |
| 206 local backup_date_time=$(date +'%Y%m%d_%H%M%S') | 198 local backup_date_time="$(date +'%Y%m%d_%H%M%S')" |
| 207 local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd" | 199 local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd" |
| 208 local backup_file_path="$FLAGS_backup_dir/$backup_file_name" | 200 local backup_file_path="$FLAGS_backup_dir/$backup_file_name" |
| 209 if mkdir -p "$FLAGS_backup_dir" && | 201 if mkdir -p "$FLAGS_backup_dir" && |
| 210 cp -f "$backup_image" "$backup_file_path"; then | 202 cp -f "$backup_image" "$backup_file_path"; then |
| 211 echo "Backup of current firmware image is stored in: $backup_file_path" | 203 echo "Backup of current firmware image is stored in: $backup_file_path" |
| 212 else | 204 else |
| 213 echo "Cannot create file in $FLAGS_backup_dir... Ignore backups." | 205 echo "WARNING: Cannot create file in $FLAGS_backup_dir... Ignore backups." |
| 214 fi | 206 fi |
| 215 fi | 207 fi |
| 216 | 208 |
| 217 # TODO(hungte) use vbutil_firmware to check if the new firmware is valid. | 209 # TODO(hungte) use vbutil_firmware to check if the new firmware is valid. |
| 210 # Or, do verification in resign_firmwarefd.sh and trust it. |
| 218 | 211 |
| 219 debug_msg "Write the image" | 212 debug_msg "Write the image" |
| 220 write_image || | 213 write_image || |
| 221 err_die "Failed to write image. Error message: $(cat "$EXEC_LOG")" | 214 err_die "Failed to write image. Error message: $(cat "$EXEC_LOG")" |
| 222 | 215 |
| 223 debug_msg "Complete." | 216 debug_msg "Complete." |
| 224 if [ -z "$FLAGS_to" ]; then | 217 if [ -z "$FLAGS_to" ]; then |
| 225 echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid" | 218 echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid" |
| 226 else | 219 else |
| 227 echo "Firmware image '$FLAGS_to' now uses Developer Keys. HWID: $new_hwid" | 220 echo "Firmware '$FLAGS_to' now uses Developer Keys. New HWID: $new_hwid" |
| 228 fi | 221 fi |
| 229 } | 222 } |
| 230 | 223 |
| 231 main | 224 main |
| OLD | NEW |