xref: /aosp_15_r20/external/vboot_reference/tests/futility/test_gscvd.sh (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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