13bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin#!/bin/sh 23bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# 3af44dce1e80ebd818770b906a328423762389753Hung-Te Lin# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 43bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Use of this source code is governed by a BSD-style license that can be 53bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# found in the LICENSE file. 63bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# 73bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# This script can change key (usually developer keys) in a firmware binary 8af44dce1e80ebd818770b906a328423762389753Hung-Te Lin# image or system live firmware (EEPROM), and assign proper HWID, FLAGS as well. 93bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 103bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinSCRIPT_BASE="$(dirname "$0")" 11605500b88cd99097d482ddcefee4ba04898781aeGaurav Shah. "$SCRIPT_BASE/common_minimal.sh" 1220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Linload_shflags || exit 1 133bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 143bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Constants used by DEFINE_* 1520525b91644a786e966c9486ac9afdf3d7c5447fHung-Te LinVBOOT_BASE='/usr/share/vboot' 1620525b91644a786e966c9486ac9afdf3d7c5447fHung-Te LinDEFAULT_KEYS_FOLDER="$VBOOT_BASE/devkeys" 173bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinDEFAULT_BACKUP_FOLDER='/mnt/stateful_partition/backups' 183bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 193bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# DEFINE_string name default_value description flag 203bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinDEFINE_string from "" "Path of input file (empty for system live firmware)" "f" 213bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinDEFINE_string to "" "Path of output file (empty for system live firmware)" "t" 2220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te LinDEFINE_string keys "$DEFAULT_KEYS_FOLDER" "Path to folder of dev keys" "k" 23af44dce1e80ebd818770b906a328423762389753Hung-Te LinDEFINE_string preamble_flags "" "Override preamble flags value. Known values: 24af44dce1e80ebd818770b906a328423762389753Hung-Te Lin 0: None. (Using RW to boot in normal. aka, two-stop) 25af44dce1e80ebd818770b906a328423762389753Hung-Te Lin 1: VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL (one-stop)" "p" 26af44dce1e80ebd818770b906a328423762389753Hung-Te LinDEFINE_boolean mod_gbb_flags \ 27af44dce1e80ebd818770b906a328423762389753Hung-Te Lin $FLAGS_TRUE "Modify GBB flags to enable developer friendly features" "" 283bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinDEFINE_boolean force_backup \ 293bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin $FLAGS_TRUE "Create backup even if source is not live" "" 303bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinDEFINE_string backup_dir \ 313bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$DEFAULT_BACKUP_FOLDER" "Path of directory to store firmware backups" "" 323bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 333bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Parse command line 343bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te LinFLAGS "$@" || exit 1 353bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lineval set -- "$FLAGS_ARGV" 363bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 373bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Globals 383bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# ---------------------------------------------------------------------------- 393bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linset -e 403bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 413bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# the image we are (temporary) working with 4220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te LinIMAGE="$(make_temp_file)" 43010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te LinIMAGE="$(readlink -f "$IMAGE")" 443bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 453bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# a log file to keep the output results of executed command 4620525b91644a786e966c9486ac9afdf3d7c5447fHung-Te LinEXEC_LOG="$(make_temp_file)" 473bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 483bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Functions 493bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# ---------------------------------------------------------------------------- 503bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 5138d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin# Disables write protection status registers 5238d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lindisable_write_protection() { 5338d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin # No need to change WP status in file mode 5438d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin if [ -n "$FLAGS_to" ]; then 5538d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin return $FLAGS_TRUE 5638d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin fi 5738d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin 5838d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin # --wp-disable command may return success even if WP is still enabled, 5938d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin # so we should use --wp-status to verify the results. 6038d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin echo "Disabling system software write protection status..." 6138d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin (flashrom --wp-disable && flashrom --wp-status) 2>&1 | 6238d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin tee "$EXEC_LOG" | 6338d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin grep -q '^WP: .* is disabled\.$' 6438d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin} 6538d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin 663bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Reads $IMAGE from $FLAGS_from 673bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linread_image() { 683bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -z "$FLAGS_from" ]; then 693bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin echo "Reading system live firmware..." 703bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if is_debug_mode; then 713bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin flashrom -V -r "$IMAGE" 723bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 733bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin flashrom -r "$IMAGE" >"$EXEC_LOG" 2>&1 743bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 753bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 763bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "reading from file: $FLAGS_from" 773bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin cp -f "$FLAGS_from" "$IMAGE" 783bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 793bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin} 803bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 813bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Writes $IMAGE to $FLAGS_to 823bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linwrite_image() { 833bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -z "$FLAGS_to" ]; then 843bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin echo "Writing system live firmware..." 8520525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin # TODO(hungte) we can enable partial write to make this faster 863bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if is_debug_mode; then 873bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin flashrom -V -w "$IMAGE" 883bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 893bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin flashrom -w "$IMAGE" >"$EXEC_LOG" 2>&1 903bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 913bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 923bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "writing to file: $FLAGS_to" 933bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin cp -f "$IMAGE" "$FLAGS_to" 943bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin chmod a+r "$FLAGS_to" 953bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 963bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin} 973bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 983bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Converts HWID from $1 to proper format with "DEV" extension 993bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linecho_dev_hwid() { 1003bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local hwid="$1" 1013bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local hwid_no_dev="${hwid% DEV}" 1023bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1033bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # NOTE: Some DEV firmware image files may put GUID in HWID. 1043bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # These are not officially supported and they will see "{GUID} DEV". 1053bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1063bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ "$hwid" != "$hwid_no_dev" ]; then 1073bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin hwid="$hwid_no_dev" 1083bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 1093bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local hwid_dev="$hwid DEV" 1103bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "echo_dev_hwid: [$1] -> [$hwid_dev]" 1113bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin echo "$hwid_dev" 1123bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin} 1133bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1143bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# Main 1153bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin# ---------------------------------------------------------------------------- 1163bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linmain() { 1173bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # Check parameters 1183bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local root_pubkey="$FLAGS_keys/root_key.vbpubk" 1193bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local recovery_pubkey="$FLAGS_keys/recovery_key.vbpubk" 1203bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local firmware_keyblock="$FLAGS_keys/firmware.keyblock" 1213bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local firmware_prvkey="$FLAGS_keys/firmware_data_key.vbprivk" 1222c7213d4dc5cef71b5cf76c44a12ff14e15dfeb4Hung-Te Lin local dev_firmware_keyblock="$FLAGS_keys/dev_firmware.keyblock" 1232c7213d4dc5cef71b5cf76c44a12ff14e15dfeb4Hung-Te Lin local dev_firmware_prvkey="$FLAGS_keys/dev_firmware_data_key.vbprivk" 1243bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local kernel_sub_pubkey="$FLAGS_keys/kernel_subkey.vbpubk" 1253bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local is_from_live=0 1263bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local backup_image= 1273bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 12820525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin debug_msg "Prerequisite check" 12920525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin ensure_files_exist \ 1303bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$root_pubkey" \ 1313bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$recovery_pubkey" \ 1323bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$firmware_keyblock" \ 1333bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$firmware_prvkey" \ 134f82f4ae92048f0af8ec4e1934fe58f438301c4e9Hung-Te Lin "$kernel_sub_pubkey" || 13520525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin exit 1 1363bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1373bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -z "$FLAGS_from" ]; then 1383bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin is_from_live=1 1393bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 140f82f4ae92048f0af8ec4e1934fe58f438301c4e9Hung-Te Lin ensure_files_exist "$FLAGS_from" || exit 1 1413bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 1423bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 14338d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin debug_msg "Checking software write protection status" 14438d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin disable_write_protection || 14538d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin if is_debug_mode; then 14638d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin err_die "Failed to disable WP. Diagnose Message: $(cat "$EXEC_LOG")" 14738d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin else 14838d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin err_die "Write protection is still enabled. " \ 14938d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin "Please verify that hardware write protection is disabled." 15038d3ef763179db8e00eb09131e6521e9d6be14c0Hung-Te Lin fi 1513bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1523bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Pulling image to $IMAGE" 1533bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin (read_image && [ -s "$IMAGE" ]) || 1543bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin err_die "Failed to read image. Error message: $(cat "$EXEC_LOG")" 1553bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1563bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Prepare to backup the file" 1573bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -n "$is_from_live" -o $FLAGS_force_backup = $FLAGS_TRUE ]; then 15820525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin backup_image="$(make_temp_file)" 1593bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Creating backup file to $backup_image..." 1603bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin cp -f "$IMAGE" "$backup_image" 1613bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 1623bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 163010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin debug_msg "Detecting developer firmware keyblock" 164010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin local expanded_firmware_dir="$(make_temp_dir)" 165010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin local use_devfw_keyblock="$FLAGS_FALSE" 166010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin (cd "$expanded_firmware_dir"; dump_fmap -x "$IMAGE" >/dev/null 2>&1) || 167010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin err_die "Failed to extract firmware image." 168010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin if [ -f "$expanded_firmware_dir/VBLOCK_A" ]; then 169010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin local has_dev=$FLAGS_TRUE has_norm=$FLAGS_TRUE 170010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin # In output of vbutil_keyblock, "!DEV" means "bootable on normal mode" and 171010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin # "DEV" means "bootable on developer mode". Here we try to match the pattern 172010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin # in output of vbutil_block, and disable the flags (has_dev, has_norm) if 173010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin # the pattern was not found. 174010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin vbutil_keyblock --unpack "$expanded_firmware_dir/VBLOCK_A" | 175010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin grep -qw '!DEV' || has_norm=$FLAGS_FALSE 176010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin vbutil_keyblock --unpack "$expanded_firmware_dir/VBLOCK_A" | 177010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin grep -qw '[^!]DEV' || has_dev=$FLAGS_FALSE 178010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin if [ "$has_norm" = "$FLAGS_FALSE" -a "$has_dev" = "$FLAGS_TRUE" ]; then 179010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin use_devfw_keyblock=$FLAGS_TRUE 180010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin fi 181010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin fi 182010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin 183010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin if [ "$use_devfw_keyblock" = "$FLAGS_TRUE" ]; then 184010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin echo "Using keyblocks (developer, normal)..." 185010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin else 186010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin echo "Using keyblocks (normal, normal)..." 187010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin dev_firmware_prvkey="$firmware_prvkey" 188010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin dev_firmware_keyblock="$firmware_keyblock" 189010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin fi 190010630f18c8880b80e564fc6a0bcf8e5eb7f9de6Hung-Te Lin 1913bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # TODO(hungte) We can use vbutil_firmware to check if the current firmware is 19220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin # valid so that we know keys and vbutil_firmware are all working fine. 1933bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 1943bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin echo "Preparing new firmware image..." 1959fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin 1969fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin debug_msg "Resign the firmware code (A/B) with new keys" 1979fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin # Note resign_firmwarefd.sh needs the original rootkey to determine firmware 1989fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin # body size, so we must resign image before changing GBB rootkey. 1999fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin 2009fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin local unsigned_image="$(make_temp_file)" 2019fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin local optional_opts="" 2029fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin if [ -n "$FLAGS_preamble_flags" ]; then 2039fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin # optional_opts: VERSION FLAGS 2049fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin debug_msg "Setting new VERSION=1, FLAGS=$FLAGS_preamble_flags" 2059fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin optional_opts="1 $FLAGS_preamble_flags" 2069fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin fi 2079fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin cp -f "$IMAGE" "$unsigned_image" 2089fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$SCRIPT_BASE/resign_firmwarefd.sh" \ 2099fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$unsigned_image" \ 2109fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$IMAGE" \ 2119fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$firmware_prvkey" \ 2129fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$firmware_keyblock" \ 2139fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$dev_firmware_prvkey" \ 2149fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$dev_firmware_keyblock" \ 2159fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin "$kernel_sub_pubkey" \ 2169fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin $optional_opts >"$EXEC_LOG" 2>&1 || 2179fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin err_die "Failed to re-sign firmware. (message: $(cat "$EXEC_LOG"))" 2189fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin if is_debug_mode; then 2199fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin cat "$EXEC_LOG" 2209fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin fi 2219fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin 2229fc41a02f5106a318c2e0d02be39b51e45337e77Hung-Te Lin debug_msg "Extract current HWID" 2233bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local old_hwid 22420525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin old_hwid="$(gbb_utility --get --hwid "$IMAGE" 2>"$EXEC_LOG" | 225af44dce1e80ebd818770b906a328423762389753Hung-Te Lin sed -rne 's/^hardware_id: (.*)$/\1/p')" 2263bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 2273bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Decide new HWID" 228af44dce1e80ebd818770b906a328423762389753Hung-Te Lin [ -z "$old_hwid" ] && 2293bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin err_die "Cannot find current HWID. (message: $(cat "$EXEC_LOG"))" 23020525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin local new_hwid="$(echo_dev_hwid "$old_hwid")" 2313bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 232af44dce1e80ebd818770b906a328423762389753Hung-Te Lin local old_gbb_flags 233af44dce1e80ebd818770b906a328423762389753Hung-Te Lin old_gbb_flags="$(gbb_utility --get --flags "$IMAGE" 2>"$EXEC_LOG" | 234af44dce1e80ebd818770b906a328423762389753Hung-Te Lin sed -rne 's/^flags: (.*)$/\1/p')" 235af44dce1e80ebd818770b906a328423762389753Hung-Te Lin debug_msg "Decide new GBB flags from: $old_gbb_flags" 236af44dce1e80ebd818770b906a328423762389753Hung-Te Lin [ -z "$old_gbb_flags" ] && 237af44dce1e80ebd818770b906a328423762389753Hung-Te Lin err_die "Cannot find GBB flags. (message: $(cat "$EXEC_LOG"))" 238af44dce1e80ebd818770b906a328423762389753Hung-Te Lin # 0x30: GBB_FLAG_FORCE_DEV_BOOT_USB | GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK 239af44dce1e80ebd818770b906a328423762389753Hung-Te Lin local new_gbb_flags="$((old_gbb_flags | 0x30))" 240af44dce1e80ebd818770b906a328423762389753Hung-Te Lin 2413bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Replace GBB parts (gbb_utility allows changing on-the-fly)" 2423bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin gbb_utility --set \ 2433bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin --hwid="$new_hwid" \ 2443bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin --rootkey="$root_pubkey" \ 2453bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin --recoverykey="$recovery_pubkey" \ 2463bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin "$IMAGE" >"$EXEC_LOG" 2>&1 || 2473bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin err_die "Failed to change GBB Data. (message: $(cat "$EXEC_LOG"))" 2483bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 249af44dce1e80ebd818770b906a328423762389753Hung-Te Lin # Old firmware does not support GBB flags, so let's make it an exception. 250af44dce1e80ebd818770b906a328423762389753Hung-Te Lin if [ "$FLAGS_mod_gbb_flags" = "$FLAGS_TRUE" ]; then 251af44dce1e80ebd818770b906a328423762389753Hung-Te Lin debug_msg "Changing GBB flags from $old_gbb_flags to $new_gbb_flags" 252af44dce1e80ebd818770b906a328423762389753Hung-Te Lin gbb_utility --set \ 253af44dce1e80ebd818770b906a328423762389753Hung-Te Lin --flags="$new_gbb_flags" \ 254af44dce1e80ebd818770b906a328423762389753Hung-Te Lin "$IMAGE" >"$EXEC_LOG" 2>&1 || 255af44dce1e80ebd818770b906a328423762389753Hung-Te Lin echo "Warning: GBB flags ($old_gbb_flags -> $new_gbb_flags) can't be set." 256af44dce1e80ebd818770b906a328423762389753Hung-Te Lin fi 257af44dce1e80ebd818770b906a328423762389753Hung-Te Lin 2583bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # TODO(hungte) compare if the image really needs to be changed. 2593bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 26020525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin debug_msg "Check if we need to make backup file(s)" 2613bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -n "$backup_image" ]; then 26220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin local backup_hwid_name="$(echo "$old_hwid" | sed 's/ /_/g')" 26320525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin local backup_date_time="$(date +'%Y%m%d_%H%M%S')" 2643bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local backup_file_name="firmware_${backup_hwid_name}_${backup_date_time}.fd" 2653bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin local backup_file_path="$FLAGS_backup_dir/$backup_file_name" 2663bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if mkdir -p "$FLAGS_backup_dir" && 2673bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin cp -f "$backup_image" "$backup_file_path"; then 268eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin true 269eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin elif cp -f "$backup_image" "/tmp/$backup_file_name"; then 270eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin backup_file_path="/tmp/$backup_file_name" 271eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin else 272eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin backup_file_path='' 273eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin fi 274eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin if [ -n "$backup_file_path" -a -s "$backup_file_path" ]; then 275eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin # TODO(hungte) maybe we can wrap the flashrom by 'make_dev_firmware.sh -r' 276eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin # so that the only command to remember would be make_dev_firmware.sh. 277eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin echo " 278eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin Backup of current firmware image is stored in: 279eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin $backup_file_path 280eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin Please copy the backup file to a safe place ASAP. 281eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin 282eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin To stop using devkeys and restore original firmware, execute command: 283eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin flashrom -w [PATH_TO_BACKUP_IMAGE] 284eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin Ex: flashrom -w $backup_file_path 285eb868eeb1d2eb15d99eaa0625521c418472e8baaHung-Te Lin " 2863bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 28720525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin echo "WARNING: Cannot create file in $FLAGS_backup_dir... Ignore backups." 2883bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 2893bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 2903bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 2913bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin # TODO(hungte) use vbutil_firmware to check if the new firmware is valid. 29220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin # Or, do verification in resign_firmwarefd.sh and trust it. 2933bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 2943bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Write the image" 2953bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin write_image || 2963bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin err_die "Failed to write image. Error message: $(cat "$EXEC_LOG")" 2973bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 2983bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin debug_msg "Complete." 2993bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin if [ -z "$FLAGS_to" ]; then 3003bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin echo "Successfully changed firmware to Developer Keys. New HWID: $new_hwid" 3013bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin else 30220525b91644a786e966c9486ac9afdf3d7c5447fHung-Te Lin echo "Firmware '$FLAGS_to' now uses Developer Keys. New HWID: $new_hwid" 3033bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin fi 3043bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin} 3053bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Lin 3063bdfc4601ebc2f637c7afb629ec6ce5a929f9e67Hung-Te Linmain 307