Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 136 lines (117 sloc) 3.08 KB
#!/bin/bash
#
# This script calculates a chain of sha1 hashes in the same way a TPM would
# when extending Platform Configuration Registers. This is handy when you need to
# seal a TPM key or NVRAM area to a PCR value that's not yet measured into
# the TPM.
#
# This script defaults to an initial state of 20 bytes of zeroes and files
# will be chained in the order that they appear on the command line
#
# Author: Kent Yoder <shpedoikal@gmail.com>
#
function usage
{
echo -e "usage: ${0##*/} [options] <file1> ... <fileN>"
echo -e " options:"
echo -e " -s <hash state> use <hash state> as the initial hash state. This should be"
echo -e " ascii, which will be converted to binary. The default"
echo -e " hash state is 20 bytes of zeros"
echo -e " -f <file> use <file> as the initial hash state. The file will not be"
echo -e " modified unless it is the same passed as the -o option"
echo -e " -o <file> use <file> as the output file. When the script terminates"
echo -e " <file> will contain the binary representation of the final"
echo -e " hash which allows you to chain calls to this script together"
echo -e " -h <hash1..N> use a list of ascii hash values in the calculation instead of"
echo -e " files. Useful for parsing /sys/kernel/security/tpm0/*"
}
function cleanup
{
rm -f $OUTFILE
}
function ascii_to_bin
{
ASCII=$1
OUT=$2
i=0
while test $i -lt ${#ASCII}; do
BYTE="\x${ASCII:${i}:2}"
echo -ne $BYTE >> $OUT
i=$(( $i + 2 ))
done
}
INIT_STATE=
INTERMEDIATE_SHA1_ASCII=
OUT_FILE=
HASH_MODE=0
STATE_FILE=
while getopts "hs:f:o:" opt; do
case $opt in
h)
HASH_MODE=1
;;
o)
OUT_FILE=${OPTARG}
;;
f)
STATE_FILE=${OPTARG}
if [ -n "${INIT_STATE}" ]; then
echo "-s and -f are mututally exclusive options"
exit -1
fi
;;
s)
INIT_STATE=${OPTARG}
if [ -n "${STATE_FILE}" ]; then
echo "-s and -f are mututally exclusive options"
exit -1
fi
;;
*)
usage
exit -1
;;
esac
done
shift $(($OPTIND - 1))
if [ ! -n "${OUT_FILE}" ]; then
OUTFILE=$(mktemp /tmp/${0##*/}-XXXXXX)
trap cleanup EXIT
else
OUTFILE=${OUT_FILE}
fi
if [ ! -n "${INIT_STATE}" ] ; then
INIT_STATE="0000000000000000000000000000000000000000"
fi
# if we're not using an initial state from file, put the initial state
# there manually
if [ ! -n "${STATE_FILE}" ]; then
truncate -s 0 ${OUTFILE}
ascii_to_bin ${INIT_STATE} ${OUTFILE}
elif [ "$(readlink -f ${STATE_FILE})" != "$(readlink -f ${OUTFILE})" ]; then
cp ${STATE_FILE} ${OUTFILE}
fi
FILE=$1
if [ "x${FILE}" == "x" ]; then
usage
exit -1
fi
while [ "x$FILE" != "x" ]; do
if [ ${HASH_MODE} -eq 1 ]; then
FILE_SHA1_ASCII=$FILE
else
if [ ! -e "${FILE}" ]; then
echo "File ${FILE} does not exist"
exit -1
fi
FILE_SHA1_ASCII=$(sha1sum $FILE | awk '{ print $1 }')
fi
ascii_to_bin $FILE_SHA1_ASCII $OUTFILE
INTERMEDIATE_SHA1_ASCII=$(sha1sum $OUTFILE | awk '{ print $1 }')
rm -f $OUTFILE
ascii_to_bin $INTERMEDIATE_SHA1_ASCII $OUTFILE
shift
FILE=$1
done
echo $INTERMEDIATE_SHA1_ASCII
exit 0
You can’t perform that action at this time.