Files
OpenCellular/util/signer/bs
Vadim Bendebury 1573f257b7 g: signer: unify order of board ID fields
The board ID fields are displayed by the Cr50 console command 'bid' as
follows: <board id>:<board id mask>:<board id flags>.

Make sure the user passes them in the same order when invoking the signer
to sign a board locked image.

BRANCH=none
BUG=none
TEST=verified proper order of the fields when generating and using a
     prod signed image.

Change-Id: Ia4569c5e9e663b26edaa591bae881c719c4f199c
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/604218
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
2017-08-09 16:32:02 -07:00

225 lines
6.4 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This script is a utility which allows to create differently signed CR50
# images from different sources.
#
set -e
set -u
progname=$(basename $0)
tmpf="/tmp/bs_manifest.$$"
trap "{ rm -rf [01].flat ${tmpf} ; }" EXIT
usage() {
local rv="${1}"
cat <<EOF
This script allows to sign CR50 RW images. By default it uses ec.RW.elf and
ec.RW_B.elf in build/cr50/RW as inputs and util/signer/ec_RW-manifest-dev.json
as the manifest, and places the newly signed images into build/cr50/ec.bin.
The only outside dependency of this script is the signing utility itself,
which is expected to be available as \$HOME/bin/codesigner.
The following command line options are accepted:
b1 - generate signature for the b1 version of the H1 chip
elves <elf1> <elf2> - sign the supplied elf files instead of the default
ones. Handy if the builder generated files need to be signed
help - print this message
hex - generate hex output instead of binary (place in 0.signed.hex and
1.signed.hex in the local directory)
prod - sign with prod key (no debug image will be signed)
This script also allows to sign dev images for running on prod RO. To do that
invoke this script as follows:
H1_DEVIDS='<dev id0> <dev id1>' ${progname} [other options, if any]
where <dev id0> <dev id1> are values reported by sysinfo command in the
DEV_ID: line when run on the CR50 for which the image is built.
The same values can be obtained in the lsusb command output:
lsusb -vd 18d1:5014 | grep -i serial
note that the lsusb reported values are in hex and need to be prefixed with
0x.
Finally, this script also allows to specify the board ID fields of the RW
headers. The fields come from the evironment variable CR50_BOARD_ID, which is
required to include three colon separated fields. The first field is a four
letter board RLZ code, the second field is board id mask in hex, no 0x prefix,
and the third field - board ID flags, again, hex, no 0x prefix.
CR50_BOARD_ID='XXYY:ffffff00:ff00' ${progname} [other options, if any]
both H1_DEVIDS and CR50_BOARD_ID can be defined independently.
EOF
exit "${rv}"
}
# This function modifies the manifest to include device ID and board ID nodes,
# if H1_DEVIDS and CR50_BOARD_ID are defined in the environment, respectively,
tweak_manifest () {
local sub
# If defined, plug in dev ID nodes before the 'fuses' node.
if [[ -z "${do_prod}" && -n "${H1_DEVIDS}" ]]; then
echo "creating a customized DEV image for DEV IDS ${H1_DEVIDS}"
sub=$(printf "\\\n \"DEV_ID0\": %s,\\\n \"DEV_ID1\": %s," ${H1_DEVIDS})
sed -i "s/\"fuses\": {/\"fuses\": {${sub}/" "${tmpf}"
fi
if [[ -z "${CR50_BOARD_ID}" ]]; then
return
fi
# CR50_BOARD_ID is set, let's parse it and plug in the board ID related
# nodes into manifest before the 'fuses' node.
local bid_params
local rlz
bid_params=( $(echo $CR50_BOARD_ID | sed 's/:/ /g') )
# A very basic sanity check: it needs to consist of three colon separated
# fields.
if [[ ${#bid_params[@]} != 3 ]]; then
echo "Wrong board ID string \"$CR50_BOARD_ID\"}" >&2
exit 1
fi
# Convert board RLZ code from ASCII to hex
rlz="0x$(echo -n ${bid_params[0]} | hexdump -ve '/1 "%02x"')"
# Prepare text of all three board ID related nodes
sub="$(printf "\\\n\"board_id\": %s,\\\n" "${rlz}")"
sub+="$(printf "\"board_id_mask\": %s,\\\n" "0x${bid_params[1]}")"
sub+="$(printf "\"board_id_flags\": %s,\\\n" "0x${bid_params[2]}")"
sed -i "s/\"fuses\": {/${sub}\"fuses\": {/" "${tmpf}"
}
# This is the suggested location of the codesigner utility.
BIN_ROOT="${HOME}/bin"
# This is where the new signed image will be pasted into.
: ${RESULT_FILE=build/cr50/ec.bin}
TMP_RESULT_FILE="${RESULT_FILE}.tmp"
if [[ -z "${CROS_WORKON_SRCROOT}" ]]; then
echo "${progname}: This script must run inside Chrome OS chroot" >&2
exit 1
fi
: ${CR50_BOARD_ID=}
: ${H1_DEVIDS=}
EC_ROOT="${CROS_WORKON_SRCROOT}/src/platform/ec"
EC_BIN_ROOT="${EC_ROOT}/util/signer"
do_hex=
do_b1=
do_prod=
# Prepare the default manifest.
cp "${EC_BIN_ROOT}/ec_RW-manifest-dev.json" "${tmpf}"
elves=( build/cr50/RW/ec.RW.elf build/cr50/RW/ec.RW_B.elf )
cd "${EC_ROOT}"
while (( $# )); do
param="${1}"
case "${param}" in
(hex) do_hex='true';;
(b1)
do_b1='true'
sed -i 's/\(.*FW_DEFINED_DATA_BLK0.*\): 2/\1: 0/' "${tmpf}"
;;
(elves)
if [[ (( $# < 3 )) ]]; then
echo "two elf file names are required" >&2
exit 1
fi
elves=( $2 $3 )
shift
shift
;;
(prod)
do_prod='true'
;;
(help)
usage 0
;;
(*)
usage 1
;;
esac
shift
done
if [[ -z "${do_hex}" && ! -f "${RESULT_FILE}" ]]; then
echo "${RESULT_FILE} not found. Run 'make BOARD=cr50' first" >&2
exit 1
fi
if [[ -n "${do_prod}" && -n "${do_b1}" ]]; then
echo "can not build prod images for B1, sorry..."
exit 1
fi
signer_command_params=()
signer_command_params+=(--b -x ${EC_BIN_ROOT}/fuses.xml)
if [[ -z "${do_prod}" ]]; then
signer_command_params+=(-k ${EC_BIN_ROOT}/cr50_rom0-dev-blsign.pem.pub)
else
cp "${EC_BIN_ROOT}/ec_RW-manifest-prod.json" "${tmpf}"
signer_command_params+=(-k ${EC_BIN_ROOT}/cr50_RW-prod.pem.pub)
fi
signer_command_params+=(-j ${tmpf})
if [[ -n "${do_hex}" ]]; then
dst_suffix='signed.hex'
else
signer_command_params+=(--format=bin)
dst_suffix='flat'
fi
tweak_manifest
count=0
for elf in ${elves[@]}; do
if [[ -n "${do_prod}" ]]; then
if grep -q "DEV/cr50" "${elf}"; then
echo "Will not sign debug image with prod keys" >&2
exit 1
fi
fi
signed_file="${count}.${dst_suffix}"
# Make sure this file is not owned by root
touch "${signed_file}"
sudo ${BIN_ROOT}/codesigner ${signer_command_params[@]} \
-i ${elf} -o "${signed_file}"
if [[ ! -s "${signed_file}" ]]; then
echo "${progname}: error: empty signed file ${signed_file}" >&2
exit 1
fi
: $(( count++ ))
done
if [[ -z "${do_hex}" ]]; then
# Full binary image is required, paste the newly signed blobs into the
# output image, preserving it in case dd fails for whatever reason.
cp "${RESULT_FILE}" "${TMP_RESULT_FILE}"
dd if="0.flat" of="${TMP_RESULT_FILE}" seek=16384 bs=1 conv=notrunc
dd if="1.flat" of="${TMP_RESULT_FILE}" seek=278528 bs=1 conv=notrunc
rm [01].flat
mv "${TMP_RESULT_FILE}" "${RESULT_FILE}"
fi
echo "SUCCESS!!!"