#!/bin/bash
# ===================================================================
# 
# Copyright (c) 2005, Intel Corp.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions 
# are met:
#
#   * Redistributions of source code must retain the above copyright 
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above 
#     copyright notice, this list of conditions and the following 
#     disclaimer in the documentation and/or other materials provided 
#     with the distribution.
#   * Neither the name of Intel Corporation nor the names of its 
#     contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ===================================================================

VTPM_IMPL_DEFINED=1

#            |        SRC        |    TAG  |      CMD SIZE     |        ORD       | type| mode
TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x01
TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x02
TPM_CMD_CLOS=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x02
TPM_CMD_DELE=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x03

TPM_SUCCESS=00000000

TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo

# -------------------- Helpers for binary streams -----------

function str_to_hex32() {
 printf "%0.8x" $1
}

function hex32_to_bin() {
 local inst=$(str_to_hex32 $1);
 
 local n1=`echo $inst | sed 's/\(..\)....../\\\\x\1/'`
 local n2=`echo $inst | sed 's/..\(..\)..../\\\\x\1/'`
 local n3=`echo $inst | sed 's/....\(..\)../\\\\x\1/'`
 local n4=`echo $inst | sed 's/......\(..\)/\\\\x\1/'`

 echo "$n1$n2$n3$n4"
}

function vtpm_manager_cmd() {
 local cmd=$1;
 local inst=$2;
 local inst_bin=$(hex32_to_bin $inst);

 #send cmd to vtpm_manager
 printf "$cmd$inst_bin" > $TX_VTPM_MANAGER

 #recv response
 local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | xxd -ps`

 #return whether the command was successful
 if [ $resp_hex != $TPM_SUCCESS ]; then
   vtpm_fatal_error=1
   false
  else
   true
 fi
}

# ------------------ Command handlers -----------------

# Create new vtpm instance & set it up for use
function vtpm_create () {
 # Creation is handled implicitly by the manager on first setup
 # so just set it up for use
 $(vtpm_start $1)
}

# Setup vtpm instance for use.
function vtpm_start() {
 $(vtpm_manager_cmd $TPM_CMD_OPEN $1)
}

function vtpm_resume() {
 $(vtpm_manager_cmd $TPM_CMD_RESM $1)
}

# Reset the vtpm AKA clear PCRs
function vtpm_reset() {
 #not used by current implemenation
 true
}

# Shutdown the vtpm while the vm is down
# This could be a suspend of shutdown
# we cannot distinquish, so save the state
# and decide on startup if we should keep is
function vtpm_suspend() {
 $(vtpm_manager_cmd $TPM_CMD_CLOS $1)
}


function vtpm_delete() {
 local inst=$1
 if $(vtpm_manager_cmd $TPM_CMD_DELE $inst); then
   rm -f /var/vtpm/vtpm_dm_$1.data
   true
 else 
   vtpm_fatal_error=1
   false
 fi
}

function vtpm_migrate() {
 echo "Error: vTPM migration accross machines not implemented."
}

function vtpm_migrate_recover() {
 true
}

