Home | History | Annotate | Download | only in image_signing
      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.
      9 SCRIPT_DIR=$(dirname "$0")
     10 
     11 # Load common constants and variables.
     12 . "${SCRIPT_DIR}/common_minimal.sh"
     13 
     14 # Abort on error.
     15 set -e
     16 
     17 usage() {
     18   cat<<EOF
     19 Usage: $0 <input_firmware> <key_dir> <output_firmware> [firmware_version] \
     20 [loem_output_dir]
     21 
     22 Signs <input_firmware> with keys in <key_dir>, setting firmware version
     23 to <firmware_version>. Outputs signed firmware to <output_firmware>.
     24 If no firmware version is specified, it is set as 1.
     25 EOF
     26   exit 1
     27 }
     28 
     29 gbb_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]
     49 sign_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.
     69 sign_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 
    104 main() {
    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 }
    128 main "$@"
    129