Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/bin/sh | |
|
gauravsh
2010/10/14 19:21:07
I think this is maybe a good time to re-factor the
Hung-Te
2010/10/15 00:28:53
Just want to comment, this script can run on a liv
| |
| 2 # | |
| 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 | |
| 5 # found in the LICENSE file. | |
| 6 # | |
| 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. | |
| 9 | |
| 10 SCRIPT_BASE="$(dirname "$0")" | |
| 11 . "$SCRIPT_BASE/common.sh" | |
| 12 | |
| 13 # Constants used by DEFINE_* | |
| 14 DEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups' | |
| 15 | |
| 16 # DEFINE_string name default_value description flag | |
| 17 DEFINE_string from "" "Path of input file (empty for system live firmware)" "f" | |
|
Randall Spangler
2010/10/14 19:46:22
"system live firmware" really means "current firmw
| |
| 18 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" | |
| 20 DEFINE_string bmpfv "$SCRIPT_BASE/rsrc/bmpfv.bin" "Path to the new bitmap FV" "" | |
| 21 DEFINE_boolean force_backup \ | |
| 22 $FLAGS_TRUE "Create backup even if source is not live" "" | |
| 23 DEFINE_string backup_dir \ | |
| 24 "$DEFAULT_BACKUP_FOLDER" "Path of directory to store firmware backups" "" | |
| 25 DEFINE_boolean debug $FLAGS_FALSE "Provide debug messages" "d" | |
| 26 | |
| 27 # Parse command line | |
| 28 FLAGS "$@" || exit 1 | |
| 29 eval set -- "$FLAGS_ARGV" | |
| 30 | |
| 31 # Globals | |
| 32 # ---------------------------------------------------------------------------- | |
| 33 set -e | |
| 34 | |
| 35 # the image we are (temporary) working with | |
| 36 IMAGE=$(make_temp_file) | |
| 37 | |
| 38 # a log file to keep the output results of executed command | |
| 39 EXEC_LOG=$(make_temp_file) | |
| 40 | |
| 41 # Functions | |
| 42 # ---------------------------------------------------------------------------- | |
| 43 # Reports error message and exit(1) | |
| 44 err_die() { | |
| 45 echo "ERROR: $*" 1>&2 | |
| 46 exit 1 | |
| 47 } | |
| 48 | |
| 49 # Returns true if we're running in debug mode | |
| 50 is_debug_mode() { | |
| 51 [ "$FLAGS_debug" = $FLAGS_TRUE ] | |
| 52 } | |
| 53 | |
| 54 # Prints messages (in parameters) in debug mode | |
| 55 debug_msg() { | |
| 56 if is_debug_mode; then | |
| 57 echo "DEBUG: $*" 1>&2 | |
| 58 fi | |
| 59 } | |
| 60 | |
| 61 # Reads $IMAGE from $FLAGS_from | |
| 62 read_image() { | |
| 63 if [ -z "$FLAGS_from" ]; then | |
| 64 echo "Reading system live firmware..." | |
| 65 if is_debug_mode; then | |
| 66 flashrom -V -r "$IMAGE" | |
| 67 else | |
| 68 flashrom -r "$IMAGE" >"$EXEC_LOG" 2>&1 | |
| 69 fi | |
| 70 else | |
| 71 debug_msg "reading from file: $FLAGS_from" | |
| 72 cp -f "$FLAGS_from" "$IMAGE" | |
| 73 fi | |
| 74 } | |
| 75 | |
| 76 # Writes $IMAGE to $FLAGS_to | |
| 77 write_image() { | |
| 78 if [ -z "$FLAGS_to" ]; then | |
| 79 echo "Writing system live firmware..." | |
| 80 if is_debug_mode; then | |
| 81 flashrom -V -w "$IMAGE" | |
| 82 else | |
| 83 flashrom -w "$IMAGE" >"$EXEC_LOG" 2>&1 | |
| 84 fi | |
| 85 else | |
| 86 debug_msg "writing to file: $FLAGS_to" | |
| 87 cp -f "$IMAGE" "$FLAGS_to" | |
| 88 chmod a+r "$FLAGS_to" | |
| 89 fi | |
| 90 } | |
| 91 | |
| 92 # Converts HWID from $1 to proper format with "DEV" extension | |
| 93 echo_dev_hwid() { | |
| 94 local hwid="$1" | |
| 95 local hwid_no_dev="${hwid% DEV}" | |
| 96 | |
| 97 # NOTE: Some DEV firmware image files may put GUID in HWID. | |
| 98 # These are not officially supported and they will see "{GUID} DEV". | |
| 99 | |
| 100 if [ "$hwid" != "$hwid_no_dev" ]; then | |
| 101 hwid="$hwid_no_dev" | |
| 102 fi | |
| 103 local hwid_dev="$hwid DEV" | |
| 104 debug_msg "echo_dev_hwid: [$1] -> [$hwid_dev]" | |
| 105 echo "$hwid_dev" | |
| 106 } | |
| 107 | |
| 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 | |
| 124 # ---------------------------------------------------------------------------- | |
| 125 main() { | |
| 126 # Check parameters | |
| 127 local root_pubkey="$FLAGS_keys/root_key.vbpubk" | |
| 128 local recovery_pubkey="$FLAGS_keys/recovery_key.vbpubk" | |
| 129 local firmware_keyblock="$FLAGS_keys/firmware.keyblock" | |
| 130 local firmware_prvkey="$FLAGS_keys/firmware_data_key.vbprivk" | |
| 131 local kernel_sub_pubkey="$FLAGS_keys/kernel_subkey.vbpubk" | |
| 132 local new_bmpfv="$FLAGS_bmpfv" | |
| 133 local is_from_live=0 | |
| 134 local backup_image= | |
| 135 | |
| 136 debug_msg "Pre-requisition check" | |
| 137 check_exist_or_die \ | |
| 138 "$root_pubkey" \ | |
| 139 "$recovery_pubkey" \ | |
| 140 "$firmware_keyblock" \ | |
| 141 "$firmware_prvkey" \ | |
| 142 "$kernel_sub_pubkey" \ | |
| 143 "$new_bmpfv" | |
| 144 | |
| 145 if [ -z "$FLAGS_from" ]; then | |
| 146 is_from_live=1 | |
| 147 else | |
| 148 check_exist_or_die "$FLAGS_from" | |
| 149 fi | |
| 150 | |
| 151 # TODO(hungte) check if GPIO.3 (WP) is enabled | |
| 152 | |
| 153 debug_msg "Pulling image to $IMAGE" | |
| 154 (read_image && [ -s "$IMAGE" ]) || | |
| 155 err_die "Failed to read image. Error message: $(cat "$EXEC_LOG")" | |
| 156 | |
| 157 debug_msg "Prepare to backup the file" | |
| 158 if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then | |
| 159 backup_image=$(make_temp_file) | |
| 160 debug_msg "Creating backup file to $backup_image..." | |
| 161 cp -f "$IMAGE" "$backup_image" | |
| 162 fi | |
| 163 | |
| 164 # 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. | |
|
gauravsh
2010/10/14 19:21:07
s/they/the/
Hung-Te
2010/10/14 23:52:35
oops, I'll fix that later
| |
| 166 | |
| 167 echo "Preparing new firmware image..." | |
| 168 | |
| 169 debug_msg "Extract current HWID and rootkey" | |
| 170 local old_hwid | |
| 171 old_hwid=$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" | | |
| 172 grep '^hardware_id:' | | |
| 173 sed 's/^hardware_id: //') | |
| 174 | |
| 175 debug_msg "Decide new HWID" | |
| 176 if [ -z "$old_hwid" ]; then | |
| 177 err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))" | |
| 178 fi | |
| 179 local new_hwid=$(echo_dev_hwid "$old_hwid") | |
| 180 | |
| 181 debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)" | |
| 182 gbb_utility --set \ | |
| 183 --hwid="$new_hwid" \ | |
| 184 --bmpfv="$new_bmpfv" \ | |
| 185 --rootkey="$root_pubkey" \ | |
| 186 --recoverykey="$recovery_pubkey" \ | |
| 187 "$IMAGE" >"$EXEC_LOG" 2>&1 || | |
| 188 err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))" | |
| 189 | |
| 190 debug_msg "Resign the firmware code (A/B) with new keys" | |
| 191 local unsigned_image=$(make_temp_file) | |
| 192 cp -f "$IMAGE" "$unsigned_image" | |
| 193 "$SCRIPT_BASE/resign_firmwarefd.sh" \ | |
| 194 "$unsigned_image" \ | |
| 195 "$IMAGE" \ | |
| 196 "$firmware_prvkey" \ | |
| 197 "$firmware_keyblock" \ | |
| 198 "$kernel_sub_pubkey" >"$EXEC_LOG" 2>&1 || | |
| 199 err_die "Failed to re-sign firmware. (message: $(cat "$EXEC_LOG"))" | |
| 200 | |
| 201 # TODO(hungte) compare if the image really needs to be changed. | |
| 202 | |
| 203 debug_msg "Backup files when reading from system live image." | |
|
gauravsh
2010/10/14 19:21:07
this should be output only if the next if-conditio
Hung-Te
2010/10/14 23:52:35
This message only appears in debug mode, and for r
| |
| 204 if [ -n "$backup_image" ]; then | |
| 205 local backup_hwid_name=$(echo "$old_hwid" | sed 's/ /_/g') | |
| 206 local backup_date_time=$(date +'%Y%m%d_%H%M%S') | |
| 207 local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd" | |
| 208 local backup_file_path="$FLAGS_backup_dir/$backup_file_name" | |
| 209 if mkdir -p "$FLAGS_backup_dir" && | |
| 210 cp -f "$backup_image" "$backup_file_path"; then | |
| 211 echo "Backup of current firmware image is stored in: $backup_file_path" | |
| 212 else | |
| 213 echo "Cannot create file in $FLAGS_backup_dir... Ignore backups." | |
| 214 fi | |
| 215 fi | |
| 216 | |
| 217 # TODO(hungte) use vbutil_firmware to check if the new firmware is valid. | |
| 218 | |
| 219 debug_msg "Write the image" | |
| 220 write_image || | |
| 221 err_die "Failed to write image. Error message: $(cat "$EXEC_LOG")" | |
| 222 | |
| 223 debug_msg "Complete." | |
| 224 if [ -z "$FLAGS_to" ]; then | |
| 225 echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid" | |
| 226 else | |
| 227 echo "Firmware image '$FLAGS_to' now uses Developer Keys. HWID: $new_hwid" | |
|
gauravsh
2010/10/14 19:21:07
"New HWID"?
Hung-Te
2010/10/14 23:52:35
Yes, but that would exceed column 80, and it seems
| |
| 228 fi | |
| 229 } | |
| 230 | |
| 231 main | |
| OLD | NEW |