diff options
-rwxr-xr-x | util/signer/bs | 13 | ||||
-rwxr-xr-x | util/signer/create_released_image.sh | 158 |
2 files changed, 167 insertions, 4 deletions
diff --git a/util/signer/bs b/util/signer/bs index b97f26036a..0339c2efb6 100755 --- a/util/signer/bs +++ b/util/signer/bs @@ -60,7 +60,7 @@ EOF BIN_ROOT="${HOME}/bin" # This is where the new signed image will be pasted into. -RESULT_FILE="build/cr50/ec.bin" +RESULT_FILE="${RESULT_FILE:=build/cr50/ec.bin}" if [ -z "${CROS_WORKON_SRCROOT}" ]; then echo "$(basename $0): This script must run inside Chrome OS chroot" >&2 @@ -90,7 +90,7 @@ while (( "$#" )); do ;; (elves) if [ -z "${2}" -o -z "${3}" ]; then - echo "two elf file names are required" 2>&1 + echo "two elf file names are required" >&2 exit 1 fi elves=( $2 $3 ) @@ -111,7 +111,7 @@ while (( "$#" )); do done if [ -z "${do_hex}" -a ! -f "${RESULT_FILE}" ]; then - echo "${RESULT_FILE} not found. Run 'make BOARD=cr50' first" >& 2 + echo "${RESULT_FILE} not found. Run 'make BOARD=cr50' first" >&2 exit 1 fi @@ -151,8 +151,13 @@ for elf in ${elves[@]}; do exit 1 fi fi + signed_file="${count}.${dst_suffix}" sudo ${BIN_ROOT}/codesigner ${signer_command_params} \ - -i ${elf} -o "${count}.${dst_suffix}" + -i ${elf} -o "${signed_file}" + if [ ! -s "${signed_file}" ]; then + echo "$(basename $0): error: empty signed file ${signed_file}" >&2 + exit 1 + fi count=$(( count + 1 )) done diff --git a/util/signer/create_released_image.sh b/util/signer/create_released_image.sh new file mode 100755 index 0000000000..6b8190fdf6 --- /dev/null +++ b/util/signer/create_released_image.sh @@ -0,0 +1,158 @@ +#!/bin/bash + +# +# Copyright 2017 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 sign dev and prod CR50 images for +# release and place them in a tarball suitable for uploading to the BCS. +# +# Manifests present in the EC directory at the time of signing are used for +# both prod and dev images. +# + +set -u +set -e + +# A very crude RO verification function. The key signature found at a fixed +# offset into the RO blob must match the RO type. Prod keys have bit D2 set to +# one, dev keys have this bit set to zero. +verify_ro() { + local ro_bin="${1}" + local type_expected="${2}" + local key_byte + + if [ ! -f "${ro_bin}" ]; then + echo "${ro_bin} not a file!" >&2 + exit 1 + fi + + # Key signature's lowest byte is byte #5 in the line at offset 0001a0. + key_byte="$(od -Ax -t x1 -v "${ro_bin}" | awk '/0001a0/ {print $6};')" + case "${key_byte}" in + (?[4567cdef]) + if [ "${type_expected}" == "prod" ]; then + return 0 + fi + ;; + (?[012389ab]) + if [ "${type_expected}" == "dev" ]; then + return 0 + fi + ;; + esac + + echo "RO key in ${ro_bin} does not match type ${type_expected}" >&2 + exit 1 +} + +# This function prepares a full CR50 image, consisting of two ROs and two RWs +# placed at their respective offsets into the resulting blob. It invokes the +# bs (binary signer) script to actually convert elf versions of RWs into +# binaries and sign them. +# +# The signed image is placed in the directory named as concatenation of RO and +# RW version numbers, which is where eventually the ebuild downloading the +# tarball from the BCS expects the dev and prod images be. +prepare_image() { + local count=0 + local extra_param= + local image_type="${1}" + local ro_a_hex="$(readlink -f "${2}")" + local ro_b_hex="$(readlink -f "${3}")" + local rw_a="$(readlink -f "${4}")" + local rw_b="$(readlink -f "${5}")" + local version + + for f in "${ro_a_hex}" "${ro_b_hex}"; do + if ! objcopy -I ihex "${f}" -O binary "${TMPD}/${count}.bin"; then + echo "failed to convert ${f} from hex to bin" >&2 + exit 1 + fi + verify_ro "${TMPD}/${count}.bin" "${image_type}" + : $(( count += 1 )) + done + + if [ "${image_type}" == "prod" ]; then + extra_param+=' prod' + fi + + if ! "${EC_ROOT}/util/signer/bs" ${extra_param} elves \ + "${rw_a}" "${rw_b}" > /dev/null; + then + echo "Failed invoking ${EC_ROOT}/util/signer/bs ${extra_param} " \ + "elves ${rw_a} ${rw_b}" >&2 + exit 1 + fi + + dd if="${TMPD}/0.bin" of="${RESULT_FILE}" conv=notrunc + dd if="${TMPD}/1.bin" of="${RESULT_FILE}" seek=262144 bs=1 conv=notrunc + + version="$(usb_updater -b "${RESULT_FILE}" |\ + awk '/^RO_A:/ {gsub(/R[OW]_A:/, ""); print "r" $1 ".w" $2}')" + + if [ -z "${dest_dir}" ]; then + # Note that this is a global variable + dest_dir="cr50.${version}" + if [ ! -d "${dest_dir}" ]; then + mkdir "${dest_dir}" + else + echo "${dest_dir} already exists, will overwrite" >&2 + fi + elif [ "${dest_dir}" != "cr50.${version}" ]; then + echo "dev and prod versions mismatch!" >&2 + exit 1 + fi + + cp "${RESULT_FILE}" "${dest_dir}/cr50.bin.${image_type}" + echo "saved ${image_type} binary in ${dest_dir}/cr50.bin.${image_type}" +} + +# Execution starts here =========================== +TMPD="$(mktemp -d /tmp/$(basename $0).XXXXX)" +trap "/bin/rm -rf ${TMPD}" SIGINT SIGTERM EXIT + +EC_ROOT="${CROS_WORKON_SRCROOT}/src/platform/ec" +RESULT_FILE="${TMPD}/release.bin" +dest_dir= +IMAGE_SIZE='524288' +export RESULT_FILE + +if [ -z "${CROS_WORKON_SRCROOT}" ]; then + echo "$(basename $0): This script must run inside Chrome OS chroot" >&2 + exit 1 +fi + +if [ "${#*}" != "6" ]; then + echo "six parameters are required: " + echo "<prod RO A>.hex " \ + "<prod RO B>.hex <dev RO A>.hex <dev RO B>.hex <RW.elf> <RW_B.elf>" >&2 + exit 1 +fi + +dd if=/dev/zero bs="${IMAGE_SIZE}" count=1 2>/dev/null | + tr \\000 \\377 > "${RESULT_FILE}" +if [ "$(stat -c '%s' "${RESULT_FILE}")" != "${IMAGE_SIZE}" ]; then + echo "Failed creating ${RESULT_FILE}" >&2 + exit 1 +fi + +prod_ro_a="${1}" +prod_ro_b="${2}" +dev_ro_a="${3}" +dev_ro_b="${4}" +rw_a="${5}" +rw_b="${6}" + +prepare_image 'dev' "${dev_ro_a}" "${dev_ro_b}" "${rw_a}" "${rw_b}" +prepare_image 'prod' "${prod_ro_a}" "${prod_ro_b}" "${rw_a}" "${rw_b}" +tarball="${dest_dir}.tbz2" +tar jcf "${tarball}" "${dest_dir}" +rm -rf "${dest_dir}" + +bcs_path="gs://chromeos-localmirror/distfiles" +echo "SUCCESS!!!!!!" +echo "use the below commands to copy the new image to the BCS" +echo "gsutil cp ${tarball} ${bcs_path}" +echo "gsutil acl ch -u AllUsers:R ${bcs_path}/${tarball}" |