#!/usr/bin/env bash # # Seal a password into the TPM 2.0 and persist it at a handle. Release of # the password is bound to a PCR policy: unsealing only succeeds if the # current PCR values match those recorded at seal time. # Requires: tpm2-tools, access to /dev/tpmrm0 (tss group or root). set -euo pipefail HANDLE="0x81010001" PCR_LIST="sha256:7" FORCE=0 usage() { cat <<-EOF Usage: $(basename "$0") [-H handle] [-l pcr-list] [-f] -H handle Persistent TPM handle to store the sealed password at (default: ${HANDLE}) -l pcr-list PCR bank and indices to bind release to, in tpm2_createpolicy --policy-pcr -l format (default: ${PCR_LIST}) -f Evict an existing object at that handle before sealing EOF } while getopts "H:l:fh" opt; do case "$opt" in H) HANDLE="$OPTARG" ;; l) PCR_LIST="$OPTARG" ;; f) FORCE=1 ;; h) usage; exit 0 ;; *) usage; exit 1 ;; esac done command -v tpm2_createprimary >/dev/null || { echo "tpm2-tools is required (apt install tpm2-tools)" >&2 exit 1 } if tpm2_readpublic -c "$HANDLE" >/dev/null 2>&1; then if [ "$FORCE" -eq 1 ]; then tpm2_evictcontrol -C o -c "$HANDLE" >/dev/null else echo "A sealed object already exists at ${HANDLE}; rerun with -f to replace it" >&2 exit 1 fi fi WORKDIR="$(mktemp -d)" trap 'rm -rf "$WORKDIR"' EXIT umask 077 read -r -s -p "Password to seal: " PASSWORD echo >&2 read -r -s -p "Confirm password: " PASSWORD_CONFIRM echo >&2 if [ "$PASSWORD" != "$PASSWORD_CONFIRM" ]; then echo "Passwords do not match" >&2 exit 1 fi tpm2_createprimary -C o -c "$WORKDIR/primary.ctx" -Q tpm2_createpolicy -Q \ --policy-pcr \ -l "$PCR_LIST" \ -L "$WORKDIR/policy.digest" printf '%s' "$PASSWORD" | tpm2_create \ -C "$WORKDIR/primary.ctx" \ -L "$WORKDIR/policy.digest" \ -i - \ -u "$WORKDIR/seal.pub" \ -r "$WORKDIR/seal.priv" \ -Q unset PASSWORD PASSWORD_CONFIRM tpm2_load \ -C "$WORKDIR/primary.ctx" \ -u "$WORKDIR/seal.pub" \ -r "$WORKDIR/seal.priv" \ -c "$WORKDIR/seal.ctx" \ -Q tpm2_evictcontrol -C o -c "$WORKDIR/seal.ctx" "$HANDLE" >/dev/null echo "Password sealed and persisted at handle ${HANDLE}, bound to PCRs ${PCR_LIST}"