92 lines
2.2 KiB
Bash
Executable File
92 lines
2.2 KiB
Bash
Executable File
#!/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}"
|