1#!/bin/bash
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18#
19# Dump boot signature info of a GKI boot image.
20#
21
22set -eo errtrace
23
24die() {
25  echo >&2 "ERROR:" "${@}"
26  exit 1
27}
28
29TEMP_DIR="$(mktemp -d)"
30readonly TEMP_DIR
31
32exit_handler() {
33  readonly EXIT_CODE="$?"
34  rm -rf "${TEMP_DIR}" ||:
35  exit "${EXIT_CODE}"
36}
37
38trap exit_handler EXIT
39trap 'die "line ${LINENO}, ${FUNCNAME:-<main>}(): \"${BASH_COMMAND}\" returned \"$?\"" ' ERR
40
41get_arg() {
42  local arg="$1"
43  shift
44  while [[ "$#" -gt 0 ]]; do
45    if [[ "$1" == "${arg}" ]]; then
46      shift
47      echo "$1"
48      return
49    fi
50    shift
51  done
52}
53
54readonly VBMETA_IMAGE="${TEMP_DIR}/boot.boot_signature"
55readonly VBMETA_IMAGE_TEMP="${VBMETA_IMAGE}.temp"
56readonly VBMETA_INFO="${VBMETA_IMAGE}.info"
57readonly BOOT_IMAGE="${TEMP_DIR}/boot.img"
58readonly BOOT_IMAGE_DIR="${TEMP_DIR}/boot.unpack_dir"
59readonly BOOT_IMAGE_ARGS="${TEMP_DIR}/boot.mkbootimg_args"
60readonly BOOT_SIGNATURE_SIZE=$(( 16 << 10 ))
61
62[[ -f "$1" ]] ||
63  die "expected one input image"
64cp "$1" "${BOOT_IMAGE}"
65
66# This could fail if there already is no AVB footer.
67avbtool erase_footer --image "${BOOT_IMAGE}" 2>/dev/null ||:
68
69unpack_bootimg --boot_img "${BOOT_IMAGE}" --out "${BOOT_IMAGE_DIR}" \
70  --format=mkbootimg -0 > "${BOOT_IMAGE_ARGS}"
71
72declare -a boot_args=()
73while IFS= read -r -d '' ARG; do
74  boot_args+=("${ARG}")
75done < "${BOOT_IMAGE_ARGS}"
76
77BOOT_IMAGE_VERSION="$(get_arg --header_version "${boot_args[@]}")"
78if [[ "${BOOT_IMAGE_VERSION}" -ge 4 ]] && [[ -f "${BOOT_IMAGE_DIR}/boot_signature" ]]; then
79  cp "${BOOT_IMAGE_DIR}/boot_signature" "${VBMETA_IMAGE}"
80else
81  tail -c "${BOOT_SIGNATURE_SIZE}" "${BOOT_IMAGE}" > "${VBMETA_IMAGE}"
82fi
83
84# Keep carving out vbmeta image from the boot signature until we fail or EOF.
85# Failing is fine because there could be padding trailing the boot signature.
86while avbtool info_image --image "${VBMETA_IMAGE}" --output "${VBMETA_INFO}" 2>/dev/null; do
87  cat "${VBMETA_INFO}"
88  echo
89
90  declare -i H A X
91  H="$(cat "${VBMETA_INFO}" | grep 'Header Block:' | awk '{print $3}')"
92  A="$(cat "${VBMETA_INFO}" | grep 'Authentication Block:' | awk '{print $3}')"
93  X="$(cat "${VBMETA_INFO}" | grep 'Auxiliary Block:' | awk '{print $3}')"
94  vbmeta_size="$(( ${H} + ${A} + ${X} ))"
95
96  tail -c "+$(( ${vbmeta_size} + 1 ))" "${VBMETA_IMAGE}" > "${VBMETA_IMAGE_TEMP}"
97  cp "${VBMETA_IMAGE_TEMP}" "${VBMETA_IMAGE}"
98done
99