summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-02-08 20:58:07 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-03-23 13:47:20 -0700
commit9a37f21fd227bf2e10f1a4a11b549dd6f22f6846 (patch)
tree617674607920852ac63c4c6871507a1aaa90bed9
parent7db12fdc3ec824e28554b96edb5e08fcdeb658cf (diff)
downloadchrome-ec-9a37f21fd227bf2e10f1a4a11b549dd6f22f6846.tar.gz
g:script to create cr50 release images
We are still building two images - for prod and dev fused H1 chips. This requires different pairs of RO images and calls for using different keys when signing RW images. Each produced image is of 512K bytes in size, the ROs are paced at offsets 0 and 0x40000, the RWs at offsets 0x4000 and 0x4000. The signed ROs come from their respective source, their processing is limited to converting into binary format and verifying that their key signatures match image designation (prod vs dev). The RWs binaries are derived from RW elf files which are the result of running 'make BOARD=cr50'. The elves are converted into binary format and signed, the bs script is used for that. The bs script is modified to accept the destination file name from the shell variable, to detect signing failures (resulting in zero sized binaries), and to fix error reporting. The new script create_released_image.sh expects exactly six command line parameters: <prod RO A>.hex <prod RO B>.hex <dev RO A>.hex <dev RO B>.hex \ <RW.elf> <RW_B.elf> and generates two cr50 binary images. The generated images are placed in the directory named cr50.r<ro vers>.w<rw vers> (the versions are retrieved from the binaries using usb_updater), and then placed in the tarball with the same base name. This naming convention is imposed by the ebuild pulling in the tarball from the binary component server (BCS). On the successful completion the script prints out commands which can be used to upload the new tarball to the BCS. BRANCH=none BUG=b:35587234 TEST=ran the script to generate the r0.0.10.w0.0.18 release, verified that all components of both imagea are properly signed (are bootable and the key signature matches the prod/dev convention). Change-Id: I87be1d44a721c979bdeeabf986d717e3a382db45 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/439907 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Caveh Jalali <caveh@google.com>
-rwxr-xr-xutil/signer/bs13
-rwxr-xr-xutil/signer/create_released_image.sh158
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}"