summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@google.com>2020-11-12 20:06:09 -0800
committerCommit Bot <commit-bot@chromium.org>2020-12-11 21:06:47 +0000
commit7e9472ab7a1729a69365a9a21516d70d11f893c4 (patch)
treede5161cc4eb871a2dec9277b091623cb9039400f
parent21b7225caf55686fd27007c878758cacac7ff55f (diff)
downloadvboot-7e9472ab7a1729a69365a9a21516d70d11f893c4.tar.gz
image_signing: use GSC nomenclature instead of Cr50
This patch does not yet provide the ability to sign Ti50 images, but prepares the signing scripts for further modifications to support a variety of security chip signing flows. BRANCH=none BUG=b:173049030 TEST=verified successful signing of a Cr50 image in a test signer setup also created a functional Cr50 image invoking sign_official_build.sh by hand. Change-Id: Ic103c9fdf7d1c4ea160c7f6849d5ae5a8303c343 Signed-off-by: Vadim Bendebury <vbendeb@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2537078 Tested-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: George Engelbrecht <engeg@google.com> Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Auto-Submit: Vadim Bendebury <vbendeb@chromium.org>
-rwxr-xr-xscripts/image_signing/sign_gsc_firmware.sh (renamed from scripts/image_signing/sign_cr50_firmware.sh)150
-rwxr-xr-xscripts/image_signing/sign_official_build.sh12
2 files changed, 105 insertions, 57 deletions
diff --git a/scripts/image_signing/sign_cr50_firmware.sh b/scripts/image_signing/sign_gsc_firmware.sh
index d11afbbc..768844ad 100755
--- a/scripts/image_signing/sign_cr50_firmware.sh
+++ b/scripts/image_signing/sign_gsc_firmware.sh
@@ -36,11 +36,11 @@ to_int32() {
print (struct.unpack('i', d)[0])"
}
-# This function accepts one argument, the name of the Cr50 manifest file which
+# This function accepts one argument, the name of the GSC manifest file which
# needs to be verified and in certain cases altered.
#
# The function verifies that the input manifest is a proper json file, and
-# that the manifest conforms to Cr50 version numbering and board ID flags
+# that the manifest conforms to GSC version numbering and board ID flags
# conventions for various build images:
#
# - only factory version binaries can be converted to node locked images,
@@ -52,9 +52,9 @@ to_int32() {
#
# - when signing mp images (major version number is odd), the 0x10000 flags
# bit must be set (this can be overridden by signing instructions).
-verify_and_prepare_cr50_manifest() {
+verify_and_prepare_gsc_manifest() {
if [[ $# -ne 1 ]]; then
- die "Usage: verify_and_prepare_cr50_manifest <manifest .json file>"
+ die "Usage: verify_and_prepare_gsc_manifest <manifest .json file>"
fi
local manifest_json="$1"
@@ -66,8 +66,8 @@ verify_and_prepare_cr50_manifest() {
local minor
local values
- values=( $(jq '.config1,.epoch,.major,.minor,.board_id_flags' \
- "${manifest_json}") )
+ mapfile -t values < <(jq '.config1,.epoch,.major,.minor,.board_id_flags' \
+ "${manifest_json}")
config1="${values[0]}"
epoch="${values[1]}"
@@ -90,7 +90,7 @@ verify_and_prepare_cr50_manifest() {
die "Node locked target without Device ID value"
fi
# Case of a node locked image, it must have the fixed factory version.
- if [[ $epoch.$major.$minor != $CR50_FACTORY_VERSION ]];then
+ if [[ "${epoch}.${major}.${minor}" != "${CR50_FACTORY_VERSION}" ]];then
die "Won't create node locked images for version $epoch.$major.$minor"
fi
@@ -100,7 +100,7 @@ verify_and_prepare_cr50_manifest() {
devid0="$(to_int32 "0x${INSN_DEVICE_ID/-*}")"
devid1="$(to_int32 "0x${INSN_DEVICE_ID/*-}")"
- cf1="$(to_int32 $(( 0x80000000 + ${config1} )))"
+ cf1="$(to_int32 $(( 0x80000000 + config1 )))"
sub="$(printf " \"DEV_ID0\": %s,\\\n \"DEV_ID1\": %s," \
"${devid0}" "${devid1}")"
@@ -217,12 +217,12 @@ determine_rma_key_base() {
echo "${base_name}.${curve}"
}
-# Sign cr50 RW firmware ELF images into a combined cr50 firmware image
+# Sign GSC RW firmware ELF images into a combined GSC firmware image
# using the provided production keys and manifests.
sign_rw() {
- if [[ $# -ne 7 ]]; then
+ if [[ $# -ne 8 ]]; then
die "Usage: sign_rw <key_file> <manifest> <fuses>" \
- "<rma_key_dir> <rw_a> <rw_b> <output>"
+ "<rma_key_dir> <rw_a> <rw_b> <output> <generation>"
fi
local key_file="$1"
@@ -231,32 +231,59 @@ sign_rw() {
local rma_key_dir="$4"
local elfs=( "$5" "$6" )
local result_file="$7"
- local temp_dir="$(make_temp_dir)"
- local rma_key_base
+ local generation="$8"
+ local temp_dir
+ local rma_key_base=""
+ local rw_a_offset
+ local rw_b_offset
+
+ temp_dir="$(make_temp_dir)"
if [[ ! -f "${result_file}" ]]; then
die "${result_file} not found."
fi
- # If signing a chip factory image (version 0.0.22) do not try figuring out the
- # RMA keys.
- local cr50_version="$(jq '.epoch * 10000 + .major * 100 + .minor' \
- "${manifest_file}")"
+ local signer_command_params=(-x "${fuses_file}" --key "${key_file}")
- if [[ "${cr50_version}" != "22" ]]; then
- rma_key_base="$(determine_rma_key_base "${rma_key_dir}" "${elfs[@]}")"
- else
- echo "Ignoring RMA keys for factory branch ${cr50_version}"
- fi
+ case "${generation}" in
+ (h)
+ # H1 image might require some tweaking.
+ # If signing a chip factory image (version 0.0.22) do not try figuring
+ # out the RMA keys.
+ local gsc_version
- local signer_command_params=(--b -x "${fuses_file}" --key "${key_file}")
+ gsc_version="$(jq '.epoch * 10000 + .major * 100 + .minor' \
+ "${manifest_file}")"
+
+ if [[ "${gsc_version}" != "22" ]]; then
+ rma_key_base="$(determine_rma_key_base "${rma_key_dir}" "${elfs[@]}")"
+ else
+ echo "Ignoring RMA keys for factory branch ${gsc_version}"
+ fi
+
+ # Swap test public RMA server key with the prod version.
+ if [[ -n "${rma_key_base}" ]]; then
+ signer_command_params+=(
+ --swap "${rma_key_base}.test,${rma_key_base}.prod"
+ )
+ fi
+
+ # Indicate H1 signing.
+ signer_command_params+=( '--b' )
+ # Fixed offsets into the binary blob where RW sections start.
+ rw_a_offset=16384
+ rw_b_offset=278528
+ ;;
+ (d)
+ # Indicate D1 signing.
+ signer_command_params+=( '--dauntless' )
+ die "Need to figure out D2 RW sections offsets"
+ ;;
+ (*)
+ die "Unknown generation value \"${generation}\""
+ ;;
+ esac
- # Swap test public RMA server key with the prod version.
- if [[ -n "${rma_key_base}" ]]; then
- signer_command_params+=(
- --swap "${rma_key_base}.test","${rma_key_base}.prod"
- )
- fi
signer_command_params+=(--json "${manifest_file}")
signer_command_params+=(--format=bin)
@@ -275,9 +302,9 @@ sign_rw() {
# Make sure output file is not owned by root.
touch "${signed_file}"
- if ! cr50-codesigner "${signer_command_params[@]}" \
+ if ! gsc-codesigner "${signer_command_params[@]}" \
-i "${elf}" -o "${signed_file}"; then
- die "cr50-codesigner ${signer_command_params[@]}" \
+ die "gsc-codesigner ${signer_command_params[*]}" \
"-i ${elf} -o ${signed_file} failed"
fi
@@ -296,9 +323,9 @@ sign_rw() {
# Full binary image is required, paste the newly signed blobs into the
# output image.
dd if="${temp_dir}/0.${dst_suffix}" of="${result_file}" \
- seek=16384 bs=1 conv=notrunc
+ seek="${rw_a_offset}" bs=1 conv=notrunc
dd if="${temp_dir}/1.${dst_suffix}" of="${result_file}" \
- seek=278528 bs=1 conv=notrunc
+ seek="${rw_b_offset}" bs=1 conv=notrunc
}
# A very crude RO verification function. The key signature found at a fixed
@@ -337,7 +364,7 @@ verify_ro() {
die "RO key (${key_byte}) in ${ro_bin} does not match type prod"
}
-# This function prepares a full CR50 image, consisting of two ROs and two RWs
+# This function prepares a full GSC 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.
@@ -346,9 +373,9 @@ verify_ro() {
# RW version numbers and board ID fields, if set to non-default. The ebuild
# downloading the tarball from the BCS expects the image to be in that
# directory.
-sign_cr50_firmware() {
+sign_gsc_firmware() {
if [[ $# -ne 9 ]]; then
- die "Usage: sign_cr50_firmware <key_file> <manifest> <fuses>" \
+ die "Usage: sign_gsc_firmware <key_file> <manifest> <fuses>" \
"<rma_key_dir> <ro_a> <ro_b> <rw_a> <rw_b> <output>"
fi
@@ -361,19 +388,37 @@ sign_cr50_firmware() {
local rw_a="$7"
local rw_b="$8"
local output_file="$9"
+ local generation
+ local manifest_file
+ local temp_dir
+ local ro_b_base
- local manifest_file="${manifest_source}.updated"
- local temp_dir="$(make_temp_dir)"
+ manifest_file="${manifest_source}.updated"
+ temp_dir="$(make_temp_dir)"
- # The H1 chip where Cr50 firmware runs has 512K of flash, the generated
- # image must match the flash size.
- IMAGE_SIZE="$(( 512 * 1024 ))"
-
- # Prepare file for inline editing.
+ # Prepare file for inline editing.
jq . < "${manifest_source}" > "${manifest_file}" || \
die "basic validation of ${manifest_json} failed"
- verify_and_prepare_cr50_manifest "${manifest_file}"
+ # Retrieve chip type from the manifest, if preset, otherwise use h1.
+ generation="$(jq '.generation' "${manifest_file}")"
+ case "${generation}" in
+ (h|null)
+ generation="h" # Just in case this is a legacy manifest.
+
+ # H1 flash size, image size must match.
+ IMAGE_SIZE="$(( 512 * 1024 ))"
+ ;;
+ (d)
+ # D2 flash size, image size must match.
+ IMAGE_SIZE="$(( 512 * 1024 ))"
+ ;;
+ (*)
+ die "Unknown generation value \"${generation}\" in signing manifest"
+ ;;
+ esac
+
+ verify_and_prepare_gsc_manifest "${manifest_file}"
dd if=/dev/zero bs="${IMAGE_SIZE}" count=1 status=none |
tr '\000' '\377' > "${output_file}"
@@ -392,20 +437,23 @@ sign_cr50_firmware() {
done
if ! sign_rw "${key_file}" "${manifest_file}" "${fuses_file}" \
- "${rma_key_dir}" "${rw_a}" "${rw_b}" "${output_file}"; then
+ "${rma_key_dir}" "${rw_a}" "${rw_b}" \
+ "${output_file}" "${generation}"; then
die "Failed invoking sign_rw for ELF files ${rw_a} ${rw_b}"
fi
+ ro_b_base=$(( IMAGE_SIZE / 2 ))
dd if="${temp_dir}/0.bin" of="${output_file}" conv=notrunc
- dd if="${temp_dir}/1.bin" of="${output_file}" seek=262144 bs=1 conv=notrunc
+ dd if="${temp_dir}/1.bin" of="${output_file}" seek="${ro_b_base}" bs=1 \
+ conv=notrunc
echo "Image successfully signed to ${output_file}"
}
-# Sign the directory holding cr50 firmware.
-sign_cr50_firmware_dir() {
+# Sign the directory holding GSC firmware.
+sign_gsc_firmware_dir() {
if [[ $# -ne 3 ]]; then
- die "Usage: sign_cr50_firmware_dir <input> <key> <output>"
+ die "Usage: sign_gsc_firmware_dir <input> <key> <output>"
fi
local input="${1%/}"
@@ -416,7 +464,7 @@ sign_cr50_firmware_dir() {
output="${output}/cr50.bin.prod"
fi
- sign_cr50_firmware \
+ sign_gsc_firmware \
"${key_file}" \
"${input}/prod.json" \
"${input}/fuses.xml" \
@@ -455,6 +503,6 @@ main() {
die "Missing input directory: ${input}"
fi
- sign_cr50_firmware_dir "${input}" "${key_file}" "${output}"
+ sign_gsc_firmware_dir "${input}" "${key_file}" "${output}"
}
main "$@"
diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh
index 9a1a405a..6167f0be 100755
--- a/scripts/image_signing/sign_official_build.sh
+++ b/scripts/image_signing/sign_official_build.sh
@@ -39,7 +39,7 @@ where <type> is one of:
verify (verify an image including rootfs hashes)
accessory_usbpd (sign USB-PD accessory firmware)
accessory_rwsig (sign accessory RW firmware)
- cr50_firmware (sign a cr50 firmware image)
+ gsc_firmware (sign a GSC firmware image)
output_image: File name of the signed output image
version_file: File name of where to read the kernel and firmware versions.
@@ -817,14 +817,14 @@ verify_uefi_signatures() {
fi
}
-# Sign a cr50 firmware image with the given keys.
+# Sign a GSC firmware image with the given keys.
# Args: CONTAINER KEY_DIR [OUTPUT_CONTAINER]
-sign_cr50_firmware() {
+sign_gsc_firmware() {
local image=$1
local key_dir=$2
local output=$3
- "${SCRIPT_DIR}/sign_cr50_firmware.sh" \
+ "${SCRIPT_DIR}/sign_gsc_firmware.sh" \
"${image}" "${key_dir}" "${output}"
}
@@ -1140,8 +1140,8 @@ elif [[ "${TYPE}" == "accessory_rwsig" ]]; then
cp "${INPUT_IMAGE}" "${OUTPUT_IMAGE}"
futility sign --type rwsig --prikey "${KEY_NAME}" \
--version "${FIRMWARE_VERSION}" "${OUTPUT_IMAGE}"
-elif [[ "${TYPE}" == "cr50_firmware" ]]; then
- sign_cr50_firmware "${INPUT_IMAGE}" "${KEY_DIR}" "${OUTPUT_IMAGE}"
+elif [[ "${TYPE}" == "gsc_firmware" ]]; then
+ sign_gsc_firmware "${INPUT_IMAGE}" "${KEY_DIR}" "${OUTPUT_IMAGE}"
else
die "Invalid type ${TYPE}"
fi