1*4f2df630SAndroid Build Coastguard Worker#!/bin/bash 2*4f2df630SAndroid Build Coastguard Worker# Copyright 2023 The ChromiumOS Authors 3*4f2df630SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*4f2df630SAndroid Build Coastguard Worker# found in the LICENSE file. 5*4f2df630SAndroid Build Coastguard Worker 6*4f2df630SAndroid Build Coastguard Worker# This script allows to quickly re-sign a GSC image to a different set of 7*4f2df630SAndroid Build Coastguard Worker# Device IDs. The script works with both Cr50 and Ti50, it must be run in the 8*4f2df630SAndroid Build Coastguard Worker# appropriate top level directory, and the respective GSC binary has to be 9*4f2df630SAndroid Build Coastguard Worker# present in the respective ./build directory. 10*4f2df630SAndroid Build Coastguard Worker# 11*4f2df630SAndroid Build Coastguard Worker# Two command line parameters are required, the device IDs of the GSC. 12*4f2df630SAndroid Build Coastguard Worker# 13*4f2df630SAndroid Build Coastguard Worker# The generated binary is saved in {cr,ti}50.<sha>.<devid0>.<devid1>.bin where 14*4f2df630SAndroid Build Coastguard Worker# <sha> is the git sha of the current source tree. The suffix '-dirty' is 15*4f2df630SAndroid Build Coastguard Worker# added to the <sha> component in case there are changes in any of the files 16*4f2df630SAndroid Build Coastguard Worker# under git control. 17*4f2df630SAndroid Build Coastguard Worker 18*4f2df630SAndroid Build Coastguard Workerset -ue 19*4f2df630SAndroid Build Coastguard Worker 20*4f2df630SAndroid Build Coastguard WorkerSCRIPT_NAME="$(basename "$0")" 21*4f2df630SAndroid Build Coastguard WorkerTMPD="$(mktemp -d "/tmp/${SCRIPT_NAME}.XXXXX")" 22*4f2df630SAndroid Build Coastguard WorkerNOCLEAN="${NOCLEAN:-}" 23*4f2df630SAndroid Build Coastguard Workerif [[ -z ${NOCLEAN} ]]; then 24*4f2df630SAndroid Build Coastguard Worker trap 'rm -rf "${TMPD}"' EXIT 25*4f2df630SAndroid Build Coastguard Workerfi 26*4f2df630SAndroid Build Coastguard Worker 27*4f2df630SAndroid Build Coastguard Worker# Make sure there is a codesigner in the path. 28*4f2df630SAndroid Build Coastguard WorkerCODESIGNER="" 29*4f2df630SAndroid Build Coastguard Workerfor f in cr50-codesigner \ 30*4f2df630SAndroid Build Coastguard Worker ../../cr50-utils/software/tools/codesigner/codesigner \ 31*4f2df630SAndroid Build Coastguard Worker codesigner; do 32*4f2df630SAndroid Build Coastguard Worker if command -v "${f}" > /dev/null 2>&1; then 33*4f2df630SAndroid Build Coastguard Worker CODESIGNER="${f}" 34*4f2df630SAndroid Build Coastguard Worker break 35*4f2df630SAndroid Build Coastguard Worker fi 36*4f2df630SAndroid Build Coastguard Workerdone 37*4f2df630SAndroid Build Coastguard Workerif [[ -z ${CODESIGNER} ]]; then 38*4f2df630SAndroid Build Coastguard Worker echo "SCRIPT_NAME error: can't find codesigner" >&2 39*4f2df630SAndroid Build Coastguard Worker exit 1 40*4f2df630SAndroid Build Coastguard Workerfi 41*4f2df630SAndroid Build Coastguard Worker 42*4f2df630SAndroid Build Coastguard Worker# Re-sign a single RW section. 43*4f2df630SAndroid Build Coastguard Workerre_sign_rw() { 44*4f2df630SAndroid Build Coastguard Worker local tmp_file="$1" 45*4f2df630SAndroid Build Coastguard Worker local flash_base="$2" 46*4f2df630SAndroid Build Coastguard Worker local rw_base="$3" 47*4f2df630SAndroid Build Coastguard Worker local codesigner_params 48*4f2df630SAndroid Build Coastguard Worker local rw_size 49*4f2df630SAndroid Build Coastguard Worker local rw_bin_base 50*4f2df630SAndroid Build Coastguard Worker local rw_bin_size 51*4f2df630SAndroid Build Coastguard Worker local skip 52*4f2df630SAndroid Build Coastguard Worker 53*4f2df630SAndroid Build Coastguard Worker codesigner_params=() 54*4f2df630SAndroid Build Coastguard Worker 55*4f2df630SAndroid Build Coastguard Worker # Retrieve the rest of the codesigner command line arguments, which are this 56*4f2df630SAndroid Build Coastguard Worker # function's arguments after the three fixed ones. 57*4f2df630SAndroid Build Coastguard Worker shift 3 58*4f2df630SAndroid Build Coastguard Worker while [[ $# != 0 ]]; do 59*4f2df630SAndroid Build Coastguard Worker codesigner_params+=( "$1" ) 60*4f2df630SAndroid Build Coastguard Worker shift 61*4f2df630SAndroid Build Coastguard Worker done 62*4f2df630SAndroid Build Coastguard Worker 63*4f2df630SAndroid Build Coastguard Worker # Determine RW size. It is 4 bytes at offset 808 into the signed header. 64*4f2df630SAndroid Build Coastguard Worker skip=$(( rw_base + 808 )) 65*4f2df630SAndroid Build Coastguard Worker rw_size="$(hexdump -s "${skip}" -n4 -e '1/4 "%d"' "${tmp_file}")" 66*4f2df630SAndroid Build Coastguard Worker 67*4f2df630SAndroid Build Coastguard Worker # Extract the RW section to re-sign, dropping the existing header. 68*4f2df630SAndroid Build Coastguard Worker rw_bin_base=$(( rw_base + 1024 )) 69*4f2df630SAndroid Build Coastguard Worker rw_bin_size=$(( rw_size - 1024 )) 70*4f2df630SAndroid Build Coastguard Worker dd if="${full_bin}" of="${TMPD}/rw.bin" skip="${rw_bin_base}" bs=1 \ 71*4f2df630SAndroid Build Coastguard Worker count="${rw_bin_size}" status="none" 72*4f2df630SAndroid Build Coastguard Worker 73*4f2df630SAndroid Build Coastguard Worker # Convert it to hex for signing 74*4f2df630SAndroid Build Coastguard Worker objcopy -I binary -O ihex --change-addresses $(( rw_bin_base + flash_base )) \ 75*4f2df630SAndroid Build Coastguard Worker "${TMPD}/rw.bin" "${TMPD}/rw.hex" 76*4f2df630SAndroid Build Coastguard Worker 77*4f2df630SAndroid Build Coastguard Worker # Sign. 78*4f2df630SAndroid Build Coastguard Worker "${CODESIGNER}" "${codesigner_params[@]}" --input="${TMPD}/rw.hex" \ 79*4f2df630SAndroid Build Coastguard Worker --output="${TMPD}/rw.signed" 80*4f2df630SAndroid Build Coastguard Worker 81*4f2df630SAndroid Build Coastguard Worker # Paste the result back into the original binary. 82*4f2df630SAndroid Build Coastguard Worker dd if="${TMPD}/rw.signed" of="${tmp_file}" seek="${rw_base}" conv="notrunc" \ 83*4f2df630SAndroid Build Coastguard Worker status="none" bs=1 84*4f2df630SAndroid Build Coastguard Worker} 85*4f2df630SAndroid Build Coastguard Worker 86*4f2df630SAndroid Build Coastguard Workermain () { 87*4f2df630SAndroid Build Coastguard Worker local bin_size 88*4f2df630SAndroid Build Coastguard Worker local dev_id0 89*4f2df630SAndroid Build Coastguard Worker local dev_id1 90*4f2df630SAndroid Build Coastguard Worker local flash_base 91*4f2df630SAndroid Build Coastguard Worker local full_bin 92*4f2df630SAndroid Build Coastguard Worker local manifest 93*4f2df630SAndroid Build Coastguard Worker local output 94*4f2df630SAndroid Build Coastguard Worker local prefix 95*4f2df630SAndroid Build Coastguard Worker local rw_a_base 96*4f2df630SAndroid Build Coastguard Worker local rw_b_base 97*4f2df630SAndroid Build Coastguard Worker local rw_key 98*4f2df630SAndroid Build Coastguard Worker local sha 99*4f2df630SAndroid Build Coastguard Worker local tmp_file 100*4f2df630SAndroid Build Coastguard Worker local xml 101*4f2df630SAndroid Build Coastguard Worker 102*4f2df630SAndroid Build Coastguard Worker if [[ $# -ne 2 ]]; then 103*4f2df630SAndroid Build Coastguard Worker echo "${SCRIPT_NAME} error:" >&2 104*4f2df630SAndroid Build Coastguard Worker echo " Two command line arguments are required, dev_id0 and dev_id1" >&2 105*4f2df630SAndroid Build Coastguard Worker exit 1 106*4f2df630SAndroid Build Coastguard Worker fi 107*4f2df630SAndroid Build Coastguard Worker 108*4f2df630SAndroid Build Coastguard Worker dev_id0="$1" 109*4f2df630SAndroid Build Coastguard Worker dev_id1="$2" 110*4f2df630SAndroid Build Coastguard Worker 111*4f2df630SAndroid Build Coastguard Worker full_bin="" 112*4f2df630SAndroid Build Coastguard Worker for f in build/ti50/dauntless/dauntless/full_image.signed.bin \ 113*4f2df630SAndroid Build Coastguard Worker build/cr50/ec.bin; do 114*4f2df630SAndroid Build Coastguard Worker if [[ -f ${f} ]]; then 115*4f2df630SAndroid Build Coastguard Worker full_bin="${f}" 116*4f2df630SAndroid Build Coastguard Worker break 117*4f2df630SAndroid Build Coastguard Worker fi 118*4f2df630SAndroid Build Coastguard Worker done 119*4f2df630SAndroid Build Coastguard Worker 120*4f2df630SAndroid Build Coastguard Worker if [[ -z ${full_bin} ]]; then 121*4f2df630SAndroid Build Coastguard Worker echo "${SCRIPT_NAME} error: GSC binary not found" >&2 122*4f2df630SAndroid Build Coastguard Worker exit 1 123*4f2df630SAndroid Build Coastguard Worker fi 124*4f2df630SAndroid Build Coastguard Worker 125*4f2df630SAndroid Build Coastguard Worker codesigner_params=( 126*4f2df630SAndroid Build Coastguard Worker --dev_id0="${dev_id0}" 127*4f2df630SAndroid Build Coastguard Worker --dev_id1="${dev_id1}" 128*4f2df630SAndroid Build Coastguard Worker --format=bin 129*4f2df630SAndroid Build Coastguard Worker --ihex 130*4f2df630SAndroid Build Coastguard Worker --no-icache 131*4f2df630SAndroid Build Coastguard Worker --override-keyid 132*4f2df630SAndroid Build Coastguard Worker --padbank 133*4f2df630SAndroid Build Coastguard Worker ) 134*4f2df630SAndroid Build Coastguard Worker 135*4f2df630SAndroid Build Coastguard Worker bin_size="$(stat -c '%s' "${full_bin}")" 136*4f2df630SAndroid Build Coastguard Worker case "${bin_size}" in 137*4f2df630SAndroid Build Coastguard Worker (524288) rw_a_base=16384 # RO area size is fixed at 16K 138*4f2df630SAndroid Build Coastguard Worker rw_b_base=$(( bin_size / 2 + rw_a_base )) 139*4f2df630SAndroid Build Coastguard Worker rw_key="util/signer/cr50_rom0-dev-blsign.pem.pub" 140*4f2df630SAndroid Build Coastguard Worker manifest="util/signer/ec_RW-manifest-dev.json" 141*4f2df630SAndroid Build Coastguard Worker xml="util/signer/fuses.xml" 142*4f2df630SAndroid Build Coastguard Worker codesigner_params+=( --b ) 143*4f2df630SAndroid Build Coastguard Worker flash_base=262144 144*4f2df630SAndroid Build Coastguard Worker prefix="cr50" 145*4f2df630SAndroid Build Coastguard Worker ;; 146*4f2df630SAndroid Build Coastguard Worker (1048576) local rw_bases 147*4f2df630SAndroid Build Coastguard Worker # Third and sixths lines showing signed header magic are base 148*4f2df630SAndroid Build Coastguard Worker # addresses of RW_A and RW_B. 149*4f2df630SAndroid Build Coastguard Worker mapfile -t rw_bases < <(od -Ax -t x1 "${full_bin}" |awk ' 150*4f2df630SAndroid Build Coastguard Worker /^....00 fd ff ff ff/ { 151*4f2df630SAndroid Build Coastguard Worker line = line + 1; 152*4f2df630SAndroid Build Coastguard Worker if (line % 3 == 0) { 153*4f2df630SAndroid Build Coastguard Worker print strtonum("0x"$1) 154*4f2df630SAndroid Build Coastguard Worker } 155*4f2df630SAndroid Build Coastguard Worker }') 156*4f2df630SAndroid Build Coastguard Worker rw_a_base="${rw_bases[0]}" 157*4f2df630SAndroid Build Coastguard Worker rw_b_base="${rw_bases[1]}" 158*4f2df630SAndroid Build Coastguard Worker rw_key="ports/dauntless/signing/ti50_dev.key" 159*4f2df630SAndroid Build Coastguard Worker manifest="ports/dauntless/signing/manifest.TOT.json" 160*4f2df630SAndroid Build Coastguard Worker xml="ports/dauntless/signing/fuses.xml" 161*4f2df630SAndroid Build Coastguard Worker codesigner_params+=( --dauntless ) 162*4f2df630SAndroid Build Coastguard Worker flash_base=524288 163*4f2df630SAndroid Build Coastguard Worker prefix="ti50" 164*4f2df630SAndroid Build Coastguard Worker ;; 165*4f2df630SAndroid Build Coastguard Worker (*) echo "What is ${full_bin}?" >&2 166*4f2df630SAndroid Build Coastguard Worker exit 1 167*4f2df630SAndroid Build Coastguard Worker ;; 168*4f2df630SAndroid Build Coastguard Worker esac 169*4f2df630SAndroid Build Coastguard Worker 170*4f2df630SAndroid Build Coastguard Worker # Determine the current git tree state. This would match the binary image's 171*4f2df630SAndroid Build Coastguard Worker # version string if it was built from this tree. 172*4f2df630SAndroid Build Coastguard Worker sha="$(git rev-parse --short HEAD)" 173*4f2df630SAndroid Build Coastguard Worker if git status --porcelain 2>&1 | grep -qv '^ *?'; then 174*4f2df630SAndroid Build Coastguard Worker sha="${sha}-dirty" 175*4f2df630SAndroid Build Coastguard Worker fi 176*4f2df630SAndroid Build Coastguard Worker 177*4f2df630SAndroid Build Coastguard Worker # Check if the output file already exists. 178*4f2df630SAndroid Build Coastguard Worker output="$(printf "${prefix}.${sha}.%08x-%08x.bin" "${dev_id0}" "${dev_id1}")" 179*4f2df630SAndroid Build Coastguard Worker if [[ -f ${output} ]]; then 180*4f2df630SAndroid Build Coastguard Worker echo "${output} is already there" 181*4f2df630SAndroid Build Coastguard Worker exit 0 182*4f2df630SAndroid Build Coastguard Worker fi 183*4f2df630SAndroid Build Coastguard Worker 184*4f2df630SAndroid Build Coastguard Worker # Make sure all necessary files are present. 185*4f2df630SAndroid Build Coastguard Worker for f in "${rw_key}" "${manifest}" "${xml}"; do 186*4f2df630SAndroid Build Coastguard Worker if [[ ! -f ${f} ]]; then 187*4f2df630SAndroid Build Coastguard Worker echo "File ${f} not found" >&2 188*4f2df630SAndroid Build Coastguard Worker exit 1 189*4f2df630SAndroid Build Coastguard Worker fi 190*4f2df630SAndroid Build Coastguard Worker done 191*4f2df630SAndroid Build Coastguard Worker 192*4f2df630SAndroid Build Coastguard Worker # Clean up the manifest. 193*4f2df630SAndroid Build Coastguard Worker sed -zE 's/"board_[^,]+,\s*//g;s/"info"[^}]+},\s*/"info": { },/' \ 194*4f2df630SAndroid Build Coastguard Worker "${manifest}" > "${TMPD}/manifest.json" 195*4f2df630SAndroid Build Coastguard Worker 196*4f2df630SAndroid Build Coastguard Worker tmp_file="${TMPD}/full.bin" 197*4f2df630SAndroid Build Coastguard Worker cp "${full_bin}" "${tmp_file}" 198*4f2df630SAndroid Build Coastguard Worker 199*4f2df630SAndroid Build Coastguard Worker codesigner_params+=( 200*4f2df630SAndroid Build Coastguard Worker --json "${TMPD}/manifest.json" 201*4f2df630SAndroid Build Coastguard Worker --key "${rw_key}" 202*4f2df630SAndroid Build Coastguard Worker -x "${xml}" 203*4f2df630SAndroid Build Coastguard Worker ) 204*4f2df630SAndroid Build Coastguard Worker 205*4f2df630SAndroid Build Coastguard Worker echo "Re-signing a ${prefix} image" 206*4f2df630SAndroid Build Coastguard Worker 207*4f2df630SAndroid Build Coastguard Worker re_sign_rw "${tmp_file}" "${flash_base}" "${rw_a_base}" \ 208*4f2df630SAndroid Build Coastguard Worker "${codesigner_params[@]}" 209*4f2df630SAndroid Build Coastguard Worker re_sign_rw "${tmp_file}" "${flash_base}" "${rw_b_base}" \ 210*4f2df630SAndroid Build Coastguard Worker "${codesigner_params[@]}" 211*4f2df630SAndroid Build Coastguard Worker 212*4f2df630SAndroid Build Coastguard Worker cp "${tmp_file}" "${output}" 213*4f2df630SAndroid Build Coastguard Worker} 214*4f2df630SAndroid Build Coastguard Worker 215*4f2df630SAndroid Build Coastguard Workermain "$@" 216