1#!/bin/bash 2# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 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 14# Abort on error. 15set -e 16 17usage() { 18 cat<<EOF 19Usage: $0 <input_firmware> <key_dir> <output_firmware> [firmware_version] \ 20[loem_output_dir] 21 22Signs <input_firmware> with keys in <key_dir>, setting firmware version 23to <firmware_version>. Outputs signed firmware to <output_firmware>. 24If no firmware version is specified, it is set as 1. 25EOF 26 exit 1 27} 28 29gbb_update() { 30 local in_firmware="$1" 31 local key_dir="$2" 32 local out_firmware="$3" 33 local rootkey="$4" 34 35 # Replace the root and recovery key in the Google Binary Block of the 36 # firmware. Note: This needs to happen after calling resign_firmwarefd.sh 37 # since it needs to be able to verify the firmware using the root key to 38 # determine the preamble flags. 39 gbb_utility \ 40 -s \ 41 --recoverykey="${key_dir}/recovery_key.vbpubk" \ 42 --rootkey="${rootkey}" \ 43 "${in_firmware}" \ 44 "${out_firmware}" 45} 46 47# Sign a single firmware image. 48# ARGS: [loem_key] [loemid] 49sign_one() { 50 local loem_key="$1" 51 local loemid="$2" 52 53 # Resign the firmware with new keys. 54 "${SCRIPT_DIR}/resign_firmwarefd.sh" \ 55 "${in_firmware}" \ 56 "${temp_fw}" \ 57 "${key_dir}/firmware_data_key${loem_key}.vbprivk" \ 58 "${key_dir}/firmware${loem_key}.keyblock" \ 59 "${key_dir}/dev_firmware_data_key${loem_key}.vbprivk" \ 60 "${key_dir}/dev_firmware${loem_key}.keyblock" \ 61 "${key_dir}/kernel_subkey.vbpubk" \ 62 "${firmware_version}" \ 63 "" \ 64 "${loem_output_dir}" \ 65 "${loemid}" 66} 67 68# Process all the keysets in the loem.ini file. 69sign_loems() { 70 local line loem_section=false loem_index loemid 71 local rootkey 72 73 rm -f "${out_firmware}" 74 while read line; do 75 # Find the [loem] section. 76 if ! ${loem_section}; then 77 if grep -q "^ *\[loem\] *$" <<<"${line}"; then 78 loem_section=true 79 fi 80 continue 81 # Abort when we hit the next section. 82 elif [[ ${line} == *"["* ]]; then 83 break 84 fi 85 86 # Strip comments/whitespace. 87 line=$(sed -e 's:#.*::' -e 's:^ *::' -e 's: *$::' <<<"${line}") 88 loem_index=$(cut -d= -f1 <<<"${line}" | sed 's: *$::') 89 loemid=$(cut -d= -f2 <<<"${line}" | sed 's:^ *::') 90 91 echo "### Processing LOEM ${loem_index} ${loemid}" 92 sign_one ".loem${loem_index}" "${loemid}" 93 94 rootkey="${key_dir}/root_key.loem${loem_index}.vbpubk" 95 cp "${rootkey}" "${loem_output_dir}/rootkey.${loemid}" 96 97 if [[ ! -e ${out_firmware} ]]; then 98 gbb_update "${temp_fw}" "${key_dir}" "${out_firmware}" "${rootkey}" 99 fi 100 echo 101 done <"${key_dir}/loem.ini" 102} 103 104main() { 105 if [[ $# -lt 3 || $# -gt 5 ]]; then 106 usage 107 fi 108 109 local in_firmware=$1 110 local key_dir=$2 111 local out_firmware=$3 112 local firmware_version=${4:-1} 113 local loem_output_dir=${5:-} 114 115 local temp_fw=$(make_temp_file) 116 117 if [[ -e ${key_dir}/loem.ini ]]; then 118 if [[ -z ${loem_output_dir} ]]; then 119 err_die "need loem_output_dir w/loem keysets" 120 fi 121 sign_loems 122 else 123 sign_one 124 gbb_update "${temp_fw}" "${key_dir}" "${out_firmware}" \ 125 "${key_dir}/root_key.vbpubk" 126 fi 127} 128main "$@" 129