| #!/bin/sh |
| # |
| # 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. |
| # |
| # Determines whether a TPM firmware update is available and prints the name of |
| # the file that contains the firmware binary. |
| |
| : "${TPM_FIRMWARE_DIR:=/lib/firmware/tpm}" |
| |
| # Parse key-value pairs and assign corresponding shell variables. Keys and |
| # values are sanitized before assigning. |
| read_key_value_pairs() { |
| local prefix="$1" |
| local field_separator="$2" |
| local input="$3" |
| local key |
| local value |
| while IFS="${field_separator}" read -r key value; do |
| local sanitized_key=$( |
| echo "${key}" | tr '[:upper:] ' '[:lower:]_' | tr -cd '[:alnum:]_-') |
| local sanitized_value=$( |
| echo "${value}" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]._-') |
| export "${prefix}_${sanitized_key}=${sanitized_value}" |
| done <<EOF |
| ${input} |
| EOF |
| } |
| |
| usage() { |
| cat 1>&2 <<EOL |
| Usage: $0 <tpm-version-info> <ifx-update-info> |
| |
| Checks TPM version information to determine whether there's a TPM firmware |
| update available that can be installed. The necessary <tpm-version-info> and |
| <ifx-update-info> parameters can be retrieved via tpmc or tpm-manager. |
| EOL |
| exit 1 |
| } |
| |
| main() { |
| local tpm_version_info="$1" |
| local ifx_upgrade_info="$2" |
| |
| read_key_value_pairs tpm_version " " "${tpm_version_info}" |
| read_key_value_pairs ifx_upgrade " " "${ifx_upgrade_info}" |
| |
| # This script can only handle Infineon TPMs. |
| if [ "${tpm_version_vendor}" != "49465800" ]; then |
| return 1 |
| fi |
| |
| # Determine firmware package ID and current build number. |
| local package_id |
| local build_number |
| if [ "${ifx_upgrade_fw0_stale_version}" != "ffffeeee" ]; then |
| package_id="${ifx_upgrade_fw0_package_id}" |
| build_number="${ifx_upgrade_fw0_version}" |
| else |
| package_id="${ifx_upgrade_fw1_package_id}" |
| build_number="${ifx_upgrade_fw1_version}" |
| fi |
| |
| local pattern |
| if [ "${ifx_upgrade_status}" = "5a3c" ]; then |
| # For bootloader mode, append the target build number. |
| pattern="${package_id}_${build_number}_${ifx_upgrade_process_fw_version}" |
| else |
| # For non-bootloader mode, attempt to get the current build number |
| # from 'tpmc getver' instead. 'getver' provides more reliable information |
| # about the current version than 'ifxfui'. |
| if [ "${tpm_version_vendor_specific}" != "" ]; then |
| build_number="0000$(echo "${tpm_version_vendor_specific}" | cut -c5-8)" |
| fi |
| pattern="${package_id}_${build_number}_*" |
| fi |
| |
| # Consider all firmware images with the correct source version and sort them |
| # to pick the one with the latest target version. |
| local path="$(ls "${TPM_FIRMWARE_DIR}"/ifx/${pattern}.bin 2>/dev/null | |
| sort -r | head -n 1)" |
| |
| if [ -f "${path}" ]; then |
| echo "${path}" |
| return 0 |
| fi |
| |
| return 1 |
| } |
| |
| if [ "$(basename "$0")" = "tpm-firmware-locate-update" ]; then |
| main "$@" |
| fi |