1#!/bin/bash 2# Copyright 2011 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6# Wrapper script for re-signing a firmware image. 7 8# Determine script directory. 9SCRIPT_DIR=$(dirname "$0") 10 11# Load common constants and variables. 12. "${SCRIPT_DIR}/common_minimal.sh" 13. "${SCRIPT_DIR}/lib/keycfg.sh" 14 15# Abort on error. 16set -e 17 18usage() { 19 cat<<EOF 20Usage: $0 <input_firmware> <key_dir> <output_firmware> [firmware_version] \ 21[loem_output_dir] 22 23Signs <input_firmware> with keys in <key_dir>, setting firmware version 24to <firmware_version>. Outputs signed firmware to <output_firmware>. 25The <input_firmware> and <output_firmware> paths may be the same. 26If no firmware version is specified, it is set as 1. 27EOF 28 exit 1 29} 30 31gbb_update() { 32 local in_firmware="$1" 33 local key_dir="$2" 34 local out_firmware="$3" 35 local rootkey="$4" 36 37 # Replace the root and recovery key in the Google Binary Block of the 38 # firmware. Note: This needs to happen after calling resign_firmwarefd.sh 39 # since it needs to be able to verify the firmware using the root key to 40 # determine the preamble flags. 41 futility gbb \ 42 -s \ 43 --recoverykey="${KEYCFG_RECOVERY_KEY_VBPUBK}" \ 44 --rootkey="${rootkey}" \ 45 "${in_firmware}" \ 46 "${out_firmware}" 47} 48 49# Sign a single firmware image. 50# ARGS: [key_dir] [loem_index] [loemid] 51sign_one() { 52 local key_dir="$1" 53 local loem_index="$2" 54 local loemid="$3" 55 56 # Resign the firmware with new keys. 57 "${SCRIPT_DIR}/resign_firmwarefd.sh" \ 58 "${in_firmware}" \ 59 "${temp_fw}" \ 60 "$(get_firmware_vbprivk "${loem_index}")" \ 61 "$(get_firmware_keyblock "${loem_index}")" \ 62 "${KEYCFG_KERNEL_SUBKEY_VBPUBK}" \ 63 "${firmware_version}" \ 64 "" \ 65 "${loem_output_dir}" \ 66 "${loemid}" 67} 68 69# Process all the keysets in the loem.ini file. 70# ARGS: [key_dir] 71sign_loems() { 72 local key_dir="$1" 73 local line loem_section=false loem_index loemid 74 local rootkey 75 76 while read line; do 77 # Find the [loem] section. 78 if ! ${loem_section}; then 79 if grep -q "^ *\[loem\] *$" <<<"${line}"; then 80 loem_section=true 81 fi 82 continue 83 # Abort when we hit the next section. 84 elif [[ ${line} == *"["* ]]; then 85 break 86 fi 87 88 # Strip comments/whitespace. 89 line=$(sed -e 's:#.*::' -e 's:^ *::' -e 's: *$::' <<<"${line}") 90 if [[ -z "${line}" ]]; then 91 # Skip blank lines. 92 continue 93 fi 94 95 loem_index=$(cut -d= -f1 <<<"${line}" | sed 's: *$::') 96 loemid=$(cut -d= -f2 <<<"${line}" | sed 's:^ *::') 97 98 echo "### Processing LOEM ${loem_index} ${loemid}" 99 sign_one "${key_dir}" "${loem_index}" "${loemid}" 100 101 rootkey="$(get_root_key_vbpubk "${key_index}")" 102 cp "${rootkey}" "${loem_output_dir}/rootkey.${loemid}" 103 104 if [[ ${loem_index} == "1" ]]; then 105 gbb_update "${temp_fw}" "${key_dir}" "${out_firmware}" "${rootkey}" 106 fi 107 echo 108 done <"${key_dir}/loem.ini" 109} 110 111main() { 112 if [[ $# -lt 3 || $# -gt 5 ]]; then 113 usage 114 fi 115 116 local in_firmware=$1 117 local key_dir=$2 118 local out_firmware=$3 119 local firmware_version=${4:-1} 120 local loem_output_dir=${5:-} 121 122 local temp_fw=$(make_temp_file) 123 124 setup_keycfg "${key_dir}" 125 if [[ -e ${key_dir}/loem.ini ]]; then 126 if [[ -z ${loem_output_dir} ]]; then 127 die "need loem_output_dir w/loem keysets" 128 fi 129 sign_loems "${key_dir}" 130 else 131 sign_one "${key_dir}" 132 gbb_update "${temp_fw}" "${key_dir}" "${out_firmware}" \ 133 "$(get_root_key_vbpubk)" 134 fi 135} 136main "$@" 137