3cd12006bb
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
161 lines
4.9 KiB
Bash
161 lines
4.9 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
# TPM setup (both active controller and remote)
|
|
|
|
CERTIFICATE_FILE="server-cert.pem"
|
|
LOGFILE="/etc/ssl/private/.install.log"
|
|
ORIGINAL_KEY=$1
|
|
TPM_OBJECT_CONTEXT=$2
|
|
PUBLIC_KEY=$3
|
|
TPM_KEY_HIERARCHY_HANDLE=0x81010002
|
|
|
|
if [ -z "$ORIGINAL_KEY" ] || [ -z "$TPM_OBJECT_CONTEXT" ] || [ -z "$PUBLIC_KEY" ]; then
|
|
echo "ERROR: Missing required parameters"
|
|
echo "USAGE: $0 <privatekey> <tpm_context> <publickey>"
|
|
exit 1
|
|
fi
|
|
|
|
CERTIFICATE_DIR=$(dirname "${ORIGINAL_KEY}")
|
|
export TPM_DATA_DIR=$CERTIFICATE_DIR
|
|
|
|
# TPM specific environment
|
|
TPM_OBJECT_NAME="$CERTIFICATE_DIR/key.blob.name"
|
|
RESOURCEMGR_DEFAULT_PORT="2323"
|
|
|
|
### Helper functions ###
|
|
|
|
# Echo's an error and exits with provided error code
|
|
# Input : error message ($1), ret code ($2)
|
|
# Output : None
|
|
# Note : If no retcode is provided, exits with 1
|
|
error_exit () {
|
|
echo "$1"
|
|
# remove previous object context
|
|
rm -f $TPM_OBJECT_CONTEXT &> /dev/null
|
|
exit "${2:-1}"
|
|
}
|
|
|
|
# func: checkTPMTools
|
|
# check if the appropriate TPM2.0-tools are installed
|
|
#
|
|
# Input : None
|
|
# Output : None
|
|
checkTPMTools () {
|
|
declare -a helper_scripts=("tss2_createprimary"
|
|
"tss2_importpem"
|
|
"tss2_getcapability"
|
|
"tss2_load"
|
|
"tss2_contextsave"
|
|
"tss2_evictcontrol"
|
|
"tss2_flushcontext"
|
|
"create_tpm2_key"
|
|
"resourcemgr")
|
|
for src in "${helper_scripts[@]}"; do
|
|
if ! type "$src" &>/dev/null; then
|
|
error_exit "ERROR: Cannot find $src. Needed for TPM configuration"
|
|
fi
|
|
done
|
|
}
|
|
|
|
startResourceMgr () {
|
|
resourcemgr &>> $LOGFILE 2>&1 &
|
|
|
|
# ensure the resourcemgr is started
|
|
for i in {1..5}
|
|
do
|
|
sleep 0.5
|
|
MGR_RUNNING=`pidof resourcemgr`
|
|
if [ ! -z $MGR_RUNNING ]; then
|
|
break
|
|
fi
|
|
done
|
|
[ ! -z $MGR_RUNNING ] || error_exit "Unable to start TPM resourcemgr"
|
|
|
|
# check to see if the resourcemgr port is open
|
|
IS_OPEN=0
|
|
for i in {1..5}
|
|
do
|
|
sleep 0.5
|
|
_test=`netstat -an | grep $RESOURCEMGR_DEFAULT_PORT | grep -i listen`
|
|
if [ ! -z "$_test" ]; then
|
|
IS_OPEN=1
|
|
break
|
|
fi
|
|
done
|
|
[ $IS_OPEN -ne 0 ] || error_exit "Unable to initialize resourcemgr"
|
|
}
|
|
|
|
stopResourceMgr () {
|
|
# Kill any previous instances of resourcemgr
|
|
pkill -c -TERM resourcemgr &> /dev/null 2>&1
|
|
}
|
|
|
|
|
|
|
|
### Main ###
|
|
# remove previous object context
|
|
rm -f $TPM_OBJECT_CONTEXT &> /dev/null
|
|
rm -f $CERTIFICATE_DIR/*.bin &> /dev/null
|
|
|
|
tpmCheck=`lsmod | grep "tpm" -c`
|
|
[ "$tpmCheck" -ne 0 ] || error_exit "TPM Kernel Module not found. Check BIOS/Kernel configuration"
|
|
|
|
# Ensure that the appropriate TPM tool utilities are
|
|
# installed on the system
|
|
checkTPMTools
|
|
|
|
# Confirm that this is a TPM 2.0 device
|
|
TPM_VERSION=`tss2_getcapability -cap 6 | grep TPM_PT_FAMILY_INDICATOR | awk '{print $4}' | xxd -r -p`
|
|
if [ "$TPM_VERSION" != "2.0" ]; then
|
|
error_exit "ERROR: TPM Device is not version 2.0 compatible"
|
|
fi
|
|
|
|
# Start the Intel ResourceMgr to clear the NV
|
|
# as well as all stale transient handles in
|
|
# the endorsement hierarchy.
|
|
# Since ResourceMgr has a number of stability,
|
|
# and security issues, we will stop it after it
|
|
# initializes the NV and Handle space
|
|
startResourceMgr
|
|
stopResourceMgr
|
|
|
|
# Create the Endorsement Primary Key hierarchy which will be used
|
|
# for wrapping the private key. Use RSA as the primary key encryption
|
|
# and SHA 256 for hashing. Allow TPM to output the object
|
|
# handle as a file context
|
|
PRIMARY_HANDLE=`tss2_createprimary -hi e -rsa -halg sha256 | grep "Handle" | awk '{print $2}'`
|
|
[ ! -z "$PRIMARY_HANDLE" ] || error_exit "Unable to create TPM Key Hierarchy"
|
|
PRIMARY_HANDLE="0x$PRIMARY_HANDLE"
|
|
|
|
# The object context will be lost over node reboots, and needs to
|
|
# be persistently stored in TPM NV.
|
|
# evict the persistent handle if it exists previously
|
|
tss2_evictcontrol -hi o -ho $TPM_KEY_HIERARCHY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE
|
|
tss2_evictcontrol -hi o -ho $PRIMARY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE &>> $LOGFILE
|
|
[ $? -eq 0 ] || error_exit "Unable to persist Key Hierarchy in TPM memory"
|
|
|
|
tss2_flushcontext -ha $PRIMARY_HANDLE
|
|
|
|
# wrap the original private key in TPM's Endorsement key hierarchy
|
|
# this will generate a TSS key blob in ASN 1 encoding
|
|
create_tpm2_key -p $TPM_KEY_HIERARCHY_HANDLE -w $ORIGINAL_KEY $TPM_OBJECT_CONTEXT &>> $LOGFILE
|
|
[ $? -eq 0 ] || error_exit "Unable to wrap provided private key into TPM Key Hierarchy"
|
|
|
|
# the apps will also need to the public key, place it in
|
|
# the certificate dirpath
|
|
mv $PUBLIC_KEY $CERTIFICATE_DIR/$CERTIFICATE_FILE
|
|
|
|
# ensure that the TPM object and the public cert are only readable by root
|
|
chown root $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT
|
|
chmod 0600 $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT
|
|
|
|
# remove all sysinv key copy artifacts
|
|
rm -f $ORIGINAL_KEY "${ORIGINAL_KEY}.sysinv" "${PUBLIC_KEY}.sysinv" &> /dev/null
|
|
|
|
exit 0
|