1*8617a60dSAndroid Build Coastguard Worker#!/bin/bash -eux 2*8617a60dSAndroid Build Coastguard Worker# Copyright 2022 The ChromiumOS Authors 3*8617a60dSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*8617a60dSAndroid Build Coastguard Worker# found in the LICENSE file. 5*8617a60dSAndroid Build Coastguard Worker 6*8617a60dSAndroid Build Coastguard Workerif [[ -z ${SCRIPT_DIR+x} ]]; then 7*8617a60dSAndroid Build Coastguard Worker # must be running standalone 8*8617a60dSAndroid Build Coastguard Worker SCRIPT_DIR="$(readlink -f "$(dirname "$0")"/..)" 9*8617a60dSAndroid Build Coastguard Worker FUTILITY="${SCRIPT_DIR}/../build/futility/futility" 10*8617a60dSAndroid Build Coastguard Workerfi 11*8617a60dSAndroid Build Coastguard Worker 12*8617a60dSAndroid Build Coastguard Workerif [[ ! -e ${FUTILITY} ]]; then 13*8617a60dSAndroid Build Coastguard Worker echo "The futility app not available, run 'make futil' in the top directory" \ 14*8617a60dSAndroid Build Coastguard Worker >&2 15*8617a60dSAndroid Build Coastguard Worker exit 1 16*8617a60dSAndroid Build Coastguard Workerfi 17*8617a60dSAndroid Build Coastguard Worker 18*8617a60dSAndroid Build Coastguard WorkerKEYS_DIR="$(readlink -f "${SCRIPT_DIR}/devkeys")" 19*8617a60dSAndroid Build Coastguard WorkerTMPD="$(mktemp -d /tmp/"$(basename "$0")".XXXXX)" 20*8617a60dSAndroid Build Coastguard Workertrap '/bin/rm -rf "${TMPD}"' EXIT 21*8617a60dSAndroid Build Coastguard Worker 22*8617a60dSAndroid Build Coastguard Worker# Test FMAP sections were taken from Nivviks image, which is 32M in size. 23*8617a60dSAndroid Build Coastguard WorkerFW_IMAGE_SIZE_K=$(( 32 * 1024 )) 24*8617a60dSAndroid Build Coastguard Worker 25*8617a60dSAndroid Build Coastguard Worker# FMAP offset in the original image 26*8617a60dSAndroid Build Coastguard WorkerFMAP_OFFSET_K=28696 27*8617a60dSAndroid Build Coastguard Worker 28*8617a60dSAndroid Build Coastguard Workermain() { 29*8617a60dSAndroid Build Coastguard Worker local bios_blob 30*8617a60dSAndroid Build Coastguard Worker local command_args 31*8617a60dSAndroid Build Coastguard Worker local warn 32*8617a60dSAndroid Build Coastguard Worker local fmap_blob 33*8617a60dSAndroid Build Coastguard Worker local hwid 34*8617a60dSAndroid Build Coastguard Worker local pubkhash 35*8617a60dSAndroid Build Coastguard Worker local section 36*8617a60dSAndroid Build Coastguard Worker local stderr_output 37*8617a60dSAndroid Build Coastguard Worker 38*8617a60dSAndroid Build Coastguard Worker cd "${SCRIPT_DIR}/futility" 39*8617a60dSAndroid Build Coastguard Worker 40*8617a60dSAndroid Build Coastguard Worker # Create a blob of the firmware image size. 41*8617a60dSAndroid Build Coastguard Worker bios_blob="${TMPD}/image.bin" 42*8617a60dSAndroid Build Coastguard Worker cat /dev/zero | tr '\000' '\377' | \ 43*8617a60dSAndroid Build Coastguard Worker dd of="${bios_blob}" bs=1K count="${FW_IMAGE_SIZE_K}" status=none 44*8617a60dSAndroid Build Coastguard Worker 45*8617a60dSAndroid Build Coastguard Worker # Paste the FMAP blob at the known location 46*8617a60dSAndroid Build Coastguard Worker fmap_blob="data/nivviks.FMAP" 47*8617a60dSAndroid Build Coastguard Worker dd if="${fmap_blob}" of="${bios_blob}" bs=1K seek="${FMAP_OFFSET_K}" \ 48*8617a60dSAndroid Build Coastguard Worker conv=notrunc status=none 49*8617a60dSAndroid Build Coastguard Worker 50*8617a60dSAndroid Build Coastguard Worker # Paste other available FMAP areas into the image. 51*8617a60dSAndroid Build Coastguard Worker command_args=() 52*8617a60dSAndroid Build Coastguard Worker for section in data/nivviks.[A-Z]*; do 53*8617a60dSAndroid Build Coastguard Worker local name 54*8617a60dSAndroid Build Coastguard Worker 55*8617a60dSAndroid Build Coastguard Worker if [[ ${section} =~ .*FMAP ]]; then 56*8617a60dSAndroid Build Coastguard Worker continue 57*8617a60dSAndroid Build Coastguard Worker fi 58*8617a60dSAndroid Build Coastguard Worker 59*8617a60dSAndroid Build Coastguard Worker name="${section##*.}" 60*8617a60dSAndroid Build Coastguard Worker command_args+=( "${name}:${section}" ) 61*8617a60dSAndroid Build Coastguard Worker done 62*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" load_fmap "${bios_blob}" "${command_args[@]}" 63*8617a60dSAndroid Build Coastguard Worker 64*8617a60dSAndroid Build Coastguard Worker # Make sure gbb flags are nonzero 65*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" gbb --set --flags=1 "${bios_blob}" 66*8617a60dSAndroid Build Coastguard Worker 67*8617a60dSAndroid Build Coastguard Worker # Sign the blob using ranges already present in the RO_GSCVD section. 68*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" gscvd --keyblock "${KEYS_DIR}"/arv_platform.keyblock \ 69*8617a60dSAndroid Build Coastguard Worker --platform_priv "${KEYS_DIR}"/arv_platform.vbprivk \ 70*8617a60dSAndroid Build Coastguard Worker --board_id XYZ1 \ 71*8617a60dSAndroid Build Coastguard Worker --root_pub_key "${KEYS_DIR}"/arv_root.vbpubk "${bios_blob}" 72*8617a60dSAndroid Build Coastguard Worker 73*8617a60dSAndroid Build Coastguard Worker # Calculate root pub key hash 74*8617a60dSAndroid Build Coastguard Worker pubkhash="$( "${FUTILITY}" gscvd --root_pub_key \ 75*8617a60dSAndroid Build Coastguard Worker "${KEYS_DIR}"/arv_root.vbpubk | tail -1)" 76*8617a60dSAndroid Build Coastguard Worker 77*8617a60dSAndroid Build Coastguard Worker # Message printed on stderr in case signature matches only after zeroing GBB 78*8617a60dSAndroid Build Coastguard Worker # flags. 79*8617a60dSAndroid Build Coastguard Worker warn="WARNING: validate_gscvd: Ranges digest matches with zeroed GBB flags" 80*8617a60dSAndroid Build Coastguard Worker 81*8617a60dSAndroid Build Coastguard Worker # Run verification, this one is expected to succeed but report GBB flags 82*8617a60dSAndroid Build Coastguard Worker # mismatch. 83*8617a60dSAndroid Build Coastguard Worker stderr_output=$("${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>&1) 84*8617a60dSAndroid Build Coastguard Worker if [[ $? != 0 ]] ; then 85*8617a60dSAndroid Build Coastguard Worker echo "Unexpected failure with nonzero GBB!" >&2 86*8617a60dSAndroid Build Coastguard Worker exit 1 87*8617a60dSAndroid Build Coastguard Worker fi 88*8617a60dSAndroid Build Coastguard Worker if [[ ${stderr_output} != "${warn}" ]]; then 89*8617a60dSAndroid Build Coastguard Worker echo "Unexpected error message \"${stderr_output}\" with nonzero GBB!" 90*8617a60dSAndroid Build Coastguard Worker exit 1 91*8617a60dSAndroid Build Coastguard Worker fi 92*8617a60dSAndroid Build Coastguard Worker 93*8617a60dSAndroid Build Coastguard Worker # Clear the flags and try verifying again, should succeed this time. 94*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" gbb --set --flags=0 "${bios_blob}" 95*8617a60dSAndroid Build Coastguard Worker if ! "${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>/dev/null ; then 96*8617a60dSAndroid Build Coastguard Worker echo "Unexpected signature MISmatch!" >&2 97*8617a60dSAndroid Build Coastguard Worker exit 1 98*8617a60dSAndroid Build Coastguard Worker fi 99*8617a60dSAndroid Build Coastguard Worker 100*8617a60dSAndroid Build Coastguard Worker # Change HWID and see that signature still matches. 101*8617a60dSAndroid Build Coastguard Worker hwid="$("${FUTILITY}" gbb --hwid "${bios_blob}" | sed 's/.*: //')" 102*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" gbb --set --hwid="${hwid}xx" "${bios_blob}" 103*8617a60dSAndroid Build Coastguard Worker if ! "${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>/dev/null ; then 104*8617a60dSAndroid Build Coastguard Worker echo "Unexpected signature MISmatch after modifying HWID!" >&2 105*8617a60dSAndroid Build Coastguard Worker exit 1 106*8617a60dSAndroid Build Coastguard Worker fi 107*8617a60dSAndroid Build Coastguard Worker 108*8617a60dSAndroid Build Coastguard Worker # Modify the recovery key and see that signature verification fails. 109*8617a60dSAndroid Build Coastguard Worker "${FUTILITY}" gbb --set \ 110*8617a60dSAndroid Build Coastguard Worker --recoverykey="${KEYS_DIR}"/recovery_kernel_data_key.vbpubk \ 111*8617a60dSAndroid Build Coastguard Worker "${bios_blob}" 112*8617a60dSAndroid Build Coastguard Worker if "${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>/dev/null ; then 113*8617a60dSAndroid Build Coastguard Worker echo "Unexpected signature match after updating recovery key!" >&2 114*8617a60dSAndroid Build Coastguard Worker exit 1 115*8617a60dSAndroid Build Coastguard Worker fi 116*8617a60dSAndroid Build Coastguard Worker} 117*8617a60dSAndroid Build Coastguard Worker 118*8617a60dSAndroid Build Coastguard Workermain "$@" 119