#!/bin/bash # # Copyright (c) 2013-2017 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # # TPM setup (both active controller and remote) export TPM_INTERFACE_TYPE=dev 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 " 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") for src in "${helper_scripts[@]}"; do if ! type "$src" &>/dev/null; then error_exit "ERROR: Cannot find $src. Needed for TPM configuration" fi done } ### 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 # Clear the NV # as well as all stale transient handles in # the endorsement hierarchy. tss2_clear -hi l # 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