tools: Remove the vtpm process model

Remove the old vtpm process model. It doesn't work very
well and is no longer supported.

Signed-off-by: Matthew Fioravante <matthew.fioravante@jhuapl.edu>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Matthew Fioravante committed 2012-11-13 10:47:00 +00:00
1 parent dde22055ac
commit b918dce5bb
101 files changed
+2 -17106

No files matched your search

-2
View File
@@ -18,8 +18,6 @@ SUBDIRS-$(CONFIG_XCUTILS) += xcutils
SUBDIRS-$(CONFIG_X86) += firmware
SUBDIRS-y += console
SUBDIRS-y += xenmon
SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
SUBDIRS-$(VTPM_TOOLS) += vtpm
SUBDIRS-y += xenstat
SUBDIRS-$(CONFIG_Linux) += $(SUBDIRS-libaio)
SUBDIRS-$(CONFIG_Linux) += memshr
-1
View File
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable.c
* - tools/vtpm_manager/util/hashtable.c
*/
#include "hashtable.h"
-1
View File
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable.h
* - tools/vtpm_manager/util/hashtable.h
*/
#ifndef __HASHTABLE_CWC22_H__
-5
View File
@@ -1,10 +1,5 @@
/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
/*
* There are duplicates of this code in:
* - tools/vtpm_manager/util/hashtable_itr.c
*/
#include "hashtable.h"
#include "hashtable_private.h"
#include "hashtable_itr.h"
-5
View File
@@ -1,10 +1,5 @@
/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
/*
* There are duplicates of this code in:
* - tools/vtpm_manager/util/hashtable_itr.h
*/
#ifndef __HASHTABLE_ITR_CWC22__
#define __HASHTABLE_ITR_CWC22__
#include "hashtable.h"
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable_private.h
* - tools/vtpm_manager/util/hashtable_private.h
*/
#ifndef __HASHTABLE_PRIVATE_CWC22_H__
-1
View File
@@ -40,7 +40,6 @@ m4_include([m4/fetcher.m4])
# Enable/disable options
AX_ARG_DEFAULT_DISABLE([githttp], [Download GIT repositories via HTTP])
AX_ARG_DEFAULT_ENABLE([monitors], [Disable xenstat and xentop monitoring tools])
AX_ARG_DEFAULT_DISABLE([vtpm], [Enable Virtual Trusted Platform Module])
AX_ARG_DEFAULT_DISABLE([xenapi], [Enable Xen API Bindings])
AX_ARG_DEFAULT_ENABLE([ocamltools], [Disable Ocaml tools])
AX_ARG_DEFAULT_DISABLE([miniterm], [Enable miniterm])
+1 -7
View File
@@ -25,13 +25,7 @@ vif-bridge - virtual network start/stop script in bridged mode
vif-common.sh - sourced by vif-bridge
vif-nat - xen virtual network start/stop script in NAT mode
vif-route - xen virtual network start/stop script in routed mode
vtpm - called by xen-backend.agent to bind/unbind vTPM devices
vtpm-common.sh - common code for vTPM handling
vtpm-delete - remove an entry from the vTPM table given the
domain's name
vtpm-hotplug-common.sh - sourced by vtpm
vtpm-migration.sh - sourced by external-device-migrate
xen-backend.agent - calls block, vif-*, vtpm scripts to add, remove, hotplug
xen-backend.agent - calls block, vif-* scripts to add, remove, hotplug
devices
xen-backend.rules - hotplug script rules
xend-config.sxp - default xend configuration file
-14
View File
@@ -104,20 +104,6 @@ disk = [ 'phy:hda1,hda1,w' ]
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Define to which TPM instance the user domain should communicate.
# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
# where INSTANCE indicates the instance number of the TPM the VM
# should be talking to and DOM provides the domain where the backend
# is located.
# Note that no two virtual machines should try to connect to the same
# TPM instance. The handling of all TPM instances does require
# some management effort in so far that VM configration files (and thus
# a VM) should be associated with a TPM instance throughout the lifetime
# of the VM / VM configuration file. The instance number must be
# greater or equal to 1.
#vtpm = [ 'instance=1,backend=0' ]
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
# for a domain to stop: poweroff, reboot, and crash. For each of these you
-14
View File
@@ -100,20 +100,6 @@ disk = [ 'phy:hda1,hda1,w' ]
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Define to which TPM instance the user domain should communicate.
# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
# where INSTANCE indicates the instance number of the TPM the VM
# should be talking to and DOM provides the domain where the backend
# is located.
# Note that no two virtual machines should try to connect to the same
# TPM instance. The handling of all TPM instances does require
# some management effort in so far that VM configration files (and thus
# a VM) should be associated with a TPM instance throughout the lifetime
# of the VM / VM configuration file. The instance number must be
# greater or equal to 1.
#vtpm = [ 'instance=1,backend=0' ]
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
-14
View File
@@ -136,20 +136,6 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Define to which TPM instance the user domain should communicate.
# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
# where INSTANCE indicates the instance number of the TPM the VM
# should be talking to and DOM provides the domain where the backend
# is located.
# Note that no two virtual machines should try to connect to the same
# TPM instance. The handling of all TPM instances does require
# some management effort in so far that VM configration files (and thus
# a VM) should be associated with a TPM instance throughout the lifetime
# of the VM / VM configuration file. The instance number must be
# greater or equal to 1.
#vtpm = ['instance=%d,backend=0' % (vmid) ]
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
-14
View File
@@ -121,20 +121,6 @@ disk = [ 'phy:hda%d,hda1,w' % (vmid)]
# Empty password disables authentication. Defaults to the vncpasswd
# configured in xend-config.sxp.
#----------------------------------------------------------------------------
# Define to which TPM instance the user domain should communicate.
# The vtpm entry is of the form 'instance=INSTANCE,backend=DOM'
# where INSTANCE indicates the instance number of the TPM the VM
# should be talking to and DOM provides the domain where the backend
# is located.
# Note that no two virtual machines should try to connect to the same
# TPM instance. The handling of all TPM instances does require
# some management effort in so far that VM configration files (and thus
# a VM) should be associated with a TPM instance throughout the lifetime
# of the VM / VM configuration file. The instance number must be
# greater or equal to 1.
#vtpm = ['instance=%d,backend=0' % (vmid) ]
#----------------------------------------------------------------------------
# Set the kernel command line for the new domain.
# You only need to define the IP parameters and hostname if the domain's
+1 -3
View File
@@ -18,14 +18,12 @@ XEN_SCRIPTS += vif-setup
XEN_SCRIPTS += block
XEN_SCRIPTS += block-enbd block-nbd
XEN_SCRIPTS += blktap
XEN_SCRIPTS += vtpm vtpm-delete
XEN_SCRIPTS += xen-hotplug-cleanup
XEN_SCRIPTS += external-device-migrate
XEN_SCRIPTS += vscsi
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
XEN_SCRIPT_DATA += block-common.sh
UDEV_RULES_DIR = $(CONFIG_DIR)/udev
UDEV_RULES = xen-backend.rules xend.rules
-22
View File
@@ -1,22 +0,0 @@
#!/bin/bash
dir=$(dirname "$0")
. "$dir/vtpm-hotplug-common.sh"
vtpm_fatal_error=0
case "$command" in
add)
vtpm_create_instance
;;
remove)
vtpm_remove_instance
;;
esac
if [ $vtpm_fatal_error -eq 0 ]; then
log debug "Successful vTPM operation '$command'."
success
else
fatal "Error while executing vTPM operation '$command'."
fi
-448
View File
@@ -1,448 +0,0 @@
#
# Copyright (c) 2005 IBM Corporation
# Copyright (c) 2005 XenSource Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
dir=$(dirname "$0")
. "$dir/logging.sh"
. "$dir/locking.sh"
VTPMDB="/var/vtpm/vtpm.db"
#In the vtpm-impl file some commands should be defined:
# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
if [ -r "$dir/vtpm-impl.alt" ]; then
. "$dir/vtpm-impl.alt"
elif [ -r "$dir/vtpm-impl" ]; then
. "$dir/vtpm-impl"
else
function vtpm_create () {
true
}
function vtpm_setup() {
true
}
function vtpm_start() {
true
}
function vtpm_suspend() {
true
}
function vtpm_resume() {
true
}
function vtpm_delete() {
true
}
function vtpm_migrate() {
echo "Error: vTPM migration accross machines not implemented."
}
function vtpm_migrate_local() {
echo "Error: local vTPM migration not supported"
}
function vtpm_migrate_recover() {
true
}
fi
#Find the instance number for the vtpm given the name of the domain
# Parameters
# - vmname : the name of the vm
# Return value
# Returns '0' if instance number could not be found, otherwise
# it returns the instance number in the variable 'instance'
function vtpmdb_find_instance () {
local vmname ret instance
vmname=$1
ret=0
instance=$(cat $VTPMDB | \
awk -vvmname=$vmname \
'{ \
if ( 1 != index($1,"#")) { \
if ( $1 == vmname ) { \
print $2; \
exit; \
} \
} \
}')
if [ "$instance" != "" ]; then
ret=$instance
fi
echo "$ret"
}
# Check whether a particular instance number is still available
# returns "0" if it is not available, "1" otherwise.
function vtpmdb_is_free_instancenum () {
local instance instances avail i
instance=$1
avail=1
#Allowed instance number range: 1-255
if [ $instance -eq 0 -o $instance -gt 255 ]; then
avail=0
else
instances=$(cat $VTPMDB | \
awk \
'{ \
if (1 != index($1,"#")) { \
printf("%s ",$2); \
} \
}')
for i in $instances; do
if [ $i -eq $instance ]; then
avail=0
break
fi
done
fi
echo "$avail"
}
# Get an available instance number given the database
# Returns an unused instance number
function vtpmdb_get_free_instancenum () {
local ctr instances don found
instances=$(cat $VTPMDB | \
awk \
'{ \
if (1 != index($1,"#")) { \
printf("%s ",$2); \
} \
}')
ctr=1
don=0
while [ $don -eq 0 ]; do
found=0
for i in $instances; do
if [ $i -eq $ctr ]; then
found=1;
break;
fi
done
if [ $found -eq 0 ]; then
don=1
break
fi
let ctr=ctr+1
done
echo "$ctr"
}
# Add a domain name and instance number to the DB file
function vtpmdb_add_instance () {
local res vmname inst
vmname=$1
inst=$2
if [ ! -f $VTPMDB ]; then
echo "#Database for VM to vTPM association" > $VTPMDB
echo "#1st column: domain name" >> $VTPMDB
echo "#2nd column: TPM instance number" >> $VTPMDB
fi
res=$(vtpmdb_validate_entry $vmname $inst)
if [ $res -eq 0 ]; then
echo "$vmname $inst" >> $VTPMDB
fi
}
#Validate whether an entry is the same as passed to this
#function
function vtpmdb_validate_entry () {
local res rc vmname inst
rc=0
vmname=$1
inst=$2
res=$(cat $VTPMDB | \
awk -vvmname=$vmname \
-vinst=$inst \
'{ \
if ( 1 == index($1,"#")) {\
} else \
if ( $1 == vmname && \
$2 == inst) { \
printf("1"); \
exit; \
} else \
if ( $1 == vmname || \
$2 == inst) { \
printf("2"); \
exit; \
} \
}')
if [ "$res" == "1" ]; then
rc=1
elif [ "$res" == "2" ]; then
rc=2
fi
echo "$rc"
}
#Remove an entry from the vTPM database given its domain name
#and instance number
function vtpmdb_remove_entry () {
local vmname instance VTPMDB_TMP
vmname=$1
instance=$2
VTPMDB_TMP="$VTPMDB".tmp
$(cat $VTPMDB | \
awk -vvmname=$vmname \
'{ \
if ( $1 != vmname ) { \
print $0; \
} \
'} > $VTPMDB_TMP)
if [ -e $VTPMDB_TMP ]; then
mv -f $VTPMDB_TMP $VTPMDB
vtpm_delete $instance
else
log err "Error creating temporary file '$VTPMDB_TMP'."
fi
}
# Find the reason for the creation of this device:
# Returns 'resume' or 'create'
function vtpm_get_create_reason () {
local resume
resume=$(xenstore_read $XENBUS_PATH/resume)
if [ "$resume" == "True" ]; then
echo "resume"
else
echo "create"
fi
}
#Create a vTPM instance
# If no entry in the TPM database is found, the instance is
# created and an entry added to the database.
function vtpm_create_instance () {
local res instance domname reason uuid
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
reason=$(vtpm_get_create_reason)
claim_lock vtpmdb
instance="0"
if [ "$uuid" != "" ]; then
instance=$(vtpmdb_find_instance $uuid)
fi
if [ "$instance" == "0" ]; then
domname=$(xenstore_read "$XENBUS_PATH"/domain)
instance=$(vtpmdb_find_instance $domname)
fi
if [ "$instance" == "0" -a "$reason" != "create" ]; then
release_lock vtpmdb
return
fi
if [ "$instance" == "0" ]; then
#Try to give the preferred instance to the domain
instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
if [ "$instance" != "" ]; then
res=$(vtpmdb_is_free_instancenum $instance)
if [ $res -eq 0 ]; then
instance=$(vtpmdb_get_free_instancenum)
fi
else
instance=$(vtpmdb_get_free_instancenum)
fi
vtpm_create $instance
if [ $vtpm_fatal_error -eq 0 ]; then
if [ "$uuid" != "" ]; then
vtpmdb_add_instance $uuid $instance
else
vtpmdb_add_instance $domname $instance
fi
fi
else
if [ "$reason" == "resume" ]; then
vtpm_resume $instance
else
vtpm_start $instance
fi
fi
release_lock vtpmdb
xenstore_write $XENBUS_PATH/instance $instance
}
#Remove an instance when a VM is terminating or suspending.
#Since it is assumed that the VM will appear again, the
#entry is kept in the VTPMDB file.
function vtpm_remove_instance () {
local instance reason domname uuid
#Stop script execution quietly if path does not exist (anymore)
xenstore-exists "$XENBUS_PATH"/domain
uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
claim_lock vtpmdb
instance="0"
if [ "$uuid" != "" ]; then
instance=$(vtpmdb_find_instance $uuid)
fi
if [ "$instance" == "0" ]; then
domname=$(xenstore_read "$XENBUS_PATH"/domain)
instance=$(vtpmdb_find_instance $domname)
fi
if [ "$instance" != "0" ]; then
vtpm_suspend $instance
fi
release_lock vtpmdb
}
#Remove an entry in the VTPMDB file given the domain's name
#1st parameter: The name of the domain
function vtpm_delete_instance () {
local instance
claim_lock vtpmdb
instance=$(vtpmdb_find_instance $1)
if [ "$instance" != "0" ]; then
vtpmdb_remove_entry $1 $instance
fi
release_lock vtpmdb
}
# Determine whether the given address is local to this machine
# Return values:
# "-1" : the given machine name is invalid
# "0" : this is not an address of this machine
# "1" : this is an address local to this machine
function vtpm_isLocalAddress() {
local addr res
addr=$(ping $1 -c 1 | \
awk '{ print substr($3,2,length($3)-2); exit }')
if [ "$addr" == "" ]; then
echo "-1"
return
fi
res=$(ifconfig | grep "inet addr" | \
awk -vaddr=$addr \
'{ \
if ( addr == substr($2, 6)) {\
print "1"; \
} \
}' \
)
if [ "$res" == "" ]; then
echo "0"
return
fi
echo "1"
}
# Perform a migration step. This function differentiates between migration
# to the local host or to a remote machine.
# Parameters:
# 1st: destination host to migrate to
# 2nd: name of the domain to migrate
# 3rd: the migration step to perform
function vtpm_migration_step() {
local res=$(vtpm_isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate $1 $2 $3
else
vtpm_migrate_local
fi
}
# Recover from migration due to an error. This function differentiates
# between migration to the local host or to a remote machine.
# Parameters:
# 1st: destination host the migration was going to
# 2nd: name of the domain that was to be migrated
# 3rd: the last successful migration step that was done
function vtpm_recover() {
local res
res=$(vtpm_isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate_recover $1 $2 $3
fi
}
#Determine the domain id given a domain's name.
#1st parameter: name of the domain
#return value: domain id or -1 if domain id could not be determined
function vtpm_domid_from_name () {
local id name ids
ids=$(xenstore-list /local/domain)
for id in $ids; do
name=$(xenstore-read /local/domain/$id/name)
if [ "$name" == "$1" ]; then
echo "$id"
return
fi
done
echo "-1"
}
#Determine the virtual TPM's instance number using the domain ID.
#1st parm: domain ID
function vtpm_uuid_by_domid() {
echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
}
# Determine the vTPM's UUID by the name of the VM
function vtpm_uuid_from_vmname() {
local domid=$(vtpm_domid_from_name $1)
if [ "$domid" != "-1" ]; then
echo $(vtpm_uuid_by_domid $domid)
return
fi
echo ""
}
#Add a virtual TPM instance number and its associated domain name
#to the VTPMDB file and activate usage of this virtual TPM instance
#by writing the instance number into the xenstore
#1st parm: name of virtual machine
#2nd parm: instance of associated virtual TPM
function vtpm_add_and_activate() {
local domid=$(vtpm_domid_from_name $1)
local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
vtpmdb_add_instance $vtpm_uuid $2
xenstore-write backend/vtpm/$domid/0/instance $2
fi
}
-18
View File
@@ -1,18 +0,0 @@
#!/bin/bash
# This scripts must be called the following way:
# vtpm-delete <vtpm uuid>
# or
# vtpm-delete --vmname <vm name>
dir=$(dirname "$0")
. "$dir/vtpm-common.sh"
if [ "$1" == "--vmname" ]; then
vtpm_uuid=$(vtpm_uuid_from_vmname $2)
if [ "$vtpm_uuid" != "" ];then
vtpm_delete_instance $vtpm_uuid
fi
else
vtpm_delete_instance $1
fi
@@ -1,35 +0,0 @@
#
# Copyright (c) 2005 IBM Corporation
# Copyright (c) 2005 XenSource Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
dir=$(dirname "$0")
. "$dir/xen-hotplug-common.sh"
findCommand "$@"
if [ "$command" != "online" ] &&
[ "$command" != "offline" ] &&
[ "$command" != "add" ] &&
[ "$command" != "remove" ]
then
log err "Invalid command: $command"
exit 1
fi
XENBUS_PATH="${XENBUS_PATH:?}"
. "$dir/vtpm-common.sh"
-208
View File
@@ -1,208 +0,0 @@
#!/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.
# ===================================================================
# | SRC | TAG | CMD SIZE | ORD |mtype|strt
TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\x01\\x00\\x00\\x01\\x01\\x01
TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\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_TYPE_PVM=\\x01
TPM_TYPE_HVM=\\x02
TPM_SUCCESS=00000000
TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo
VTPM_MIG=/usr/bin/vtpm_migrator
# -------------------- 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);
claim_lock vtpm_mgr
#send cmd to vtpm_manager
printf "$cmd$inst_bin" > $TX_VTPM_MANAGER
#recv response
set +e
local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | xxd -ps`
set -e
release_lock vtpm_mgr
#return whether the command was successful
if [ $resp_hex -ne $TPM_SUCCESS ]; then
vtpm_fatal_error=1
false
else
true
fi
}
# Helper to get vm type to pass to vtpm_manager open/resume
function vtpm_get_type() {
local inst=$(xenstore_read $XENBUS_PATH/frontend-id)
local vm=$(xenstore_read /local/domain/$inst/vm)
if [ "$vm" != "" ]; then
local ostype=$(xenstore-read $vm/image/ostype)
if [ "$ostype" == "hvm" ]; then
echo $TPM_TYPE_HVM;
else
echo $TPM_TYPE_PVM;
fi
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() {
local vmtype=$(vtpm_get_type);
$(vtpm_manager_cmd $TPM_CMD_OPEN$vmtype $1)
}
function vtpm_resume() {
local vmtype=$(vtpm_get_type);
$(vtpm_manager_cmd $TPM_CMD_RESM$vmtype $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
}
# Perform a migration step. This function differentiates between migration
# to the local host or to a remote machine.
# Parameters:
# 1st: destination host to migrate to
# 2nd: name of the domain to migrate
# 3rd: the migration step to perform
function vtpm_migrate() {
local instance res
instance=$(vtpmdb_find_instance $2)
if [ "$instance" == "" ]; then
log err "VTPM Migratoin failed. Unable to translation of domain name"
echo "Error: VTPM Migration failed while looking up instance number"
fi
case "$3" in
0)
#Incicate migration supported
echo "0"
;;
1)
# Get Public Key from Destination
# Call vtpm_manager's migration part 1
claim_lock vtpm_mgr
$VTPM_MIG $1 $2 $instance $3
release_lock vtpm_mgr
;;
2)
# Call manager's migration step 2 and send result to destination
# If successful remove from db
claim_lock vtpm_mgr
$VTPM_MIG $1 $2 $instance $3
release_lock vtpm_mgr
;;
3)
if `ps x | grep "$VTPM_MIG $1"`; then
log err "VTPM Migration failed to complete."
echo "Error: VTPM Migration failed to complete."
fi
;;
esac
}
function vtpm_migrate_recover() {
echo "Error: Recovery not supported yet"
}
function vtpm_migrate_local() {
echo "Error: local vTPM migration not supported"
}
-19
View File
@@ -1,19 +0,0 @@
#
# Copyright (c) 2005 IBM Corporation
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
dir=$(dirname "$0")
. "$dir/vtpm-common.sh"
-1
View File
@@ -1,6 +1,5 @@
SUBSYSTEM=="xen-backend", KERNEL=="tap*", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/blktap $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/block $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ENV{UDEV_CALL}="1", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ENV{UDEV_CALL}="1", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif"
-74
View File
@@ -1,74 +0,0 @@
XEN_ROOT = $(CURDIR)/../..
# Base definitions and rules
include $(XEN_ROOT)/tools/vtpm/Rules.mk
# Dir name for emulator (as dom0 tpm driver)
TPM_EMULATOR_DIR = tpm_emulator
# Dir name for vtpm instance
VTPM_DIR = vtpm
ORIG_DIR = orig
# Emulator tarball name
TPM_EMULATOR_NAME = tpm_emulator-0.5.1
TPM_EMULATOR_TARFILE = $(TPM_EMULATOR_NAME).tar.gz
GMP_HEADER = /usr/include/gmp.h
.PHONY: all
all: build
.PHONY: build
build: build_sub
.PHONY: install
install: build
$(MAKE) -C $(VTPM_DIR) install-recursive
.PHONY: clean
clean:
@if [ -d $(TPM_EMULATOR_DIR) ]; \
then $(MAKE) -C $(TPM_EMULATOR_DIR) clean; \
fi
@if [ -d $(VTPM_DIR) ]; \
then $(MAKE) -C $(VTPM_DIR) clean; \
fi
.PHONY: mrproper
mrproper:
rm -f $(TPM_EMULATOR_TARFILE) tpm_emulator.patch.old vtpm.patch.old
rm -rf $(TPM_EMULATOR_DIR) $(VTPM_DIR) $(ORIG_DIR)
# Download Swiss emulator
$(TPM_EMULATOR_TARFILE):
wget http://download.berlios.de/tpm-emulator/$(TPM_EMULATOR_TARFILE)
# Create vtpm dirs
$(VTPM_DIR)/tpmd/tpmd: $(TPM_EMULATOR_TARFILE) vtpm-0.5.1.patch
rm -rf $(VTPM_DIR)
tar -xzf $(TPM_EMULATOR_TARFILE)
mv $(TPM_EMULATOR_NAME) $(VTPM_DIR)
set -e; cd $(VTPM_DIR); \
patch -p1 < ../vtpm-0.5.1.patch; \
patch -p1 < ../vtpm-0.5.1-LDLIBS.patch
orig: $(TPM_EMULATOR_TARFILE)
mkdir $(ORIG_DIR);
set -e; cd $(ORIG_DIR); \
tar -xzf ../$(TPM_EMULATOR_TARFILE);
updatepatches: clean orig
find $(VTPM_DIR) -name "*.orig" -print | xargs rm -f;
mv vtpm.patch vtpm.patch.old;
diff -uprN $(TPM_EMULATOR_DIR) $(VTPM_DIR) > vtpm.patch || true;
.PHONY: build_sub
build_sub: $(VTPM_DIR)/tpmd/tpmd
set -e; if [ -e $(GMP_HEADER) ]; then \
$(MAKE) -C $(VTPM_DIR) version; \
$(MAKE) -C $(VTPM_DIR) all-recursive; \
else \
echo "=== Unable to build VTPMs. libgmp could not be found."; \
fi
-45
View File
@@ -1,45 +0,0 @@
Directory Structure
===================
tools/vtpm/tpm_emulator-0.2b.tar.gz -> TPM Emulator downloaded at build time that will
be patched and used for our vtpms
tools/vtpm/vtpm.patch -> patch applied to tpm_emulator to make vtpm
tools/vtpm/vtpm/ -> (created on build) tpm_emulator moved to ring 3,
listens on a pair of fifos for TPM commands,
persistent state is sent via named fifo to vtpm
manager, which encrypts it and protects it.
tools/vtpm/tpm_emulator.patch -> To allow for debugging and testing on non-TPM
platforms, this patches the emulator to allow
it to be inserted into the dom0 kernel
tools/vtpm/tpm_emulator-0.2 -> (created on build) directory containing patched emulator
Compile Flags
===================
VTPM_MULTI_VM -> Defined (not finished): VTPMs run in their own VMs
Not Defined (default): VTPMs are processes
Requirements
============
- xen-unstable
- IBM frontend/backend vtpm driver patch
- vtpm_managerd
- GNU MP Big number library (GMP)
vtpmd Flow (for vtpm_manager. vtpmd never run by default)
============================
- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
- VTPM Manager listens to TPM BE.
- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend.
- When the manager receives the open message from the BE, it launches a vtpm
- Xend allows the VM to continue booting.
- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
- The fifo listener begins listening for the reply from vtpm for the request.
- Vtpm processes request and replies to manager over shared named fifo.
- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
tpm_emulator flow
==================
Read documentation in tpm_emulator-0.2 directory
-26
View File
@@ -1,26 +0,0 @@
# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
include $(XEN_ROOT)/tools/Rules.mk
#
# Tool definitions
#
# General compiler flags
CFLAGS = -Werror -g3
# Generic project files
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
# Generic (non-header) dependencies
$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm/Rules.mk
$(OBJS): $(SRCS)
-include $(DEPS)
BUILD_EMULATOR = y
# Make sure these are just rules
.PHONY : all build install clean
File diff suppressed because it is too large. Load diff
-12
View File
@@ -1,12 +0,0 @@
diff -Naurp tpm_emulator-0.5.1/tpmd/Makefile tpm_emulator-0.5.1/tpmd/Makefile
--- tpm_emulator-0.5.1/tpmd/Makefile
+++ tpm_emulator-0.5.1/tpmd/Makefile
@@ -8,7 +8,7 @@ WFLAGS := -Wall -Wno-unused -Wpointer-a
#WFLAGS += -Wextra -Wcast-qual -Wmissing-prototypes -Wmissing-declarations -Wstrict-aliasing
CFLAGS += $(WFLAGS) -g -I.. -I. -O2 -fno-strict-aliasing
CFLAGS += -I../../../../tools/vtpm_manager/manager
-LDFLAGS += -lgmp
+LDLIBS += -lgmp
BINDIR := /usr/bin/
-766
View File
@@ -1,766 +0,0 @@
diff -Naurp tpm_emulator-0.5.1/Makefile tpm5-test/Makefile
--- tpm_emulator-0.5.1/Makefile 2008-02-14 03:22:48.000000000 -0500
+++ tpm5-test/Makefile 2009-07-15 09:45:28.000000000 -0400
@@ -10,7 +10,7 @@ VERSION_MINOR := 5
VERSION_BUILD := $(shell date +"%s")
VERSION_SUFFIX := .1
-SUBDIRS := tpmd tpmd_dev tddl
+SUBDIRS := tpmd
all: version all-recursive
@@ -48,12 +48,12 @@ user_install: user
modules_install: modules
@$(MAKE) -C tpmd_dev install || exit -1
-DIRS := . tpm crypto tpmd tpmd_dev tddl tpmd_dev_openbsd
+DIRS := . tpm crypto tpmd
DISTSRC := $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
DISTSRC += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.h))
-DIRS := . tpmd tpmd_dev tddl tpmd_dev_openbsd
+DIRS := . tpmd
DISTSRC += $(foreach dir, $(DIRS), $(dir)/Makefile)
-DISTSRC += ./README ./AUTHORS ./ChangeLog tpmd_dev/tpmd_dev.rules.in
+DISTSRC += ./README ./AUTHORS ./ChangeLog
DISTDIR := tpm_emulator-$(VERSION_MAJOR).$(VERSION_MINOR)$(VERSION_SUFFIX)
dist: $(DISTSRC)
diff -Naurp tpm_emulator-0.5.1/tpm/tpm_capability.c tpm5-test/tpm/tpm_capability.c
--- tpm_emulator-0.5.1/tpm/tpm_capability.c 2008-02-14 03:22:48.000000000 -0500
+++ tpm5-test/tpm/tpm_capability.c 2009-07-16 12:04:20.000000000 -0400
@@ -136,8 +136,19 @@ static TPM_RESULT cap_property(UINT32 su
case TPM_CAP_PROP_TIS_TIMEOUT:
debug("[TPM_CAP_PROP_TIS_TIMEOUT]");
- /* TODO: TPM_CAP_PROP_TIS_TIMEOUT */
- return TPM_FAIL;
+ /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */
+ UINT32 len = *respSize = 16;
+ BYTE *ptr = *resp = tpm_malloc(*respSize);
+ if (ptr == NULL ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000)) {
+ tpm_free(*resp);
+ return TPM_FAIL;
+ }
+ return TPM_SUCCESS;
+
case TPM_CAP_PROP_STARTUP_EFFECT:
debug("[TPM_CAP_PROP_STARTUP_EFFECT]");
@@ -189,8 +200,12 @@ static TPM_RESULT cap_property(UINT32 su
case TPM_CAP_PROP_DURATION:
debug("[TPM_CAP_PROP_DURATION]");
- /* TODO: TPM_CAP_PROP_DURATION */
- return TPM_FAIL;
+ /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */
+ BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0};
+ *respSize = 16;
+ *resp = tpm_malloc(*respSize);
+ memcpy(*resp,dur,16);
+
case TPM_CAP_PROP_ACTIVE_COUNTER:
debug("[TPM_CAP_PROP_ACTIVE_COUNTER]");
diff -Naurp tpm_emulator-0.5.1/tpmd/Makefile tpm5-test/tpmd/Makefile
--- tpm_emulator-0.5.1/tpmd/Makefile 2008-02-14 03:22:48.000000000 -0500
+++ tpm5-test/tpmd/Makefile 2009-07-16 12:08:26.000000000 -0400
@@ -8,9 +8,10 @@ WFLAGS := -Wall -Wno-unused -Wpointer-a
-Wwrite-strings -Wsign-compare -Wno-multichar
#WFLAGS += -Wextra -Wcast-qual -Wmissing-prototypes -Wmissing-declarations -Wstrict-aliasing
CFLAGS += $(WFLAGS) -g -I.. -I. -O2 -fno-strict-aliasing
+CFLAGS += -I../../../../tools/vtpm_manager/manager
LDFLAGS += -lgmp
-BINDIR := /usr/sbin/
+BINDIR := /usr/bin/
TPMD := tpmd
DIRS := ../tpm ../crypto
@@ -18,6 +19,8 @@ SRCS := $(foreach dir, $(DIRS), $(wil
OBJS := $(patsubst %.c, %.o, $(SRCS))
OBJS := $(foreach dir, $(DIRS), $(patsubst $(dir)/%.o, %.o, $(filter $(dir)/%.o, $(OBJS))))
+VTPM_BIN := vtpmd
+
vpath %.c $(strip $(DIRS))
all: $(TPMD)
@@ -32,10 +35,8 @@ TPMD_GROUP ?= tss
INSTALL ?= install
install: $(TPMD)
- $(INSTALL) -m 755 -o $(TPMD_USER) -g $(TPMD_GROUP) -d $(DESTDIR)/var/lib/tpm
- $(INSTALL) -m 755 -o $(TPMD_USER) -g $(TPMD_GROUP) -d $(DESTDIR)/var/run/tpm
$(INSTALL) -D -d $(DESTDIR)/$(BINDIR)
- $(INSTALL) -m 755 $(TPMD) $(DESTDIR)/$(BINDIR)
+ $(INSTALL) -m 755 $(TPMD) $(DESTDIR)/$(BINDIR)/$(VTPM_BIN)
.PHONY: all clean install
diff -Naurp tpm_emulator-0.5.1/tpmd/tpmd.c tpm5-test/tpmd/tpmd.c
--- tpm_emulator-0.5.1/tpmd/tpmd.c 2008-02-14 03:22:48.000000000 -0500
+++ tpm5-test/tpmd/tpmd.c 2009-07-16 11:19:05.000000000 -0400
@@ -32,6 +32,9 @@
#include <grp.h>
#include "tpm_emulator_config.h"
#include "tpm/tpm_emulator.h"
+#include "tpm/tpm_structures.h"
+#include "tpm/tpm_marshalling.h"
+#include "vtpm_manager.h"
#define TPM_DAEMON_NAME "tpmd"
#define TPM_CMD_BUF_SIZE 4096
@@ -39,6 +42,24 @@
#define TPM_RANDOM_DEVICE "/dev/urandom"
#undef TPM_MKDIRS
+#ifdef VTPM_MULTI_VM
+ #define DEV_BE "/dev/vtpm"
+ #define DEV_FE "/dev/tpm"
+#else
+ #define PVM_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
+ #define PVM_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
+ #define HVM_RX_FIFO_D "/var/vtpm/socks/%d.socket"
+
+ #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
+ #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
+
+ static char *vtpm_rx_name=NULL;
+#endif
+
+ static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
+
+#define BUFFER_SIZE 2048
+
static volatile int stopflag = 0;
static int is_daemon = 0;
static int opt_debug = 0;
@@ -49,6 +70,8 @@ static const char *opt_storage_file = "/
static uid_t opt_uid = 0;
static gid_t opt_gid = 0;
static int tpm_startup = 2;
+static int vtpm_type = VTPM_TYPE_PVM;
+int dmi_id = 0;
static int rand_fh;
void tpm_log(int priority, const char *fmt, ...)
@@ -90,56 +113,241 @@ uint64_t tpm_get_ticks(void)
int tpm_write_to_file(uint8_t *data, size_t data_length)
{
- int fh;
- ssize_t res;
- fh = open(opt_storage_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
- if (fh < 0) return -1;
- while (data_length > 0) {
- res = write(fh, data, data_length);
- if (res < 0) {
- close(fh);
- return -1;
- }
- data_length -= res;
- data += res;
+ int res, out_data_size, in_header_size;
+ BYTE *ptr, *out_data, *in_header;
+ UINT32 result, len, in_rsp_size;
+ UINT16 tag = VTPM_TAG_REQ;
+
+ printf("Saving NVM\n");
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_FE, O_RDWR);
+#else
+ vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
+#endif
+ }
+
+ if (vtpm_tx_fh < 0) {
+ return -1;
+ }
+
+ // Send request to VTPM Manager to encrypt data
+#ifdef VTPM_MUTLI_VM
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
+#else
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
+#endif
+
+ out_data = ptr = (BYTE *) malloc(len);
+
+ if (ptr == NULL
+#ifndef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, dmi_id)
+#endif
+ || tpm_marshal_UINT16(&ptr, &len, tag)
+#ifdef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size)
+#else
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
+#endif
+ || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
+ || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
+ free(out_data);
+ return -1;
+ }
+
+ printf("\tSending SaveNVM Command.\n");
+ res = write(vtpm_tx_fh, out_data, out_data_size);
+ free(out_data);
+ if (res != out_data_size) return -1;
+
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = vtpm_tx_fh
+#else
+ if (vtpm_rx_name == NULL) {
+ vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
+ sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
}
- close(fh);
- return 0;
+ vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
+#endif
+ }
+
+ if (vtpm_rx_fh < 0) {
+ return -1;
+ }
+
+ // Read Header of response so we can get the size & status
+#ifdef VTPM_MUTLI_VM
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ in_header = ptr = malloc(in_header_size);
+
+ printf("\tReading SaveNVM header.\n");
+ res = read(vtpm_rx_fh, in_header, in_header_size);
+
+ if ( (res != in_header_size)
+#ifndef VTPM_MUTLI_VM
+ || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
+#endif
+ || tpm_unmarshal_UINT16(&ptr, &len, &tag)
+ || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
+ || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
+ free(in_header);
+ return -1;
+ }
+ free(in_header);
+
+ if (result != VTPM_SUCCESS) {
+ return -1;
+ }
+
+#ifdef VTPM_MUTLI_VM
+ close(vtpm_tx_fh); close(vtpm_rx_fh);
+#endif
+
+ printf("\tFinishing up SaveNVM\n");
+ return (0);
}
int tpm_read_from_file(uint8_t **data, size_t *data_length)
{
- int fh;
- ssize_t res;
- size_t total_length;
- fh = open(opt_storage_file, O_RDONLY);
- if (fh < 0) return -1;
- total_length = lseek(fh, 0, SEEK_END);
- lseek(fh, 0, SEEK_SET);
- *data = tpm_malloc(total_length);
- if (*data == NULL) {
- close(fh);
- return -1;
- }
- *data_length = 0;
- while (total_length > 0) {
- res = read(fh, &(*data)[*data_length], total_length);
- if (res < 0) {
- close(fh);
- tpm_free(*data);
- return -1;
- }
- *data_length += res;
- total_length -= res;
+ int res, out_data_size, in_header_size;
+ uint8_t *ptr, *out_data, *in_header;
+ UINT16 tag = VTPM_TAG_REQ;
+ UINT32 len, in_rsp_size, result;
+#ifdef VTPM_MUTLI_VM
+ int vtpm_rx_fh, vtpm_tx_fh;
+#endif
+
+ printf("Loading NVM.\n");
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_FE, O_RDWR);
+#else
+ vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
+#endif
+ }
+
+ if (vtpm_tx_fh < 0) {
+ printf("Error in read_from_file:301\n");
+ return -1;
+ }
+
+ // Send request to VTPM Manager to encrypt data
+#ifdef VTPM_MUTLI_VM
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ out_data = ptr = (BYTE *) malloc(len);
+
+ if (ptr == NULL
+#ifndef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, dmi_id)
+#endif
+ || tpm_marshal_UINT16(&ptr, &len, tag)
+#ifdef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size)
+#else
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
+#endif
+ || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
+ free(out_data);
+ printf("Error in read_from_file:325\n");
+
+ return -1;
+ }
+
+ printf("\tSending LoadNVM command\n");
+ res = write(vtpm_tx_fh, out_data, out_data_size);
+ free(out_data);
+ if (res != out_data_size)
+ {
+ printf("Error in read_from_file:335\n");
+ return -1;
+ }
+
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = vtpm_tx_fh;
+#else
+ if (vtpm_rx_name == NULL) {
+ vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
+ sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
}
- close(fh);
- return 0;
+ vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
+#endif
+ }
+
+ if (vtpm_rx_fh < 0) {
+ printf("Error in read_from_file:352\n");
+ return -1;
+ }
+
+ // Read Header of response so we can get the size & status
+#ifdef VTPM_MUTLI_VM
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ in_header = ptr = malloc(in_header_size);
+
+ printf("\tReading LoadNVM header\n");
+ res = read(vtpm_rx_fh, in_header, in_header_size);
+
+ if ( (res != in_header_size)
+#ifndef VTPM_MUTLI_VM
+ || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
+#endif
+ || tpm_unmarshal_UINT16(&ptr, &len, &tag)
+ || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
+ || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
+ free(in_header);
+ printf("Error in read_from_file:375\n");
+ return -1;
+ }
+ free(in_header);
+
+ if (result != VTPM_SUCCESS) {
+ printf("Error in read_from_file:381\n");
+ return -1;
+ }
+
+ // Read Encrypted data from VTPM Manager
+ *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+ *data = (uint8_t *) malloc(*data_length);
+
+ printf("\tReading clear data from LoadNVM.\n");
+ res = read(vtpm_rx_fh, *data, *data_length);
+#ifdef VTPM_MUTLI_VM
+ close(vtpm_rx_fh);close(vtpm_tx_fh);
+#endif
+
+ printf("\tReturing from loading NVM\n");
+ if (res != (int)*data_length) {
+ free(*data);
+ printf("Error in read_from_file:398\n");
+ return -1;
+ } else {
+ return 0;
+ }
+
+
+
}
static void print_usage(char *name)
{
printf("usage: %s [-d] [-f] [-s storage file] [-u unix socket name] "
- "[-o user name] [-g group name] [-h] [startup mode]\n", name);
+ "[-o user name] [-g group name] [-h]"
+#ifdef VTPM_MULTI_VM
+ "clear|save|deactivated\n", name);
+#else
+ "clear|save|deactivated pvm|hvm vtpmid\n", name);
+#endif
printf(" d : enable debug mode\n");
printf(" f : forces the application to run in the foreground\n");
printf(" s : storage file to use (default: %s)\n", opt_storage_file);
@@ -205,7 +413,13 @@ static void parse_options(int argc, char
exit(EXIT_SUCCESS);
}
}
- if (optind < argc) {
+ /*Make sure we have all required options*/
+#ifdef VTPM_MULTI_VM
+#define EXTRA_OPTS 0
+#else
+#define EXTRA_OPTS 2
+#endif
+ if (optind < argc - EXTRA_OPTS ) {
debug("startup mode = '%s'", argv[optind]);
if (!strcmp(argv[optind], "clear")) {
tpm_startup = 1;
@@ -219,6 +433,25 @@ static void parse_options(int argc, char
print_usage(argv[0]);
exit(EXIT_SUCCESS);
}
+#ifndef VTPM_MULTI_VM
+ ++optind;
+ if(!strcmp(argv[optind], "pvm")) {
+ vtpm_type = VTPM_TYPE_PVM; // Get commands from vTPM Manager through fifo
+ } else if (!strcmp(argv[optind], "hvm")) {
+ vtpm_type = VTPM_TYPE_HVM; // Get commands from qemu via socket
+ } else {
+ error("Invalid vm mode '%s'; must be 'pvm', "
+ "or 'hvm' ", argv[optind]);
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ }
+ ++optind;
+ dmi_id = atoi(argv[optind]);
+#endif
+ } else {
+ error("Invalid number of arguments");
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
}
}
@@ -348,93 +581,180 @@ static int init_socket(const char *name)
static void main_loop(void)
{
- int sock, fh, res;
- int32_t in_len;
+ int32_t in_len, written;
uint32_t out_len;
- uint8_t in[TPM_CMD_BUF_SIZE], *out;
+ uint8_t in[TPM_CMD_BUF_SIZE], *out, *addressed_out;
+ int guest_id=-1;
+ int i;
+ char *vtpm_rx_file=NULL;
+ int res;
+
+#ifndef VTPM_MULTI_VM
+ int sockfd = -1;
struct sockaddr_un addr;
- socklen_t addr_len;
- fd_set rfds;
- struct timeval tv;
+ struct sockaddr_un client_addr;
+ unsigned int client_length;
+#endif
+
+ int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
+
+#ifndef VTPM_MULTI_VM
+ if (vtpm_type == VTPM_TYPE_PVM) {
+ vtpm_rx_file = malloc(10 + strlen(PVM_RX_FIFO_D));
+ sprintf(vtpm_rx_file, PVM_RX_FIFO_D, (uint32_t) dmi_id);
+ } else {
+ vtpm_rx_file = malloc(10 + strlen(HVM_RX_FIFO_D));
+ sprintf(vtpm_rx_file, HVM_RX_FIFO_D, (uint32_t) dmi_id);
+
+ if ( (sockfd = socket(PF_UNIX,SOCK_STREAM,0)) < 0) {
+ error("Unable to create socket. errno = %d\n", errno);
+ exit (-1);
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path,vtpm_rx_file );
+ unlink(addr.sun_path);
+ }
+#endif
info("staring main loop");
- /* open UNIX socket */
- sock = init_socket(opt_socket_name);
- if (sock < 0) exit(EXIT_FAILURE);
/* init tpm emulator */
- debug("initializing TPM emulator: %d", tpm_startup);
+#ifdef VTPM_MULTI_VM
+ debug("initializing TPM emulator: state=%d", tpm_startup);
+#else
+ debug("initializing TPM emulator: state=%d, type=%d, id=%d", tpm_startup, vtpm_type, dmi_id);
+#endif
tpm_emulator_init(tpm_startup);
/* start command processing */
while (!stopflag) {
/* wait for incomming connections */
debug("waiting for connections...");
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
- tv.tv_sec = 10;
- tv.tv_usec = 0;
- res = select(sock + 1, &rfds, NULL, NULL, &tv);
- if (res < 0) {
- error("select(sock) failed: %s", strerror(errno));
- break;
- } else if (res == 0) {
- continue;
- }
- addr_len = sizeof(addr);
- fh = accept(sock, (struct sockaddr*)&addr, &addr_len);
- if (fh < 0) {
- error("accept() failed: %s", strerror(errno));
- continue;
- }
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = open(DEV_BE, O_RDWR);
+#else
+ if (vtpm_type == VTPM_TYPE_PVM)
+ {
+ vtpm_rx_fh = open(vtpm_rx_file, O_RDONLY);
+ } else {
+ if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ error("Unable to bind(). errno = %d\n", errno);
+ exit (-1);
+ }
+
+ if (listen(sockfd, 10) <0) {
+ error("Unable to listen(). errno = %d\n", errno);
+ exit (-1);
+ }
+
+ memset(&client_addr, 0, sizeof(client_addr));
+ client_length = sizeof(client_addr);
+
+ vtpm_rx_fh = vtpm_tx_fh = accept(sockfd, (struct sockaddr *)&client_addr, &client_length);
+ }
+#endif
+ }
+
+ /*Error Checking*/
+ if (vtpm_rx_fh < 0) {
+ error("Failed to open devices to listen to guest.\n");
+ exit(-1);
+ }
+
/* receive and handle commands */
in_len = 0;
do {
debug("waiting for commands...");
- FD_ZERO(&rfds);
- FD_SET(fh, &rfds);
- tv.tv_sec = TPM_COMMAND_TIMEOUT;
- tv.tv_usec = 0;
- res = select(fh + 1, &rfds, NULL, NULL, &tv);
- if (res < 0) {
- error("select(fh) failed: %s", strerror(errno));
- close(fh);
- break;
- } else if (res == 0) {
-#ifdef TPMD_DISCONNECT_IDLE_CLIENTS
- info("connection closed due to inactivity");
- close(fh);
- break;
-#else
- continue;
-#endif
- }
- in_len = read(fh, in, sizeof(in));
- if (in_len > 0) {
+
+ in_len = read(vtpm_rx_fh, in, sizeof(in));
+ /*Magic size of minimum TPM command is 6*/
+ //FIXME Magic size check may not be required anymore
+ if (in_len < 6) {
+ info("Recv incomplete command of %d bytes.", in_len);
+ if (in_len <= 0) {
+ close(vtpm_rx_fh);
+ vtpm_rx_fh = -1;
+ continue;
+ }
+ } else {
+ /*Debug Printouts*/
debug("received %d bytes", in_len);
+ debug_nostop("Recv[%d]: 0x", in_len);
+ for (i=0; i< in_len; i++)
+ debug_more("%x ", in[i]);
+ debug_more("\n");
+ /*Multiple Guest check*/
+ if (guest_id == -1) {
+ guest_id = *((int32_t *) in);
+ } else {
+ if (guest_id != *((int32_t *) in) ) {
+ error("WARNING: More than one guest attached\n");
+ }
+ }
+
+ /*Open tx handle now*/
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_BE, O_RDWR);
+ vtpm_rx_fh = vtpm_tx_fh;
+#else
+ if (vtpm_type == VTPM_TYPE_PVM) {
+ vtpm_tx_fh = open(PVM_TX_FIFO, O_WRONLY);
+ } // No need to open the other direction for HVM
+#endif
+ }
+ if (vtpm_tx_fh < 0) {
+ error("Failed to open devices to respond to guest.\n");
+ exit(-1);
+ }
+
+ /*Handle the TPM command now*/
out = NULL;
- res = tpm_handle_command(in, in_len, &out, &out_len);
+ res = tpm_handle_command(in + sizeof(uint32_t), in_len - sizeof(uint32_t), &out, &out_len);
if (res < 0) {
error("tpm_handle_command() failed");
} else {
debug("sending %d bytes", out_len);
+ //FIXME this prepending may or may not be needed
+ /*Prepend the first 4 bytes of the in buffer.. why?*/
+ addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_len);
+ *(uint32_t *) addressed_out = *(uint32_t *) in;
+ memcpy(addressed_out + sizeof(uint32_t), out, out_len);
+ out_len += sizeof(uint32_t);
+ /*End Prepend*/
+
+ /*Perform write operation now*/
while (out_len > 0) {
- res = write(fh, out, out_len);
+ res = write(vtpm_tx_fh, addressed_out, out_len);
+
if (res < 0) {
error("write(%d) failed: %s", out_len, strerror(errno));
break;
- }
+ } else {
+ debug_nostop("Sent[%Zu]: ", out_len);
+ for (i=0; (unsigned int)i< out_len; i++)
+ debug_more("%x ", addressed_out[i]);
+ debug_more("\n");
+ }
out_len -= res;
}
tpm_free(out);
+ tpm_free(addressed_out);
}
}
} while (in_len > 0);
- close(fh);
+ //close(fh);
}
+
/* shutdown tpm emulator */
tpm_emulator_shutdown();
- /* close socket */
- close(sock);
- unlink(opt_socket_name);
+ /* Close handles */
+ close(vtpm_tx_fh);
+#ifndef VTPM_MULTI_VM
+ close(vtpm_rx_fh);
+ free(vtpm_rx_file);
+#endif
info("main loop stopped");
}
@@ -450,12 +770,13 @@ int main(int argc, char **argv)
/* open random device */
init_random();
/* init signal handlers */
- init_signal_handler();
+ //init_signal_handler();
/* unless requested otherwiese, fork and daemonize process */
- if (!opt_foreground) daemonize();
+ //if (!opt_foreground) daemonize();
/* start main processing loop */
main_loop();
info("stopping TPM Emulator daemon");
closelog();
return 0;
}
+
diff -Naurp tpm_emulator-0.5.1/tpmd/tpm_emulator_config.h tpm5-test/tpmd/tpm_emulator_config.h
--- tpm_emulator-0.5.1/tpmd/tpm_emulator_config.h 2008-02-14 03:22:48.000000000 -0500
+++ tpm5-test/tpmd/tpm_emulator_config.h 2009-07-16 11:25:26.000000000 -0400
@@ -29,23 +29,28 @@
/* TPM emulator configuration */
-#undef TPM_STRONG_PERSISTENCE
-#undef TPM_GENERATE_EK
+#define TPM_STRONG_PERSISTENCE
+#define TPM_GENERATE_EK
#undef TPM_GENERATE_SEED_DAA
#undef TPM_MEMORY_ALIGNMENT_MANDATORY
+extern int dmi_id;
+
/* log macros */
void tpm_log(int priority, const char *fmt, ...);
-#define debug(fmt, ...) tpm_log(LOG_DEBUG, "%s:%d: Debug: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
-#define info(fmt, ...) tpm_log(LOG_INFO, "%s:%d: Info: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
-#define error(fmt, ...) tpm_log(LOG_ERR, "%s:%d: Error: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
-#define alert(fmt, ...) tpm_log(LOG_ALERT, "%s:%d: Alert: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) tpm_log(LOG_DEBUG, "VTPMD[%d]: %s:%d: Debug: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define info(fmt, ...) tpm_log(LOG_INFO, "VTPMD[%d]: %s:%d: Info: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) tpm_log(LOG_ERR, "VTPMD[%d]: %s:%d: Error: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define alert(fmt, ...) tpm_log(LOG_ALERT, "VTPMD[%d]: %s:%d: Alert: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug_nostop(fmt, ...) tpm_log(LOG_DEBUG, "VTPMD[%d]: %s:%d: Debug: " fmt, \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug_more(fmt, ...) tpm_log(LOG_DEBUG, fmt, ## __VA_ARGS__)
/* min/max macros that also do strict type-checking */
-716
View File
@@ -1,716 +0,0 @@
diff -uprN tpm_emulator/AUTHORS vtpm/AUTHORS
--- tpm_emulator/AUTHORS 2006-12-08 12:51:29.000000000 -0800
+++ vtpm/AUTHORS 2006-12-13 16:38:52.000000000 -0800
@@ -1,3 +1,3 @@
Mario Strasser <mast@gmx.net>
Heiko Stamer <stamer@gaos.org> [DAA]
-INTEL Corp <> [Dropped to Ring3]
+INTEL Corp <> [VTPM Extensions]
diff -uprN tpm_emulator/ChangeLog vtpm/ChangeLog
--- tpm_emulator/ChangeLog 2006-12-08 12:51:29.000000000 -0800
+++ vtpm/ChangeLog 2006-12-13 16:38:52.000000000 -0800
@@ -1,5 +1,6 @@
????-??-?? Intel Corp
* Moved module out of kernel to run as a ring 3 app
+ * Modified save_to_file and load_from_file to call xen VTPM manager
2006-06-23 Mario Strasser <mast@gmx.net>
* tpm_startup.c: behaviour of ST_CLEAR and storage of
diff -uprN tpm_emulator/linux_module.h vtpm/linux_module.h
--- tpm_emulator/linux_module.h 2006-12-08 12:51:29.000000000 -0800
+++ vtpm/linux_module.h 2007-01-09 14:49:06.000000000 -0800
@@ -44,18 +44,26 @@
#define TPM_DEVICE_NAME "tpm"
#define TPM_MODULE_NAME "tpm_emulator"
+/* debug and log output functions */
+extern int dmi_id;
+
#ifdef DEBUG
-#define debug(fmt, ...) printf("TPMD: %s:%d: Debug: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug_nostop(fmt, ...) printf("TPMD[%d]: %s:%d: Debug: " fmt, \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define debug_more(fmt, ...) printf( fmt, ## __VA_ARGS__ )
#else
#define debug(fmt, ...)
+#define debug_nostop(fmt, ...)
+#define debug_more(fmt, ...)
#endif
-#define info(fmt, ...) printf("TPMD: %s:%d: Info: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
-#define error(fmt, ...) printf("TPMD: %s:%d: Error: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
-#define alert(fmt, ...) printf("TPMD: %s:%d: Alert: " fmt "\n", \
- __FILE__, __LINE__, ## __VA_ARGS__)
+#define info(fmt, ...) printf("TPMD[%d]: %s:%d: Info: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) printf("TPMD[%d]: %s:%d: Error: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
+#define alert(fmt, ...) printf("TPMD[%d]: %s:%d: Alert: " fmt "\n", \
+ dmi_id, __FILE__, __LINE__, ## __VA_ARGS__)
/* memory allocation */
diff -uprN tpm_emulator/Makefile vtpm/Makefile
--- tpm_emulator/Makefile 2006-12-08 12:51:29.000000000 -0800
+++ vtpm/Makefile 2006-12-13 16:38:52.000000000 -0800
@@ -7,7 +7,7 @@
COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
# module settings
-BIN := tpm_emulator
+BIN := vtpmd
VERSION_MAJOR := 0
VERSION_MINOR := 4
VERSION_BUILD := $(shell date +"%s")
@@ -22,7 +22,7 @@ TOOLS_INSTALL_DIR = $(DESTDIR)/usr/bin
CC := gcc
CFLAGS += -g -Wall $(INCLUDE) -DDEBUG
-CFLAGS += -I. -Itpm
+CFLAGS += -I. -Itpm -I../../vtpm_manager/manager
# Is the simulator running in it's own vm?
#CFLAGS += -DVTPM_MULTI_VM
@@ -62,7 +62,6 @@ $(BIN): $(src)/crypto/gmp.h $(src)/crypt
install: $(BIN)
$(INSTALL_PROG) $(BIN) $(TOOLS_INSTALL_DIR)
- @if [ ! -d "/var/tpm" ]; then mkdir /var/tpm; fi
clean:
rm -f $(src)/crypto/gmp.h $(src)/crypto/libgmp.a $(OBJS)
@@ -98,3 +97,4 @@ version:
@echo "#endif /* _TPM_VERSION_H_ */" >> $(src)/tpm_version.h
.PHONY: all install clean dist gmp version
+
diff -uprN tpm_emulator/tpm/tpm_capability.c vtpm/tpm/tpm_capability.c
--- tpm_emulator/tpm/tpm_capability.c 2006-06-23 03:37:07.000000000 -0700
+++ vtpm/tpm/tpm_capability.c 2007-01-10 10:00:49.000000000 -0800
@@ -136,8 +136,18 @@ static TPM_RESULT cap_property(UINT32 su
case TPM_CAP_PROP_TIS_TIMEOUT:
debug("[TPM_CAP_PROP_TIS_TIMEOUT]");
- /* TODO: TPM_CAP_PROP_TIS_TIMEOUT */
- return TPM_FAIL;
+ /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */
+ UINT32 len = *respSize = 16;
+ BYTE *ptr = *resp = tpm_malloc(*respSize);
+ if (ptr == NULL ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000) ||
+ tpm_marshal_UINT32(&ptr, &len, 200000)) {
+ tpm_free(*resp);
+ return TPM_FAIL;
+ }
+ return TPM_SUCCESS;
case TPM_CAP_PROP_STARTUP_EFFECT:
debug("[TPM_CAP_PROP_STARTUP_EFFECT]");
@@ -190,7 +200,11 @@ static TPM_RESULT cap_property(UINT32 su
case TPM_CAP_PROP_DURATION:
debug("[TPM_CAP_PROP_DURATION]");
- /* TODO: TPM_CAP_PROP_DURATION */
+ /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */
+ BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0};
+ *respSize = 16;
+ *resp = tpm_malloc(*respSize);
+ memcpy(*resp,dur,16);
return TPM_FAIL;
case TPM_CAP_PROP_ACTIVE_COUNTER:
diff -uprN tpm_emulator/tpm/tpm_cmd_handler.c vtpm/tpm/tpm_cmd_handler.c
--- tpm_emulator/tpm/tpm_cmd_handler.c 2008-02-27 16:35:41.000000000 -0500
+++ vtpm/tpm/tpm_cmd_handler.c 2008-02-28 14:43:28.000000000 -0500
@@ -94,12 +94,18 @@ void tpm_compute_out_param_digest(TPM_CO
sha1_ctx_t sha1;
UINT32 res = CPU_TO_BE32(rsp->result);
UINT32 ord = CPU_TO_BE32(ordinal);
+ UINT32 offset = 0;
/* compute SHA1 hash */
sha1_init(&sha1);
sha1_update(&sha1, (BYTE*)&res, 4);
sha1_update(&sha1, (BYTE*)&ord, 4);
- sha1_update(&sha1, rsp->param, rsp->paramSize);
+ if (ordinal == TPM_ORD_LoadKey2) {
+ offset = 4;
+ }
+ if (rsp->paramSize - offset > 0) {
+ sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset);
+ }
sha1_final(&sha1, rsp->auth1->digest);
if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest,
rsp->auth1->digest, sizeof(rsp->auth1->digest));
diff -uprN tpm_emulator/tpm/tpm_data.c vtpm/tpm/tpm_data.c
--- tpm_emulator/tpm/tpm_data.c 2008-02-27 16:35:41.000000000 -0500
+++ vtpm/tpm/tpm_data.c 2008-02-27 16:35:40.000000000 -0500
@@ -1,6 +1,7 @@
/* Software-Based Trusted Platform Module (TPM) Emulator for Linux
* Copyright (C) 2004 Mario Strasser <mast@gmx.net>,
* Swiss Federal Institute of Technology (ETH) Zurich
+ * Copyright (C) 2005 INTEL Corp
*
* This module is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
@@ -15,10 +16,15 @@
* $Id: tpm_data.c 98 2006-05-07 14:16:29Z hstamer $
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
#include "tpm_emulator.h"
#include "tpm_structures.h"
#include "tpm_marshalling.h"
-#include "linux_module.h"
+#include "vtpm_manager.h"
TPM_DATA tpmData;
@@ -158,45 +164,232 @@ void tpm_release_data(void)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h>
-#define TPM_STORAGE_FILE "/var/tpm/tpm_emulator-1.2." STR(VERSION_MAJOR) "." STR(VERSION_MINOR)
+ static int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
+
+#ifdef VTPM_MUTLI_VM
+ #define DEV_FE "/dev/tpm"
+#else
+ #define VTPM_RX_FIFO_D "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
+ #define VTPM_TX_FIFO "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
+
+ extern int dmi_id;
+ static char *vtpm_rx_name=NULL;
+#endif
static int write_to_file(uint8_t *data, size_t data_length)
{
- int res;
- int fp;
- fp = open(TPM_STORAGE_FILE, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
- res = write(fp, data, data_length);
- close(fp);
- return (res == data_length) ? 0 : -1;
+ int res, out_data_size, in_header_size;
+ BYTE *ptr, *out_data, *in_header;
+ UINT32 result, len, in_rsp_size;
+ UINT16 tag = VTPM_TAG_REQ;
+
+ printf("Saving NVM\n");
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_FE, O_RDWR);
+#else
+ vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
+#endif
+ }
+
+ if (vtpm_tx_fh < 0) {
+ return -1;
+ }
+
+ // Send request to VTPM Manager to encrypt data
+#ifdef VTPM_MUTLI_VM
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT + data_length;
+#else
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV + data_length;
+#endif
+
+ out_data = ptr = (BYTE *) malloc(len);
+
+ if (ptr == NULL
+#ifndef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, dmi_id)
+#endif
+ || tpm_marshal_UINT16(&ptr, &len, tag)
+#ifdef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size)
+#else
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
+#endif
+ || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_SAVENVM)
+ || tpm_marshal_BYTE_ARRAY(&ptr, &len, data, data_length)) {
+ free(out_data);
+ return -1;
+ }
+
+ printf("\tSending SaveNVM Command.\n");
+ res = write(vtpm_tx_fh, out_data, out_data_size);
+ free(out_data);
+ if (res != out_data_size) return -1;
+
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = vtpm_tx_fh
+#else
+ if (vtpm_rx_name == NULL) {
+ vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
+ sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
+ }
+ vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
+#endif
+ }
+
+ if (vtpm_rx_fh < 0) {
+ return -1;
+ }
+
+ // Read Header of response so we can get the size & status
+#ifdef VTPM_MUTLI_VM
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ in_header = ptr = malloc(in_header_size);
+
+ printf("\tReading SaveNVM header.\n");
+ res = read(vtpm_rx_fh, in_header, in_header_size);
+
+ if ( (res != in_header_size)
+#ifndef VTPM_MUTLI_VM
+ || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
+#endif
+ || tpm_unmarshal_UINT16(&ptr, &len, &tag)
+ || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
+ || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
+ free(in_header);
+ return -1;
+ }
+ free(in_header);
+
+ if (result != VTPM_SUCCESS) {
+ return -1;
+ }
+
+#ifdef VTPM_MUTLI_VM
+ close(vtpm_tx_fh); close(vtpm_rx_fh);
+#endif
+
+ printf("\tFinishing up SaveNVM\n");
+ return (0);
}
static int read_from_file(uint8_t **data, size_t *data_length)
{
- int res;
- int fp, file_status;
- struct stat file_info;
- fp = open(TPM_STORAGE_FILE, O_RDONLY, 0);
- file_status = fstat(fp, &file_info);
- if (file_status < 0) {
- close(fp);
- return -1;
- }
+ int res, out_data_size, in_header_size;
+ uint8_t *ptr, *out_data, *in_header;
+ UINT16 tag = VTPM_TAG_REQ;
+ UINT32 len, in_rsp_size, result;
+#ifdef VTPM_MUTLI_VM
+ int vtpm_rx_fh, vtpm_tx_fh;
+#endif
+
+ printf("Loading NVM.\n");
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_FE, O_RDWR);
+#else
+ vtpm_tx_fh = open(VTPM_TX_FIFO, O_WRONLY);
+#endif
+ }
- *data_length = file_info.st_size;
- *data = tpm_malloc(*data_length);
- if (*data == NULL) {
- close(fp);
+ if (vtpm_tx_fh < 0) {
+ return -1;
+ }
+
+ // Send request to VTPM Manager to encrypt data
+#ifdef VTPM_MUTLI_VM
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ out_data_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ out_data = ptr = (BYTE *) malloc(len);
+
+ if (ptr == NULL
+#ifndef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, dmi_id)
+#endif
+ || tpm_marshal_UINT16(&ptr, &len, tag)
+#ifdef VTPM_MUTLI_VM
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size)
+#else
+ || tpm_marshal_UINT32(&ptr, &len, out_data_size - sizeof(uint32_t))
+#endif
+ || tpm_marshal_UINT32(&ptr, &len, VTPM_ORD_LOADNVM)) {
+ free(out_data);
return -1;
}
- res = read(fp, *data, *data_length);
- close(fp);
+
+ printf("\tSending LoadNVM command\n");
+ res = write(vtpm_tx_fh, out_data, out_data_size);
+ free(out_data);
+ if (res != out_data_size) return -1;
+
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = vtpm_tx_fh;
+#else
+ if (vtpm_rx_name == NULL) {
+ vtpm_rx_name = malloc(10 + strlen(VTPM_RX_FIFO_D));
+ sprintf(vtpm_rx_name, VTPM_RX_FIFO_D, (uint32_t) dmi_id);
+ }
+ vtpm_rx_fh = open(vtpm_rx_name, O_RDONLY);
+#endif
+ }
+
+ if (vtpm_rx_fh < 0) {
+ return -1;
+ }
+
+ // Read Header of response so we can get the size & status
+#ifdef VTPM_MUTLI_VM
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_CLT;
+#else
+ in_header_size = len = VTPM_COMMAND_HEADER_SIZE_SRV;
+#endif
+ in_header = ptr = malloc(in_header_size);
+
+ printf("\tReading LoadNVM header\n");
+ res = read(vtpm_rx_fh, in_header, in_header_size);
+
+ if ( (res != in_header_size)
+#ifndef VTPM_MUTLI_VM
+ || tpm_unmarshal_UINT32(&ptr, &len, (UINT32*)&dmi_id)
+#endif
+ || tpm_unmarshal_UINT16(&ptr, &len, &tag)
+ || tpm_unmarshal_UINT32(&ptr, &len, &in_rsp_size)
+ || tpm_unmarshal_UINT32(&ptr, &len, &result) ) {
+ free(in_header);
+ return -1;
+ }
+ free(in_header);
+
+ if (result != VTPM_SUCCESS) {
+ return -1;
+ }
+
+ // Read Encrypted data from VTPM Manager
+ *data_length = in_rsp_size - VTPM_COMMAND_HEADER_SIZE_CLT;
+ *data = (uint8_t *) malloc(*data_length);
+
+ printf("\tReading clear data from LoadNVM.\n");
+ res = read(vtpm_rx_fh, *data, *data_length);
+#ifdef VTPM_MUTLI_VM
+ close(vtpm_rx_fh);close(vtpm_tx_fh);
+#endif
+
+ printf("\tReturing from loading NVM\n");
if (res != *data_length) {
- tpm_free(*data);
- return -1;
+ free(*data);
+ return -1;
+ } else {
+ return 0;
}
- return 0;
+
}
#else
diff -uprN tpm_emulator/tpmd.c vtpm/tpmd.c
--- tpm_emulator/tpmd.c 2006-12-08 12:51:29.000000000 -0800
+++ vtpm/tpmd.c 2007-01-09 14:48:56.000000000 -0800
@@ -21,12 +21,24 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
#include "tpm_emulator.h"
+#include "vtpm_manager.h"
-#define TPM_RX_FNAME "/var/tpm/tpm_in.fifo"
-#define TPM_TX_FNAME "/var/tpm/tpm_out.fifo"
+#ifdef VTPM_MULTI_VM
+ #define DEV_BE "/dev/vtpm"
+#else
+ #define PVM_RX_FIFO_D "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
+ #define PVM_TX_FIFO "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
+ #define HVM_RX_FIFO_D "/var/vtpm/socks/%d.socket"
+#endif
+
+ int dmi_id;
+
#define BUFFER_SIZE 2048
static int devurandom=0;
@@ -38,7 +50,7 @@ void get_random_bytes(void *buf, int nby
}
if (read(devurandom, buf, nbytes) != nbytes) {
- printf("Can't get random number.\n");
+ error("Can't get random number.\n");
exit(-1);
}
}
@@ -52,105 +64,182 @@ uint64_t tpm_get_ticks(void)
int main(int argc, char **argv)
{
- uint8_t in[BUFFER_SIZE], *out;
+ uint8_t type, in[BUFFER_SIZE], *out, *addressed_out;
+ char *vtpm_rx_file=NULL;
uint32_t out_size;
int in_size, written;
- int i;
- struct stat file_info;
+ int i, guest_id=-1;
- int tpm_tx_fh=-1, tpm_rx_fh=-1;
+#ifndef VTPM_MULTI_VM
+ int sockfd = -1;
+ struct sockaddr_un addr;
+ struct sockaddr_un client_addr;
+ unsigned int client_length;
+
+#endif
+
+ int vtpm_tx_fh=-1, vtpm_rx_fh=-1;
+#ifdef VTPM_MULTI_VM
if (argc < 2) {
- printf("Usage: tpmd clear|save|deactivated\n" );
+ error("Usage: tpmd clear|save|deactivated\n" );
+#else
+ if (argc < 4) {
+ error("Usage: tpmd clear|save|deactivated pvm|hvm vtpmid\n" );
+#endif
return -1;
}
+#ifndef VTPM_MULTI_VM
+ /* setup type of vm */
+ if (!strcmp(argv[2], "pvm")) {
+ type = VTPM_TYPE_PVM; // Get commands from vTPM Manager through fifo
+ } else if (!strcmp(argv[2], "hvm")) {
+ type = VTPM_TYPE_HVM; // Get commands from qemu via socket
+ } else {
+ error("invalid vTPM type '%s'.\n", argv[2]);
+ }
+
+ dmi_id = atoi(argv[3]);
+
+ if (type == VTPM_TYPE_PVM) {
+ vtpm_rx_file = malloc(10 + strlen(PVM_RX_FIFO_D));
+ sprintf(vtpm_rx_file, PVM_RX_FIFO_D, (uint32_t) dmi_id);
+ } else {
+ vtpm_rx_file = malloc(10 + strlen(HVM_RX_FIFO_D));
+ sprintf(vtpm_rx_file, HVM_RX_FIFO_D, (uint32_t) dmi_id);
+
+ if ( (sockfd = socket(PF_UNIX,SOCK_STREAM,0)) < 0) {
+ error("Unable to create socket. errno = %d\n", errno);
+ exit (-1);
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path,vtpm_rx_file );
+ unlink(addr.sun_path);
+ }
+#endif
+
+#ifdef VTPM_MULTI_VM
+ info("Initializing tpm state: %s\n", argv[1]);
+#else
+ info("Initializing tpm state: %s, type: %s, id: %d\n", argv[1], argv[2], dmi_id);
+#endif
+
/* initialize TPM emulator */
if (!strcmp(argv[1], "clear")) {
- printf("Initializing tpm: %s\n", argv[1]);
tpm_emulator_init(1);
- } else if (!strcmp(argv[1], "save")) {
- printf("Initializing tpm: %s\n", argv[1]);
+ } else if (!strcmp(argv[1], "save")) {
tpm_emulator_init(2);
} else if (!strcmp(argv[1], "deactivated")) {
- printf("Initializing tpm: %s\n", argv[1]);
tpm_emulator_init(3);
} else {
- printf("invalid startup mode '%s'; must be 'clear', "
+ error("invalid startup mode '%s'; must be 'clear', "
"'save' (default) or 'deactivated", argv[1]);
return -1;
}
-
- if ( stat(TPM_RX_FNAME, &file_info) == -1) {
- if ( mkfifo(TPM_RX_FNAME, S_IWUSR | S_IRUSR ) ) {
- printf("Failed to create fifo %s.\n", TPM_RX_FNAME);
- return -1;
- }
- }
-
- if ( stat(TPM_TX_FNAME, &file_info) == -1) {
- if ( mkfifo(TPM_TX_FNAME, S_IWUSR | S_IRUSR ) ) {
- printf("Failed to create fifo %s.\n", TPM_TX_FNAME);
- return -1;
- }
- }
-
+
while (1) {
abort_command:
- if (tpm_rx_fh < 0) {
- tpm_rx_fh = open(TPM_RX_FNAME, O_RDONLY);
+ if (vtpm_rx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_rx_fh = open(DEV_BE, O_RDWR);
+#else
+ if (type == VTPM_TYPE_PVM) {
+ vtpm_rx_fh = open(vtpm_rx_file, O_RDONLY);
+ } else {
+ if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ error("Unable to bind(). errno = %d\n", errno);
+ exit (-1);
+ }
+
+ if (listen(sockfd, 10) <0) {
+ error("Unable to listen(). errno = %d\n", errno);
+ exit (-1);
+ }
+
+ memset(&client_addr, 0, sizeof(client_addr));
+ client_length = sizeof(client_addr);
+
+ vtpm_rx_fh = vtpm_tx_fh = accept(sockfd, (struct sockaddr *)&client_addr, &client_length);
+ }
+#endif
}
- if (tpm_rx_fh < 0) {
- printf("ERROR: failed to open devices to listen to guest.\n");
+ if (vtpm_rx_fh < 0) {
+ error("Failed to open devices to listen to guest.\n");
return -1;
}
- if (tpm_tx_fh < 0) {
- tpm_tx_fh = open(TPM_TX_FNAME, O_WRONLY);
- }
-
- if (tpm_tx_fh < 0) {
- printf("ERROR: failed to open devices to respond to guest.\n");
- return -1;
- }
-
- in_size = read(tpm_rx_fh, in, BUFFER_SIZE);
+ in_size = read(vtpm_rx_fh, in, BUFFER_SIZE);
if (in_size < 6) { // Magic size of minium TPM command
- printf("Recv[%d] to small: 0x", in_size);
+ info("Recv incomplete command of %d bytes.", in_size);
if (in_size <= 0) {
- close(tpm_rx_fh);
- tpm_rx_fh = -1;
+ close(vtpm_rx_fh);
+ vtpm_rx_fh = -1;
goto abort_command;
}
} else {
- printf("Recv[%d]: 0x", in_size);
+ debug_nostop("Recv[%d]: 0x", in_size);
for (i=0; i< in_size; i++)
- printf("%x ", in[i]);
- printf("\n");
+ debug_more("%x ", in[i]);
+ debug_more("\n");
}
-
- if (tpm_handle_command(in, in_size, &out, &out_size) != 0) {
- printf("ERROR: Handler Failed.\n");
+ if (guest_id == -1) {
+ guest_id = *((uint32_t *) in);
+ } else {
+ if (guest_id != *((uint32_t *) in) ) {
+ error("WARNING: More than one guest attached\n");
+ }
+ }
+
+ if (vtpm_tx_fh < 0) {
+#ifdef VTPM_MUTLI_VM
+ vtpm_tx_fh = open(DEV_BE, O_RDWR);
+ vtpm_rx_fh = vtpm_tx_fh;
+#else
+ if (type == VTPM_TYPE_PVM) {
+ vtpm_tx_fh = open(PVM_TX_FIFO, O_WRONLY);
+ } // No need to open the other direction for HVM
+#endif
+ }
+
+ if (vtpm_tx_fh < 0) {
+ error("Failed to open devices to respond to guest.\n");
+ return -1;
+ }
+
+ // Handle the command, but skip the domain id header
+ if (tpm_handle_command(in + sizeof(uint32_t), in_size - sizeof(uint32_t), &out, &out_size) != 0) {
+ error("Handler Failed.\n");
}
- written = write(tpm_tx_fh, out, out_size);
+ addressed_out = (uint8_t *) tpm_malloc(sizeof(uint32_t) + out_size);
+ *(uint32_t *) addressed_out = *(uint32_t *) in;
+ memcpy(addressed_out + sizeof(uint32_t), out, out_size);
+
+ written = write(vtpm_tx_fh, addressed_out, out_size + sizeof(uint32_t));
- if (written != out_size ) {
- printf("ERROR: Part of response not written %d/%d.\nAttempt: ", written, out_size);
+ if (written != out_size + sizeof(uint32_t)) {
+ error("Part of response not written %d/%d.\n", written, out_size);
} else {
- printf("Sent[%Zu]: ", out_size);
+ debug_nostop("Sent[%Zu]: ", out_size + sizeof(uint32_t));
+ for (i=0; i< out_size+ sizeof(uint32_t); i++)
+ debug_more("%x ", addressed_out[i]);
+ debug_more("\n");
}
- for (i=0; i< out_size; i++)
- printf("%x ", out[i]);
- printf("\n");
tpm_free(out);
+ tpm_free(addressed_out);
} // loop
tpm_emulator_shutdown();
- close(tpm_tx_fh);
- close(tpm_rx_fh);
+ close(vtpm_tx_fh);
+#ifndef VTPM_MUTLI_VM
+ close(vtpm_rx_fh);
+ free (vtpm_rx_file);
+#endif
}
-32
View File
@@ -1,32 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
-18
View File
@@ -1,18 +0,0 @@
XEN_ROOT = $(CURDIR)/../..
# Base definitions and rules
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
SUBDIRS = crypto tcs util manager migration
OPENSSL_HEADER = /usr/include/openssl/crypto.h
.PHONY: all clean install
all clean install: %: subdirs-%
.PHONY: mrproper
mrproper:
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
-94
View File
@@ -1,94 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
Directory Structure
===================
tools/vtpm_manager/crypto -> crypto files
tools/vtpm_manager/TCS -> TCS implementation
tools/vtpm_manager/util -> Utility Library. Include disk-io and buffers.
tools/vtpm_manager/manager -> VTPM Manager
Compile Flags
===================
LOGGING_MODULES -> How extensive logging happens
see util/log.h for more info
VTPM_MULTI_VM -> Defined: VTPMs run in their own VMs
Not Defined (default): VTPMs are processes
# Debugging flags that may disappear without notice in the future
DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and
/tmp/out.fifo rather than backend
MANUAL_DM_LAUNCH -> Must manually launch & kill VTPMs
WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password for the owner,
use a well known value. This is useful for debugging and for
poor bios which do not support clearing TPM if OwnerAuth is
lost. However this has no protection from malicious app
issuing a TPM_OwnerClear to wipe the TPM
Requirements
============
- xen-unstable
- vtpm frontend/backend driver patch
- OpenSSL Library
Single-VM Flow
============================
- Launch the VTPM manager (vtpm_managerd) which which begins listening to the BE with one thread
and listens to a named fifo that is shared by the vtpms to commuincate with the manager.
- VTPM Manager listens to TPM BE.
- When xend launches a tpm frontend equipped VM it contacts the manager over the vtpm backend.
- When the manager receives the open message from the BE, it launches a vtpm
- Xend allows the VM to continue booting.
- When a TPM request is issued to the front end, the front end transmits the TPM request to the backend.
- The manager receives the TPM requests and uses a named fifo to forward the request to the vtpm.
- The fifo listener begins listening for the reply from vtpm for the request.
- Vtpm processes request and replies to manager over shared named fifo.
- If needed, the vtpm may send a request to the vtpm_manager at any time to save it's secrets to disk.
- Manager receives response from vtpm and passes it back to backend for forwarding to guest.
NOTES:
* SaveService SHOULD seal it's table before saving it to disk. However,
the current Xen infrastructure does not provide a mechanism for this to be
unsealed later. Specifically, the auth and wrapped key must be available ONLY
to the service, or it's not even worth encrypting
In the future the vtpm manager will be protected by an early boot mechanism
that will allow for better protection of it's data.
TODO:
- Timeout on crashed vtpms
- create lock for shared fifo for talking to vtpms.
-59
View File
@@ -1,59 +0,0 @@
# Base definitions and rules (XEN_ROOT must be defined in including Makefile)
include $(XEN_ROOT)/tools/Rules.mk
#
# Tool definitions
#
# General compiler flags
CFLAGS = -Werror -g3
# Generic project files
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
# Generic (non-header) dependencies
$(SRCS): Makefile $(XEN_ROOT)/tools/Rules.mk $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
$(OBJS): $(SRCS)
-include $(FILES)
# Make sure these are just rules
.PHONY : all build install clean
#
# Project-specific definitions
#
# Need UNIX98 spec for pthread rwlocks
CFLAGS += -D_GNU_SOURCE
# Logging Level. See utils/tools.h for usage
CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMASK(VTPM_LOG_VTPM))"
# Silent Mode
#CFLAGS += -DLOGGING_MODULES=0x0
#CFLAGS += -DLOGGING_MODULES=0xff
# Use frontend/backend pairs between manager & DMs?
#CFLAGS += -DVTPM_MULTI_VM
# vtpm_manager listens on fifo's rather than backend
#CFLAGS += -DDUMMY_BACKEND
# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
#CFLAGS += -DDUMMY_TPM
# Do not have manager launch DMs.
#CFLAGS += -DMANUAL_DM_LAUNCH
# Fixed OwnerAuth
#CFLAGS += -DWELL_KNOWN_OWNER_AUTH
# Include
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/crypto
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/util
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/tcs
CFLAGS += -I$(XEN_ROOT)/tools/vtpm_manager/manager
-24
View File
@@ -1,24 +0,0 @@
XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
BIN = libtcpaCrypto.a
.PHONY: all
all: build
.PHONY: build
build: $(BIN)
.PHONY: install
install: build
.PHONY: clean
clean:
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
.PHONY: mrproper
mrproper: clean
rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
-88
View File
@@ -1,88 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// crypto.c
//
// This file will handle all the TPM Crypto functionality
//
// ==================================================================
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "crypto.h"
#include "log.h"
/**
* Initialize cryptography library
* @rand: random seed
* @size: size of @rand
*/
void Crypto_Init(const BYTE* rand, int size) {
ERR_load_crypto_strings();
CRYPTO_malloc_init();
OpenSSL_add_all_algorithms();
SYM_CIPHER = EVP_aes_128_cbc();
RAND_poll();
if (rand == NULL)
return;
RAND_add(rand, size, size);
}
/**
* Shutdown cryptography library
*/
void Crypto_Exit() {
ERR_free_strings();
ERR_remove_state(0);
EVP_cleanup();
}
/**
* Get random data
* @data: (OUT) Random data
* @size: Size of @data
*/
void Crypto_GetRandom(void* data, int size) {
int result;
result = RAND_pseudo_bytes((BYTE*) data, size);
if (result <= 0)
vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: %s\n",
ERR_error_string (ERR_get_error(), NULL));
}
-175
View File
@@ -1,175 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// crypto.h
//
// This file defines the TPM Crypto API
//
// ==================================================================
#ifndef __CRYPTO_H__
#define __CRYPTO_H__
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "tcg.h"
#include "sym_crypto.h"
#define CRYPTO_MAX_SIG_SIZE (2048 / 8)
#define CRYPTO_MAX_RSA_KEY_SIZE (4096 / 8) //in bytes
#define OAEP_P "TCPA"
#define OAEP_P_SIZE 4
// Algorithms supported by crypto. Stored in CRYPTO_INFO.algorithmID
#define CRYPTO_ALGORITH_RSA 0x01
// Supported Encryption Schemes CRYPTO_INFO.encScheme
#define CRYPTO_ES_NONE 0x0001
#define CRYPTO_ES_RSAESPKCSv15 0x0002
#define CRYPTO_ES_RSAESOAEP_SHA1_MGF1 0x0003
// Supported Signature schemes CRYPTO_INFO.sigScheme
#define CRYPTO_SS_NONE 0x0001
#define CRYPTO_SS_RSASSAPKCS1v15_SHA1 0x0002
#define CRYPTO_SS_RSASSAPKCS1v15_DER 0x0003
typedef struct CRYPTO_INFO {
void *keyInfo;
UINT32 algorithmID;
UINT32 encScheme;
UINT32 sigScheme;
} CRYPTO_INFO;
void Crypto_Init(const BYTE* rand, int size);
void Crypto_Exit();
void Crypto_GetRandom(void* data, int size);
void Crypto_HMAC( const BYTE* text,
int text_len,
const BYTE* key,
int key_len,
BYTE* digest);
TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
const buffer_t * key,
BYTE * o_digest); /* presumably of 20 bytes */
void Crypto_SHA1Full( const BYTE* text,
UINT32 size,
BYTE* hash); //Complete 3part SHA1
// o_hash needs to be large enough to hold the digest, ie 20 bytes
TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
BYTE * o_hash);
void Crypto_SHA1Start(UINT32* maxNumBytes);
void Crypto_SHA1Update(int numBytes, const BYTE* hashData);
void Crypto_SHA1Complete( int hashDataSize,
const BYTE* hashData,
BYTE* hashValue);
void Crypto_RSACreateKey( /*in*/ UINT32 keySize,
/*in*/ UINT32 pubExpSize,
/*in*/ BYTE *pubExp,
/*out*/ UINT32 *privExpSize,
/*out*/ BYTE *privExp,
/*out*/ UINT32 *modulusSize,
/*out*/ BYTE *modulus,
/*out*/ CRYPTO_INFO *keys);
void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize,
/*[IN]*/ BYTE *pubExp,
/*[IN]*/ UINT32 privExpSize,
/*[IN]*/ BYTE *privExp,
/*[IN]*/ UINT32 modulusSize,
/*[IN]*/ BYTE *modulus,
/*[OUT]*/ CRYPTO_INFO* cryptoInfo);
void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/ UINT32 pubExpSize,
/*[IN]*/ BYTE *pubExp,
/*[IN]*/ UINT32 modulusSize,
/*[IN]*/ BYTE *modulus,
CRYPTO_INFO* cryptoInfo);
//
// symmetric pack and unpack operations
//
TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
BYTE ** io_buf, UINT32 * io_buflen);
TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
BYTE * in, UINT32 len,
UINT32 * o_lenread);
// return 0 on success, -1 on error
int Crypto_RSAEnc( CRYPTO_INFO *keys,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *outDataSize,
/*out*/ BYTE *outData);
// return 0 on success, -1 on error
int Crypto_RSADec( CRYPTO_INFO *keys,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *outDataSize,
/*out*/ BYTE *outData);
// return 0 on success, -1 on error
int Crypto_RSASign( CRYPTO_INFO *keys,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *sigSize,
/*out*/ BYTE *sig);
bool Crypto_RSAVerify( CRYPTO_INFO *keys,
UINT32 inDataSize,
BYTE *inData,
UINT32 sigSize,
BYTE *sig);
//private:
int RSA_verify_DER(int dtype, unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, CRYPTO_INFO *key);
int RSA_sign_DER(int type, unsigned char *m, unsigned int m_len,
unsigned char *sigret, unsigned int *siglen, CRYPTO_INFO *key);
#endif // __CRYPTO_H__
-153
View File
@@ -1,153 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// hash.c
//
// This file will handle all the TPM Hash functionality
//
// ==================================================================
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include "tcg.h" // for TPM_SUCCESS
#include "crypto.h"
static SHA_CTX g_shaContext;
void Crypto_HMAC( const BYTE* text,
int text_len,
const BYTE* key,
int key_len,
BYTE* digest) {
if (text == NULL || key == NULL || text_len == 0 || key_len == 0)
return;
HMAC(EVP_sha1(), key, key_len, text, text_len, digest, NULL);
}
TPM_RESULT Crypto_HMAC_buf (const buffer_t * text,
const buffer_t * key,
BYTE * o_digest) { /* presumably of 20 bytes */
Crypto_HMAC (text->bytes, text->size,
key->bytes, key->size,
o_digest);
return TPM_SUCCESS;
}
/*
* SHA1
* (OUT) Create a SHA1 hash of text. Calls all three SHA1 steps internally
*/
void Crypto_SHA1Full( const BYTE* text,
uint32_t size,
BYTE* hash) {
if (text == NULL || size == 0)
return;
// Run SHA1Start + SHAUpdate (if necessary) + SHAComplete
uint32_t maxBytes; // Not used for anything
Crypto_SHA1Start(&maxBytes);
while (size > 64){
Crypto_SHA1Update(64, text);
size -= 64;
text += 64;
}
Crypto_SHA1Complete(size, text, hash);
}
// same thing using buffer_t
TPM_RESULT Crypto_SHA1Full_buf (const buffer_t * buf,
BYTE * o_digest) {
if (buf->bytes == NULL || buf->size == 0)
return TPM_BAD_PARAMETER;
Crypto_SHA1Full (buf->bytes, buf->size, o_digest);
return TPM_SUCCESS;
}
/*
* Initialize SHA1
* (OUT) Maximum number of bytes that can be sent to SHA1Update.
* Must be a multiple of 64 bytes.
*/
void Crypto_SHA1Start(uint32_t* maxNumBytes) {
int max = SHA_CBLOCK;
// Initialize the crypto library
SHA1_Init(&g_shaContext);
*maxNumBytes = max;
}
/*
* Process SHA1
* @numBytes: (IN) The number of bytes in hashData.
* Must be a multiple of 64 bytes.
* @hashData: (IN) Bytes to be hashed.
*/
void Crypto_SHA1Update(int numBytes, const BYTE* hashData) {
if (hashData == NULL || numBytes == 0 || numBytes%64 != 0)
return;
SHA1_Update(&g_shaContext, hashData, numBytes);
}
/*
* Complete the SHA1 process
* @hashDataSize: (IN) Number of bytes in hashData.
* Must be a multiple of 64 bytes.
* @hashData: (IN) Final bytes to be hashed.
* @hashValue: (OUT) The output of the SHA-1 hash.
*/
void Crypto_SHA1Complete(int hashDataSize,
const BYTE* hashData,
BYTE* hashValue) {
SHA1_Update(&g_shaContext, hashData, hashDataSize);
SHA1_Final(hashValue, &g_shaContext);
}
-434
View File
@@ -1,434 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// rsa.c
//
// This file will handle all the TPM RSA crypto functionality
//
// ==================================================================
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <stdio.h>
#include "tcg.h"
#include "buffer.h"
#include "crypto.h"
#include "log.h"
void Crypto_RSACreateKey( /*in*/ UINT32 keySize,
/*in*/ UINT32 pubExpSize,
/*in*/ BYTE *pubExp,
/*out*/ UINT32 *privExpSize,
/*out*/ BYTE *privExp,
/*out*/ UINT32 *modulusSize,
/*out*/ BYTE *modulus,
/*out*/ CRYPTO_INFO *keys) {
unsigned long e_value;
if (pubExpSize == 0) // Default e = 2^16+1
e_value = (0x01 << 16) + 1;
else {
// This is not supported, but the following line MIGHT work
// under then assumption that the format is BigNum compatable
// Though it's not in the spec, so who knows what it is.
// Forcing the default.
//BN_bin2bn(pubExp, pubExpSize, NULL);
e_value = (0x01 << 16) + 1;
}
RSA *rsa = RSA_generate_key(keySize, e_value, NULL, NULL);
if (keys) {
keys->keyInfo = rsa;
keys->algorithmID = CRYPTO_ALGORITH_RSA;
}
if (modulus) *modulusSize = BN_bn2bin(rsa->n, modulus);
if (privExp) *privExpSize = BN_bn2bin(rsa->d, privExp);
}
// Create a CRYPTO_INFO struct from the BYTE * key parts.
// If pubExp info is NULL, use TCG default.
// If there is a remainder while calculating the privExp, return FALSE.
void Crypto_RSABuildCryptoInfo( /*[IN]*/ UINT32 pubExpSize,
/*[IN]*/ BYTE *pubExp,
/*[IN]*/ UINT32 privExpSize,
/*[IN]*/ BYTE *privExp,
/*[IN]*/ UINT32 modulusSize,
/*[IN]*/ BYTE *modulus,
CRYPTO_INFO* cryptoInfo) {
cryptoInfo->keyInfo = RSA_new();
RSA *rsa = (RSA *) cryptoInfo->keyInfo;
rsa->e = BN_new();
if (pubExpSize == 0) { // Default e = 2^16+1
BN_set_bit(rsa->e, 16);
BN_set_bit(rsa->e, 0);
} else {
// This is not supported, but the following line MIGHT work
// under then assumption that the format is BigNum compatable
// Though it's not in the spec, so who knows what it is.
// Forcing the default.
//BN_bin2bn(pubExp, pubExpSize, NULL);
BN_set_bit(rsa->e, 16);
BN_set_bit(rsa->e, 0);
}
rsa->n = BN_bin2bn(modulus, modulusSize, NULL);
rsa->d = BN_bin2bn(privExp, privExpSize, NULL);
}
// Create a CRYPTO_INFO struct from the BYTE * key parts.
// If pubExp info is NULL, use TCG default.
// If there is a remainder while calculating the privExp, return FALSE.
void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/ UINT32 pubExpSize,
/*[IN]*/ BYTE *pubExp,
/*[IN]*/ UINT32 modulusSize,
/*[IN]*/ BYTE *modulus,
CRYPTO_INFO* cryptoInfo) {
cryptoInfo->keyInfo = RSA_new();
RSA *rsa = (RSA *) cryptoInfo->keyInfo;
rsa->e = BN_new();
if (pubExpSize == 0) { // Default e = 2^16+1
BN_set_bit(rsa->e, 16);
BN_set_bit(rsa->e, 0);
} else {
// This is not supported, but the following line MIGHT work
// under then assumption that the format is BigNum compatable
// Though it's not in the spec, so who knows what it is.
// Forcing the default.
//BN_bin2bn(pubExp, pubExpSize, NULL);
BN_set_bit(rsa->e, 16);
BN_set_bit(rsa->e, 0);
}
rsa->n = BN_bin2bn(modulus, modulusSize, NULL);
}
int Crypto_RSAEnc( CRYPTO_INFO *key,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *outDataSize,
/*out*/ BYTE *outData) {
RSA *rsa = (RSA *) key->keyInfo;
UINT32 paddedDataSize = RSA_size (rsa);
BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);
int rc;
if (paddedData == NULL)
return -1;
*outDataSize = 0;
switch (key->encScheme) {
case CRYPTO_ES_RSAESPKCSv15:
if (RSA_padding_add_PKCS1_type_2(paddedData, paddedDataSize, inData, inDataSize) <= 0) {
rc = -1;
goto abort_egress;
}
break;
case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:
if (RSA_padding_add_PKCS1_OAEP(paddedData,paddedDataSize,inData,inDataSize, (BYTE *) OAEP_P,OAEP_P_SIZE) <= 0 ) {
rc = -1;
goto abort_egress;
}
break;
default:
rc = -1;
goto abort_egress;
}
rc = RSA_public_encrypt(paddedDataSize, paddedData, outData, rsa, RSA_NO_PADDING);
if (rc == -1)
goto abort_egress;
*outDataSize = rc;
if (rc > 0) rc = 0;
goto egress;
abort_egress:
egress:
if (paddedData)
free (paddedData);
return rc;
}
int Crypto_RSADec( CRYPTO_INFO *key,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *outDataSize,
/*out*/ BYTE *outData) {
RSA *rsa = (RSA *) key->keyInfo;
UINT32 paddedDataSize = RSA_size (rsa);
BYTE *paddedData = (BYTE *)malloc(sizeof(BYTE) * paddedDataSize);
int rc;
if (paddedData == NULL)
goto abort_egress;
rc = RSA_private_decrypt(inDataSize, inData, paddedData, rsa, RSA_NO_PADDING);
if (rc == -1) {
vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_private_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto abort_egress;
}
paddedDataSize = rc;
switch (key->encScheme) {
case CRYPTO_ES_RSAESPKCSv15:
rc = RSA_padding_check_PKCS1_type_2 (outData, paddedDataSize,
paddedData + 1, paddedDataSize - 1,
RSA_size(rsa));
if (rc == -1) {
vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_type_2: %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto abort_egress;
}
*outDataSize = rc;
break;
case CRYPTO_ES_RSAESOAEP_SHA1_MGF1:
rc = RSA_padding_check_PKCS1_OAEP(outData, paddedDataSize,
paddedData + 1, paddedDataSize - 1,
RSA_size(rsa),
(BYTE *) OAEP_P, OAEP_P_SIZE);
if (rc == -1) {
vtpmlogerror(VTPM_LOG_CRYPTO, "RSA_padding_check_PKCS1_OAEP: %s\n",
ERR_error_string(ERR_get_error(), NULL));
goto abort_egress;
}
*outDataSize = rc;
break;
default:
*outDataSize = 0;
}
free(paddedData); paddedData = NULL;
goto egress;
abort_egress:
if (paddedData)
free (paddedData);
return -1;
egress:
return 0;
}
// Signs either a SHA1 digest of a message or a DER encoding of a message
// Textual messages MUST be encoded or Hashed before sending into this function
// It will NOT SHA the message.
int Crypto_RSASign( CRYPTO_INFO *key,
UINT32 inDataSize,
BYTE *inData,
/*out*/ UINT32 *sigSize,
/*out*/ BYTE *sig) {
int status;
unsigned int intSigSize;
switch(key->sigScheme) {
case CRYPTO_SS_RSASSAPKCS1v15_SHA1:
status = RSA_sign(NID_sha1, inData, inDataSize, sig, &intSigSize, (RSA *) key->keyInfo);
break;
case CRYPTO_SS_RSASSAPKCS1v15_DER:
// status = Crypto_RSA_sign_DER(NID_md5_sha1, inData, inDataSize, sig, &intSigSize, key);
vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", key->sigScheme);
status = 0;
break;
default:
status = 0;
}
if (status == 0) {
*sigSize = 0;
vtpmlogerror(VTPM_LOG_CRYPTO, "%s\n", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
*sigSize = (UINT32) intSigSize;
return 0;
}
bool Crypto_RSAVerify( CRYPTO_INFO *key,
UINT32 inDataSize,
BYTE *inData,
UINT32 sigSize,
BYTE *sig) {
int status;
switch(key->sigScheme){
case CRYPTO_SS_RSASSAPKCS1v15_SHA1:
status = RSA_verify(NID_sha1, inData, inDataSize, sig, sigSize, (RSA *) key->keyInfo);
break;
case CRYPTO_SS_RSASSAPKCS1v15_DER:
//status = Crypto_RSA_verify_DER(NID_md5_sha1, inData, inDataSize, sig, sigSize, key);
vtpmlogerror(VTPM_LOG_CRYPTO, "Crypto: Unimplemented sign type (%d)\n", key->sigScheme);
status = 0;
break;
default:
status = 0;
}
if (status)
return(1);
else {
vtpmlogerror(VTPM_LOG_CRYPTO, "RSA verify: %s\n", ERR_error_string(ERR_get_error(), NULL));
return(0);
}
}
// helper which packs everything into a BIO!
// packs the parameters first, then the private key, then the public key
// if *io_buf is NULL, allocate it here as needed. otherwise its size is in
// *io_buflen
TPM_RESULT Crypto_RSAPackCryptoInfo (const CRYPTO_INFO* cryptoInfo,
BYTE ** io_buf, UINT32 * io_buflen) {
TPM_RESULT status = TPM_SUCCESS;
BYTE * buf;
long len, outlen = *io_buflen;
const long PARAMSLEN = 3*sizeof(UINT32);
RSA *rsa = (RSA *) cryptoInfo->keyInfo;
BIO *mem = BIO_new(BIO_s_mem());
// write the openssl keys to the BIO
if ( i2d_RSAPrivateKey_bio (mem, rsa) == 0 ) {
ERR_print_errors_fp (stderr);
ERRORDIE (TPM_SIZE);
}
if ( i2d_RSAPublicKey_bio (mem, rsa) == 0 ) {
ERR_print_errors_fp (stderr);
ERRORDIE (TPM_SIZE);
}
// get the buffer out
len = BIO_get_mem_data (mem, &buf);
// see if we need to allocate a return buffer
if (*io_buf == NULL) {
*io_buf = (BYTE*) malloc (PARAMSLEN + len);
if (*io_buf == NULL)
ERRORDIE (TPM_SIZE);
} else { // *io_buf is already allocated
if (outlen < len + PARAMSLEN)
ERRORDIE (TPM_SIZE); // but not large enough!
}
// copy over the parameters (three UINT32's starting at algorithmID)
memcpy (*io_buf, &cryptoInfo->algorithmID, PARAMSLEN);
// copy over the DER keys
memcpy (*io_buf + PARAMSLEN, buf, len);
*io_buflen = len + PARAMSLEN;
goto egress;
abort_egress:
egress:
BIO_free (mem);
return status;
}
// sets up ci, and returns the number of bytes read in o_lenread
TPM_RESULT Crypto_RSAUnpackCryptoInfo (CRYPTO_INFO * ci,
BYTE * in, UINT32 len,
UINT32 * o_lenread) {
TPM_RESULT status = TPM_SUCCESS;
long l;
BIO *mem;
RSA *rsa;
// first load up the params
l = 3 * sizeof(UINT32);
memcpy (&ci->algorithmID, in, l);
len -= l;
in += l;
// and now the openssl keys, private first
mem = BIO_new_mem_buf (in, len);
if ( (rsa = d2i_RSAPrivateKey_bio (mem, NULL)) == NULL ) {
ERR_print_errors_fp (stderr);
ERRORDIE (TPM_BAD_PARAMETER);
}
// now use the same RSA object and fill in the private key
if ( d2i_RSAPublicKey_bio (mem, &rsa) == NULL ) {
ERR_print_errors_fp (stderr);
ERRORDIE (TPM_BAD_PARAMETER);
}
ci->keyInfo = rsa; // needs to be freed somehow later
// FIXME: havent figured out yet how to tell how many bytes were read in the
// above oprations! so o_lenread is not set
goto egress;
abort_egress:
egress:
BIO_free (mem);
return status;
}
-237
View File
@@ -1,237 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// sym_crypto.c
//
// Symmetric crypto portion of crypto
//
// ==================================================================
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "tcg.h"
#include "sym_crypto.h"
typedef enum crypt_op_type_t {
CRYPT_ENCRYPT,
CRYPT_DECRYPT
} crypt_op_type_t;
TPM_RESULT ossl_symcrypto_op (symkey_t* key,
const buffer_t* in,
const buffer_t* iv,
buffer_t * out,
crypt_op_type_t optype);
// this is initialized in Crypto_Init()
const EVP_CIPHER * SYM_CIPHER = NULL;
const BYTE ZERO_IV[EVP_MAX_IV_LENGTH] = {0};
TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits) {
TPM_RESULT status = TPM_SUCCESS;
EVP_CIPHER_CTX_init (&key->context);
key->cipher = SYM_CIPHER;
TPMTRYRETURN( buffer_init_copy (&key->key, keybits));
goto egress;
abort_egress:
EVP_CIPHER_CTX_cleanup (&key->context);
egress:
return status;
}
TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
int res;
TPM_RESULT status = TPM_SUCCESS;
// hmm, EVP_CIPHER_CTX_init does not return a value
EVP_CIPHER_CTX_init (&key->context);
key->cipher = SYM_CIPHER;
TPMTRYRETURN( buffer_init (&key->key, EVP_CIPHER_key_length(key->cipher), NULL)) ;
// and generate the key material
res = RAND_pseudo_bytes (key->key.bytes, key->key.size);
if (res < 0)
ERRORDIE (TPM_SHORTRANDOM);
goto egress;
abort_egress:
EVP_CIPHER_CTX_cleanup (&key->context);
buffer_free (&key->key);
egress:
return status;
}
TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
const buffer_t* clear,
buffer_t* o_cipher) {
TPM_RESULT status = TPM_SUCCESS;
buffer_t iv, cipher_alias;
buffer_init_const (&iv, EVP_MAX_IV_LENGTH, ZERO_IV);
buffer_init (o_cipher,
clear->size +
EVP_CIPHER_iv_length(key->cipher) +
EVP_CIPHER_block_size (key->cipher),
0);
// copy the IV into the front
buffer_copy (o_cipher, &iv);
// make an alias into which we'll put the ciphertext
buffer_init_alias (&cipher_alias, o_cipher, EVP_CIPHER_iv_length(key->cipher), 0);
TPMTRYRETURN( ossl_symcrypto_op (key, clear, &iv, &cipher_alias, CRYPT_ENCRYPT) );
// set the output size correctly
o_cipher->size += cipher_alias.size;
goto egress;
abort_egress:
egress:
return status;
}
TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
const buffer_t* cipher,
buffer_t* o_clear) {
TPM_RESULT status = TPM_SUCCESS;
buffer_t iv, cipher_alias;
// alias for the IV
buffer_init_alias (&iv, cipher, 0, EVP_CIPHER_iv_length(key->cipher));
// make an alias to where the ciphertext is, after the IV
buffer_init_alias (&cipher_alias, cipher, EVP_CIPHER_iv_length(key->cipher), 0);
// prepare the output buffer
TPMTRYRETURN( buffer_init (o_clear,
cipher->size
- EVP_CIPHER_iv_length(key->cipher)
+ EVP_CIPHER_block_size(key->cipher),
0) );
// and decrypt
TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear, CRYPT_DECRYPT) );
goto egress;
abort_egress:
buffer_free (o_clear);
egress:
return status;
}
TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) {
buffer_memset (&key->key, 0);
buffer_free (&key->key);
EVP_CIPHER_CTX_cleanup (&key->context);
return TPM_SUCCESS;
}
TPM_RESULT ossl_symcrypto_op (symkey_t* key,
const buffer_t* in,
const buffer_t* iv,
buffer_t * out,
crypt_op_type_t optype) {
TPM_RESULT status = TPM_SUCCESS;
int inlen, outlen;
tpm_size_t running;
if ( ! EVP_CipherInit_ex (&key->context,
key->cipher, NULL, key->key.bytes, iv->bytes,
optype == CRYPT_ENCRYPT ? 1 : 0) )
ERRORDIE (TPM_FAIL);
inlen = in->size;
outlen = 0;
running = 0;
if ( ! EVP_CipherUpdate (&key->context, out->bytes, &outlen, in->bytes, inlen) )
ERRORDIE (TPM_FAIL);
running += outlen;
if ( ! EVP_CipherFinal_ex (&key->context, out->bytes + running, &outlen) )
ERRORDIE (TPM_FAIL);
running += outlen;
out->size = running;
goto egress;
abort_egress:
egress:
return status;
}
-72
View File
@@ -1,72 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// sym_crypto.h
//
// Symmetric Crypto
//
// ==================================================================
#ifndef _SYM_CRYPTO_H
#define _SYM_CRYPTO_H
#include <openssl/evp.h>
#include "buffer.h"
typedef struct symkey_t {
buffer_t key;
EVP_CIPHER_CTX context;
const EVP_CIPHER * cipher;
} symkey_t;
extern const EVP_CIPHER * SYM_CIPHER;
TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key);
TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t* keybits);
// these functions will allocate their output buffers
TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
const buffer_t* clear,
buffer_t* o_cipher);
TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
const buffer_t* cipher,
buffer_t* o_clear);
// only free the internal parts, not the 'key' ptr
TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key);
#endif /* _SYM_CRYPTO_H */
-38
View File
@@ -1,38 +0,0 @@
XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
BIN = vtpm_managerd
.PHONY: all
all: build
.PHONY: build
build: $(BIN)
.PHONY: install
install: build
if [ ! -d "$(DESTDIR)/var/vtpm/fifos" ]; \
then mkdir -p $(DESTDIR)/var/vtpm/fifos; \
fi
if [ ! -d "$(DESTDIR)/var/vtpm/socks" ]; \
then mkdir -p $(DESTDIR)/var/vtpm/socks; \
fi
$(INSTALL_PROG) $(BIN) $(DESTDIR)$(BINDIR)
.PHONY: clean
clean:
rm -f $(BIN)
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
.PHONY: mrproper
mrproper: clean
rm -f *~
$(BIN): $(OBJS)
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
# libraries
LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
LIBS += -lcrypto $(PTHREAD_LIBS) -lm
CFLAGS += $(PTHREAD_CFLAGS)
LDFLAGS += $(PTHREAD_LDFLAGS)
-266
View File
@@ -1,266 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// dmictl.c
//
// Functions for creating and destroying DMIs
//
// ==================================================================
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "vtpmpriv.h"
#include "bsg.h"
#include "buffer.h"
#include "log.h"
#include "hashtable.h"
#include "hashtable_itr.h"
#include "vtpm_ipc.h"
#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
// if dmi_res is non-null, then return a pointer to new object.
// Also, this does not fill in the measurements. They should be filled by
// design dependent code or saveNVM
TPM_RESULT init_dmi(UINT32 dmi_id, BYTE dmi_type, VTPM_DMI_RESOURCE **dmi_res) {
TPM_RESULT status=TPM_SUCCESS;
VTPM_DMI_RESOURCE *new_dmi=NULL;
UINT32 *dmi_id_key=NULL;
if ((new_dmi = (VTPM_DMI_RESOURCE *) malloc (sizeof(VTPM_DMI_RESOURCE))) == NULL) {
status = TPM_RESOURCES;
goto abort_egress;
}
memset(new_dmi, 0, sizeof(VTPM_DMI_RESOURCE));
new_dmi->dmi_id = dmi_id;
new_dmi->dmi_type = dmi_type;
new_dmi->connected = FALSE;
new_dmi->TCSContext = 0;
new_dmi->NVMLocation = (char *) malloc(11 + strlen(DMI_NVM_FILE));
sprintf(new_dmi->NVMLocation, DMI_NVM_FILE, (uint32_t) new_dmi->dmi_id);
if ((dmi_id_key = (UINT32 *) malloc (sizeof(UINT32))) == NULL) {
status = TPM_RESOURCES;
goto abort_egress;
}
*dmi_id_key = new_dmi->dmi_id;
// install into map
if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, new_dmi)){
vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance into table. Aborting.\n", dmi_id);
status = TPM_FAIL;
goto abort_egress;
}
if (dmi_res)
*dmi_res = new_dmi;
goto egress;
abort_egress:
if (new_dmi) {
free(new_dmi->NVMLocation);
free(new_dmi);
}
free(dmi_id_key);
egress:
return status;
}
TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) {
if (dmi_res == NULL)
return TPM_SUCCESS;
if (dmi_res->dmi_id == VTPM_CTL_DM)
return(TPM_BAD_PARAMETER);
TCS_CloseContext(dmi_res->TCSContext);
dmi_res->connected = FALSE;
vtpm_globals->connected_dmis--;
return (VTPM_Close_DMI_Extra(dmi_res) );
}
TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) {
VTPM_DMI_RESOURCE *new_dmi=NULL;
TPM_RESULT status=TPM_FAIL;
BYTE dmi_type, vm_type, startup_mode;
UINT32 dmi_id;
if (param_buf == NULL) { // Assume creation of Dom 0 control
dmi_type = VTPM_TYPE_NON_MIGRATABLE;
dmi_id = VTPM_CTL_DM;
} else if (buffer_len(param_buf) != sizeof(BYTE) * 3 + sizeof(UINT32)) {
vtpmloginfo(VTPM_LOG_VTPM, "New DMI command wrong length: %d.\n", buffer_len(param_buf));
status = TPM_BAD_PARAMETER;
goto abort_egress;
} else {
vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
BSG_UnpackList( param_buf->bytes, 4,
BSG_TYPE_BYTE, &dmi_type,
BSG_TYPE_BYTE, &startup_mode,
BSG_TYPE_BYTE, &vm_type,
BSG_TYPE_UINT32, &dmi_id);
}
if ((dmi_type != VTPM_TYPE_NON_MIGRATABLE) && (dmi_type != VTPM_TYPE_MIGRATABLE)) {
vtpmlogerror(VTPM_LOG_VTPM, "Creation of VTPM with illegal type.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
new_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
if (new_dmi == NULL) {
vtpmloginfo(VTPM_LOG_VTPM, "Creating new DMI instance %d attached.\n", dmi_id );
// Brand New DMI. Initialize the persistent pieces
TPMTRYRETURN(init_dmi(dmi_id, dmi_type, &new_dmi) );
} else
vtpmloginfo(VTPM_LOG_VTPM, "Re-attaching DMI instance %d.\n", dmi_id);
if (new_dmi->connected) {
vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach, currently attached instance %d. Ignoring\n", dmi_id);
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
if (new_dmi->dmi_type == VTPM_TYPE_MIGRATED) {
vtpmlogerror(VTPM_LOG_VTPM, "Attempt to re-attach previously migrated instance %d without recovering first. Ignoring\n", dmi_id);
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// Initialize the Non-persistent pieces
TPMTRYRETURN( TCS_OpenContext(&new_dmi->TCSContext) );
new_dmi->connected = TRUE;
// Design specific new DMI code.
// Includes: create IPCs, Measuring DMI, and maybe launching DMI
TPMTRYRETURN(VTPM_New_DMI_Extra(new_dmi, vm_type, startup_mode) );
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to create DMI id=%d due to status=%s. Cleaning.\n", dmi_id, tpm_get_error_name(status));
close_dmi(new_dmi );
egress:
return status;
}
TPM_RESULT VTPM_Handle_Close_DMI( const buffer_t *param_buf) {
TPM_RESULT status=TPM_FAIL;
VTPM_DMI_RESOURCE *dmi_res=NULL;
UINT32 dmi_id;
if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
BSG_UnpackList( param_buf->bytes, 1,
BSG_TYPE_UINT32, &dmi_id);
vtpmloginfo(VTPM_LOG_VTPM, "Closing DMI %d.\n", dmi_id);
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
if (dmi_res == NULL ) {
vtpmlogerror(VTPM_LOG_VTPM, "Trying to close nonexistent DMI.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
if (!dmi_res->connected) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing non-connected DMI.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// Close Dmi
TPMTRYRETURN(close_dmi( dmi_res ));
status=TPM_SUCCESS;
goto egress;
abort_egress:
egress:
return status;
}
TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t *param_buf) {
TPM_RESULT status=TPM_FAIL;
VTPM_DMI_RESOURCE *dmi_res=NULL;
UINT32 dmi_id;
if ((param_buf == NULL) || (buffer_len(param_buf) != sizeof(UINT32)) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing DMI has bad size.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
BSG_UnpackList( param_buf->bytes, 1,
BSG_TYPE_UINT32, &dmi_id);
vtpmloginfo(VTPM_LOG_VTPM, "Deleting DMI %d.\n", dmi_id);
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_remove(vtpm_globals->dmi_map, &dmi_id);
if (dmi_res == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing non-existent DMI.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
//vtpm scripts delete file dmi_res->NVMLocation for us
// Close DMI first
TPMTRYRETURN(close_dmi( dmi_res ));
free ( dmi_res );
status=TPM_SUCCESS;
goto egress;
abort_egress:
egress:
return status;
}
-307
View File
@@ -1,307 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// dmictl.c
//
// Functions for creating and destroying DMIs
//
// ==================================================================
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "vtpmpriv.h"
#include "bsg.h"
#include "buffer.h"
#include "log.h"
#include "hashtable.h"
TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
buffer_t *result_buf) {
TPM_RESULT status=TPM_FAIL;
VTPM_DMI_RESOURCE *mig_dmi=NULL;
UINT32 dmi_id;
buffer_t dmi_state_abuf = NULL_BUF, enc_dmi_abuf = NULL_BUF, clear_dmi_blob = NULL_BUF;
if (param_buf == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad parameter.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
struct pack_buf_t enc_dmi_state_pack;
BSG_UnpackList(param_buf->bytes, 2,
BSG_TYPE_UINT32, &dmi_id,
BSG_TPM_SIZE32_DATA, &enc_dmi_state_pack) ;
vtpmloginfo(VTPM_LOG_VTPM, "Migrating VTPM in dmi %d.\n", dmi_id);
mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
if (mig_dmi) {
vtpmlogerror(VTPM_LOG_VTPM, "Incoming VTPM claims unavailable id: %d.\n", dmi_id);
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/** UnBind Blob **/
TPMTRYRETURN( buffer_init_alias_convert( &enc_dmi_abuf,
enc_dmi_state_pack.size,
enc_dmi_state_pack.data) );
TPMTRYRETURN( envelope_decrypt( &enc_dmi_abuf,
vtpm_globals->manager_tcs_handle,
vtpm_globals->storageKeyHandle,
(const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
&clear_dmi_blob) );
// Create new dmi
TPMTRYRETURN( init_dmi(dmi_id, VTPM_TYPE_MIGRATABLE, &mig_dmi ) );
/** Open Blob **/
struct pack_buf_t dmi_state_pack;
BSG_UnpackList(clear_dmi_blob.bytes, 2,
BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
BSG_TPM_SIZE32_DATA, &dmi_state_pack);
TPMTRYRETURN( buffer_init_alias_convert(&dmi_state_abuf,
dmi_state_pack.size,
dmi_state_pack.data) );
TPMTRYRETURN( VTPM_Handle_Save_NVM(mig_dmi, &dmi_state_abuf, NULL ) );
status=TPM_SUCCESS;
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration IN of instance %d failed because of %s.\n", dmi_id, tpm_get_error_name(status) );
egress:
buffer_free(&clear_dmi_blob);
buffer_free(&dmi_state_abuf);
return status;
}
TPM_RESULT VTPM_Handle_Migrate_Out( const buffer_t *param_buf,
buffer_t *result_buf) {
TPM_RESULT status=TPM_FAIL;
VTPM_DMI_RESOURCE *mig_dmi;
UINT32 dmi_id;
VTPM_MIGKEY_LIST *last_mig, *mig_key;
buffer_t dmi_state=NULL_BUF, clear_dmi_blob=NULL_BUF;
if (param_buf == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad parameter.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
struct pack_buf_t name_pack;
BSG_UnpackList( param_buf->bytes, 2,
BSG_TYPE_UINT32, &dmi_id,
BSG_TPM_SIZE32_DATA, &name_pack);
vtpmloginfo(VTPM_LOG_VTPM, "Migrating out dmi %d.\n", dmi_id);
mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
if (mig_dmi == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Non-existent VTPM instance (%d) in migration.\n", dmi_id );
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
if (mig_dmi->dmi_type != VTPM_TYPE_MIGRATABLE) {
vtpmlogerror(VTPM_LOG_VTPM, "Bad VTPM type (%d) in migration of instance (%d).\n", mig_dmi->dmi_type, dmi_id );
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/** Find migration key for dest **/
last_mig = NULL;
mig_key = vtpm_globals->mig_keys;
while (mig_key != NULL) {
if (mig_key->name_size == name_pack.size)
if (memcmp(mig_key->name, name_pack.data, name_pack.size) == 0) {
break;
}
last_mig = mig_key;
mig_key = mig_key->next;
}
if (!mig_key) {
vtpmlogerror(VTPM_LOG_VTPM, "Unknown Migration target host.\n");
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/** Mark vtpm as migrated **/
mig_dmi->dmi_type = VTPM_TYPE_MIGRATED;
/** Build Blob **/
TPMTRYRETURN( VTPM_Handle_Load_NVM(mig_dmi, NULL, &dmi_state) );
TPMTRYRETURN( buffer_init(&clear_dmi_blob, sizeof(TPM_DIGEST) + sizeof(UINT32) + buffer_len(&dmi_state), NULL ) );
struct pack_constbuf_t dmi_state_pack;
dmi_state_pack.size = buffer_len(&dmi_state);
dmi_state_pack.data = dmi_state.bytes;
BSG_PackList(clear_dmi_blob.bytes, 2,
BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
BSG_TPM_SIZE32_DATA, &dmi_state_pack);
/** Bind Blob **/
TPMTRYRETURN( envelope_encrypt( &clear_dmi_blob,
&mig_key->key,
result_buf) );
if (last_mig)
last_mig->next = mig_key->next;
else
vtpm_globals->mig_keys = mig_key->next;
free(mig_key->name);
free(mig_key);
status=TPM_SUCCESS;
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration OUT of instance %d failed because of %s. Migratoin recovery may be needed.\n", dmi_id, tpm_get_error_name(status) );
//TODO: Create and implement a policy for what happens to mig_key on failed migrations.
egress:
buffer_free(&clear_dmi_blob);
buffer_free(&dmi_state);
return status;
}
TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
buffer_t *result_buf) {
TPM_RESULT status=TPM_FAIL;
vtpmloginfo(VTPM_LOG_VTPM, "Getting Migration Public Key.\n");
struct pack_buf_t pubkey_exp_pack, pubkey_mod_pack;
TPM_KEY mig_key;
// Unpack/return key structure
BSG_Unpack(BSG_TPM_KEY, vtpm_globals->storageKeyWrap.bytes , &mig_key);
TPM_RSA_KEY_PARMS rsaKeyParms;
BSG_Unpack(BSG_TPM_RSA_KEY_PARMS,
mig_key.algorithmParms.parms,
&rsaKeyParms);
pubkey_exp_pack.size = rsaKeyParms.exponentSize;
pubkey_exp_pack.data = rsaKeyParms.exponent;
pubkey_mod_pack.size = mig_key.pubKey.keyLength;
pubkey_mod_pack.data = mig_key.pubKey.key;
TPMTRYRETURN( buffer_init( result_buf, 2*sizeof(UINT32) +
pubkey_exp_pack.size +
pubkey_mod_pack.size, NULL ) );
BSG_PackList( result_buf->bytes, 2,
BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
status=TPM_SUCCESS;
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "VTPM Get Migration Key failed because of %s.\n", tpm_get_error_name(status) );
egress:
return status;
}
TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
buffer_t *result_buf) {
TPM_RESULT status=TPM_FAIL;
VTPM_MIGKEY_LIST *mig_key;
vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
//FIXME: Review all uses of unpacking pack_buf_t and ensure free.
//FIXME: Review all declarations/initializations of buffer_t that could have a goto that skips them and then tries to free them
struct pack_buf_t name_pack, pubkey_exp_pack, pubkey_mod_pack;
//FIXME: scan list and verify name is not already in the list
BSG_UnpackList( param_buf->bytes, 3,
BSG_TPM_SIZE32_DATA, &name_pack,
BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
//TODO: Maintain a persistent list for pub_keys.
//TODO: Verify pub_key is trusted
mig_key = (VTPM_MIGKEY_LIST *) malloc(sizeof(VTPM_MIGKEY_LIST));
memset(mig_key, 0, sizeof(VTPM_MIGKEY_LIST) );
mig_key->name_size = name_pack.size;
mig_key->name = name_pack.data;
mig_key->key.encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
Crypto_RSABuildCryptoInfoPublic( pubkey_exp_pack.size,
pubkey_exp_pack.data,
pubkey_mod_pack.size,
pubkey_mod_pack.data,
&mig_key->key);
mig_key->next = vtpm_globals->mig_keys;
vtpm_globals->mig_keys = mig_key;
// free(name_pack.data); Do not free. data is now part of mig_key.
free(pubkey_exp_pack.data);
free(pubkey_mod_pack.data);
return TPM_SUCCESS;
}
-512
View File
@@ -1,512 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// securestorage.c
//
// Functions regarding securely storing DMI secrets.
//
// ==================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "tcg.h"
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "vtsp.h"
#include "bsg.h"
#include "crypto.h"
#include "hashtable.h"
#include "hashtable_itr.h"
#include "buffer.h"
#include "log.h"
TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
CRYPTO_INFO *asymkey,
buffer_t *sealed_data) {
TPM_RESULT status = TPM_SUCCESS;
symkey_t symkey;
buffer_t data_cipher = NULL_BUF,
symkey_cipher = NULL_BUF;
UINT32 i;
struct pack_constbuf_t symkey_cipher32, data_cipher32;
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf));
for (i=0; i< buffer_len(inbuf); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
// Generate a sym key and encrypt state with it
TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &data_cipher) );
// Encrypt symmetric key
TPMTRYRETURN( VTSP_Bind( asymkey,
&symkey.key,
&symkey_cipher) );
// Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher
symkey_cipher32.size = buffer_len(&symkey_cipher);
symkey_cipher32.data = symkey_cipher.bytes;
data_cipher32.size = buffer_len(&data_cipher);
data_cipher32.data = data_cipher.bytes;
TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL));
BSG_PackList(sealed_data->bytes, 2,
BSG_TPM_SIZE32_DATA, &symkey_cipher32,
BSG_TPM_SIZE32_DATA, &data_cipher32);
vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data));
for (i=0; i< buffer_len(sealed_data); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n.");
egress:
buffer_free ( &data_cipher);
buffer_free ( &symkey_cipher);
Crypto_symcrypto_freekey (&symkey);
return status;
}
TPM_RESULT envelope_decrypt(const buffer_t *cipher,
TCS_CONTEXT_HANDLE TCSContext,
TPM_HANDLE keyHandle,
const TPM_AUTHDATA *key_usage_auth,
buffer_t *unsealed_data) {
TPM_RESULT status = TPM_SUCCESS;
symkey_t symkey;
buffer_t data_cipher = NULL_BUF,
symkey_clear = NULL_BUF,
symkey_cipher = NULL_BUF;
struct pack_buf_t symkey_cipher32, data_cipher32;
int i;
memset(&symkey, 0, sizeof(symkey_t));
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%d]: 0x", buffer_len(cipher) );
for (i=0; i< buffer_len(cipher); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
BSG_UnpackList(cipher->bytes, 2,
BSG_TPM_SIZE32_DATA, &symkey_cipher32,
BSG_TPM_SIZE32_DATA, &data_cipher32);
TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher,
symkey_cipher32.size,
symkey_cipher32.data) );
TPMTRYRETURN( buffer_init_alias_convert (&data_cipher,
data_cipher32.size,
data_cipher32.data) );
// Decrypt Symmetric Key
TPMTRYRETURN( VTSP_Unbind( TCSContext,
keyHandle,
&symkey_cipher,
key_usage_auth,
&symkey_clear,
&(vtpm_globals->keyAuth) ) );
// create symmetric key using saved bits
Crypto_symcrypto_initkey (&symkey, &symkey_clear);
// Decrypt State
TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data));
for (i=0; i< buffer_len(unsealed_data); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n.");
egress:
buffer_free ( &data_cipher);
buffer_free ( &symkey_clear);
buffer_free ( &symkey_cipher);
Crypto_symcrypto_freekey (&symkey);
return status;
}
TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf) {
TPM_RESULT status = TPM_SUCCESS;
int fh;
long bytes_written;
buffer_t sealed_NVM = NULL_BUF;
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf));
TPMTRYRETURN( envelope_encrypt(inbuf,
&vtpm_globals->storageKey,
&sealed_NVM) );
// Write sealed blob off disk from NVMLocation
// TODO: How to properly return from these. Do we care if we return failure
// after writing the file? We can't get the old one back.
// TODO: Backup old file and try and recover that way.
fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) ) != (long) buffer_len(&sealed_NVM))) {
vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_NVM));
status = TPM_IOERROR;
goto abort_egress;
}
close(fh);
Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement);
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
egress:
buffer_free(&sealed_NVM);
return status;
}
/* Expected Params: inbuf = null, outbuf = sealed blob size, sealed blob.*/
TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf) {
TPM_RESULT status = TPM_SUCCESS;
buffer_t sealed_NVM = NULL_BUF;
long fh_size;
int fh, stat_ret, i;
struct stat file_stat;
TPM_DIGEST sealedNVMHash;
if (myDMI->NVMLocation == NULL) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n");
status = TPM_AUTHFAIL;
goto abort_egress;
}
//Read sealed blob off disk from NVMLocation
fh = open(myDMI->NVMLocation, O_RDONLY);
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
fh_size = file_stat.st_size;
else {
status = TPM_IOERROR;
goto abort_egress;
}
TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) );
if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) != fh_size) {
status = TPM_IOERROR;
goto abort_egress;
}
close(fh);
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n", buffer_len(&sealed_NVM));
Crypto_SHA1Full(sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &sealedNVMHash);
// Verify measurement of sealed blob.
if (memcmp(&sealedNVMHash, &myDMI->NVM_measurement, sizeof(TPM_DIGEST)) ) {
vtpmlogerror(VTPM_LOG_VTPM, "VTPM LoadNVM NVM measurement check failed.\n");
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Correct hash: ");
for (i=0; i< sizeof(TPM_DIGEST); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&myDMI->NVM_measurement)[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Measured hash: ");
for (i=0; i< sizeof(TPM_DIGEST); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", ((BYTE*)&sealedNVMHash)[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
status = TPM_AUTHFAIL;
goto abort_egress;
}
TPMTRYRETURN( envelope_decrypt(&sealed_NVM,
myDMI->TCSContext,
vtpm_globals->storageKeyHandle,
(const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
outbuf) );
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
egress:
buffer_free( &sealed_NVM );
return status;
}
TPM_RESULT VTPM_SaveManagerData(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, dmis=-1;
BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL;
buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF;
UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
BYTE vtpm_manager_gen = VTPM_MANAGER_GEN;
struct hashtable_itr *dmi_itr;
VTPM_DMI_RESOURCE *dmi_res;
UINT32 boot_key_size = 0, flat_dmis_size = 0;
// Initially fill these with buffer sizes for each data type. Later fill
// in actual size, once flattened.
boot_key_size = sizeof(UINT32) + // bootkeysize
bootKeySize; // boot key
TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version
3*sizeof(TPM_DIGEST) + // Auths
sizeof(UINT32) +// storagekeysize
storageKeySize, NULL) ); // storage key
flat_boot_key = (BYTE *) malloc( boot_key_size );
flat_enc = (BYTE *) malloc( sizeof(UINT32) );
boot_key_size = BSG_PackList(flat_boot_key, 1,
BSG_TPM_SIZE32_DATA, &boot_key_pack);
BSG_PackList(clear_flat_global.bytes, 4,
BSG_TYPE_BYTE, &vtpm_manager_gen,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
&vtpm_globals->bootKey,
&enc_flat_global) );
BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
// Per DMI values to be saved (if any exit)
if (hashtable_count(vtpm_globals->dmi_map) > 1) {
flat_dmis = (BYTE *) malloc(
(hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
(sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info
dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
dmis++;
// No need to save dmi0.
if (dmi_res->dmi_id == 0)
continue;
flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
BSG_TYPE_BYTE, &dmi_res->dmi_type,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
} while (hashtable_iterator_advance(dmi_itr));
}
fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
if (fh == -1) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
status = TPM_IOERROR;
goto abort_egress;
}
if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
status = TPM_IOERROR;
goto abort_egress;
}
goto egress;
abort_egress:
egress:
free(flat_boot_key);
free(flat_enc);
buffer_free(&enc_flat_global);
free(flat_dmis);
close(fh);
vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Manager state (status = %d, dmis = %d)\n", (int) status, dmis);
return status;
}
TPM_RESULT VTPM_LoadManagerData(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, stat_ret, dmis=0;
long fh_size = 0, step_size;
BYTE *flat_table=NULL;
buffer_t unsealed_data, enc_table_abuf;
struct pack_buf_t storage_key_pack, boot_key_pack;
UINT32 *dmi_id_key, enc_size;
BYTE vtpm_manager_gen;
VTPM_DMI_RESOURCE *dmi_res;
UINT32 dmi_id;
BYTE dmi_type;
struct stat file_stat;
TPM_HANDLE boot_key_handle;
TPM_AUTHDATA boot_usage_auth;
memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
fh = open(STATE_FILE, O_RDONLY );
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
fh_size = file_stat.st_size;
else {
status = TPM_IOERROR;
goto abort_egress;
}
flat_table = (BYTE *) malloc(fh_size);
if ((long) read(fh, flat_table, fh_size) != fh_size ) {
status = TPM_IOERROR;
goto abort_egress;
}
// Read Boot Key
step_size = BSG_UnpackList( flat_table, 2,
BSG_TPM_SIZE32_DATA, &boot_key_pack,
BSG_TYPE_UINT32, &enc_size);
TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
TPMTRYRETURN(buffer_init_alias_convert(&enc_table_abuf, enc_size, flat_table + step_size) );
TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) );
//Load Boot Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->bootKeyWrap,
&SRK_AUTH,
&boot_key_handle,
&vtpm_globals->keyAuth,
&vtpm_globals->bootKey,
FALSE) );
TPMTRYRETURN( envelope_decrypt(&enc_table_abuf,
vtpm_globals->manager_tcs_handle,
boot_key_handle,
(const TPM_AUTHDATA*) &boot_usage_auth,
&unsealed_data) );
step_size += enc_size;
if (*unsealed_data.bytes != VTPM_MANAGER_GEN) {
// Once there is more than one gen, this will include some compatability stuff
vtpmlogerror(VTPM_LOG_VTPM, "Warning: Manager Data file is gen %d, which this manager is gen %d.\n", vtpm_manager_gen, VTPM_MANAGER_GEN);
}
// Global Values needing to be saved
BSG_UnpackList( unsealed_data.bytes, 4,
BSG_TYPE_BYTE, &vtpm_manager_gen,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
// Per DMI values to be saved
while ( step_size < fh_size ){
if (fh_size - step_size < (long) (sizeof(UINT32) + sizeof(BYTE) + 2*sizeof(TPM_DIGEST))) {
vtpmlogerror(VTPM_LOG_VTPM, "Encountered %ld extra bytes at end of manager state.\n", fh_size-step_size);
step_size = fh_size;
} else {
step_size += BSG_UnpackList(flat_table + step_size, 2,
BSG_TYPE_UINT32, &dmi_id,
BSG_TYPE_BYTE, &dmi_type);
//TODO: Try and gracefully recover from problems.
TPMTRYRETURN(init_dmi(dmi_id, dmi_type, &dmi_res) );
dmis++;
step_size += BSG_UnpackList(flat_table + step_size, 2,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
}
}
vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
egress:
free(flat_table);
close(fh);
// TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
return status;
}
-110
View File
@@ -1,110 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// tpmpassthrough.c
//
// Functions regarding passing DMI requests to HWTPM
//
// ==================================================================
#include "tcg.h"
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "vtsp.h"
#include "log.h"
TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi,
buffer_t *inbuf,
buffer_t *outbuf) {
TPM_RESULT status = TPM_SUCCESS;
TPM_COMMAND_CODE *ord;
ord = (TPM_COMMAND_CODE *) (inbuf->bytes + sizeof(TPM_TAG) + sizeof(UINT32));
switch (*ord) {
// Forbidden for DMI use
case TPM_ORD_TakeOwnership:
case TPM_ORD_ChangeAuthOwner:
case TPM_ORD_DirWriteAuth:
case TPM_ORD_DirRead:
case TPM_ORD_AuthorizeMigrationKey:
case TPM_ORD_CreateMaintenanceArchive:
case TPM_ORD_LoadMaintenanceArchive:
case TPM_ORD_KillMaintenanceFeature:
case TPM_ORD_LoadManuMaintPub:
case TPM_ORD_ReadManuMaintPub:
case TPM_ORD_SelfTestFull:
case TPM_ORD_SelfTestStartup:
case TPM_ORD_CertifySelfTest:
case TPM_ORD_ContinueSelfTest:
case TPM_ORD_GetTestResult:
case TPM_ORD_Reset:
case TPM_ORD_OwnerClear:
case TPM_ORD_DisableOwnerClear:
case TPM_ORD_ForceClear:
case TPM_ORD_DisableForceClear:
case TPM_ORD_GetCapabilityOwner:
case TPM_ORD_OwnerSetDisable:
case TPM_ORD_PhysicalEnable:
case TPM_ORD_PhysicalDisable:
case TPM_ORD_SetOwnerInstall:
case TPM_ORD_PhysicalSetDeactivated:
case TPM_ORD_SetTempDeactivated:
case TPM_ORD_CreateEndorsementKeyPair:
case TPM_ORD_GetAuditEvent:
case TPM_ORD_GetAuditEventSigned:
case TPM_ORD_GetOrdinalAuditStatus:
case TPM_ORD_SetOrdinalAuditStatus:
case TPM_ORD_SetRedirection:
case TPM_ORD_FieldUpgrade:
case TSC_ORD_PhysicalPresence:
status = TPM_DISABLED_CMD;
goto abort_egress;
break;
} // End ORD Switch
// Call TCS with command
TPMTRY(TPM_IOERROR, VTSP_RawTransmit( dmi->TCSContext,inbuf, outbuf) );
goto egress;
abort_egress:
vtpmloginfo(VTPM_LOG_VTPM, "TPM Command Failed in tpmpassthrough.\n");
egress:
return status;
}
-141
View File
@@ -1,141 +0,0 @@
// ===================================================================
//
// 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_ipc.c Implements ipc routines using file io. This file can
// be replaced with other ipc types.
//
// ===================================================================
#include <sys/stat.h>
#include "vtpm_ipc.h"
#include "vtpmpriv.h"
#include "log.h"
int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL create) {
ipc_h->name = name;
ipc_h->flags = flags;
ipc_h->fh = VTPM_IPC_CLOSED;
if (create)
return(vtpm_ipc_create(ipc_h));
else
return 0;
}
// Create the file that needs opening. Used only for FIFOs
// FYI: This may cause problems in other file IO schemes. We'll see.
int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
int fh;
struct stat file_info;
if ((!ipc_h) || (!ipc_h->name))
return -1;
if ( stat(ipc_h->name, &file_info) == -1) {
if ( mkfifo(ipc_h->name, S_IWUSR | S_IRUSR ) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to create fifo %s.\n", ipc_h->name);
return -1;
}
}
ipc_h->fh = VTPM_IPC_CLOSED;
return 0;
}
// Read size bytes. If FH isn't open, open it.
int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size){
vtpm_ipc_handle_t *my_ipc_h;
int result;
if (ipc_h) {
my_ipc_h = ipc_h;
} else {
my_ipc_h = alt_ipc_h;
}
if (my_ipc_h->fh == VTPM_IPC_CLOSED) {
my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags);
}
if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) {
vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for reading.\n", my_ipc_h->name);
return -1;
}
result = read(my_ipc_h->fh, bytes, size);
if (result < 0) {
my_ipc_h->fh = VTPM_IPC_CLOSED;
}
return (result);
}
// Write size bytes. If FH isn't open, open it.
int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h, vtpm_ipc_handle_t *alt_ipc_h, BYTE *bytes, UINT32 size) {
vtpm_ipc_handle_t *my_ipc_h;
int result;
if (ipc_h) {
my_ipc_h = ipc_h;
} else {
my_ipc_h = alt_ipc_h;
}
if (my_ipc_h->fh == VTPM_IPC_CLOSED) {
my_ipc_h->fh = open(my_ipc_h->name, my_ipc_h->flags);
}
if ( my_ipc_h->fh == VTPM_IPC_CLOSED ) {
vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s for writing.\n", my_ipc_h->name);
return -1;
}
result = write(my_ipc_h->fh, bytes, size);
if (result < 0) {
my_ipc_h->fh = VTPM_IPC_CLOSED;
}
return (result);
}
// Mark file as closed and try and close it. Errors not reported.
void vtpm_ipc_close(vtpm_ipc_handle_t *ipc_h) {
if (ipc_h) {
close(ipc_h->fh);
ipc_h->fh = VTPM_IPC_CLOSED;
}
}
-71
View File
@@ -1,71 +0,0 @@
// ===================================================================
//
// 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_ipc.h Header for interprocess communication between VTPM manager
// and Guests or VTPMs
//
// ===================================================================
#ifndef __VTPM_IO_H__
#define __VTPM_IO_H__
#include "tcg.h"
#define VTPM_IPC_CLOSED -1
// Represents an (somewhat) abstracted io handle.
typedef struct vtpm_ipc_handle_t {
int fh; // IO handle.
int flags; // Flags for opening. This may need to become
// a void *, but for now files use an int.
char *name; // Names for debugging as well as filenames
// for file-based io.
} vtpm_ipc_handle_t;
int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL create);
// Create the file that needs opening. Used only for FIFOs
// FYI: This may cause problems in other file IO schemes. We'll see.
int vtpm_ipc_create(vtpm_ipc_handle_t *ioh);
// Read size bytes. If FH isn't open, open it.
int vtpm_ipc_read(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size);
// Write size bytes. If FH isn't open, open it.
int vtpm_ipc_write(vtpm_ipc_handle_t *ioh, vtpm_ipc_handle_t *alt_ioh, BYTE *bytes, UINT32 size);
// Mark file as closed and try and close it. Errors not reported.
void vtpm_ipc_close(vtpm_ipc_handle_t *ioh);
#endif
-63
View File
@@ -1,63 +0,0 @@
// ===================================================================
//
// 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_lock.c Provided controlled sync around access to vtpm structures
//
// ===================================================================
#include <pthread.h>
#include "vtpm_lock.h"
static pthread_rwlock_t vtpm_lock;
void vtpm_lock_init() {
pthread_rwlock_init( &vtpm_lock, NULL);
}
void vtpm_lock_destroy(){
pthread_rwlock_destroy(&vtpm_lock);
}
void vtpm_lock_rdlock(){
pthread_rwlock_rdlock(&vtpm_lock);
}
void vtpm_lock_wrlock(){
pthread_rwlock_wrlock(&vtpm_lock);
}
void vtpm_lock_unlock(){
pthread_rwlock_unlock(&vtpm_lock);
}
-48
View File
@@ -1,48 +0,0 @@
// ===================================================================
//
// 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_lock.h Provided controlled sync around access to vtpm structures
//
// ===================================================================
#ifndef __VTPM_LOCK_H__
#define __VTPM_LOCK_H__
void vtpm_lock_init();
void vtpm_lock_destroy();
void vtpm_lock_rdlock();
void vtpm_lock_wrlock();
void vtpm_lock_unlock();
#endif
-285
View File
@@ -1,285 +0,0 @@
// ===================================================================
//
// 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_manager.c
//
// This file will house the main logic of the VTPM Manager
//
// ==================================================================
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "vtsp.h"
#include "bsg.h"
#include "hashtable.h"
#include "hashtable_itr.h"
#include "log.h"
#include "buffer.h"
VTPM_GLOBALS *vtpm_globals=NULL;
// --------------------------- Well Known Auths --------------------------
const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#ifdef WELL_KNOWN_OWNER_AUTH
static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#endif
// -------------------------- Hash table functions --------------------
static unsigned int hashfunc32(void *ky) {
return (* (UINT32 *) ky);
}
static int equals32(void *k1, void *k2) {
return (*(UINT32 *) k1 == *(UINT32 *) k2);
}
// --------------------------- Functions ------------------------------
TPM_RESULT VTPM_Create_Manager(){
TPM_RESULT status = TPM_SUCCESS;
// Generate Auth for Owner
#ifdef WELL_KNOWN_OWNER_AUTH
memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
#else
Crypto_GetRandom(vtpm_globals->owner_usage_auth, sizeof(TPM_AUTHDATA) );
#endif
// Take Owership of TPM
CRYPTO_INFO ek_cryptoInfo;
status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
// If we can read PubEK then there is no owner and we should take it.
// We use the abilty to read the pubEK to flag that the TPM is owned.
// FIXME: Change to just trying to take ownership and react to the status
if (status == TPM_SUCCESS) {
TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
(const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
&SRK_AUTH,
&ek_cryptoInfo,
&vtpm_globals->keyAuth));
TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
(const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
&vtpm_globals->keyAuth));
} else {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
}
// Generate storage key's auth
Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
sizeof(TPM_AUTHDATA) );
TCS_AUTH osap;
TPM_AUTHDATA sharedsecret;
TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
&SRK_AUTH,
&sharedsecret,
&osap) );
osap.fContinueAuthSession = FALSE;
TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
TPM_KEY_BIND,
(const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&sharedsecret,
&vtpm_globals->storageKeyWrap,
&osap) );
// Generate boot key's auth
TPM_AUTHDATA bootKeyWrapAuth;
memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
&SRK_AUTH,
&sharedsecret,
&osap) );
osap.fContinueAuthSession = FALSE;
// FIXME: This key protects the global secrets on disk. It should use TPM
// PCR bindings to limit its use to legit configurations.
// Current binds are open, implying a Trusted VM contains this code.
// If this VM is not Trusted, use measurement and PCR bindings.
TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
TPM_KEY_BIND,
(const TPM_AUTHDATA*)&bootKeyWrapAuth,
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&sharedsecret,
&vtpm_globals->bootKeyWrap,
&osap) );
// Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->bootKeyWrap,
NULL,
NULL,
NULL,
&vtpm_globals->bootKey,
TRUE ) );
TPMTRYRETURN( VTSP_SaveState(vtpm_globals->manager_tcs_handle) );
goto egress;
abort_egress:
exit(1);
egress:
vtpmloginfo(VTPM_LOG_VTPM, "Finished initialized new VTPM manager (Status = %d).\n", status);
return status;
}
///////////////////////////////////////////////////////////////////////////////
TPM_RESULT VTPM_Init_Manager() {
TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize=256;
if ((vtpm_globals = (VTPM_GLOBALS *) malloc(sizeof(VTPM_GLOBALS))) == NULL){
status = TPM_FAIL;
goto abort_egress;
}
memset(vtpm_globals, 0, sizeof(VTPM_GLOBALS));
vtpm_globals->connected_dmis = 0;
if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){
status = TPM_FAIL;
goto abort_egress;
}
// Create new TCS Object
vtpm_globals->manager_tcs_handle = 0;
TPMTRYRETURN(TCS_create());
// Create TCS Context for service
TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
TPMTRYRETURN( TCSP_GetRandom(vtpm_globals->manager_tcs_handle,
&randomsize,
&randomsead));
Crypto_Init(randomsead, randomsize);
TPMTRYRETURN( TCS_FreeMemory (vtpm_globals->manager_tcs_handle, randomsead));
// Create OIAP session for service's authorized commands
TPMTRYRETURN( VTSP_OIAP( vtpm_globals->manager_tcs_handle,
&vtpm_globals->keyAuth) );
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
vtpm_globals->mig_keys = NULL;
// If fails, create new Manager.
serviceStatus = VTPM_LoadManagerData();
if (serviceStatus == TPM_IOERROR) {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to read manager file. Assuming first time initialization.\n");
TPMTRYRETURN( VTPM_Create_Manager() );
TPMTRYRETURN( VTPM_SaveManagerData() );
} else if (serviceStatus != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file");
exit(1);
}
//Load Storage Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->storageKeyWrap,
&SRK_AUTH,
&vtpm_globals->storageKeyHandle,
&vtpm_globals->keyAuth,
&vtpm_globals->storageKey,
FALSE ) );
// Create entry for Dom0 for control messages
TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
goto egress;
abort_egress:
egress:
return(status);
}
///////////////////////////////////////////////////////////////////////////////
void VTPM_Stop_Manager() {
VTPM_DMI_RESOURCE *dmi_res;
struct hashtable_itr *dmi_itr;
// Close all the TCS contexts. TCS should evict keys based on this
if (hashtable_count(vtpm_globals->dmi_map) > 0) {
dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
if (dmi_res->connected)
close_dmi( dmi_res ); // Not really interested in return code
} while (hashtable_iterator_advance(dmi_itr));
free (dmi_itr);
}
if ( VTPM_SaveManagerData() != TPM_SUCCESS )
vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
TCS_CloseContext(vtpm_globals->manager_tcs_handle);
TCS_destroy();
hashtable_destroy(vtpm_globals->dmi_map, 1);
free(vtpm_globals);
Crypto_Exit();
vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager stopped.\n");
}
-150
View File
@@ -1,150 +0,0 @@
// ===================================================================
//
// 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_manager.h
//
// Public Interface header for VTPM Manager
//
// ==================================================================
#ifndef __VTPM_MANAGER_H__
#define __VTPM_MANAGER_H__
#define VTPM_TAG_REQ 0x01c1
#define VTPM_TAG_RSP 0x01c4
#define COMMAND_BUFFER_SIZE 4096
// Header sizes. Note Header MAY include the DMI
#define VTPM_COMMAND_HEADER_SIZE_CLT ( 2 + 4 + 4)
// sizeof(TPM_TAG + UINT32 + TPM_COMMAND_CODE)
#define VTPM_COMMAND_HEADER_SIZE_SRV ( 4 + VTPM_COMMAND_HEADER_SIZE_CLT )
// sizeof( UINT32 + VTPM_COMMAND_HEADER_SIZE_CLT)
//************************ Command Codes ****************************
#define VTPM_ORD_BASE 0x0000
#define VTPM_PRIV_MASK 0x01000000 // Priviledged VTPM Command
#define VTPM_PRIV_BASE (VTPM_ORD_BASE | VTPM_PRIV_MASK)
// Non-priviledged VTPM Commands (From DMI's)
#define VTPM_ORD_SAVENVM (VTPM_ORD_BASE + 1) // DMI Saves Secrets
#define VTPM_ORD_LOADNVM (VTPM_ORD_BASE + 2) // DMI Loads Secrets
#define VTPM_ORD_TPMCOMMAND (VTPM_ORD_BASE + 3) // DMI issues HW TPM Command
#define VTPM_ORD_GET_MIG_KEY (VTPM_ORD_BASE + 4) // Get manager's migration key
#define VTPM_ORD_LOAD_MIG_KEY (VTPM_ORD_BASE + 5) // load dest migration key
// Priviledged VTPM Commands (From management console)
#define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
#define VTPM_ORD_CLOSE (VTPM_PRIV_BASE + 2) // Closes a DMI
#define VTPM_ORD_DELETE (VTPM_PRIV_BASE + 3) // Permemently Deletes DMI
#define VTPM_ORD_MIGRATE_IN (VTPM_PRIV_BASE + 4) // Load migrated VTPM
#define VTPM_ORD_MIGRATE_OUT (VTPM_PRIV_BASE + 5) // migrate VTPM to dest
//************************ Return Codes ****************************
#define VTPM_TYPE_PVM 1 // Paravirtualized Domain
#define VTPM_TYPE_HVM 2 // HVM Domain
//************************ Return Codes ****************************
#define VTPM_SUCCESS 0
#define VTPM_FAIL 1
#define VTPM_UNSUPPORTED 2
#define VTPM_FORBIDDEN 3
#define VTPM_RESTORE_CONTEXT_FAILED 4
#define VTPM_INVALID_REQUEST 5
//*********************** Parameter Values *************************
#define VTPM_TYPE_NON_MIGRATABLE 0x00
#define VTPM_TYPE_MIGRATABLE 0x01
#define VTPM_TYPE_MIGRATED 0xFF // VTPM has been migrated.
// VTPM can be recovered or deleted only
/******************* Command Parameter API *************************
VTPM Command Format
dmi: 4 bytes // Source of message.
// WARNING: This is prepended by the channel.
// Thus it is received by VTPM Manager,
// but not sent by DMI
tpm tag: 2 bytes
command size: 4 bytes // Size of command including header but not DMI
ord: 4 bytes // Command ordinal above
parameters: size - 10 bytes // Command Parameter
VTPM Response Format
tpm tag: 2 bytes
response_size: 4 bytes
status: 4 bytes
parameters: size - 10 bytes
VTPM_Open:
Input Parameters:
mig_type: 1 byte
startup_mode: 1 byte // Cold Boot = 1, resume = 2, deactive = 3
domain type: 1 byte
instance_id: 4 bytes
Output Parameters:
None
VTPM_Close
Input Parameters:
instance_id: 4 bytes
Output Parameters:
None
VTPM_Delete
Input Parameters:
instance_id: 4 bytes
Output Parameters:
None
VTPM_SaveNVM
Input Parameters:
data: n bytes (Header indicates size of data)
Output Parameters:
None
VTPM_LoadNVM
Input Parameters:
None
Output Parameters:
data: n bytes (Header indicates size of data)
VTPM_TPMCommand
Input Parameters:
TPM Command Byte Stream: n bytes
Output Parameters:
TPM Reponse Byte Stream: n bytes
*********************************************************************/
#endif //_VTPM_MANAGER_H_
@@ -1,488 +0,0 @@
// ===================================================================
//
// 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_manager_handler.c
//
// This file will house the main logic of the VTPM Manager
//
// ==================================================================
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "vtsp.h"
#include "bsg.h"
#include "hashtable.h"
#include "hashtable_itr.h"
#include "log.h"
#include "buffer.h"
#define vtpmhandlerloginfo(module,fmt,args...) vtpmloginfo (module, "[%s]: " fmt, thread_name, ##args );
#define vtpmhandlerloginfomore(module,fmt,args...) vtpmloginfomore (module, fmt, ##args );
#define vtpmhandlerlogerror(module,fmt,args...) vtpmlogerror (module, "[%s]: " fmt, thread_name, ##args );
// ---------------------- Prototypes -------------------
TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
TPM_COMMAND_CODE ord,
buffer_t *command_buf,
buffer_t *result_buf,
BOOL is_priv,
char *thread_name);
TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
VTPM_DMI_RESOURCE *dmi_res,
BYTE *cmd_header,
buffer_t *param_buf,
buffer_t *result_buf,
char *thread_name);
TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
BOOL fw_tpm, // Forward TPM cmds?
vtpm_ipc_handle_t *fw_tx_ipc_h,
vtpm_ipc_handle_t *fw_rx_ipc_h,
BOOL is_priv,
char *thread_name) {
TPM_RESULT status = TPM_FAIL; // Should never return
UINT32 dmi, in_param_size, cmd_size, out_param_size, out_message_size, reply_size;
BYTE *cmd_header=NULL, *in_param=NULL, *out_message=NULL, *reply;
buffer_t *command_buf=NULL, *result_buf=NULL;
TPM_TAG tag;
TPM_COMMAND_CODE ord;
VTPM_DMI_RESOURCE *dmi_res;
int size_read, size_write, i;
BOOL add_header=TRUE; // This indicates to prepend a header on result_buf before sending
cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
command_buf = (buffer_t *) malloc(sizeof(buffer_t));
result_buf = (buffer_t *) malloc(sizeof(buffer_t));
// ------------------------ Main Loop --------------------------------
while(1) {
vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n", thread_name);
// --------------------- Read Cmd from Sender ----------------
// Read command header
size_read = vtpm_ipc_read(rx_ipc_h, NULL, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
if (size_read > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV[%d]: 0x", size_read);
for (i=0; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono = %d. Aborting... \n", thread_name, errno);
goto abort_command;
}
if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "\n");
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command shorter than normal header (%d bytes). Aborting...\n", size_read);
goto abort_command;
}
// Unpack header
BSG_UnpackList(cmd_header, 4,
BSG_TYPE_UINT32, &dmi,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &in_param_size,
BSG_TPM_COMMAND_CODE, &ord );
// Using the header info, read the parameters of the command
// Note that in_param_size is in the client's context
cmd_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
if (cmd_size > 0) {
in_param = (BYTE *) malloc(cmd_size);
size_read = vtpm_ipc_read( rx_ipc_h, NULL, in_param, cmd_size);
if (size_read > 0) {
for (i=0; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error reading cmd from ipc. Aborting... \n", thread_name);
goto abort_command;
}
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
if (size_read < (int) cmd_size) {
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d). Aborting...\n", size_read, cmd_size);
goto abort_command;
}
} else {
in_param = NULL;
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
}
// Init the buffers used to handle the command and the response
if ( (buffer_init_convert(command_buf, cmd_size, in_param) != TPM_SUCCESS) ||
(buffer_init(result_buf, 0, 0) != TPM_SUCCESS) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
goto abort_command;
}
// -------------- Dispatch Commands to Handlers -----------
if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) {
vtpm_lock_wrlock();
} else {
vtpm_lock_rdlock();
}
if ( !(dmi_res = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi)) ||
(!dmi_res->connected) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempted access to non-existent or disconnected DMI %d. Aborting...\n", dmi);
status = TPM_BAD_PARAMETER;
// We have no one to reply to, they don't exist.
goto abort_command;
}
if (tag == VTPM_TAG_REQ) {
status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf, result_buf, is_priv, thread_name);
} else { // This is not a VTPM Command at all.
if (fw_tpm) {
status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h, dmi_res, cmd_header, command_buf, result_buf, thread_name);
// This means calling the DMI failed, not that the cmd failed in the DMI
// Since the return will be interpretted by a TPM app, all errors are IO_ERRORs to the app
if (status != TPM_SUCCESS) {
status = TPM_IOERROR;
goto abort_with_error;
}
// Unlike all other commands, forwarded commands yield a result_buf that includes the DMI's status. This
// should be forwarded to the caller VM
add_header = FALSE;
} else {
// We are not supposed to forward TPM commands at all.
int i;
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Attempt to use unsupported direct access to TPM.\n");
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "Bad Command. dmi:%d, tag:%d, size:%d, ord:%d, Params: ", dmi, tag, in_param_size, ord);
for (i=0; i<cmd_size; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
status = TPM_FAIL;
goto abort_with_error;
}
} // end else for is VTPM Command
// ------------------- Respond to Sender ------------------
// Errors while handling responses jump here to reply with error messages
// NOTE: Currently there are no recoverable errors in multi-VM mode. If one
// is added to the code, this ifdef should be removed.
// Also note this is NOT referring to errors in commands, but rather
// this is about I/O errors and such.
#ifndef VTPM_MULTI_VM
abort_with_error:
#endif
if (add_header) {
// Prepend VTPM header with destination DM stamped
out_param_size = buffer_len(result_buf);
out_message_size = VTPM_COMMAND_HEADER_SIZE_CLT + out_param_size;
reply_size = VTPM_COMMAND_HEADER_SIZE_SRV + out_param_size;
out_message = (BYTE *) malloc (reply_size);
reply = out_message;
BSG_PackList(out_message, 4,
BSG_TYPE_UINT32, (BYTE *) &dmi,
BSG_TPM_TAG, (BYTE *) &tag,
BSG_TYPE_UINT32, (BYTE *) &out_message_size,
BSG_TPM_RESULT, (BYTE *) &status);
if (buffer_len(result_buf) > 0)
memcpy(out_message + VTPM_COMMAND_HEADER_SIZE_SRV, result_buf->bytes, out_param_size);
//Note: Send message + dmi_id
} else {
reply = result_buf->bytes;
reply_size = buffer_len(result_buf);
}
size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ? dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size );
if (size_write > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
for (i=0; i < reply_size; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", reply[i]);
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s had error writing to ipc. Aborting... \n", thread_name);
goto abort_command;
}
free(out_message); out_message=NULL;
if (size_write < (int)reply_size) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s unable to write full command to ipc (%d/%d)\n", thread_name, size_write, reply_size);
goto abort_command;
}
// On certain failures an error message cannot be sent.
// This marks the beginning of cleanup in preperation for the next command.
abort_command:
//free buffers
bzero(cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
//free(in_param); // This was converted to command_buf. No need to free
buffer_free(result_buf);
buffer_free(command_buf);
// If we have a write lock, save the manager table
if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&
(VTPM_SaveManagerData() != TPM_SUCCESS) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "ERROR: Unable to save manager data.\n");
}
vtpm_lock_unlock();
add_header = TRUE; // Reset to the default
} // End while(1)
}
/////////////////////////////////////////////////////////////////////////
TPM_RESULT vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
TPM_COMMAND_CODE ord,
buffer_t *command_buf,
buffer_t *result_buf,
BOOL is_priv,
char *thread_name) {
TPM_RESULT status = TPM_FAIL;
switch (ord) {
case VTPM_ORD_SAVENVM:
status= VTPM_Handle_Save_NVM(dmi_res,
command_buf,
result_buf);
break;
case VTPM_ORD_LOADNVM:
status= VTPM_Handle_Load_NVM(dmi_res,
command_buf,
result_buf);
break;
case VTPM_ORD_TPMCOMMAND:
status= VTPM_Handle_TPM_Command(dmi_res,
command_buf,
result_buf);
break;
case VTPM_ORD_GET_MIG_KEY:
status = VTPM_Handle_Get_Migration_key(command_buf,
result_buf);
break;
case VTPM_ORD_LOAD_MIG_KEY:
status = VTPM_Handle_Load_Migration_key(command_buf,
result_buf);
break;
default:
// Privileged handlers can do maintanance
if (is_priv) {
switch (ord) {
case VTPM_ORD_OPEN:
status = VTPM_Handle_New_DMI(command_buf);
break;
case VTPM_ORD_CLOSE:
status = VTPM_Handle_Close_DMI(command_buf);
break;
case VTPM_ORD_DELETE:
status = VTPM_Handle_Delete_DMI(command_buf);
break;
case VTPM_ORD_MIGRATE_IN:
status = VTPM_Handle_Migrate_In(command_buf, result_buf);
break;
case VTPM_ORD_MIGRATE_OUT:
status = VTPM_Handle_Migrate_Out(command_buf, result_buf);
break;
default:
status = TPM_BAD_ORDINAL;
} // switch
} else { // is priv command
status = TPM_BAD_ORDINAL;
} // inner switch
} // outer switch
return(status);
}
/////////////////////////////////////////////////////////////////////
TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
VTPM_DMI_RESOURCE *dmi_res,
BYTE *cmd_header,
buffer_t *param_buf,
buffer_t *result_buf,
char *thread_name) {
TPM_RESULT status = TPM_FAIL;
UINT32 dmi_dst;
TPM_COMMAND_CODE ord;
TPM_TAG tag_out;
UINT32 dmi_cmd_size, in_param_size, adj_param_size;
BYTE *dmi_cmd, *in_param;
int size_read, size_write, i;
//// Dom0 can't talk to the BE, so this must be a broken FE/BE or badness
if (dmi_res->dmi_id == VTPM_CTL_DM) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Illegal use of TPM command from dom0\n");
status = TPM_FAIL;
goto abort_with_error;
}
vtpmhandlerloginfo(VTPM_LOG_VTPM, "Forwarding command to DMI.\n");
//Forward TPM CMD stamped with dmi_id to DMI for handling
if (buffer_len(param_buf)) {
dmi_cmd = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf));
dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf);
memcpy(dmi_cmd, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
memcpy(dmi_cmd + VTPM_COMMAND_HEADER_SIZE_SRV, param_buf->bytes, buffer_len(param_buf));
size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, dmi_cmd, dmi_cmd_size);
if (size_write > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(param_buf); i++) {
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", dmi_cmd[i]);
}
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
status = TPM_IOERROR;
goto abort_with_error;
}
free(dmi_cmd);
} else {
dmi_cmd_size = VTPM_COMMAND_HEADER_SIZE_SRV;
size_write = vtpm_ipc_write(tx_ipc_h, dmi_res->tx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV );
if (size_write > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT (DMI): 0x");
for (i=0; i<VTPM_COMMAND_HEADER_SIZE_SRV; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error writing to DMI. Aborting... \n");
status = TPM_IOERROR;
goto abort_with_error;
}
}
if (size_write != (int) dmi_cmd_size)
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Could not write entire command to DMI (%d/%d)\n", size_write, dmi_cmd_size);
buffer_free(param_buf);
// Read header for response to TPM command from DMI
size_read = vtpm_ipc_read( rx_ipc_h, dmi_res->rx_tpm_ipc_h, cmd_header, VTPM_COMMAND_HEADER_SIZE_SRV);
if (size_read > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "RECV (DMI): 0x");
for (i=0; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from DMI. Aborting... \n");
status = TPM_IOERROR;
goto abort_with_error;
}
if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command from DMI shorter than normal header. Aborting...\n");
status = TPM_IOERROR;
goto abort_with_error;
}
// Unpack response from DMI for TPM command
BSG_UnpackList(cmd_header, 4,
BSG_TYPE_UINT32, &dmi_dst,
BSG_TPM_TAG, &tag_out,
BSG_TYPE_UINT32, &in_param_size,
BSG_TPM_COMMAND_CODE, &status );
// If response has parameters, read them.
// Note that in_param_size is in the client's context
adj_param_size = in_param_size - VTPM_COMMAND_HEADER_SIZE_CLT;
if (adj_param_size > 0) {
in_param = (BYTE *) malloc(adj_param_size);
size_read = vtpm_ipc_read(rx_ipc_h, dmi_res->rx_tpm_ipc_h, in_param, adj_param_size);
if (size_read > 0) {
for (i=0; i<size_read; i++)
vtpmhandlerloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param[i]);
} else {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Error reading from BE. Aborting... \n");
goto abort_with_error;
}
vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
if (size_read < (int)adj_param_size) {
vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Command read(%d) from DMI is shorter than header indicates(%d). Aborting...\n", size_read, adj_param_size);
status = TPM_IOERROR;
goto abort_with_error;
}
} else {
in_param = NULL;
vtpmhandlerloginfomore(VTPM_LOG_VTPM, "\n");
}
if ( (buffer_init(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV, cmd_header) != TPM_SUCCESS) ||
(buffer_append_raw(result_buf, adj_param_size, in_param) != TPM_SUCCESS) ) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers. Aborting...\n");
status = TPM_FAIL;
goto abort_with_error;
}
vtpmhandlerloginfo(VTPM_LOG_VTPM, "Sending DMI's response to guest.\n");
status = TPM_SUCCESS;
abort_with_error:
return status;
}
-371
View File
@@ -1,371 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// vtpmd.c
//
// Application
//
// ===================================================================
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "tcg.h"
#include "log.h"
#include "vtpm_ipc.h"
#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
#define VTPM_BE_FNAME "/dev/vtpm"
#define VTPM_DUMMY_TX_BE_FNAME "/var/vtpm/fifos/dummy_out.fifo"
#define VTPM_DUMMY_RX_BE_FNAME "/var/vtpm/fifos/dummy_in.fifo"
#define VTPM_TX_TPM_FNAME "/var/vtpm/fifos/tpm_cmd_to_%d.fifo"
#define VTPM_RX_TPM_FNAME "/var/vtpm/fifos/tpm_rsp_from_all.fifo"
#define VTPM_TX_VTPM_FNAME "/var/vtpm/fifos/vtpm_rsp_to_%d.fifo"
#define VTPM_RX_VTPM_FNAME "/var/vtpm/fifos/vtpm_cmd_from_all.fifo"
#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/to_console.fifo"
#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/from_console.fifo"
#define VTPM_TYPE_PVM_STRING "pvm"
#define VTPM_TYPE_HVM_STRING "hvm"
struct vtpm_thread_params_s {
vtpm_ipc_handle_t *tx_ipc_h;
vtpm_ipc_handle_t *rx_ipc_h;
BOOL fw_tpm;
vtpm_ipc_handle_t *fw_tx_ipc_h;
vtpm_ipc_handle_t *fw_rx_ipc_h;
BOOL is_priv;
char *thread_name;
};
// This is needed to all extra_close_dmi to close this to prevent a
// broken pipe when no DMIs are left.
static vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
void *vtpm_manager_thread(void *arg_void) {
TPM_RESULT *status = (TPM_RESULT *) malloc(sizeof(TPM_RESULT) );
struct vtpm_thread_params_s *arg = (struct vtpm_thread_params_s *) arg_void;
*status = VTPM_Manager_Handler(arg->tx_ipc_h, arg->rx_ipc_h,
arg->fw_tpm, arg->fw_tx_ipc_h, arg->fw_rx_ipc_h,
arg->is_priv, arg->thread_name);
return (status);
}
void signal_handler(int reason) {
if (pthread_equal(pthread_self(), vtpm_globals->master_pid)) {
vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal %d.\n", reason);
} else {
// For old Linux Thread machines, signals are delivered to each thread. Deal with them.
vtpmloginfo(VTPM_LOG_VTPM, "Child shutting down\n");
pthread_exit(NULL);
}
VTPM_Stop_Manager();
exit(-1);
}
struct sigaction ctl_c_handler;
TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode) {
TPM_RESULT status = TPM_SUCCESS;
int fh;
char dmi_id_str[11]; // UINT32s are up to 10 digits + NULL
char *tx_vtpm_name, *tx_tpm_name, *vm_type_string;
struct stat file_info;
if (dmi_res->dmi_id == VTPM_CTL_DM) {
dmi_res->tx_tpm_ipc_h = NULL;
dmi_res->rx_tpm_ipc_h = NULL;
dmi_res->tx_vtpm_ipc_h = NULL;
dmi_res->rx_vtpm_ipc_h = NULL;
} else {
// Create a pair of fifo pipes
dmi_res->rx_tpm_ipc_h = NULL;
dmi_res->rx_vtpm_ipc_h = NULL;
if ( ((dmi_res->tx_tpm_ipc_h = (vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) ||
((dmi_res->tx_vtpm_ipc_h =(vtpm_ipc_handle_t *) malloc (sizeof(vtpm_ipc_handle_t))) == NULL ) ||
((tx_tpm_name = (char *) malloc(11 + strlen(VTPM_TX_TPM_FNAME))) == NULL ) ||
((tx_vtpm_name =(char *) malloc(11 + strlen(VTPM_TX_VTPM_FNAME))) == NULL) ) {
status =TPM_RESOURCES;
goto abort_egress;
}
sprintf(tx_tpm_name, VTPM_TX_TPM_FNAME, (uint32_t) dmi_res->dmi_id);
sprintf(tx_vtpm_name, VTPM_TX_VTPM_FNAME, (uint32_t) dmi_res->dmi_id);
if ( (vtpm_ipc_init(dmi_res->tx_tpm_ipc_h, tx_tpm_name, O_WRONLY | O_NONBLOCK, TRUE) != 0) ||
(vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY, TRUE) != 0) ) { //FIXME: O_NONBLOCK?
status = TPM_IOERROR;
goto abort_egress;
}
// Measure DMI
// FIXME: This will measure DMI. Until then use a fixed DMI_Measurement value
// Also, this mechanism is specific to 1 VM architecture.
/*
fh = open(TPM_EMULATOR_PATH, O_RDONLY);
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
dmi_size = file_stat.st_size;
else {
vtpmlogerror(VTPM_LOG_VTPM, "Could not open vtpmd!!\n");
status = TPM_IOERROR;
goto abort_egress;
}
dmi_buffer
*/
memset(&dmi_res->DMI_measurement, 0xcc, sizeof(TPM_DIGEST));
if (vm_type == VTPM_TYPE_PVM)
vm_type_string = (BYTE *)&VTPM_TYPE_PVM_STRING;
else
vm_type_string = (BYTE *)&VTPM_TYPE_HVM_STRING;
// Launch DMI
sprintf(dmi_id_str, "%d", (int) dmi_res->dmi_id);
#ifdef MANUAL_DM_LAUNCH
vtpmlogerror(VTPM_LOG_VTPM, "Manually start VTPM with dmi=%s now.\n", dmi_id_str);
dmi_res->dmi_pid = 0;
#else
pid_t pid = fork();
if (pid == -1) {
vtpmlogerror(VTPM_LOG_VTPM, "Could not fork to launch vtpm\n");
status = TPM_RESOURCES;
goto abort_egress;
} else if (pid == 0) {
switch (startup_mode) {
case TPM_ST_CLEAR:
execl (TPM_EMULATOR_PATH, "vtpmd", "clear", vm_type_string, dmi_id_str, NULL);
break;
case TPM_ST_STATE:
execl (TPM_EMULATOR_PATH, "vtpmd", "save", vm_type_string, dmi_id_str, NULL);
break;
case TPM_ST_DEACTIVATED:
execl (TPM_EMULATOR_PATH, "vtpmd", "deactivated", vm_type_string, dmi_id_str, NULL);
break;
default:
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// Returning from these at all is an error.
vtpmlogerror(VTPM_LOG_VTPM, "Could not exec to launch vtpm\n");
} else {
dmi_res->dmi_pid = pid;
vtpmloginfo(VTPM_LOG_VTPM, "Launching DMI on PID = %d\n", pid);
}
#endif // MANUAL_DM_LAUNCH
} // If DMI = VTPM_CTL_DM
status = TPM_SUCCESS;
abort_egress:
return (status);
}
TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
TPM_RESULT status = TPM_SUCCESS;
if (vtpm_globals->connected_dmis == 0) {
// No more DMI's connected. Close fifo to prevent a broken pipe.
// This is hackish. Need to think of another way.
vtpm_ipc_close(g_rx_tpm_ipc_h);
}
if (dmi_res->dmi_id != VTPM_CTL_DM) {
vtpm_ipc_close(dmi_res->tx_tpm_ipc_h);
vtpm_ipc_close(dmi_res->tx_vtpm_ipc_h);
free(dmi_res->tx_tpm_ipc_h->name);
free(dmi_res->tx_vtpm_ipc_h->name);
#ifndef MANUAL_DM_LAUNCH
if (dmi_res->dmi_id != VTPM_CTL_DM) {
if (dmi_res->dmi_pid != 0) {
vtpmloginfo(VTPM_LOG_VTPM, "Killing dmi on pid %d.\n", dmi_res->dmi_pid);
if (kill(dmi_res->dmi_pid, SIGKILL) !=0) {
vtpmloginfo(VTPM_LOG_VTPM, "DMI on pid %d is already dead.\n", dmi_res->dmi_pid);
} else if (waitpid(dmi_res->dmi_pid, NULL, 0) != dmi_res->dmi_pid) {
vtpmlogerror(VTPM_LOG_VTPM, "DMI on pid %d failed to stop.\n", dmi_res->dmi_pid);
status = TPM_FAIL;
}
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Could not kill dmi because it's pid was 0.\n");
status = TPM_FAIL;
}
}
#endif
} //endif ! dom0
return status;
}
int main(int argc, char **argv) {
vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, rx_tpm_ipc_h, rx_vtpm_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h;
struct vtpm_thread_params_s be_thread_params, dmi_thread_params, hp_thread_params;
pthread_t be_thread, dmi_thread, hp_thread;
#ifdef DUMMY_BACKEND
vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h;
#else
vtpm_ipc_handle_t real_be_ipc_h;
#endif
vtpmloginfo(VTPM_LOG_VTPM, "Starting VTPM.\n");
// -------------------- Initialize Manager -----------------
if (VTPM_Init_Manager() != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during startup.\n");
return -1;
}
// -------------------- Setup Ctrl+C Handlers --------------
ctl_c_handler.sa_handler = signal_handler;
sigemptyset(&ctl_c_handler.sa_mask);
ctl_c_handler.sa_flags = 0;
if (sigaction(SIGINT, &ctl_c_handler, NULL) == -1)
vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGINT handler. Ctl+break will not stop manager gently.\n");
// For easier debuggin with gdb
if (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1)
vtpmlogerror(VTPM_LOG_VTPM, "Could not install SIGHUP handler. Ctl+break will not stop manager gently.\n");
sigset_t sig_mask;
sigemptyset(&sig_mask);
sigaddset(&sig_mask, SIGPIPE);
sigprocmask(SIG_BLOCK, &sig_mask, NULL);
// ------------------- Set up file ipc structures ----------
#ifdef DUMMY_BACKEND
if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR, TRUE) != 0) ||
(vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR, TRUE) != 0) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n");
exit(-1);
}
tx_be_ipc_h = &tx_dummy_ipc_h;
rx_be_ipc_h = &rx_dummy_ipc_h;
#else
vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE);
tx_be_ipc_h = &real_be_ipc_h;
rx_be_ipc_h = &real_be_ipc_h;
#endif
if ( (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE) != 0) ||
(vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE) != 0) || //FIXME: O_RDONLY?
(vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) ||
(vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n");
exit(-1);
}
g_rx_tpm_ipc_h = &rx_tpm_ipc_h;
// -------------------- Set up thread params -------------
be_thread_params.tx_ipc_h = tx_be_ipc_h;
be_thread_params.rx_ipc_h = rx_be_ipc_h;
be_thread_params.fw_tpm = TRUE;
be_thread_params.fw_tx_ipc_h = NULL;
be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
be_thread_params.is_priv = FALSE;
be_thread_params.thread_name = "Backend Listener";
dmi_thread_params.tx_ipc_h = NULL;
dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h;
dmi_thread_params.fw_tpm = FALSE;
dmi_thread_params.fw_tx_ipc_h = NULL;
dmi_thread_params.fw_rx_ipc_h = NULL;
dmi_thread_params.is_priv = FALSE;
dmi_thread_params.thread_name = "VTPM Listener";
hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
hp_thread_params.fw_tpm = FALSE;
hp_thread_params.fw_tx_ipc_h = NULL;
hp_thread_params.fw_rx_ipc_h = NULL;
hp_thread_params.is_priv = TRUE;
hp_thread_params.thread_name = "Hotplug Listener";
// --------------------- Launch Threads -----------------
vtpm_lock_init();
vtpm_globals->master_pid = pthread_self();
if (pthread_create(&be_thread, NULL, vtpm_manager_thread, &be_thread_params) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch BE Thread.\n");
exit(-1);
}
if (pthread_create(&dmi_thread, NULL, vtpm_manager_thread, &dmi_thread_params) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch DMI Thread.\n");
exit(-1);
}
if (pthread_create(&hp_thread, NULL, vtpm_manager_thread, &hp_thread_params) != 0) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to launch HP Thread.\n");
exit(-1);
}
//Join the other threads until exit time.
pthread_join(be_thread, NULL);
pthread_join(dmi_thread, NULL);
pthread_join(hp_thread, NULL);
vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n");
VTPM_Stop_Manager();
vtpm_lock_destroy();
return 0;
}
-186
View File
@@ -1,186 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// vtpmpriv.h
//
// Structures and functions private to the manager
//
// ==================================================================
#ifndef __VTPMPRIV_H__
#define __VTPMPRIV_H__
#include "vtpm_manager.h"
#include "tcg.h"
#include "tcs.h"
#include "buffer.h"
#include "crypto.h"
#include "vtpm_ipc.h"
#define VTPM_MANAGER_GEN 2 // This is incremented when the manager's table
// is changed. It's used for backwards compatability
#define STATE_FILE "/var/vtpm/VTPM"
#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data"
#define VTPM_CTL_DM 0
// ------------------------ Private Structures -----------------------
typedef struct VTPM_DMI_RESOURCE_T {
// I/O info for Manager to talk to DMI's and controllers
vtpm_ipc_handle_t *tx_vtpm_ipc_h; // TX VTPM Results to DMI
vtpm_ipc_handle_t *rx_vtpm_ipc_h; // RX VTPM Commands from DMI
vtpm_ipc_handle_t *tx_tpm_ipc_h; // TX TPM Commands to DMI
vtpm_ipc_handle_t *rx_tpm_ipc_h; // RX TPM Results from DMI
#ifndef VTPM_MULTI_VM
pid_t dmi_pid;
#endif
// Non-persistent Information
bool connected;
UINT32 dmi_domain_id;
TCS_CONTEXT_HANDLE TCSContext; // TCS Handle
char *NVMLocation; // NULL term string indicating location
// of NVM.
// Persistent Information about DMI
UINT32 dmi_id;
BYTE dmi_type;
TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob
TPM_DIGEST DMI_measurement; // Correct measurement of the owning DMI
} VTPM_DMI_RESOURCE;
typedef struct tdVTPM_MIGKEY_LIST {
UINT32 name_size;
BYTE *name; // Name of destination (IP addr, domain name, etc)
CRYPTO_INFO key;
struct tdVTPM_MIGKEY_LIST *next;
} VTPM_MIGKEY_LIST;
typedef struct tdVTPM_GLOBALS {
// Non-persistent data
#ifndef VTPM_MULTI_VM
pid_t master_pid;
#endif
int connected_dmis; // To close guest_rx when no dmis are connected
struct hashtable *dmi_map; // Table of all DMI's known indexed by persistent instance #
VTPM_MIGKEY_LIST *mig_keys; // Table of migration keys
// Currently keys are loaded at migration time,
// TODO: Make VTPM man store a keys persistently
// and update script to check if key is needed
// before fetching it.
TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager
TPM_HANDLE storageKeyHandle; // Key used by persistent store
CRYPTO_INFO storageKey; // For software encryption
CRYPTO_INFO bootKey; // For saving table
TCS_AUTH keyAuth; // OIAP session for storageKey
// Persistent Data
TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM
buffer_t storageKeyWrap; // Wrapped copy of storageKey
TPM_AUTHDATA srk_usage_auth;
TPM_AUTHDATA storage_key_usage_auth;
buffer_t bootKeyWrap; // Wrapped copy of boot key
}VTPM_GLOBALS;
// --------------------------- Global Values --------------------------
extern VTPM_GLOBALS *vtpm_globals; // Key info and DMI states
extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value
// ********************** VTPM Functions *************************
TPM_RESULT VTPM_Init_Manager(); // Start VTPM Service
void VTPM_Stop_Manager(); // Stop VTPM Service
TPM_RESULT VTPM_Manager_Handler(vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
BOOL fw_tpm, // Should forward TPM cmds
vtpm_ipc_handle_t *fw_tx_ipc_h,
vtpm_ipc_handle_t *fw_rx_ipc_h,
BOOL is_priv,
char *client_name);
// ********************** Command Handler Prototypes ***********************
TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf);
TPM_RESULT VTPM_Handle_Save_NVM( VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf);
TPM_RESULT VTPM_Handle_TPM_Command( VTPM_DMI_RESOURCE *dmi,
buffer_t *inbuf,
buffer_t *outbuf);
TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf);
TPM_RESULT VTPM_Handle_Close_DMI(const buffer_t *param_buf);
TPM_RESULT VTPM_Handle_Delete_DMI(const buffer_t *param_buf);
TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
buffer_t *result_buf);
TPM_RESULT VTPM_Handle_Migrate_Out ( const buffer_t *param_buf,
buffer_t *result_buf);
TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
buffer_t *result_buf);
TPM_RESULT VTPM_SaveManagerData(void);
TPM_RESULT VTPM_LoadManagerData(void);
TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type, BYTE startup_mode);
TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res);
// Helper functions
TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type, VTPM_DMI_RESOURCE **dmi_res);
TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
CRYPTO_INFO *asymkey,
buffer_t *sealed_data);
TPM_RESULT envelope_decrypt(const buffer_t *cipher,
TCS_CONTEXT_HANDLE TCSContext,
TPM_HANDLE keyHandle,
const TPM_AUTHDATA *key_usage_auth,
buffer_t *unsealed_data);
#endif // __VTPMPRIV_H__
File diff suppressed because it is too large. Load diff
-126
View File
@@ -1,126 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// vtsp.h
//
// Higher level interface to TCS.
//
// ==================================================================
#ifndef __VTSP_H__
#define __VTSP_H__
#include "tcg.h"
#include "tcs.h"
#define KEY_BUFFER_SIZE 2048
TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext,
const buffer_t *inbuf,
buffer_t *outbuf );
TPM_RESULT VTSP_OIAP( const TCS_CONTEXT_HANDLE hContext,
TCS_AUTH *auth);
TPM_RESULT VTSP_OSAP( const TCS_CONTEXT_HANDLE hContext,
const TPM_ENTITY_TYPE entityType,
const UINT32 entityValue,
const TPM_AUTHDATA *usageAuth,
TPM_SECRET *sharedsecret,
TCS_AUTH *auth);
TPM_RESULT VTSP_TerminateHandle(const TCS_CONTEXT_HANDLE hContext,
const TCS_AUTH *auth);
TPM_RESULT VTSP_ReadPubek( const TCS_CONTEXT_HANDLE hContext,
CRYPTO_INFO *cypto_info);
TPM_RESULT VTSP_TakeOwnership( const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *ownerAuth,
const TPM_AUTHDATA *srkAuth,
CRYPTO_INFO *ek_cryptoInfo,
TCS_AUTH *auth);
TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *ownerAuth,
TCS_AUTH *auth);
TPM_RESULT VTSP_CreateWrapKey( const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_USAGE usage,
const TPM_AUTHDATA *newKeyAuth,
const TCS_KEY_HANDLE parentHandle,
const TPM_AUTHDATA *osapSharedSecret,
buffer_t *pubKeyBuf,
TCS_AUTH *auth);
TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
const TCS_KEY_HANDLE hUnwrappingKey,
const buffer_t *rgbWrappedKeyBlob,
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *pAuth,
CRYPTO_INFO *cryptoinfo,
const BOOL skipTPMLoad);
TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE key_handle,
const buffer_t *bound_data,
const TPM_AUTHDATA *usage_auth,
buffer_t *clear_data,
TCS_AUTH *auth);
TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
const buffer_t *inData,
buffer_t *outData);
TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_AUTHDATA *sealDataAuth,
const TPM_PCR_COMPOSITE *pcrComp,
const buffer_t *inData,
TPM_STORED_DATA *sealedData,
const TPM_SECRET *osapSharedSecret,
TCS_AUTH *auth);
TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_STORED_DATA *sealedData,
const TPM_AUTHDATA *key_usage_auth,
const TPM_AUTHDATA *data_usage_auth,
buffer_t *outData,
TCS_AUTH *auth,
TCS_AUTH *dataAuth);
TPM_RESULT VTSP_SaveState( const TCS_CONTEXT_HANDLE hContext);
#endif //_VTSP_H_
-42
View File
@@ -1,42 +0,0 @@
XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
VPATH = ../manager
BIND = vtpm_migratord
BINC = vtpm_migrator
SRCSD = vtpm_manager_if.c vtpm_migratord.c vtpm_migratord_handler.c vtpm_ipc.c
SRCSC = vtpm_manager_if.c vtpm_migrator_if.c vtpm_migratorc.c vtpm_ipc.c
OBJSD = $(patsubst %.c,%.o,$(SRCSD))
OBJSC = $(patsubst %.c,%.o,$(SRCSC))
.PHONY: all
all: build
.PHONY: build
build: $(BIND) $(BINC)
.PHONY: install
install: build
$(INSTALL_PROG) $(BIND) $(DESTDIR)$(BINDIR)
$(INSTALL_PROG) $(BINC) $(DESTDIR)$(BINDIR)
.PHONY: clean
clean:
rm -f $(BINC) $(BIND)
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
.PHONY: mrproper
mrproper: clean
rm -f *~
$(BIND): $(OBJSD)
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
$(BINC): $(OBJSC)
$(CC) $(LDFLAGS) $^ $(LIBS) -o $@
# libraries
LIBS += ../util/libTCGUtils.a
@@ -1,186 +0,0 @@
// ===================================================================
//
// 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_manager_if.c
//
// Provides functions to call local vtpm manager interface (Hotplug)
//
// ==================================================================
#include <stdio.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include "tcg.h"
#include "buffer.h"
#include "log.h"
#include "vtpm_ipc.h"
#include "bsg.h"
#include "vtpm_migrator.h"
#include "vtpm_manager.h"
#define VTPM_TX_HP_FNAME "/var/vtpm/fifos/from_console.fifo"
#define VTPM_RX_HP_FNAME "/var/vtpm/fifos/to_console.fifo"
static vtpm_ipc_handle_t tx_ipc_h, rx_ipc_h;
TPM_RESULT vtpm_manager_open(){
if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE) != 0) || //FIXME: wronly
(vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE) != 0) ) { //FIXME: rdonly
vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n");
return TPM_IOERROR;
}
return TPM_SUCCESS;
}
void vtpm_manager_close() {
vtpm_ipc_close(&tx_ipc_h);
vtpm_ipc_close(&rx_ipc_h);
}
TPM_RESULT vtpm_manager_command(TPM_COMMAND_CODE ord,
buffer_t *command_param_buf,
TPM_RESULT *cmd_status, /* out */
buffer_t *result_param_buf) {
TPM_RESULT status = TPM_FAIL;
int size_read, size_write, i;
BYTE *adj_command, response_header[VTPM_COMMAND_HEADER_SIZE_SRV];
UINT32 dmi_id=0, adj_command_size, out_param_size, adj_param_size;
TPM_TAG tag=VTPM_TAG_REQ;
if ( (!command_param_buf) || (!result_param_buf) || (!cmd_status) ) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
adj_command_size = VTPM_COMMAND_HEADER_SIZE_SRV + buffer_len(command_param_buf);
adj_command = (BYTE *) malloc( adj_command_size );
if (!adj_command) {
status = TPM_RESOURCES;
goto abort_egress;
}
out_param_size = VTPM_COMMAND_HEADER_SIZE + buffer_len(command_param_buf);
BSG_PackList(adj_command, 4,
BSG_TYPE_UINT32, &dmi_id,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &out_param_size,
BSG_TPM_COMMAND_CODE, &ord );
memcpy(adj_command + VTPM_COMMAND_HEADER_SIZE_SRV, command_param_buf->bytes, buffer_len(command_param_buf));
size_write = vtpm_ipc_write(&tx_ipc_h, NULL, adj_command, adj_command_size);
if (size_write > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT (MGR): 0x");
for (i=0; i< adj_command_size; i++) {
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", adj_command[i]);
}
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error writing VTPM Manager console.\n");
status = TPM_IOERROR;
goto abort_egress;
}
if (size_write != (int) adj_command_size )
vtpmlogerror(VTPM_LOG_VTPM, "Could not write entire command to mgr (%d/%d)\n", size_write, adj_command_size);
// Read header for response to manager command
size_read = vtpm_ipc_read(&rx_ipc_h, NULL, response_header, VTPM_COMMAND_HEADER_SIZE_SRV);
if (size_read > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV (MGR): 0x");
for (i=0; i<size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", response_header[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from vtpm manager.\n");
status = TPM_IOERROR;
goto abort_egress;
}
if (size_read < (int) VTPM_COMMAND_HEADER_SIZE_SRV) {
vtpmlogerror(VTPM_LOG_VTPM, "Command from vtpm_manager shorter than std header.\n");
status = TPM_IOERROR;
goto abort_egress;
}
// Unpack response from DMI for TPM command
BSG_UnpackList(response_header, 4,
BSG_TYPE_UINT32, &dmi_id,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &out_param_size,
BSG_TPM_COMMAND_CODE, cmd_status );
// If response has parameters, read them.
// Note that out_param_size is in the client's context
adj_param_size = out_param_size - VTPM_COMMAND_HEADER_SIZE;
if (adj_param_size > 0) {
TPMTRYRETURN( buffer_init( result_param_buf, adj_param_size, NULL) );
size_read = vtpm_ipc_read(&rx_ipc_h, NULL, result_param_buf->bytes, adj_param_size);
if (size_read > 0) {
for (i=0; i< size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", result_param_buf->bytes[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from vtpm manager.\n");
goto abort_egress;
}
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
if (size_read < (int)adj_param_size) {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d).\n", size_read, adj_param_size);
status = TPM_IOERROR;
goto abort_egress;
}
} else {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
}
status=TPM_SUCCESS;
goto egress;
abort_egress:
egress:
return status;
}
@@ -1,104 +0,0 @@
// ===================================================================
//
// 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_migrator.h
//
// Public Interface header for VTPM Migrator
//
// ==================================================================
#ifndef __VTPM_MIGRATOR_H__
#define __VTPM_MIGRATOR_H__
#define VTPM_MTAG_REQ 0x02c1
#define VTPM_MTAG_RSP 0x02c4
// Header sizes.
#define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
// sizeof(TPM_TAG + UINT32 + TPM_COMMAND_CODE)
//*********************** Connection Info **************************
#define VTPM_MIG_PORT 48879
//************************ Command Codes ***************************
#define VTPM_MORD_MIG_STEP1 0x00
#define VTPM_MORD_MIG_STEP2 0x01
#define VTPM_MORD_MIG_STEP3 0x02
#define VTPM_MORD_MIG_STEP4 0x03
//************************ Return Codes ****************************
#define VTPM_SUCCESS 0
#define VTPM_FAIL 1
/******************* Command Parameter API *************************
VTPM Command Format
tpm tag: 2 bytes
command size: 4 bytes // Size of command including header but not DMI
ord: 4 bytes // Command ordinal above
parameters: size - 10 bytes // Command Parameter
VTPM Response Format
tpm tag: 2 bytes
response_size: 4 bytes
status: 4 bytes
parameters: size - 10 bytes
VTPM_Mig_Phase1:
Unsupported: (Handled by scripts)
VTPM_Mig_Phase2
Input Parameters:
domain_name_size: 4 bytes
domain_name : domain_name_size bytes
Output Parameters:
pub_exp_size: 4 bytes
pub_exp: pub_exp_size bytes
pub_mod_size: 4 bytes
pub_mod: pub_mod_size bytes
VTPM_Mig_Phase3
Input Parameters:
vtpm_state_size: 4 bytes
vtpm_state: vtpm_state_size bytes
Output Parameters:
none
VTPM_Mig_Phase4
Unsupported: (Handled by scripts)
*********************************************************************/
#endif //_VTPM_MANAGER_H_
@@ -1,219 +0,0 @@
// ===================================================================
//
// 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_migrator_if.c
//
// Provides functions to call open network connection & call
// a function on the vtpm_migratord on the destination
//
// ==================================================================
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <malloc.h>
#include "tcg.h"
#include "buffer.h"
#include "log.h"
#include "bsg.h"
#include "vtpm_migrator.h"
static int sock_desc;
TPM_RESULT vtpm_migratord_open(char *server_address){
TPM_RESULT status = TPM_FAIL;
/* network variables */
struct in_addr ip_addr;
struct sockaddr_in server_addr;
int addr_len;
struct hostent *dns_info=NULL;
/* set up connection to server*/
dns_info = gethostbyname(server_address);
ip_addr.s_addr = *((unsigned long *) dns_info->h_addr_list[0]);
if(ip_addr.s_addr < 0) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
/* set up server variable */
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(VTPM_MIG_PORT);
server_addr.sin_addr.s_addr = ip_addr.s_addr;
/* open socket, make connection */
sock_desc = socket(AF_INET, SOCK_STREAM, 0);
if (sock_desc < 0 ) {
status = TPM_IOERROR;
goto abort_egress;
}
if (connect(sock_desc,
(struct sockaddr *)&server_addr,
sizeof(server_addr)) < 0 ) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
status = TPM_SUCCESS;
goto egress;
abort_egress:
egress:
return status;
}
void vtpm_migratord_close() {
close(sock_desc);
}
TPM_RESULT vtpm_migratord_command(TPM_COMMAND_CODE ord,
buffer_t *command_param_buf,
TPM_RESULT *cmd_status, /* out */
buffer_t *result_param_buf) {
TPM_RESULT status = TPM_FAIL;
int size_read, size_write, i;
BYTE *command, response_header[VTPM_COMMAND_HEADER_SIZE];
UINT32 dmi_id=0, command_size, out_param_size, adj_param_size;
TPM_TAG tag=VTPM_MTAG_REQ;
if ( (!command_param_buf) || (!result_param_buf) || (!cmd_status) ) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
command_size = VTPM_COMMAND_HEADER_SIZE + buffer_len(command_param_buf);
command = (BYTE *) malloc( command_size );
if (!command) {
status = TPM_RESOURCES;
goto abort_egress;
}
BSG_PackList(command, 3,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &command_size,
BSG_TPM_COMMAND_CODE, &ord );
memcpy(command + VTPM_COMMAND_HEADER_SIZE, command_param_buf->bytes, buffer_len(command_param_buf));
size_write = write(sock_desc, command, command_size);
if (size_write > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT (MIGd): 0x");
for (i=0; i< command_size; i++) {
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", command[i]);
}
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error writing to migration server via network.\n");
status = TPM_IOERROR;
goto abort_egress;
}
if (size_write != (int) command_size )
vtpmlogerror(VTPM_LOG_VTPM, "Could not write entire command to migration server (%d/%d)\n", size_write, command_size);
// Read header for response
size_read = read(sock_desc, response_header, VTPM_COMMAND_HEADER_SIZE);
if (size_read > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV (MIGd): 0x");
for (i=0; i<size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", response_header[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from Migration Server.\n");
status = TPM_IOERROR;
goto abort_egress;
}
if (size_read < (int) VTPM_COMMAND_HEADER_SIZE) {
vtpmlogerror(VTPM_LOG_VTPM, "Command from migration server shorter than std header.\n");
status = TPM_IOERROR;
goto abort_egress;
}
// Unpack response from DMI for TPM command
BSG_UnpackList(response_header, 3,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &out_param_size,
BSG_TPM_COMMAND_CODE, cmd_status );
// If response has parameters, read them.
adj_param_size = out_param_size - VTPM_COMMAND_HEADER_SIZE;
if (adj_param_size > 0) {
TPMTRYRETURN( buffer_init( result_param_buf, adj_param_size, NULL) );
size_read = read(sock_desc, result_param_buf->bytes, adj_param_size);
if (size_read > 0) {
for (i=0; i< size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", result_param_buf->bytes[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from migration server.\n");
goto abort_egress;
}
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
if (size_read < (int)adj_param_size) {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d).\n", size_read, adj_param_size);
status = TPM_IOERROR;
goto abort_egress;
}
} else {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
}
status=TPM_SUCCESS;
goto egress;
abort_egress:
egress:
return status;
}
@@ -1,211 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <stdio.h>
#include <string.h>
#include "tcg.h"
#include "log.h"
#include "bsg.h"
#include "buffer.h"
#include "vtpm_migrator.h"
#include "vtpm_manager.h"
TPM_RESULT handle_vtpm_mig_step2(char *server_addr,
char *name,
UINT32 instance) {
TPM_RESULT status, cmd_status;
buffer_t out_param_buf=NULL_BUF, mig_key_buf=NULL_BUF, empty_buf=NULL_BUF;
UINT32 offset;
struct pack_buf_t addr_data32;
//===== Get Destination's Public Migration Key ======
TPMTRYRETURN( vtpm_migratord_open(server_addr) );
TPMTRYRETURN( vtpm_migratord_command(VTPM_MORD_MIG_STEP2,
&out_param_buf,
&cmd_status,
&mig_key_buf) );
vtpm_migratord_close();
TPMTRYRETURN(cmd_status);
//===== Load migration key into vtpm_manager ========
addr_data32.data = (BYTE *)server_addr;
addr_data32.size = strlen(server_addr) + 1; // Include the null
TPMTRYRETURN ( buffer_init ( &out_param_buf,
sizeof(UINT32) + addr_data32.size +buffer_len(&mig_key_buf),
NULL ) ) ;
offset = BSG_PackList(out_param_buf.bytes, 1,
BSG_TPM_SIZE32_DATA, &addr_data32);
memcpy(out_param_buf.bytes + offset , mig_key_buf.bytes, buffer_len(&mig_key_buf) );
TPMTRYRETURN ( vtpm_manager_open() );
TPMTRYRETURN ( vtpm_manager_command(VTPM_ORD_LOAD_MIG_KEY,
&out_param_buf,
&cmd_status,
&empty_buf) );
vtpm_manager_close();
TPMTRYRETURN(cmd_status);
goto egress;
abort_egress:
egress:
buffer_free(&mig_key_buf);
buffer_free(&out_param_buf);
return status;
}
TPM_RESULT handle_vtpm_mig_step3(char *server_addr,
char *name,
UINT32 instance) {
TPM_RESULT status, cmd_status;
buffer_t out_param_buf=NULL_BUF, state_buf=NULL_BUF, empty_buf=NULL_BUF;
struct pack_buf_t addr_data32, name_data32, state_data32;
//===== Get vtpm state from vtpm_manager ========
addr_data32.data = (BYTE *)server_addr;
addr_data32.size = strlen(server_addr) + 1; // Include the null
TPMTRYRETURN ( buffer_init ( &out_param_buf,
(2 * sizeof(UINT32)) + addr_data32.size,
NULL ) ) ;
BSG_PackList(out_param_buf.bytes, 2,
BSG_TYPE_UINT32, &instance,
BSG_TPM_SIZE32_DATA, &addr_data32);
TPMTRYRETURN ( vtpm_manager_open() );
TPMTRYRETURN ( vtpm_manager_command(VTPM_ORD_MIGRATE_OUT,
&out_param_buf,
&cmd_status,
&state_buf) );
vtpm_manager_close();
TPMTRYRETURN(cmd_status);
TPMTRYRETURN( buffer_free( &out_param_buf ) );
//===== Send vtpm state to destination ======
name_data32.data = (BYTE *)name;
name_data32.size = strlen(name) + 1; // Include the null
state_data32.data = state_buf.bytes;
state_data32.size = buffer_len(&state_buf);
TPMTRYRETURN( buffer_init( &out_param_buf,
2 * sizeof(UINT32) + name_data32.size + state_data32.size,
NULL ) ) ;
BSG_PackList(out_param_buf.bytes, 2,
BSG_TPM_SIZE32_DATA, &name_data32,
BSG_TPM_SIZE32_DATA, &state_data32);
TPMTRYRETURN( vtpm_migratord_open(server_addr) );
TPMTRYRETURN( vtpm_migratord_command(VTPM_MORD_MIG_STEP3,
&out_param_buf,
&cmd_status,
&empty_buf) );
vtpm_migratord_close();
TPMTRYRETURN(cmd_status);
goto egress;
abort_egress:
egress:
buffer_free( &out_param_buf);
buffer_free( &state_buf);
buffer_free( &empty_buf);
return status;
}
// Usage vtpm_migrator addr domain_name instance step
int main(int argc, char **argv) {
/* variables for processing of command */
TPM_RESULT status = TPM_FAIL;
char *server_addr, *name;
UINT32 instance, step;
if (argc != 5) {
vtpmlogerror(VTPM_LOG_VTPM, "Usage: vtpm_migrator addr vm_name instance step\n");
vtpmlogerror(VTPM_LOG_VTPM, " params given %d\n", argc);
status= TPM_BAD_PARAMETER;
goto abort_egress;
}
server_addr = argv[1];
name = argv[2];
instance = atoi( argv[3] );
step = atoi( argv[4] );
switch (step) {
case VTPM_MORD_MIG_STEP2:
status = handle_vtpm_mig_step2(server_addr, name, instance);
break;
case VTPM_MORD_MIG_STEP3:
status = handle_vtpm_mig_step3(server_addr, name, instance);
break;
default:
status = TPM_BAD_PARAMETER;
goto abort_egress;
break;
}
goto egress;
abort_egress:
egress:
return status;
}
@@ -1,202 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "tcg.h"
#include "log.h"
#include "bsg.h"
#include "buffer.h"
#include "vtpm_migrator.h"
void build_error_msg( buffer_t *buf, TPM_RESULT status) {
TPM_TAG tag = VTPM_MTAG_RSP;
UINT32 out_param_size = VTPM_COMMAND_HEADER_SIZE;
buffer_init(buf, out_param_size, NULL);
BSG_PackList(buf->bytes, 3,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &out_param_size,
BSG_TPM_RESULT, &status );
}
int main() {
/* network variables */
int sock_descr, client_sock=-1, len;
struct sockaddr_in addr;
struct sockaddr_in client_addr;
unsigned int client_length;
int bytes;
/* variables for processing of command */
TPM_RESULT status = TPM_FAIL;
BYTE cmd_header[VTPM_COMMAND_HEADER_SIZE];
TPM_TAG tag;
TPM_COMMAND_CODE ord;
UINT32 in_param_size, adj_param_size;
int i, size_read, size_write;
buffer_t in_param_buf=NULL_BUF, result_buf=NULL_BUF;
/* setup socket */
sock_descr = socket(AF_INET, SOCK_STREAM, 0);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(VTPM_MIG_PORT);
if (bind(sock_descr, (struct sockaddr *)&addr, sizeof(addr)) == -1 ) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to bind to port %d.\n", VTPM_MIG_PORT);
return 1;
}
listen(sock_descr, 10);
for(;;) {
// ============ clear client info and wait for connection ==========
memset(&client_addr, 0, sizeof(client_addr));
client_length = sizeof(client_addr);
vtpmloginfo(VTPM_LOG_VTPM, "Waiting for incoming migrations...\n");
client_sock=accept(sock_descr, &client_addr, &client_length);
if (client_sock == -1) {
vtpmlogerror(VTPM_LOG_VTPM, "Incoming connectionn failed.\n");
goto abort_command;
} else {
vtpmloginfo(VTPM_LOG_VTPM, "Incoming connection accepted.\n");
}
// =================== Read incoming command ======================
size_read = read( client_sock, cmd_header, VTPM_COMMAND_HEADER_SIZE);
if (size_read > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "RECV: 0x");
for (i=0; i<size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cmd_header[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from socket.\n");
build_error_msg(&result_buf, TPM_IOERROR);
goto abort_command_with_error;
}
if (size_read < (int) VTPM_COMMAND_HEADER_SIZE) {
vtpmlogerror(VTPM_LOG_VTPM, "Command from socket shorter than std header.\n");
build_error_msg(&result_buf, TPM_BAD_PARAMETER);
goto abort_command_with_error;
}
// Unpack response from client
BSG_UnpackList(cmd_header, 3,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &in_param_size,
BSG_TPM_COMMAND_CODE, &ord );
// If response has parameters, read them.
// Note that out_param_size is in the client's context
adj_param_size = in_param_size - VTPM_COMMAND_HEADER_SIZE;
if (adj_param_size > 0) {
buffer_init( &in_param_buf, adj_param_size, NULL);
size_read = read(client_sock, in_param_buf.bytes, adj_param_size);
if (size_read > 0) {
for (i=0; i< size_read; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", in_param_buf.bytes[i]);
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error reading from socket.\n");
build_error_msg(&result_buf, TPM_IOERROR);
goto abort_command_with_error;
}
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
if (size_read < (int)adj_param_size) {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
vtpmlogerror(VTPM_LOG_VTPM, "Command read(%d) is shorter than header indicates(%d).\n", size_read, adj_param_size);
build_error_msg(&result_buf, TPM_BAD_PARAMETER);
goto abort_command_with_error;
}
} else {
vtpmloginfomore(VTPM_LOG_VTPM, "\n");
}
/* Handle Command */
switch (ord) {
case VTPM_MORD_MIG_STEP2:
handle_vtpm_mig_step2(&in_param_buf, &result_buf);
break;
case VTPM_MORD_MIG_STEP3:
handle_vtpm_mig_step3(&in_param_buf, &result_buf);
break;
default:
build_error_msg(&result_buf, TPM_BAD_PARAMETER);
goto abort_command_with_error;
}
abort_command_with_error:
/* Write Response */
size_write = write(client_sock, result_buf.bytes, buffer_len(&result_buf));
if (size_write > 0) {
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
for (i=0; i< buffer_len(&result_buf); i++) {
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", result_buf.bytes[i]);
}
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
} else {
vtpmlogerror(VTPM_LOG_VTPM, "Error writing response to client.\n");
goto abort_command;
}
if (size_write != (int) buffer_len(&result_buf) )
vtpmlogerror(VTPM_LOG_VTPM, "Could not send entire response to client(%d/%d)\n", size_write, buffer_len(&result_buf));
abort_command:
close(client_sock);
buffer_free(&in_param_buf);
buffer_free(&result_buf);
} // For (;;)
return 0;
}
@@ -1,177 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <stdlib.h>
#include <string.h>
#include "tcg.h"
#include "bsg.h"
#include "log.h"
#include "vtpm_migrator.h"
#include "vtpm_manager.h"
#define VTPM_SH_CMD_HDR "bash -c \"cd /etc/xen/scripts; source /etc/xen/scripts/vtpm-common.sh;"
#define VTPM_SH_CMD_FTR "\""
#define VTPM_SH_GETINST "vtpmdb_get_free_instancenum"
#define VTPM_SH_ADD "vtpm_add_and_activate"
#define VTPM_SH_RESUME "vtpm_resume"
// This must be updated to the longest command name. Currently GETINST
#define VTPM_SH_CMD_SIZE (strlen(VTPM_SH_CMD_HDR) + strlen(VTPM_SH_CMD_FTR) + 1 + strlen(VTPM_SH_GETINST) + 2)
void handle_vtpm_mig_step2(buffer_t *in_param_buf, buffer_t *result_buf)
{
TPM_TAG tag = VTPM_TAG_RSP;
buffer_t out_param_buf= NULL_BUF, mig_key_buf=NULL_BUF;
TPM_RESULT status=TPM_SUCCESS, cmd_status;
UINT32 out_param_size;
if ( (!in_param_buf) || (!result_buf) ) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// ================= Call manager and get mig key ===============
TPMTRYRETURN( vtpm_manager_open() );
TPMTRYRETURN( vtpm_manager_command(VTPM_ORD_GET_MIG_KEY,
&out_param_buf, // Empty
&cmd_status,
&mig_key_buf) );
vtpm_manager_close();
TPMTRYRETURN(cmd_status);
// ==================== return the mig key =====================
out_param_size = VTPM_COMMAND_HEADER_SIZE + buffer_len(&mig_key_buf);
TPMTRYRETURN( buffer_init(result_buf,
out_param_size,
NULL) );
BSG_PackList( result_buf->bytes, 3,
BSG_TPM_TAG, &tag,
BSG_TYPE_UINT32, &out_param_size,
BSG_TPM_RESULT, &status);
memcpy(result_buf->bytes + VTPM_COMMAND_HEADER_SIZE,
mig_key_buf.bytes, buffer_len(&mig_key_buf));
goto egress;
abort_egress:
buffer_free(result_buf);
build_error_msg(result_buf, status);
egress:
return;
}
void handle_vtpm_mig_step3(buffer_t *in_param_buf, buffer_t *result_buf)
{
TPM_TAG tag = VTPM_TAG_RSP;
buffer_t out_param_buf= NULL_BUF, mig_key_buf=NULL_BUF, empty_buf=NULL_BUF;
TPM_RESULT status=TPM_SUCCESS, cmd_status;
UINT32 out_param_size, instance;
char *shell_cmd_str=NULL;
size_t shell_cmd_strlen;
FILE *shell_f=NULL;
if ( (!in_param_buf) || (!result_buf) ) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// ================= Read Parameters ===============
struct pack_buf_t name_data32, state_data32;
BSG_UnpackList(in_param_buf->bytes, 2,
BSG_TPM_SIZE32_DATA, &name_data32,
BSG_TPM_SIZE32_DATA, &state_data32);
// Before using this string, protect us from a non-null term array.
if (name_data32.data[name_data32.size -1] != 0x00) {
name_data32.data[name_data32.size -1] = 0x00;
}
// ====== Call hotplug-script and get an instance ======
shell_cmd_strlen = VTPM_SH_CMD_SIZE + name_data32.size + 10;
shell_cmd_str = (char *) malloc(shell_cmd_strlen); // 10 is just padding for the UINT32
snprintf(shell_cmd_str, shell_cmd_strlen,
VTPM_SH_CMD_HDR VTPM_SH_GETINST VTPM_SH_CMD_FTR);
shell_f = popen(shell_cmd_str, "r");
fscanf(shell_f, "%d", &instance);
pclose(shell_f);
// ====== Call hotplug-script and add instance ======
snprintf(shell_cmd_str, shell_cmd_strlen,
VTPM_SH_CMD_HDR VTPM_SH_ADD " %s %d" VTPM_SH_CMD_FTR,
name_data32.data, instance);
system(shell_cmd_str);
// ========= Call vtpm_manager and load VTPM =======
TPMTRYRETURN( buffer_init( &out_param_buf,
2*sizeof(UINT32) + state_data32.size,
NULL) );
BSG_PackList(out_param_buf.bytes, 2,
BSG_TYPE_UINT32, &instance,
BSG_TPM_SIZE32_DATA, &state_data32);
TPMTRYRETURN( vtpm_manager_open() );
TPMTRYRETURN( vtpm_manager_command(VTPM_ORD_MIGRATE_IN,
&out_param_buf,
&cmd_status,
&empty_buf) );
vtpm_manager_close();
TPMTRYRETURN(cmd_status);
// ====== Call hotplug-script and resume instance ======
snprintf(shell_cmd_str, shell_cmd_strlen,
VTPM_SH_CMD_HDR VTPM_SH_RESUME " %d" VTPM_SH_CMD_FTR, instance);
system(shell_cmd_str);
goto egress;
abort_egress:
egress:
free(shell_cmd_str);
// In this case no params come back, so reuse build_error_msg even for succes.
build_error_msg(result_buf, status);
return;
}
-24
View File
@@ -1,24 +0,0 @@
XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
BIN = libTCS.a
.PHONY: all
all: build
.PHONY: build
build: $(BIN)
.PHONY: install
install: build
.PHONY: clean
clean:
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
.PHONY: mrproper
mrproper: clean
rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
-224
View File
@@ -1,224 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// contextmgr.c
//
// This file contains the context management functions for TCS.
//
// ==================================================================
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "tcs.h"
#include "contextmgr.h"
#include "log.h"
#include "hashtable.h"
BYTE* AddMemBlock(CONTEXT_HANDLE* pContextHandle, // in
int BlockSize) { // in
BLOCK* pCurrentBlock = NULL;
BLOCK* pBlock = NULL;
// check incoming params
if (pContextHandle == NULL || BlockSize == 0)
return NULL;
// Create New Block
pBlock = (BLOCK *)malloc(sizeof(BLOCK));
if (pBlock == NULL)
return (0);
pBlock->aMemory = (BYTE *)malloc(sizeof(BYTE) * BlockSize);
if (pBlock->aMemory == NULL)
return (0);
memset(pBlock->aMemory, 0, BlockSize);
pBlock->nBlockSize = BlockSize;
pBlock->pNextBlock = NULL;
// search for the last block created where to add the
// newly created block
if(pContextHandle->pTopBlock != NULL) {
pCurrentBlock = pContextHandle->pTopBlock;
while(pCurrentBlock->pNextBlock != NULL)
pCurrentBlock = pCurrentBlock->pNextBlock;
pCurrentBlock->pNextBlock= pBlock;
} else
pContextHandle->pTopBlock = pBlock;
pContextHandle->nBlockCount++;
return pBlock->aMemory;
}
BOOL DeleteMemBlock(CONTEXT_HANDLE* pContextHandle, // in
BYTE* pTCPA_BYTEs) { // in
BLOCK* pCurrentBlock = NULL;
BLOCK* pParentBlock = NULL;
BOOL bFound = FALSE;
if (pContextHandle == NULL)
return FALSE;
// Search for the Block in the context by aMemory pointer
pParentBlock = NULL;
pCurrentBlock = pContextHandle->pTopBlock;
while(pCurrentBlock != NULL) {
// If aMemory block is found, delete it
if(pCurrentBlock->aMemory == pTCPA_BYTEs || pTCPA_BYTEs == NULL) {
// if it is the top Block, remove it from the top,
// otherwise remove it from the ParentBlock and stitch
// the NextBlock to the ParentBlock
if(pParentBlock == NULL)
pContextHandle->pTopBlock = pContextHandle->pTopBlock->pNextBlock;
else
pParentBlock->pNextBlock = pCurrentBlock->pNextBlock;
// delete memory Block associated with pointer pTCPA_BYTEs
free(pCurrentBlock->aMemory);
pCurrentBlock->aMemory = NULL;
free(pCurrentBlock);
pCurrentBlock = pParentBlock;
pContextHandle->nBlockCount--;
bFound = TRUE;
}
if(pCurrentBlock != NULL) {
pParentBlock = pCurrentBlock;
pCurrentBlock = pCurrentBlock->pNextBlock;
}
}
return bFound;
}
BOOL AddHandleToList(TCS_CONTEXT_HANDLE hContext, // in
TPM_RESOURCE_TYPE type, // in
TPM_HANDLE handle) { // in
HANDLE_LIST* pNewHandle = NULL;
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Adding Handle to list\n");
CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
if (pContextHandle == NULL)
return 0;
pNewHandle = (HANDLE_LIST *)malloc(sizeof(HANDLE_LIST));
if (pNewHandle == NULL)
return (0);
pNewHandle->handle = handle;
pNewHandle->type = type;
pNewHandle->pNextHandle = pContextHandle->pHandleList;
pContextHandle->pHandleList = pNewHandle;
return 1;
}
BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE hContext, // in
TPM_HANDLE handle) { // in
CONTEXT_HANDLE* pContextHandle = LookupContext(hContext);
HANDLE_LIST *pCurrentHandle = pContextHandle->pHandleList,
*pLastHandle = pCurrentHandle;
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Deleting Handle from list\n");
if (pContextHandle == NULL)
return 0;
while (1) {
if (pCurrentHandle->handle == handle) { // Found element
if (pCurrentHandle == pLastHandle) { // First element in list
pContextHandle->pHandleList = pCurrentHandle->pNextHandle;
free(pCurrentHandle);
} else { // Ordinary element
pLastHandle->pNextHandle = pCurrentHandle->pNextHandle;
free(pCurrentHandle);
}
return 1;
} else { // Not found yet;
pLastHandle = pCurrentHandle;
pCurrentHandle = pCurrentHandle->pNextHandle;
if (pCurrentHandle == NULL) // Found end of list
return 0;
}
}
}
BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle) { // in
HANDLE_LIST* pCurrentHandle;
BOOL returncode = TRUE;
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n");
if (pContextHandle == NULL)
return 1;
pCurrentHandle = pContextHandle->pHandleList;
while (pCurrentHandle != NULL) {
switch (pCurrentHandle->type) {
case TPM_RT_KEY:
returncode = returncode && !TCSP_EvictKey(pContextHandle->handle, pCurrentHandle->handle);
break;
case TPM_RT_AUTH:
returncode = returncode && !TCSP_TerminateHandle(pContextHandle->handle, pCurrentHandle->handle);
break;
default:
returncode = FALSE;
}
pCurrentHandle = pCurrentHandle->pNextHandle;
}
return 1;
}
-82
View File
@@ -1,82 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// contextmgr.c
//
// This file contains the context management functions for TCS.
//
// ==================================================================
#ifndef __CONTEXTMGR_H__
#define __CONTEXTMGR_H__
#include "tcg.h"
#define BLOCK_SIZE 300
typedef struct block {
int nBlockSize;
BYTE* aMemory;
struct block* pNextBlock;
} BLOCK;
typedef struct handle_List {
TPM_HANDLE handle;
TPM_RESOURCE_TYPE type;
struct handle_List* pNextHandle;
} HANDLE_LIST;
typedef struct context_handle {
TCS_CONTEXT_HANDLE handle;
int nBlockCount;
BLOCK* pTopBlock;
HANDLE_LIST* pHandleList;
} CONTEXT_HANDLE;
BYTE* AddMemBlock( CONTEXT_HANDLE* pContextHandle, // in
int BlockSize); // in
BOOL DeleteMemBlock(CONTEXT_HANDLE* pContextHandle, // in
BYTE* pTCPA_BYTEs); // in
BOOL AddHandleToList( TCS_CONTEXT_HANDLE hContext, // in
TPM_RESOURCE_TYPE type, // in
TPM_HANDLE handle); // in
BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE hContext, // in
TPM_HANDLE handle); // in
BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle); // in
#endif //_CONTEXTMGR_H_
File diff suppressed because it is too large. Load diff
-245
View File
@@ -1,245 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// tcs.h
//
// This file declares the TCS API
//
// ==================================================================
#ifndef __TCS_H__
#define __TCS_H__
#include "tcg.h"
#include "contextmgr.h"
#include "buffer.h"
#define HANDLE_NULL 0
// ------------------------------------------------------------------
// Exposed API
// ------------------------------------------------------------------
TPM_RESULT TCS_create();
void TCS_destroy();
TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext );
TPM_RESULT TCS_CloseContext ( /* IN */ TCS_CONTEXT_HANDLE hContext );
TPM_RESULT TCS_Malloc ( TCS_CONTEXT_HANDLE hContext, // in
UINT32 MemSize, // in
BYTE** ppMemPtr ); //out
TPM_RESULT TCS_FreeMemory ( TCS_CONTEXT_HANDLE hContext, // in
BYTE* pMemory); // in
// ------------------------------------------------------------------
// Exposed API
// ------------------------------------------------------------------
// TPM v1.1B Command Set
// Authorzation
TPM_RESULT TCSP_OIAP( TCS_CONTEXT_HANDLE hContext, // in
TCS_AUTHHANDLE* authHandle, // out
TPM_NONCE* nonce0 // out
);
TPM_RESULT TCSP_OSAP ( TCS_CONTEXT_HANDLE hContext, // in
TPM_ENTITY_TYPE entityType, // in
UINT32 entityValue, // in
TPM_NONCE nonceOddOSAP, // in
TCS_AUTHHANDLE* authHandle, // out
TPM_NONCE* nonceEven, // out
TPM_NONCE* nonceEvenOSAP // out
);
TPM_RESULT TCSP_TakeOwnership ( TCS_CONTEXT_HANDLE hContext, // in
UINT16 protocolID, // in
UINT32 encOwnerAuthSize, // in
BYTE* encOwnerAuth, // in
UINT32 encSrkAuthSize, // in
BYTE* encSrkAuth, // in
UINT32* SrkSize, // in, out
BYTE** Srk, // in, out
TCS_AUTH* ownerAuth // in, out
);
TPM_RESULT TCSP_DisablePubekRead ( TCS_CONTEXT_HANDLE hContext, // in
TCS_AUTH* ownerAuth // in, out
);
TPM_RESULT TCSP_TerminateHandle ( TCS_CONTEXT_HANDLE hContext, // in
TCS_AUTHHANDLE handle // in
);
TPM_RESULT TCSP_FlushSpecific ( TCS_CONTEXT_HANDLE hContext, // in
TCS_AUTHHANDLE handle, // in
TPM_RESOURCE_TYPE resourceType //in
);
// TPM Mandatory
TPM_RESULT TCSP_Extend ( TCS_CONTEXT_HANDLE hContext, // in
TPM_PCRINDEX pcrNum, // in
TPM_DIGEST inDigest, // in
TPM_PCRVALUE* outDigest // out
);
TPM_RESULT TCSP_PcrRead ( TCS_CONTEXT_HANDLE hContext, // in
TPM_PCRINDEX pcrNum, // in
TPM_PCRVALUE* outDigest // out
);
TPM_RESULT TCSP_Quote ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE keyHandle, // in
TPM_NONCE antiReplay, // in
UINT32* PcrDataSize, // in, out
BYTE** PcrData, // in, out
TCS_AUTH* privAuth, // in, out
UINT32* sigSize, // out
BYTE** sig // out
);
TPM_RESULT TCSP_Seal ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE keyHandle, // in
TPM_ENCAUTH encAuth, // in
UINT32 pcrInfoSize, // in
BYTE* PcrInfo, // in
UINT32 inDataSize, // in
BYTE* inData, // in
TCS_AUTH* pubAuth, // in, out
UINT32* SealedDataSize, // out
BYTE** SealedData // out
);
TPM_RESULT TCSP_Unseal ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE parentHandle, // in
UINT32 SealedDataSize, // in
BYTE* SealedData, // in
TCS_AUTH* parentAuth, // in, out
TCS_AUTH* dataAuth, // in, out
UINT32* DataSize, // out
BYTE** Data // out
);
TPM_RESULT TCSP_DirWriteAuth ( TCS_CONTEXT_HANDLE hContext, // in
TPM_DIRINDEX dirIndex, // in
TPM_DIRVALUE newContents, // in
TCS_AUTH* ownerAuth // in, out
);
TPM_RESULT TCSP_DirRead ( TCS_CONTEXT_HANDLE hContext, // in
TPM_DIRINDEX dirIndex, // in
TPM_DIRVALUE* dirValue // out
);
TPM_RESULT TCSP_UnBind ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE keyHandle, // in
UINT32 inDataSize, // in
BYTE* inData, // in
TCS_AUTH* privAuth, // in, out
UINT32* outDataSize, // out
BYTE** outData // out
);
TPM_RESULT TCSP_CreateWrapKey ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE hWrappingKey, // in
TPM_ENCAUTH KeyUsageAuth, // in
TPM_ENCAUTH KeyMigrationAuth, // in
UINT32* pcKeySize, // in, out
BYTE** prgbKey, // in, out
TCS_AUTH* pAuth // in, out
);
TPM_RESULT TCSP_LoadKeyByBlob ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE hUnwrappingKey, // in
UINT32 cWrappedKeyBlobSize, // in
BYTE* rgbWrappedKeyBlob, // in
TCS_AUTH* pAuth, // in, out
TCS_KEY_HANDLE* phKeyTCSI, // out
TCS_KEY_HANDLE* phKeyHMAC // out
);
TPM_RESULT TCSP_GetPubKey ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE hKey, // in
TCS_AUTH* pAuth, // in, out
UINT32* pcPubKeySize, // out
BYTE** prgbPubKey // out
);
TPM_RESULT TCSP_EvictKey ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE hKey // in
);
TPM_RESULT TCSP_Sign ( TCS_CONTEXT_HANDLE hContext, // in
TCS_KEY_HANDLE keyHandle, // in
UINT32 areaToSignSize, // in
BYTE* areaToSign, // in
TCS_AUTH* privAuth, // in, out
UINT32* sigSize, // out
BYTE** sig // out
);
TPM_RESULT TCSP_GetRandom ( TCS_CONTEXT_HANDLE hContext, // in
UINT32* bytesRequested, // in, out
BYTE** randomBytes // out
);
TPM_RESULT TCSP_StirRandom ( TCS_CONTEXT_HANDLE hContext, // in
UINT32 inDataSize, // in
BYTE* inData // in
);
TPM_RESULT TCSP_ReadPubek ( TCS_CONTEXT_HANDLE hContext, // in
TPM_NONCE antiReplay, // in
UINT32* pubEndorsementKeySize, // out
BYTE** pubEndorsementKey, // out
TPM_DIGEST* checksum // out
);
// Non-Standard TCSP calls
TPM_RESULT TCSP_SaveState(TCS_CONTEXT_HANDLE hContext); // in
//Give direct access to TransmitData.
// Key and Auth Management is done before transfering command to TDDL.
TPM_RESULT TCSP_RawTransmitData(UINT32 inDataSize, // in
BYTE *inData, // in
UINT32 *outDataSize,// in/out
BYTE *outData); // out
///////////// Private Functions ////////////////////
CONTEXT_HANDLE* LookupContext( TCS_CONTEXT_HANDLE hContext);
#endif //TCS_H
-69
View File
@@ -1,69 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// tpmddl.c
//
// This file defines the TDDLI API
//
// ==================================================================
#ifndef __TPMDDL_H__
#define __TPMDDL_H__
#define TDDL_CAP_PROP_MANUFACTURER 0x0001
#define TDDL_E_FAIL 1
#define TDDL_E_SUCCESS 0
#define TDDL_SUCCESS 0
typedef unsigned int TDDL_UINT32;
typedef TDDL_UINT32 TDDL_RESULT;
typedef unsigned char TDDL_BYTE;
TDDL_RESULT TDDL_Open();
void TDDL_Close();
TDDL_RESULT TDDL_TransmitData( TDDL_BYTE* in,
TDDL_UINT32 insize,
TDDL_BYTE* out,
TDDL_UINT32* outsize);
TDDL_RESULT TDDL_GetStatus();
TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
TDDL_UINT32 sub,
TDDL_BYTE* buffer,
TDDL_UINT32* size);
TDDL_RESULT TDDL_SetCapability( TDDL_UINT32 cap,
TDDL_UINT32 sub,
TDDL_BYTE* buffer,
TDDL_UINT32* size);
#endif // __TPMDDL_H__
-147
View File
@@ -1,147 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include "tcg.h"
#include "buffer.h"
#include "log.h"
#include "tpmddl.h"
// flag to track whether TDDL has been opened
static int g_TDDL_open = 0;
static int g_tx_fd = -1; // the fd to the TPM
#ifndef DUMMY_TPM
#define TPM_TX_FNAME "/dev/tpm0"
static int *g_rx_fdp = &g_tx_fd;
#else
#define TPM_TX_FNAME "/var/tpm/tpm_in.fifo"
#define TPM_RX_FNAME "/var/tpm/tpm_out.fifo"
static int g_rx_fd = -1;
static int *g_rx_fdp = &g_rx_fd; // the fd to the TPM
#endif
TPM_RESULT
TDDL_TransmitData( TDDL_BYTE* in,
TDDL_UINT32 insize,
TDDL_BYTE* out,
TDDL_UINT32* outsize) {
TPM_RESULT status = TPM_SUCCESS;
TDDL_UINT32 i;
vtpmloginfo(VTPM_LOG_TXDATA, "Sending buffer = 0x");
for(i = 0 ; i < insize ; i++)
vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", in[i]);
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
ssize_t size = 0;
// send the request
size = write (g_tx_fd, in, insize);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "write() failed");
ERRORDIE (TPM_IOERROR);
}
else if ((TDDL_UINT32) size < insize) {
vtpmlogerror(VTPM_LOG_TXDATA, "Wrote %d instead of %d bytes!\n", (int) size, insize);
// ... ?
}
// read the response
size = read (*g_rx_fdp, out, TCPA_MAX_BUFFER_LENGTH);
if (size < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "read() failed");
ERRORDIE (TPM_IOERROR);
}
vtpmloginfo(VTPM_LOG_TXDATA, "Receiving buffer = 0x");
for(i = 0 ; i < size ; i++)
vtpmloginfomore(VTPM_LOG_TXDATA, "%2.2x ", out[i]);
vtpmloginfomore(VTPM_LOG_TXDATA, "\n");
*outsize = size;
// close connection
goto egress;
abort_egress:
egress:
return status;
}
TPM_RESULT TDDL_Open() {
TDDL_RESULT status = TDDL_SUCCESS;
if (g_TDDL_open)
return TPM_FAIL;
#ifdef DUMMY_TPM
*g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
#endif
g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
if (g_tx_fd < 0) {
vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
return TPM_IOERROR;
}
g_TDDL_open = 1;
return status;
}
void TDDL_Close() {
if (! g_TDDL_open)
return;
if (g_tx_fd>= 0) {
if (close(g_tx_fd) < 0)
vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
g_tx_fd = -1;
}
if (*g_rx_fdp>= 0) {
if (close(*g_rx_fdp) < 0)
vtpmlogerror(VTPM_LOG_TXDATA, "closeing tpm failed");
*g_rx_fdp = -1;
}
g_TDDL_open = 0;
}
-24
View File
@@ -1,24 +0,0 @@
XEN_ROOT = $(CURDIR)/../../..
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
BIN = libTCGUtils.a
.PHONY: all
all: build
.PHONY: build
build: $(BIN)
.PHONY: install
install: build
.PHONY: clean
clean:
rm -f *.a *.so *.o *.rpm $(DEP_FILES)
.PHONY: mrproper
mrproper: clean
rm -f *~
$(BIN): $(OBJS)
$(AR) rcs $(BIN) $(OBJS)
-829
View File
@@ -1,829 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// bsg.cpp
//
// This file will handle all the TPM Byte Stream functions
//
// ==================================================================
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <malloc.h>
#include "tcg.h"
#include "crypto.h"
#include "bsg.h"
#include "log.h"
static int g_log_recursion_level = 0;
// a largest buffer size. if we get a buf size bigger than this when unpacking,
// will complain!
#define BSG_MAX_BUF_SIZE (1<<18)
#define bsglog(fmt, ...) do { \
int __i; \
for (__i=0; __i < g_log_recursion_level; __i++) { \
vtpmloginfomore (VTPM_LOG_BSG, "%s", " "); \
} \
vtpmloginfomore (VTPM_LOG_BSG, fmt, __VA_ARGS__); \
} while (0)
// FIXME: trigger the selfcheck--need to use glibc hook to do this
//BOOL dummy1 = BSG_static_selfcheck();
// Interpretting Types
// -------------------
//
// Incoming Types are composed of two parts {format, info} squished into a
// BSG_UINT32. The first 4 bits is a format spec indicating what type of
// data it is. If the first 4 bits are zero the info corresponds to a value in
// BSG_s_fmt[]. This is a structure whose composition is described in
// BSG_s_fmt[]. If the value is non-zero, info corresponds to the size of the
// data (in bytes) being passed in. For example a UINT32 being passed in would
// have a format of (__FMT_CONST | 4). If both, the format and info are zero,
// this is interpretted as the end of the structure, and the result is returned.
// these flags are mutually exclusive, so I'll just make them
// format values which indicate the semantics of the 'info' part and the source
// data. The above description has been accordingly adjusted.
// format values for determining what type of data the incoming type is
// it's a 4 bit value, occupying the high 4 bits
#define __FMT_CONST (1UL << 28) // Constant sized value
#define __FMT_DATA (2UL << 28) // Believed to be raw data NOT {size,data}
#define __FMT_SIZE (3UL << 28) // A size. Used in FMT_SIZE??_DATA.
#define __FMT_HSIZE (4UL << 28) // A number of handles
#define __FMT_PACKED (5UL << 28) // 'info' is unused; the source data consists
// of {size32, data} but we're to pack only the
// data as that is already packed, and so
// can/must be unpacked without
// explicitly reading it size
#define __FMT_MASK 0x0FFFFFFFUL // this masks out the 4-bit format
#define __FMT_MASK_SIZE(type) ((type) & __FMT_MASK)
#define __FMT_MASK_FORMAT(type) ((type) & (~__FMT_MASK))
// constant (8/16/32-bits)
#define FMT_U8 (__FMT_CONST | 1UL)
#define FMT_U16 (__FMT_CONST | 2UL)
#define FMT_U32 (__FMT_CONST | 4UL)
// const with a compiler-computed size
#define FMT_SIZEOF(type) (__FMT_CONST | sizeof(type))
// other data (size bytes)
// Used primarily for DIGESTS -> FMT_DATA(20)
#define FMT_DATA(size) (__FMT_DATA | ((BSG_UINT32) (size) & __FMT_MASK))
// 16/32-bit size followed by N bytes of data
#define FMT_SIZE16_DATA (__FMT_SIZE | 2UL)
#define FMT_SIZE32_DATA (__FMT_SIZE | 4UL)
// 16-bit size followed by N key handles
#define FMT_SIZE16_HANDLES (__FMT_HSIZE | 2UL)
#define DIGEST_SIZE 20
typedef BSG_UINT32 BSG_HANDLE;
// TCPA_AUTH has 11 fields!
#define MAX_FIELDS 11
typedef struct BSG_Format
{
BSG_Type type;
const char* name;
BSG_UINT32 fields[MAX_FIELDS + 1];
} BSG_Format;
/*
* TCPA structure data formats
*/
// this has to be manually kept in sync with the
// Type enum!! the static_selfcheck() function should be used regularly!
static BSG_Format s_fmt[] =
{
{BSG_TYPE_UINT32, "BSG_TYPE_UINT32", {FMT_U32, 0}},
{BSG_TYPE_UINT16, "BSG_TYPE_UINT16", {FMT_U16, 0}},
{BSG_TYPE_BYTE, "BSG_TYPE_BYTE", {FMT_U8, 0}},
{BSG_TYPE_BOOL, "BSG_TYPE_BOOL", {FMT_U8, 0}},
{BSG_TPM_SIZE32_DATA, "BSG_TPM_SIZE32_DATA", {FMT_SIZE32_DATA, 0}},
{BSG_TPM_TAG, "BSG_TPM_TAG", {FMT_SIZEOF(TPM_TAG), 0}},
{BSG_TPM_HANDLE, "BSG_TPM_HANDLE", {FMT_SIZEOF(TPM_HANDLE), 0}},
{BSG_TPM_RESULT, "BSG_TPM_RESULT", {FMT_SIZEOF(TPM_RESULT), 0}},
{BSG_TPM_RESOURCE_TYPE, "BSG_TPM_RESOURCE_TYPE", {FMT_SIZEOF(TPM_RESOURCE_TYPE), 0}},
{BSG_TPM_COMMAND_CODE, "BSG_TPM_COMMAND_CODE", {FMT_U32, 0}},
{BSG_TPM_AUTH_DATA_USAGE, "BSG_TPM_AUTH_DATA_USAGE", {FMT_U8, 0}},
{BSG_TPM_ALGORITHM_ID, "BSG_TPM_ALGORITHM_ID", {FMT_U32, 0}},
{BSG_TPM_PROTOCOL_ID, "BSG_TPM_PROTOCOL_ID", {FMT_SIZEOF(TPM_PROTOCOL_ID), 0}},
{BSG_TPM_KEY_USAGE, "BSG_TPM_KEY_USAGE", {FMT_U16, 0}},
{BSG_TPM_ENC_SCHEME, "BSG_TPM_ENC_SCHEME", {FMT_U16, 0}},
{BSG_TPM_SIG_SCHEME, "BSG_TPM_SIG_SCHEME", {FMT_U16, 0}},
{BSG_TPM_MIGRATE_SCHEME, "BSG_TPM_MIGRATE_SCHEME", {FMT_U16, 0}},
{BSG_TPM_KEY_FLAGS, "BSG_TPM_KEY_FLAGS", {FMT_U32, 0}},
{BSG_TPM_AUTHDATA, "BSG_TPM_AUTHDATA", {FMT_DATA(DIGEST_SIZE), 0}},
{BSG_TPM_SECRET, "BSG_TPM_SECRET", {BSG_TPM_AUTHDATA, 0}},
{BSG_TPM_ENCAUTH, "BSG_TPM_ENCAUTH", {BSG_TPM_AUTHDATA, 0}},
{BSG_TPM_PAYLOAD_TYPE, "BSG_TPM_PAYLOAD_TYPE", {FMT_SIZEOF(TPM_PAYLOAD_TYPE), 0}},
{BSG_TPM_VERSION, "BSG_TPM_VERSION", {FMT_DATA(4), 0}}, // vers 1.2
{BSG_TPM_DIGEST, "BSG_TPM_DIGEST", {FMT_DATA(DIGEST_SIZE), 0}},
{BSG_TPM_COMPOSITE_HASH, "BSG_TPM_COMPOSITE_HASH", {BSG_TPM_DIGEST, 0}},
{BSG_TPM_CHOSENID_HASH, "BSG_TPM_CHOSENID_HASH", {BSG_TPM_DIGEST, 0}},
{BSG_TPM_NONCE, "BSG_TPM_NONCE", {FMT_DATA(DIGEST_SIZE), 0}},
{BSG_TPM_KEY_HANDLE, "BSG_TPM_KEY_HANDLE", {FMT_SIZEOF(TPM_KEY_HANDLE), 0}},
{BSG_TPM_KEY_HANDLE_LIST, "BSG_TPM_KEY_HANDLE_LIST",
{FMT_SIZE16_HANDLES, 0}},
{BSG_TPM_KEY_PARMS, "BSG_TPM_KEY_PARMS", {
BSG_TPM_ALGORITHM_ID,
BSG_TPM_ENC_SCHEME,
BSG_TPM_SIG_SCHEME,
FMT_SIZE32_DATA,
0}},
{BSG_TPM_RSA_KEY_PARMS, "BSG_TPM_RSA_KEY_PARMS", {
FMT_U32, FMT_U32, FMT_SIZE32_DATA, 0}},
{BSG_TPM_STORE_PUBKEY, "BSG_TPM_STORE_PUBKEY", {FMT_SIZE32_DATA, 0}},
{BSG_TPM_PUBKEY, "BSG_TPM_PUBKEY", {BSG_TPM_KEY_PARMS, BSG_TPM_STORE_PUBKEY, 0}},
{BSG_TPM_KEY, "BSG_TPM_KEY", {
BSG_TPM_VERSION,
BSG_TPM_KEY_USAGE,
BSG_TPM_KEY_FLAGS,
BSG_TPM_AUTH_DATA_USAGE,
BSG_TPM_KEY_PARMS,
FMT_SIZE32_DATA, // the PCR_INFO
BSG_TPM_STORE_PUBKEY,
FMT_SIZE32_DATA, // the encrypted part
0}},
{BSG_TPM_MIGRATIONKEYAUTH, "BSG_TPM_MIGRATIONKEYAUTH", {
BSG_TPM_PUBKEY,
BSG_TPM_MIGRATE_SCHEME,
BSG_TPM_DIGEST, 0}},
{BSG_TCPA_AUDIT_EVENT, "TCPA_AUDIT_EVENT", {
BSG_TPM_COMMAND_CODE,
BSG_TPM_RESULT, 0 }},
{BSG_TCPA_EVENT_CERT, "TCPA_EVENT_CERT", {
BSG_TPM_DIGEST,
BSG_TPM_DIGEST,
FMT_DATA(2),
FMT_SIZE32_DATA, 0}},
{BSG_TPM_PCR_SELECTION, "BSG_TPM_PCR_SELECTION", {FMT_SIZE16_DATA, 0} },
{BSG_TPM_PCR_COMPOSITE, "BSG_TPM_PCR_COMPOSITE", { BSG_TPM_PCR_SELECTION,
FMT_SIZE32_DATA,
0} },
{BSG_TPM_PCR_INFO, "BSG_TPM_PCR_INFO", { BSG_TPM_PCR_SELECTION,
BSG_TPM_COMPOSITE_HASH,
BSG_TPM_COMPOSITE_HASH,
0} },
{BSG_TPM_STORED_DATA, "BSG_TPM_STORED_DATA", {
BSG_TPM_VERSION,
FMT_SIZE32_DATA,
FMT_SIZE32_DATA,
0}},
{BSG_TPM_SYMMETRIC_KEY, "BSG_TPM_SYMMETRIC_KEY", {
BSG_TPM_ALGORITHM_ID,
BSG_TPM_ENC_SCHEME,
FMT_SIZE16_DATA,
0}},
{BSG_TPM_STORE_PRIVKEY, "BSG_TPM_STORE_PRIVKEY", {FMT_SIZE32_DATA, 0}},
{BSG_TPM_STORE_ASYMKEY, "BSG_TPM_STORE_ASYMKEY", {
BSG_TPM_PAYLOAD_TYPE,
BSG_TPM_SECRET,
BSG_TPM_SECRET,
BSG_TPM_DIGEST,
BSG_TPM_STORE_PRIVKEY,
0}},
{BSG_TPM_MIGRATE_ASYMKEY, "BSG_TPM_MIGRATE_ASYMKEY", {
BSG_TPM_PAYLOAD_TYPE,
BSG_TPM_SECRET,
BSG_TPM_DIGEST,
FMT_U32,
BSG_TPM_STORE_PRIVKEY,
0}},
{BSG_TPM_QUOTE_INFO, "BSG_TPM_QUOTE_INFO", {
BSG_TPM_VERSION,
FMT_DATA(4),
BSG_TPM_COMPOSITE_HASH,
BSG_TPM_NONCE,
0}},
{BSG_TPM_IDENTITY_CONTENTS, "BSG_TPM_IDENTITY_CONTENTS", {
BSG_TPM_VERSION,
FMT_U32,
BSG_TPM_CHOSENID_HASH,
BSG_TPM_PUBKEY,
0}},
{BSG_TPM_PCRVALUE, "BSG_TPM_PCRVALUE", {FMT_DATA(DIGEST_SIZE), 0}},
{BSG_TCPA_PCR_FLAGS, "TCPA_PCR_FLAGS", {
FMT_U8,
FMT_U8,
0}},
{BSG_TCS_AUTH, "TCS_AUTH", {
BSG_TYPE_UINT32,
BSG_TPM_NONCE,
BSG_TPM_NONCE,
BSG_TYPE_BOOL,
BSG_TPM_AUTHDATA,
0}},
{BSG_TPM_KEY_NONSENSITIVE, "BSG_TPM_KEY_NONSENSITIVE", {
BSG_TPM_VERSION,
BSG_TPM_KEY_USAGE,
BSG_TPM_KEY_FLAGS,
BSG_TPM_AUTH_DATA_USAGE,
BSG_TPM_KEY_PARMS,
FMT_SIZE32_DATA,
BSG_TPM_STORE_PUBKEY,
0}},
{BSG_PACKED, "BSG_PACKED", {
__FMT_PACKED,
0 }},
{BSG_TYPE_MAX, "", {0}},
};
static const BSG_Format* find_format (BSG_Type t) {
BSG_Format * f = s_fmt;
if (t >= BSG_TYPE_MAX) {
return NULL;
}
// WARNING: this depends on the enum and s_fmt[] array being in sync! make
// sure to run the static_selfcheck() to make sure
f = s_fmt + (t - BSG_TYPE_FIRST);
return f;
}
//
// a consistency-checking routine which can be run at compile time
// (ie. immediately after compilation)
//
// tasks:
// - verify that s_fmt has one entry per Type t, and that entry is at s_fmt[t]
//
// conditions:
// - need that s_fmt[0] is the first type listed in the Type enum! ie the first
// Type has value 0, not 1
//
// FIXME: should have a function be passed in here which is called if the test
// fails. Then the caller can decide what to do: abort, notify, whatever
//
BOOL BSG_static_selfcheck ()
{
int i;
for (i=BSG_TYPE_FIRST; i <= BSG_TYPE_MAX; i++) {
if (s_fmt[i - BSG_TYPE_FIRST].type != i) {
bsglog ("%s\n", "BSG: static_selfcheck failed!\n");
bsglog ("failure at %i, allegedly %s\n",
i, s_fmt[i - BSG_TYPE_FIRST].name);
abort();
return FALSE;
}
}
bsglog ("%s\n", "BSG: static_selfcheck success!");
return TRUE;
}
/**
* Flatten a TCPA structure into a buffer in big-endian format
* @type: TCPA structure type
* @src: (IN) TCPA structure (OUT) end of TCPA structure
* @dst: (OUT) flattened data
* Returns: Flattened size or -1 for unknown types
*/
// make it so that it can just run through the whole process and return
// the packed size, without packing anything. this will be done if dst is NULL.
static int BSG_Pack_private(BSG_Type type, const BSG_BYTE** src, BSG_BYTE* dst)
{
// check incoming parameters
if (*src == NULL)
return 0;
const BSG_BYTE* s = *src;
BSG_BYTE* d = dst;
BSG_UINT32 size = __FMT_MASK_SIZE(type);
BSG_UINT32 format = __FMT_MASK_FORMAT(type);
if (format == __FMT_CONST) // We are dealing with a fixed length value eg. UINT32
{
BSG_UINT32 val = 0;
switch (size) {
case 1: val = * (BYTE*) s; break;
case 2: val = * (unsigned short*) s; break;
case 4: val = * (BSG_UINT32*) s; break;
}
if (dst)
BSG_PackConst(val, size, d);
s += size;
d += size;
} else if (format == __FMT_DATA) { // We are dealing with raw data. Not sure when
// this is used.
if (dst) {
bsglog ("BSG: __FMT_DATA size %d, src %p, dst %p\n", size, s, d);
memcpy(d, s, size);
}
s += size;
d += size;
} else if (format == __FMT_SIZE || format == __FMT_HSIZE) { // It's a size, followed by that much data or handles
BSG_UINT32 psize = 0;
switch (size) {
case 1: psize = * (BYTE*) s; break;
case 2: psize = * (unsigned short*) s; break;
case 4: psize = * (BSG_UINT32*) s; break;
}
if (dst)
BSG_PackConst(psize, size, d);
s += size;
d += size;
// now 's' points to an address, so cast it to BSG_BYTE**
const BSG_BYTE* pdata = * ((BSG_BYTE**) s);
s += sizeof(BSG_BYTE*);
if (format == __FMT_HSIZE) {// This is a list of psize Handles
if (dst) {
BSG_HANDLE* d2 = (BSG_HANDLE*) d;
BSG_HANDLE* p2 = (BSG_HANDLE*) pdata;
BSG_UINT32 i;
for (i = 0; i < psize; i++)
d2[i] = BSG_UnpackConst((BSG_BYTE*)(p2 + i), 4);
}
d += psize * sizeof(BSG_HANDLE);
} else {// If it's not psize handles, it's psize data.
if (psize > 0) {
if (dst) {
bsglog ("BSG: __FMT_SIZE, size=%d, src=%p, dst=%p\n",
psize, pdata, d);
memcpy(d, pdata, psize);
}
}
d += psize;
}
} else if (format == __FMT_PACKED) {
// the source buffer is a pack_constbuf_t, which has a size and a
// pointer. just copy the buffer value, the size is not included in the
// output stream.
pack_constbuf_t * buf = (pack_constbuf_t*) s;
if (dst) {
bsglog ("BSG: __FMT_PACKED, size=%d, src=%p, dst=%p\n",
buf->size, buf->data, d);
memcpy(d, buf->data, buf->size);
}
s += buf->size;
d += buf->size;
} else if (format == 0) {// No flags are set. This is a structure & it should
// be looked up in the bsg_s_fmt[]
const BSG_Format* x = find_format (type);
if (x == NULL) {
vtpmloginfo(VTPM_LOG_BSG, "BSG_Pack: cannot find type %d\n", type);
return -1;
}
if (dst)
bsglog ("BSG_Pack type %s\n", x->name);
// iterate through the fields
const BSG_UINT32* f = x->fields;
for (; *f; f++) {
int fsize;
g_log_recursion_level++;
fsize = BSG_Pack_private((BSG_Type) *f, &s, dst ? d : NULL);
g_log_recursion_level--;
if (fsize <= 0)
return fsize;
d += fsize;
}
} else {
vtpmlogerror(VTPM_LOG_BSG, "BSG_Pack(): Unknown format %d\n", format);
return -1;
}
*src = s;
return (d - dst);
}
/**
* Unflatten a TCPA structure from a buffer in big-endian format
* @type: TCPA structure type
* @src: flattened data
* @dst: (IN) TCPA structure (OUT) end of TCPA structure
* Returns: Flattened size
* Note: Returns flattened size NOT the unpacked structure size
*/
static int BSG_Unpack_private(BSG_Type type, const BSG_BYTE* src, BSG_BYTE** dst) {
// check incoming parameters
if (src == NULL)
return 0;
const BSG_BYTE* s = src;
BSG_BYTE* d = dst ? *dst:NULL;
if (dst && !d)
dst = NULL;
BSG_UINT32 size = __FMT_MASK_SIZE(type);
BSG_UINT32 format = __FMT_MASK_FORMAT(type);
if (format == __FMT_CONST) {// We are dealing with a fixed length value ie. UINT32
BSG_UINT32 val = BSG_UnpackConst(s, size);
if (dst) {
switch (size) {
case 1: *(BYTE *) d = (BSG_BYTE) val; break;
case 2: *(unsigned short*) d = (unsigned short) val; break;
case 4: *(BSG_UINT32*) d = (BSG_UINT32) val; break;
}
}
s += size;
d += size;
} else if (format == __FMT_DATA) {// We are dealing with raw data. Not sure when this is used.
if (dst)
memcpy(d, s, size);
d += size;
s += size;
} else if (format == __FMT_SIZE || format == __FMT_HSIZE) {// It's a size, followed by that much data or handles
BSG_UINT32 psize = BSG_UnpackConst(s, size);
if (psize > BSG_MAX_BUF_SIZE) {
vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack runs into var-sized data bigger than %u bytes!!\n",
BSG_MAX_BUF_SIZE);
return -1;
}
if (dst) {
switch (size) {
case 1: *(BYTE *) d = (BSG_BYTE) psize; break;
case 2: *(unsigned short*) d = (unsigned short) psize; break;
case 4: *(BSG_UINT32*) d = (BSG_UINT32) psize; break;
}
}
s += size;
d += size;
BSG_BYTE* pdata = NULL;
if (psize) {
if (format == __FMT_HSIZE) { // This is a list of psize Handles
if (dst) {
BSG_HANDLE* s2 = (BSG_HANDLE*) s;
pdata = (BSG_BYTE *)malloc(psize * sizeof(BSG_HANDLE));
if (!pdata)
return -1;
BSG_HANDLE* p2 = (BSG_HANDLE*) pdata;
BSG_UINT32 i;
for (i = 0; i < psize; i++) {
BSG_PackConst(s2[i], 4, (BSG_BYTE*)(p2 + i));
}
}
s += psize * sizeof(BSG_HANDLE);
} else { // If it's not psize handles, it's psize data.
if (dst) {
pdata = (BSG_BYTE *)malloc(sizeof(BSG_BYTE) * psize);
if (!pdata)
return -1;
memcpy(pdata, s, psize);
}
s += psize;
}
}
if (dst)
*(void**) d = pdata;
d += sizeof(void*);
} else if (format == __FMT_PACKED) {
// this doesn't make sense for unpacking!
vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack() called with format __FMT_PACKED. "
"This does not make sense\n");
return -1;
} else if (format == 0) {// No flags are set. This is a structure & it should
// be looked up in the bsg_s_fmt[]
const BSG_Format* x = find_format (type);
if (x == NULL) {
vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack: cannot find type %d\n", type);
return -1;
}
const BSG_UINT32* f = x->fields;
for (; *f; f++) {
int fsize = BSG_Unpack_private((BSG_Type) *f, s, dst ? &d:NULL);
if (fsize <= 0)
return fsize;
s += fsize;
}
}
if (dst)
*dst = d;
return (s - src);
}
/**
* Free memory associated with unpacked TCPA structure
* @type: TCPA structure type
* @src: (IN) TCPA structure (OUT) end of TCPA structure
* Note: Destroy should be called on all structures created with Unpack
* to ensure that any allocated memory is freed
*/
static void BSG_Destroy_private(BSG_Type type, BSG_BYTE** src) {
BSG_BYTE* s = *src;
BSG_UINT32 size = __FMT_MASK_SIZE(type);
BSG_UINT32 format = __FMT_MASK_FORMAT(type);
if ((src == NULL) || (*src == NULL)) {
vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with NULL src\n");
return;
}
if (format == __FMT_CONST || format == __FMT_DATA)
s += size;
else if (format == __FMT_SIZE || format == __FMT_HSIZE) {
s += size;
BSG_BYTE* ptr = *(BSG_BYTE**) s;
free(ptr);
s += sizeof(void*);
} else if (format == __FMT_PACKED) {
// this doesn't make sense for unpacking, hence also for Destroy()
vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with format __FMT_PACKED. "
"This does not make sense\n");
return;
} else if (format == 0) {
const BSG_Format* x = find_format (type);
if (x == NULL) {
vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy: cannot find type %d\n", type);
return;
}
const BSG_UINT32* f = x->fields;
for (; *f; f++)
BSG_Destroy_private((BSG_Type) *f, &s);
}
*src = s;
}
int BSG_Pack(BSG_Type type, const void* src, BSG_BYTE* dst)
{
const BSG_BYTE* src2 = (const BSG_BYTE*) src;
return BSG_Pack_private(type, &src2, dst);
}
int BSG_Unpack(BSG_Type type, const BSG_BYTE* src, void* dst)
{
BSG_BYTE* dst2 = (BSG_BYTE*) dst;
return BSG_Unpack_private(type, src, dst ? &dst2:NULL);
}
void BSG_Destroy(BSG_Type type, void* src)
{
BSG_BYTE* src2 = (BSG_BYTE*) src;
BSG_Destroy_private(type, &src2);
}
/**
* Pack a 8/16/32-bit constant into a buffer in big-endian format
* @val: constant value
* @size: constant size in bytes (1, 2, or 4)
* @dst: (OUT) buffer
*/
void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst) {
bsglog ("BSG: PackConst on %d of size %i into address %p\n", val, size, dst);
switch (size) {
case 4:
dst[0] = (BSG_BYTE)((val >> 24) & 0xff);
dst[1] = (BSG_BYTE)((val >> 16) & 0xff);
dst[2] = (BSG_BYTE)((val >> 8) & 0xff);
dst[3] = (BSG_BYTE)(val & 0xff);
break;
case 2:
dst[0] = (BSG_BYTE)((val >> 8) & 0xff);
dst[1] = (BSG_BYTE)(val & 0xff);
break;
case 1:
dst[0] = (BSG_BYTE)(val & 0xff);
break;
}
}
/**
* Unpack a 8/16/32-bit constant from a buffer in big-endian format
* @src: buffer
* @size: constant size in bytes (1, 2, or 4)
*/
BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size) {
BSG_UINT32 val = 0;
if (src == NULL)
return 0;
switch (size) {
case 4:
val = (((BSG_UINT32) src[0]) << 24
| ((BSG_UINT32) src[1]) << 16
| ((BSG_UINT32) src[2]) << 8
| (BSG_UINT32) src[3]);
break;
case 2:
val = (((BSG_UINT32) src[0]) << 8 | (BSG_UINT32) src[1]);
break;
case 1:
val = (BSG_UINT32) src[0];
break;
}
return val;
}
// Pack a list of parameters. Beware not to send values, but rather you must
// send a pointer to your values Instead. This includes UINT32's.
int BSG_PackList( BSG_BYTE* dst, int ParamCount, ... ) {
int ParamNumber;
BSG_Type format;
BSG_BYTE* val = NULL;
int size=0;
va_list paramList;
va_start( paramList, ParamCount );
for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
//Strangeness with int is because gcc wanted an int rather than a enum of ints.
format = (BSG_Type) va_arg( paramList, int );
val = va_arg( paramList, BSG_BYTE* );
size += BSG_Pack(format, val, dst == NULL ? NULL : dst + size);
}
va_end (paramList);
return size;
}
// Unpack a list of parameters.
int BSG_UnpackList( const BSG_BYTE* src, int ParamCount, ... ) {
int ParamNumber = 0;
BSG_Type format;
BSG_BYTE* val = NULL;
int size = 0;
va_list paramList;
va_start( paramList, ParamCount );
for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
format = (BSG_Type) va_arg( paramList, int );
val = va_arg( paramList, BSG_BYTE* );
size += BSG_Unpack(format, src + size, val);
}
va_end( paramList );
return size;
}
// Destroy any memory allocated by calls to unpack
void BSG_DestroyList(int ParamCount, ... ) {
int ParamNumber = 0;
BSG_Type argType;
BSG_BYTE* paramValue = NULL;
va_list paramList;
va_start( paramList, ParamCount );
for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) {
argType = (BSG_Type) va_arg( paramList, int );
paramValue = va_arg( paramList, BSG_BYTE* );
BSG_Destroy(argType, paramValue);
}
va_end( paramList );
return;
}
// and a tuple version
TPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]) {
int i;
for (i = 0; i < numParams; i++)
BSG_Destroy (params[i].type, params[i].addr);
return TPM_SUCCESS;
}
//
// wrappers of Pack and PackList which malloc the ouput buffer. to be freed
// by the caller later
//
int BSG_PackMalloc (BSG_Type type, const void* src, BSG_BYTE** o_dst) {
int size = BSG_Pack (type, src, NULL);
BSG_BYTE * dest = (BSG_BYTE*) malloc (size);
if (dest == NULL)
return -1;
size = BSG_Pack(type, src, dest);
*o_dst = dest;
return size;
}
int BSG_PackListMalloc(BSG_BYTE** outBuffer, int ParamCount, ... ) {
va_list args;
int size;
va_start (args, ParamCount);
size = BSG_PackList (NULL, ParamCount, args);
va_end (args);
BSG_BYTE * dest = (BSG_BYTE*) malloc (size);
if (dest == NULL)
return -1;
va_start (args, ParamCount);
size = BSG_PackList (dest, ParamCount, args);
va_end (args);
*outBuffer = dest;
return size;
}
-166
View File
@@ -1,166 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// bsg.h
//
// This file contains API's for the TPM Byte Stream functions
//
// ==================================================================
#ifndef __BSG_H__
#define __BSG_H__
#include <stdarg.h>
#include "buffer.h"
typedef unsigned int BSG_UINT32;
typedef unsigned char BSG_BYTE;
// forward decl
struct pack_const_tuple_t;
struct pack_tuple_t;
/**
* Byte stream generator
*/
// this has to be manually kept in sync with the
// s_fmt array!!
// but now we have a self-check function which can make sure things are well
// (if used!)
typedef enum BSG_Type
{
BSG_TYPE_FIRST = 1,
BSG_TYPE_UINT32 = 1, // start at 1 so that Type 0 only serves as an
// unused/special value
BSG_TYPE_UINT16,
BSG_TYPE_BYTE,
BSG_TYPE_BOOL,
BSG_TPM_SIZE32_DATA, // a 32 bit unsigned size, followed by
// a pointer to that much data. can pass a
// struct pack_buf_t as the param
BSG_TPM_TAG,
BSG_TPM_HANDLE,
BSG_TPM_RESULT,
BSG_TPM_RESOURCE_TYPE,
BSG_TPM_COMMAND_CODE,
BSG_TPM_AUTH_DATA_USAGE,
BSG_TPM_ALGORITHM_ID,
BSG_TPM_PROTOCOL_ID,
BSG_TPM_KEY_USAGE,
BSG_TPM_ENC_SCHEME,
BSG_TPM_SIG_SCHEME,
BSG_TPM_MIGRATE_SCHEME,
BSG_TPM_KEY_FLAGS,
BSG_TPM_AUTHDATA,
BSG_TPM_SECRET,
BSG_TPM_ENCAUTH,
BSG_TPM_PAYLOAD_TYPE,
BSG_TPM_VERSION,
BSG_TPM_DIGEST,
BSG_TPM_COMPOSITE_HASH,
BSG_TPM_CHOSENID_HASH,
BSG_TPM_NONCE,
BSG_TPM_KEY_HANDLE,
BSG_TPM_KEY_HANDLE_LIST,
BSG_TPM_KEY_PARMS,
BSG_TPM_RSA_KEY_PARMS,
BSG_TPM_STORE_PUBKEY,
BSG_TPM_PUBKEY,
BSG_TPM_KEY,
BSG_TPM_MIGRATIONKEYAUTH,
BSG_TCPA_AUDIT_EVENT,
BSG_TCPA_EVENT_CERT,
BSG_TPM_PCR_SELECTION,
BSG_TPM_PCR_COMPOSITE,
BSG_TPM_PCR_INFO,
BSG_TPM_STORED_DATA,
BSG_TPM_SYMMETRIC_KEY,
BSG_TPM_STORE_PRIVKEY,
BSG_TPM_STORE_ASYMKEY,
BSG_TPM_MIGRATE_ASYMKEY,
BSG_TPM_QUOTE_INFO,
BSG_TPM_IDENTITY_CONTENTS,
BSG_TPM_PCRVALUE,
BSG_TCPA_PCR_FLAGS,
BSG_TCS_AUTH,
// this is the BSG_TPM_KEY struct without the encData field
BSG_TPM_KEY_NONSENSITIVE,
BSG_PACKED,
BSG_TYPE_MAX
} BSG_Type;
struct pack_const_tuple_t {
BSG_Type type;
const void * addr;
};
typedef struct pack_tuple_t {
BSG_Type type;
void * addr;
} pack_tuple_t;
int BSG_Pack(BSG_Type type, const void* src, BSG_BYTE* dst);
int BSG_Unpack(BSG_Type type, const BSG_BYTE* src, void* dst);
void BSG_Destroy(BSG_Type type, void* src);
// wrappers of Pack and PackList which malloc the ouput buffer. to be freed
// by the caller later. returns size of allocated buffer, or -1 in case
// allocation failed
int BSG_PackMalloc (BSG_Type type, const void* src, BSG_BYTE** o_dst);
int BSG_PackListMalloc (BSG_BYTE** outBuffer, int ParamCount, ... );
// a va_list version of PackList
int BSG_PackList(BSG_BYTE* outBuffer, int ParamCount, ... );
int BSG_UnpackList(const BSG_BYTE* inBuffer, int ParamCount, ... );
void BSG_DestroyList(int ParamCount, ... );
// wrapper of PackList which uses a buffer_t
TPM_RESULT BSG_PackListBuf (buffer_t * o_buf, int ParamCount, ...);
// and a tuple version
TPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]);
void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst);
BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size);
BOOL BSG_static_selfcheck ();
#endif
-226
View File
@@ -1,226 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/param.h>
#include "tcg.h"
#include "bsg.h"
#include "buffer.h"
static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize);
//
// buffer functions!
//
TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const BYTE* initval) {
if (initsize == 0) {
memset(buf, 0, sizeof(*buf));
return TPM_SUCCESS;
}
buf->bytes = (BYTE*) malloc (initsize);
if (buf->bytes == NULL)
return TPM_RESOURCES;
buf->size = initsize;
buf->alloc_size = initsize;
if (initval)
memcpy (buf->bytes, initval, initsize);
buf->is_owner = TRUE;
return TPM_SUCCESS;
}
TPM_RESULT buffer_init_convert (buffer_t * buf, tpm_size_t initsize, BYTE* initval) {
buf->size = initsize;
buf->alloc_size = initsize;
buf->bytes = initval;
buf->is_owner = TRUE;
return TPM_SUCCESS;
}
TPM_RESULT buffer_init_copy (buffer_t * buf, const buffer_t * src) {
TPM_RESULT status = buffer_init (buf, src->size, src->bytes);
buf->is_owner = TRUE;
return status;
}
// make an alias to a constant array
TPM_RESULT buffer_init_const (buffer_t * buf, tpm_size_t size, const BYTE* val) {
// TODO: try to enforce the const things somehow!
buf->bytes = (BYTE*) val;
buf->size = size;
buf->alloc_size = 0; // this field is now unneeded
buf->is_owner = FALSE;
return TPM_SUCCESS;
}
// make an alias into buf, with given offset and length
// if len = 0, make the alias go to the end of buf
TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
tpm_size_t offset, tpm_size_t len) {
if (offset + len > b->size) {
return TPM_NOSPACE;
}
buf->bytes = b->bytes + offset;
buf->size = len > 0 ? len : b->size - offset;
//VS/ buf->alloc_size = 0;
if (len ==0)
buf->alloc_size = b->alloc_size - offset;
else
buf->alloc_size = MIN(b->alloc_size - offset, len);
buf->is_owner = FALSE;
return TPM_SUCCESS;
}
// make an alias buffer_t into bytestream, with given length
TPM_RESULT buffer_init_alias_convert (buffer_t * buf, tpm_size_t size, BYTE* val) {
buf->size = size;
buf->alloc_size = size;
buf->bytes = val;
buf->is_owner = FALSE;
return TPM_SUCCESS;
}
// copy into the start of dest
TPM_RESULT buffer_copy (buffer_t * dest, const buffer_t* src)
{
TPM_RESULT status = TPM_SUCCESS;
if (dest->alloc_size < src->size) {
TPMTRYRETURN( buffer_priv_realloc (dest, src->size) );
}
memcpy (dest->bytes, src->bytes, src->size);
dest->size = src->size;
//VS/ dest->is_owner = TRUE;
abort_egress:
return status;
}
BOOL buffer_eq (const buffer_t * a, const buffer_t * b) {
return (a->size == b->size && memcmp (a->bytes, b->bytes, a->size) == 0);
}
void buffer_memset (buffer_t * buf, BYTE b) {
memset (buf->bytes, b, buf->size);
}
TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes) {
TPM_RESULT status = TPM_SUCCESS;
if (buf->alloc_size < buf->size + len) {
TPMTRYRETURN( buffer_priv_realloc (buf, buf->size + len) );
}
memcpy (buf->bytes + buf->size, bytes, len);
buf->size += len;
goto egress;
abort_egress:
egress:
return status;
}
tpm_size_t buffer_len (const buffer_t* buf) {
return buf->size;
}
TPM_RESULT buffer_free (buffer_t * buf) {
if (buf && buf->is_owner && buf->bytes != NULL) {
free (buf->bytes);
buf->bytes = NULL;
buf->size = buf->alloc_size = 0;
}
return TPM_SUCCESS;
}
TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize) {
// we want to realloc to twice the size, or the new size, whichever
// bigger
BYTE * tmpbuf = NULL;
newsize = MAX (buf->alloc_size * 2, newsize);
tmpbuf = (BYTE*) realloc (buf->bytes, newsize);
if (tmpbuf == NULL)
return TPM_SIZE;
buf->bytes = tmpbuf;
buf->alloc_size = newsize;
return TPM_SUCCESS;
}
-95
View File
@@ -1,95 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#ifndef __VTPM_BUFFER_H__
#define __VTPM_BUFFER_H__
#include <stddef.h> // for pointer NULL
#include "tcg.h"
typedef UINT32 tpm_size_t;
// first version, probably will be expanded...
#define NULL_BUF {0,0,0,0}
typedef struct {
// private!!
tpm_size_t size, alloc_size;
BYTE * bytes;
BOOL is_owner; // do we own this buffer, and need to free it?
} buffer_t;
// allocate the buffer if initsize > 0, copying over initval if provided
TPM_RESULT buffer_init (buffer_t * buf,
tpm_size_t initsize,
const BYTE* initval);
// Create a new buffer from a BYTE *. Use buffer_free to destroy original BYTE *
TPM_RESULT buffer_init_convert (buffer_t * buf,
tpm_size_t initsize,
BYTE* initval);
// make an alias to a constant array, no copying
TPM_RESULT buffer_init_const (buffer_t * buf, tpm_size_t size, const BYTE* val);
// make an alias into buf, with given offset and length
// if len = 0, make the alias go to the end of buf
TPM_RESULT buffer_init_alias (buffer_t * buf, const buffer_t * b,
tpm_size_t offset, tpm_size_t);
// make an alias buffer into a bytestream
TPM_RESULT buffer_init_alias_convert (buffer_t * buf,
tpm_size_t size, BYTE* val);
// "copy constructor"
TPM_RESULT buffer_init_copy (buffer_t * buf, const buffer_t * src);
// copy into the start of a
TPM_RESULT buffer_copy (buffer_t * dest, const buffer_t* src);
// are they equal?
BOOL buffer_eq (const buffer_t * a, const buffer_t * b);
// set the buffer to a constant byte
void buffer_memset (buffer_t * buf, BYTE b);
tpm_size_t buffer_len (const buffer_t* buf);
TPM_RESULT buffer_free (buffer_t * buf);
TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const BYTE* bytes);
#endif // _TOOLS_H_
-316
View File
@@ -1,316 +0,0 @@
/*
* Copyright (c) 2005, Intel Corp
* Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk>
* 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 the original author; nor the names of any 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.
*/
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable.c
* - tools/blktap2/drivers/hashtable.c
*/
#include "hashtable.h"
#include "hashtable_private.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
/*
Credit for primes table: Aaron Krowne
http://br.endernet.org/~akrowne/
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
*/
static const unsigned int primes[] = {
53, 97, 193, 389,
769, 1543, 3079, 6151,
12289, 24593, 49157, 98317,
196613, 393241, 786433, 1572869,
3145739, 6291469, 12582917, 25165843,
50331653, 100663319, 201326611, 402653189,
805306457, 1610612741
};
const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
const float max_load_factor = 0.65;
/*****************************************************************************/
struct hashtable *
create_hashtable(unsigned int minsize,
unsigned int (*hashf) (void*),
int (*eqf) (void*,void*))
{
struct hashtable *h;
unsigned int pindex, size = primes[0];
/* Check requested hashtable isn't too large */
if (minsize > (1u << 30)) return NULL;
/* Enforce size as prime */
for (pindex=0; pindex < prime_table_length; pindex++) {
if (primes[pindex] > minsize) { size = primes[pindex]; break; }
}
h = (struct hashtable *)malloc(sizeof(struct hashtable));
if (NULL == h) return NULL; /*oom*/
h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
if (NULL == h->table) { free(h); return NULL; } /*oom*/
memset(h->table, 0, size * sizeof(struct entry *));
h->tablelength = size;
h->primeindex = pindex;
h->entrycount = 0;
h->hashfn = hashf;
h->eqfn = eqf;
h->loadlimit = (unsigned int) ceil(size * max_load_factor);
#ifdef HASHTABLE_THREADED
pthread_mutex_init(&h->mutex, NULL);
#endif
return h;
}
/*****************************************************************************/
unsigned int
hash(struct hashtable *h, void *k)
{
unsigned int i = h->hashfn(k);
i += ~(i << 9);
i ^= ((i >> 14) | (i << 18)); /* >>> */
i += (i << 4);
i ^= ((i >> 10) | (i << 22)); /* >>> */
return i;
}
/*****************************************************************************/
static int
hashtable_expand(struct hashtable *h)
{
/* Double the size of the table to accomodate more entries */
struct entry **newtable;
struct entry *e;
struct entry **pE;
unsigned int newsize, i, index;
/* Check we're not hitting max capacity */
if (h->primeindex == (prime_table_length - 1)) return 0;
newsize = primes[++(h->primeindex)];
newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
if (NULL != newtable)
{
memset(newtable, 0, newsize * sizeof(struct entry *));
/* This algorithm is not 'stable'. ie. it reverses the list
* when it transfers entries between the tables */
for (i = 0; i < h->tablelength; i++) {
while (NULL != (e = h->table[i])) {
h->table[i] = e->next;
index = indexFor(newsize,e->h);
e->next = newtable[index];
newtable[index] = e;
}
}
free(h->table);
h->table = newtable;
}
/* Plan B: realloc instead */
else
{
newtable = (struct entry **)
realloc(h->table, newsize * sizeof(struct entry *));
if (NULL == newtable) { (h->primeindex)--; return 0; }
h->table = newtable;
memset(newtable[h->tablelength], 0, newsize - h->tablelength);
for (i = 0; i < h->tablelength; i++) {
for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
index = indexFor(newsize,e->h);
if (index == i)
{
pE = &(e->next);
}
else
{
*pE = e->next;
e->next = newtable[index];
newtable[index] = e;
}
}
}
}
h->tablelength = newsize;
h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
return -1;
}
/*****************************************************************************/
unsigned int
hashtable_count(struct hashtable *h)
{
unsigned int count;
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
count = h->entrycount;
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return count;
}
/*****************************************************************************/
int
hashtable_insert(struct hashtable *h, void *k, void *v)
{
/* This method allows duplicate keys - but they shouldn't be used */
unsigned int index;
struct entry *e;
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
if (++(h->entrycount) > h->loadlimit)
{
/* Ignore the return value. If expand fails, we should
* still try cramming just this value into the existing table
* -- we may not have memory for a larger table, but one more
* element may be ok. Next time we insert, we'll try expanding again.*/
hashtable_expand(h);
}
e = (struct entry *)malloc(sizeof(struct entry));
if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
e->h = hash(h,k);
index = indexFor(h->tablelength,e->h);
e->k = k;
e->v = v;
e->next = h->table[index];
h->table[index] = e;
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return -1;
}
/*****************************************************************************/
void * /* returns value associated with key */
hashtable_search(struct hashtable *h, void *k)
{
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
struct entry *e;
unsigned int hashvalue, index;
hashvalue = hash(h,k);
index = indexFor(h->tablelength,hashvalue);
e = h->table[index];
while (NULL != e)
{
/* Check hash value to short circuit heavier comparison */
if ((hashvalue == e->h) && (h->eqfn(k, e->k))) {
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return e->v;
}
e = e->next;
}
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return NULL;
}
/*****************************************************************************/
void * /* returns value associated with key */
hashtable_remove(struct hashtable *h, void *k)
{
/* TODO: consider compacting the table when the load factor drops enough,
* or provide a 'compact' method. */
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
struct entry *e;
struct entry **pE;
void *v;
unsigned int hashvalue, index;
hashvalue = hash(h,k);
index = indexFor(h->tablelength,hash(h,k));
pE = &(h->table[index]);
e = *pE;
while (NULL != e)
{
/* Check hash value to short circuit heavier comparison */
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
{
*pE = e->next;
h->entrycount--;
v = e->v;
freekey(e->k);
free(e);
return v;
}
pE = &(e->next);
e = e->next;
}
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return NULL;
}
/*****************************************************************************/
/* destroy */
void
hashtable_destroy(struct hashtable *h, int free_values)
{
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
unsigned int i;
struct entry *e, *f;
struct entry **table = h->table;
if (free_values)
{
for (i = 0; i < h->tablelength; i++)
{
e = table[i];
while (NULL != e)
{ f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
}
}
else
{
for (i = 0; i < h->tablelength; i++)
{
e = table[i];
while (NULL != e)
{ f = e; e = e->next; freekey(f->k); free(f); }
}
}
free(h->table);
#ifdef HASHTABLE_THREADED
pthread_mutex_destroy(&h->mutex);
#endif
free(h);
}
-204
View File
@@ -1,204 +0,0 @@
/*
* Copyright (c) 2005, Intel Corp
* Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk>
* 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 the original author; nor the names of any 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.
*/
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable.h
* - tools/blktap2/drivers/hashtable.h
*/
#ifndef __HASHTABLE_CWC22_H__
#define __HASHTABLE_CWC22_H__
struct hashtable;
/* Example of use:
*
* struct hashtable *h;
* struct some_key *k;
* struct some_value *v;
*
* static unsigned int hash_from_key_fn( void *k );
* static int keys_equal_fn ( void *key1, void *key2 );
*
* h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
* k = (struct some_key *) malloc(sizeof(struct some_key));
* v = (struct some_value *) malloc(sizeof(struct some_value));
*
* (initialise k and v to suitable values)
*
* if (! hashtable_insert(h,k,v) )
* { exit(-1); }
*
* if (NULL == (found = hashtable_search(h,k) ))
* { printf("not found!"); }
*
* if (NULL == (found = hashtable_remove(h,k) ))
* { printf("Not found\n"); }
*
*/
/* Macros may be used to define type-safe(r) hashtable access functions, with
* methods specialized to take known key and value types as parameters.
*
* Example:
*
* Insert this at the start of your file:
*
* DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
* DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
* DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
*
* This defines the functions 'insert_some', 'search_some' and 'remove_some'.
* These operate just like hashtable_insert etc., with the same parameters,
* but their function signatures have 'struct some_key *' rather than
* 'void *', and hence can generate compile time errors if your program is
* supplying incorrect data as a key (and similarly for value).
*
* Note that the hash and key equality functions passed to create_hashtable
* still take 'void *' parameters instead of 'some key *'. This shouldn't be
* a difficult issue as they're only defined and passed once, and the other
* functions will ensure that only valid keys are supplied to them.
*
* The cost for this checking is increased code size and runtime overhead
* - if performance is important, it may be worth switching back to the
* unsafe methods once your program has been debugged with the safe methods.
* This just requires switching to some simple alternative defines - eg:
* #define insert_some hashtable_insert
*
*/
/*****************************************************************************
* create_hashtable
* @name create_hashtable
* @param minsize minimum initial size of hashtable
* @param hashfunction function for hashing keys
* @param key_eq_fn function for determining key equality
* @return newly created hashtable or NULL on failure
*/
struct hashtable *
create_hashtable(unsigned int minsize,
unsigned int (*hashfunction) (void*),
int (*key_eq_fn) (void*,void*));
/*****************************************************************************
* hashtable_insert
* @name hashtable_insert
* @param h the hashtable to insert into
* @param k the key - hashtable claims ownership and will free on removal
* @param v the value - does not claim ownership
* @return non-zero for successful insertion
*
* This function will cause the table to expand if the insertion would take
* the ratio of entries to table size over the maximum load factor.
*
* This function does not check for repeated insertions with a duplicate key.
* The value returned when using a duplicate key is undefined -- when
* the hashtable changes size, the order of retrieval of duplicate key
* entries is reversed.
* If in doubt, remove before insert.
*/
int
hashtable_insert(struct hashtable *h, void *k, void *v);
#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
int fnname (struct hashtable *h, keytype *k, valuetype *v) \
{ \
return hashtable_insert(h,k,v); \
}
/*****************************************************************************
* hashtable_search
* @name hashtable_search
* @param h the hashtable to search
* @param k the key to search for - does not claim ownership
* @return the value associated with the key, or NULL if none found
*/
void *
hashtable_search(struct hashtable *h, void *k);
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
valuetype * fnname (struct hashtable *h, keytype *k) \
{ \
return (valuetype *) (hashtable_search(h,k)); \
}
/*****************************************************************************
* hashtable_remove
* @name hashtable_remove
* @param h the hashtable to remove the item from
* @param k the key to search for - does not claim ownership
* @return the value associated with the key, or NULL if none found
*/
void * /* returns value */
hashtable_remove(struct hashtable *h, void *k);
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
valuetype * fnname (struct hashtable *h, keytype *k) \
{ \
return (valuetype *) (hashtable_remove(h,k)); \
}
/*****************************************************************************
* hashtable_count
* @name hashtable_count
* @param h the hashtable
* @return the number of items stored in the hashtable
*/
unsigned int
hashtable_count(struct hashtable *h);
/*****************************************************************************
* hashtable_destroy
* @name hashtable_destroy
* @param h the hashtable
* @param free_values whether to call 'free' on the remaining values
*/
void
hashtable_destroy(struct hashtable *h, int free_values);
#endif /* __HASHTABLE_CWC22_H__ */
-236
View File
@@ -1,236 +0,0 @@
/*
* Copyright (c) 2005, Intel Corp
* Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk>
* 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 the original author; nor the names of any 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.
*/
/*
* There are duplicates of this code in:
* - tools/blktap2/drivers/hashtable_itr.c
*/
#include "hashtable.h"
#include "hashtable_private.h"
#include "hashtable_itr.h"
#include <stdlib.h> /* defines NULL */
/*****************************************************************************/
/* hashtable_iterator - iterator constructor */
struct hashtable_itr *
hashtable_iterator(struct hashtable *h)
{
unsigned int i, tablelength;
struct hashtable_itr *itr = (struct hashtable_itr *)
malloc(sizeof(struct hashtable_itr));
if (NULL == itr) return NULL;
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
itr->h = h;
itr->e = NULL;
itr->parent = NULL;
tablelength = h->tablelength;
itr->index = tablelength;
if (0 == h->entrycount) {
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return itr;
}
for (i = 0; i < tablelength; i++)
{
if (NULL != h->table[i])
{
itr->e = h->table[i];
itr->index = i;
break;
}
}
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return itr;
}
/*****************************************************************************/
/* key - return the key of the (key,value) pair at the current position */
/* value - return the value of the (key,value) pair at the current position */
void *
hashtable_iterator_key(struct hashtable_itr *i)
{ return i->e->k; }
void *
hashtable_iterator_value(struct hashtable_itr *i)
{ return i->e->v; }
/*****************************************************************************/
/* advance - advance the iterator to the next element
* returns zero if advanced to end of table */
int
hashtable_iterator_advance(struct hashtable_itr *itr)
{
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&itr->h->mutex);
#endif
unsigned int j,tablelength;
struct entry **table;
struct entry *next;
int ret;
if (NULL == itr->e) { /* stupidity check */
ret = 0;
goto egress;
}
next = itr->e->next;
if (NULL != next)
{
itr->parent = itr->e;
itr->e = next;
ret = -1;
goto egress;
}
tablelength = itr->h->tablelength;
itr->parent = NULL;
if (tablelength <= (j = ++(itr->index)))
{
itr->e = NULL;
ret = 0;
goto egress;
}
table = itr->h->table;
while (NULL == (next = table[j]))
{
if (++j >= tablelength)
{
itr->index = tablelength;
itr->e = NULL;
ret = 0;
goto egress;
}
}
itr->index = j;
itr->e = next;
ret = -1;
egress:
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&itr->h->mutex);
#endif
return ret;
}
/*****************************************************************************/
/* remove - remove the entry at the current iterator position
* and advance the iterator, if there is a successive
* element.
* If you want the value, read it before you remove:
* beware memory leaks if you don't.
* Returns zero if end of iteration. */
int
hashtable_iterator_remove(struct hashtable_itr *itr)
{
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&itr->h->mutex);
#endif
struct entry *remember_e, *remember_parent;
int ret;
/* Do the removal */
if (NULL == (itr->parent))
{
/* element is head of a chain */
itr->h->table[itr->index] = itr->e->next;
} else {
/* element is mid-chain */
itr->parent->next = itr->e->next;
}
/* itr->e is now outside the hashtable */
remember_e = itr->e;
itr->h->entrycount--;
freekey(remember_e->k);
/* Advance the iterator, correcting the parent */
remember_parent = itr->parent;
ret = hashtable_iterator_advance(itr);
if (itr->parent == remember_e) { itr->parent = remember_parent; }
free(remember_e);
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&itr->h->mutex);
#endif
return ret;
}
/*****************************************************************************/
int /* returns zero if not found */
hashtable_iterator_search(struct hashtable_itr *itr,
struct hashtable *h, void *k)
{
#ifdef HASHTABLE_THREADED
pthread_mutex_lock(&h->mutex);
#endif
struct entry *e, *parent;
unsigned int hashvalue, index;
int ret;
hashvalue = hash(h,k);
index = indexFor(h->tablelength,hashvalue);
e = h->table[index];
parent = NULL;
while (NULL != e)
{
/* Check hash value to short circuit heavier comparison */
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
{
itr->index = index;
itr->e = e;
itr->parent = parent;
itr->h = h;
ret= -1;
goto egress;
}
parent = e;
e = e->next;
}
ret = 0;
egress:
#ifdef HASHTABLE_THREADED
pthread_mutex_unlock(&h->mutex);
#endif
return ret;
}
-109
View File
@@ -1,109 +0,0 @@
/*
* Copyright (c) 2005, Intel Corp
* Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk>
* 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 the original author; nor the names of any 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.
*/
/*
* There are duplicates of this code in:
* - tools/blktap2/drivers/hashtable_itr.h
*/
#ifndef __HASHTABLE_ITR_CWC22__
#define __HASHTABLE_ITR_CWC22__
#include "hashtable.h"
#include "hashtable_private.h" /* needed to enable inlining */
/*****************************************************************************/
/* This struct is only concrete here to allow the inlining of two of the
* accessor functions. */
struct hashtable_itr
{
struct hashtable *h;
struct entry *e;
struct entry *parent;
unsigned int index;
};
/*****************************************************************************/
/* hashtable_iterator
*/
struct hashtable_itr *
hashtable_iterator(struct hashtable *h);
/*****************************************************************************/
/* hashtable_iterator_key
* - return the value of the (key,value) pair at the current position */
void *hashtable_iterator_key(struct hashtable_itr *i);
/*****************************************************************************/
/* value - return the value of the (key,value) pair at the current position */
void *hashtable_iterator_value(struct hashtable_itr *i);
/*****************************************************************************/
/* advance - advance the iterator to the next element
* returns zero if advanced to end of table */
int
hashtable_iterator_advance(struct hashtable_itr *itr);
/*****************************************************************************/
/* remove - remove current element and advance the iterator to the next element
* NB: if you need the value to free it, read it before
* removing. ie: beware memory leaks!
* returns zero if advanced to end of table */
int
hashtable_iterator_remove(struct hashtable_itr *itr);
/*****************************************************************************/
/* search - overwrite the supplied iterator, to point to the entry
* matching the supplied key.
h points to the hashtable to be searched.
* returns zero if not found. */
int
hashtable_iterator_search(struct hashtable_itr *itr,
struct hashtable *h, void *k);
#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
{ \
return (hashtable_iterator_search(i,h,k)); \
}
#endif /* __HASHTABLE_ITR_CWC22__*/
@@ -1,96 +0,0 @@
/*
* Copyright (c) 2005, Intel Corp
* Copyright (c) 2002, Christopher Clark <firstname.lastname@cl.cam.ac.uk>
* 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 the original author; nor the names of any 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.
*/
/*
* There are duplicates of this code in:
* - tools/xenstore/hashtable_private.h
* - tools/blktap2/drivers/hashtable_private.h
*/
#ifndef __HASHTABLE_PRIVATE_CWC22_H__
#define __HASHTABLE_PRIVATE_CWC22_H__
#include "hashtable.h"
#ifdef HASHTABLE_THREADED
#include <pthread.h>
#endif
/*****************************************************************************/
struct entry
{
void *k, *v;
unsigned int h;
struct entry *next;
};
struct hashtable {
unsigned int tablelength;
struct entry **table;
unsigned int entrycount;
unsigned int loadlimit;
unsigned int primeindex;
unsigned int (*hashfn) (void *k);
int (*eqfn) (void *k1, void *k2);
#ifdef HASHTABLE_THREADED
pthread_mutex_t mutex;
#endif
};
/*****************************************************************************/
unsigned int
hash(struct hashtable *h, void *k);
/*****************************************************************************/
/* indexFor */
static inline unsigned int
indexFor(unsigned int tablelength, unsigned int hashvalue) {
return (hashvalue % tablelength);
};
/* Only works if tablelength == 2^N */
/*static inline unsigned int
indexFor(unsigned int tablelength, unsigned int hashvalue)
{
return (hashvalue & (tablelength - 1u));
}
*/
/*****************************************************************************/
#define freekey(X) free(X)
/*define freekey(X) ; */
/*****************************************************************************/
#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
-142
View File
@@ -1,142 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "buffer.h"
#include "tcg.h"
// Helper code for the consts, eg. to produce messages for error codes.
typedef struct error_code_entry_t {
TPM_RESULT code;
char * code_name;
char * msg;
} error_code_entry_t;
static const error_code_entry_t error_msgs [] = {
{ TPM_SUCCESS, "TPM_SUCCESS", "Successful completion of the operation" },
{ TPM_AUTHFAIL, "TPM_AUTHFAIL", "Authentication failed" },
{ TPM_BADINDEX, "TPM_BADINDEX", "The index to a PCR, DIR or other register is incorrect" },
{ TPM_BAD_PARAMETER, "TPM_BAD_PARAMETER", "One or more parameter is bad" },
{ TPM_AUDITFAILURE, "TPM_AUDITFAILURE", "An operation completed successfully but the auditing of that operation failed." },
{ TPM_CLEAR_DISABLED, "TPM_CLEAR_DISABLED", "The clear disable flag is set and all clear operations now require physical access" },
{ TPM_DEACTIVATED, "TPM_DEACTIVATED", "The TPM is deactivated" },
{ TPM_DISABLED, "TPM_DISABLED", "The TPM is disabled" },
{ TPM_DISABLED_CMD, "TPM_DISABLED_CMD", "The target command has been disabled" },
{ TPM_FAIL, "TPM_FAIL", "The operation failed" },
{ TPM_BAD_ORDINAL, "TPM_BAD_ORDINAL", "The ordinal was unknown or inconsistent" },
{ TPM_INSTALL_DISABLED, "TPM_INSTALL_DISABLED", "The ability to install an owner is disabled" },
{ TPM_INVALID_KEYHANDLE, "TPM_INVALID_KEYHANDLE", "The key handle presented was invalid" },
{ TPM_KEYNOTFOUND, "TPM_KEYNOTFOUND", "The target key was not found" },
{ TPM_INAPPROPRIATE_ENC, "TPM_INAPPROPRIATE_ENC", "Unacceptable encryption scheme" },
{ TPM_MIGRATEFAIL, "TPM_MIGRATEFAIL", "Migration authorization failed" },
{ TPM_INVALID_PCR_INFO, "TPM_INVALID_PCR_INFO", "PCR information could not be interpreted" },
{ TPM_NOSPACE, "TPM_NOSPACE", "No room to load key." },
{ TPM_NOSRK, "TPM_NOSRK", "There is no SRK set" },
{ TPM_NOTSEALED_BLOB, "TPM_NOTSEALED_BLOB", "An encrypted blob is invalid or was not created by this TPM" },
{ TPM_OWNER_SET, "TPM_OWNER_SET", "There is already an Owner" },
{ TPM_RESOURCES, "TPM_RESOURCES", "The TPM has insufficient internal resources to perform the requested action." },
{ TPM_SHORTRANDOM, "TPM_SHORTRANDOM", "A random string was too short" },
{ TPM_SIZE, "TPM_SIZE", "The TPM does not have the space to perform the operation." },
{ TPM_WRONGPCRVAL, "TPM_WRONGPCRVAL", "The named PCR value does not match the current PCR value." },
{ TPM_BAD_PARAM_SIZE, "TPM_BAD_PARAM_SIZE", "The paramSize argument to the command has the incorrect value" },
{ TPM_SHA_THREAD, "TPM_SHA_THREAD", "There is no existing SHA-1 thread." },
{ TPM_SHA_ERROR, "TPM_SHA_ERROR", "The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error." },
{ TPM_FAILEDSELFTEST, "TPM_FAILEDSELFTEST", "Self-test has failed and the TPM has shutdown." },
{ TPM_AUTH2FAIL, "TPM_AUTH2FAIL", "The authorization for the second key in a 2 key function failed authorization" },
{ TPM_BADTAG, "TPM_BADTAG", "The tag value sent to for a command is invalid" },
{ TPM_IOERROR, "TPM_IOERROR", "An IO error occurred transmitting information to the TPM" },
{ TPM_ENCRYPT_ERROR, "TPM_ENCRYPT_ERROR", "The encryption process had a problem." },
{ TPM_DECRYPT_ERROR, "TPM_DECRYPT_ERROR", "The decryption process did not complete." },
{ TPM_INVALID_AUTHHANDLE, "TPM_INVALID_AUTHHANDLE", "An invalid handle was used." },
{ TPM_NO_ENDORSEMENT, "TPM_NO_ENDORSEMENT", "The TPM does not a EK installed" },
{ TPM_INVALID_KEYUSAGE, "TPM_INVALID_KEYUSAGE", "The usage of a key is not allowed" },
{ TPM_WRONG_ENTITYTYPE, "TPM_WRONG_ENTITYTYPE", "The submitted entity type is not allowed" },
{ TPM_INVALID_POSTINIT, "TPM_INVALID_POSTINIT", "The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup" },
{ TPM_INAPPROPRIATE_SIG, "TPM_INAPPROPRIATE_SIG", "Signed data cannot include additional DER information" },
{ TPM_BAD_KEY_PROPERTY, "TPM_BAD_KEY_PROPERTY", "The key properties in TPM_KEY_PARMs are not supported by this TPM" },
{ TPM_BAD_MIGRATION, "TPM_BAD_MIGRATION", "The migration properties of this key are incorrect." },
{ TPM_BAD_SCHEME, "TPM_BAD_SCHEME", "The signature or encryption scheme for this key is incorrect or not permitted in this situation." },
{ TPM_BAD_DATASIZE, "TPM_BAD_DATASIZE", "The size of the data (or blob) parameter is bad or inconsistent with the referenced key" },
{ TPM_BAD_MODE, "TPM_BAD_MODE", "A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob." },
{ TPM_BAD_PRESENCE, "TPM_BAD_PRESENCE", "Either the physicalPresence or physicalPresenceLock bits have the wrong value" },
{ TPM_BAD_VERSION, "TPM_BAD_VERSION", "The TPM cannot perform this version of the capability" },
{ TPM_NO_WRAP_TRANSPORT, "TPM_NO_WRAP_TRANSPORT", "The TPM does not allow for wrapped transport sessions" },
{ TPM_AUDITFAIL_UNSUCCESSFUL, "TPM_AUDITFAIL_UNSUCCESSFUL", "TPM audit construction failed and the underlying command was returning a failure code also" },
{ TPM_AUDITFAIL_SUCCESSFUL, "TPM_AUDITFAIL_SUCCESSFUL", "TPM audit construction failed and the underlying command was returning success" },
{ TPM_NOTRESETABLE, "TPM_NOTRESETABLE", "Attempt to reset a PCR register that does not have the resettable attribute" },
{ TPM_NOTLOCAL, "TPM_NOTLOCAL", "Attempt to reset a PCR register that requires locality and locality modifier not part of command transport" },
{ TPM_BAD_TYPE, "TPM_BAD_TYPE", "Make identity blob not properly typed" },
{ TPM_INVALID_RESOURCE, "TPM_INVALID_RESOURCE", "When saving context identified resource type does not match actual resource" },
{ TPM_NOTFIPS, "TPM_NOTFIPS", "The TPM is attempting to execute a command only available when in FIPS mode" },
{ TPM_INVALID_FAMILY, "TPM_INVALID_FAMILY", "The command is attempting to use an invalid family ID" },
{ TPM_NO_NV_PERMISSION, "TPM_NO_NV_PERMISSION", "The permission to manipulate the NV storage is not available" },
{ TPM_REQUIRES_SIGN, "TPM_REQUIRES_SIGN", "The operation requires a signed command" },
{ TPM_KEY_NOTSUPPORTED, "TPM_KEY_NOTSUPPORTED", "Wrong operation to load an NV key" },
{ TPM_AUTH_CONFLICT, "TPM_AUTH_CONFLICT", "NV_LoadKey blob requires both owner and blob authorization" },
{ TPM_AREA_LOCKED, "TPM_AREA_LOCKED", "The NV area is locked and not writtable" },
{ TPM_BAD_LOCALITY, "TPM_BAD_LOCALITY", "The locality is incorrect for the attempted operation" },
{ TPM_READ_ONLY, "TPM_READ_ONLY", "The NV area is read only and can't be written to" },
{ TPM_PER_NOWRITE, "TPM_PER_NOWRITE", "There is no protection on the write to the NV area" },
{ TPM_FAMILYCOUNT, "TPM_FAMILYCOUNT", "The family count value does not match" },
{ TPM_WRITE_LOCKED, "TPM_WRITE_LOCKED", "The NV area has already been written to" },
{ TPM_BAD_ATTRIBUTES, "TPM_BAD_ATTRIBUTES", "The NV area attributes conflict" },
{ TPM_INVALID_STRUCTURE, "TPM_INVALID_STRUCTURE", "The structure tag and version are invalid or inconsistent" },
{ TPM_KEY_OWNER_CONTROL, "TPM_KEY_OWNER_CONTROL", "The key is under control of the TPM Owner and can only be evicted by the TPM Owner." },
{ TPM_BAD_COUNTER, "TPM_BAD_COUNTER", "The counter handle is incorrect" },
{ TPM_NOT_FULLWRITE, "TPM_NOT_FULLWRITE", "The write is not a complete write of the area" },
{ TPM_CONTEXT_GAP, "TPM_CONTEXT_GAP", "The gap between saved context counts is too large" },
{ TPM_MAXNVWRITES, "TPM_MAXNVWRITES", "The maximum number of NV writes without an owner has been exceeded" },
{ TPM_NOOPERATOR, "TPM_NOOPERATOR", "No operator authorization value is set" },
{ TPM_RESOURCEMISSING, "TPM_RESOURCEMISSING", "The resource pointed to by context is not loaded" },
{ TPM_DELEGATE_LOCK, "TPM_DELEGATE_LOCK", "The delegate administration is locked" },
{ TPM_DELEGATE_FAMILY, "TPM_DELEGATE_FAMILY", "Attempt to manage a family other then the delegated family" },
{ TPM_DELEGATE_ADMIN, "TPM_DELEGATE_ADMIN", "Delegation table management not enabled" },
{ TPM_TRANSPORT_EXCLUSIVE, "TPM_TRANSPORT_EXCLUSIVE", "There was a command executed outside of an exclusive transport session" },
};
// helper function for the error codes:
const char* tpm_get_error_name (TPM_RESULT code) {
// just do a linear scan for now
unsigned i;
for (i = 0; i < sizeof(error_msgs)/sizeof(error_msgs[0]); i++)
if (code == error_msgs[i].code)
return error_msgs[i].code_name;
return("Unknown Error Code");
}
-94
View File
@@ -1,94 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
#ifndef __VTPM_LOG_H__
#define __VTPM_LOG_H__
#include <stdint.h> // for uint32_t
#include <stddef.h> // for pointer NULL
// =========================== LOGGING ==============================
// the logging module numbers
#define VTPM_LOG_CRYPTO 1
#define VTPM_LOG_BSG 2
#define VTPM_LOG_TXDATA 3
#define VTPM_LOG_TCS 4
#define VTPM_LOG_TCS_DEEP 5
#define VTPM_LOG_VTSP 6
#define VTPM_LOG_VTPM 7
#define VTPM_LOG_VTPM_DEEP 8
#define VTPM_LOG_VTSP_DEEP 9
static char *module_names[] = { "",
"CRYPTO",
"BSG",
"TXDATA",
"TCS",
"TCS",
"VTSP",
"VTPM",
"VTPM",
"VTSP"
};
// Default to standard logging
#ifndef LOGGING_MODULES
#define LOGGING_MODULES (BITMASK(VTPM_LOG_VTPM))
#endif
// bit-access macros
#define BITMASK(idx) ( 1U << (idx) )
#define GETBIT(num,idx) ( ((num) & BITMASK(idx)) >> idx )
#define SETBIT(num,idx) (num) |= BITMASK(idx)
#define CLEARBIT(num,idx) (num) &= ( ~ BITMASK(idx) )
#define vtpmloginfo(module, fmt, args...) \
if (GETBIT (LOGGING_MODULES, module) == 1) { \
fprintf (stdout, "INFO[%s]: " fmt, module_names[module], ##args); \
}
#define vtpmloginfomore(module, fmt, args...) \
if (GETBIT (LOGGING_MODULES, module) == 1) { \
fprintf (stdout, fmt,##args); \
}
#define vtpmlogerror(module, fmt, args...) \
fprintf (stderr, "ERROR[%s]: " fmt, module_names[module], ##args);
//typedef UINT32 tpm_size_t;
// helper function for the error codes:
const char* tpm_get_error_name (TPM_RESULT code);
#endif // _VTPM_LOG_H_
-503
View File
@@ -1,503 +0,0 @@
// ===================================================================
//
// 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.
// ===================================================================
//
// tcg.h
//
// This file contains all the structure and type definitions
//
// ==================================================================
#ifndef __TCG_H__
#define __TCG_H__
// This pragma is used to disallow structure padding
#pragma pack(push, 1)
// *************************** TYPEDEFS *********************************
typedef unsigned char BYTE;
typedef unsigned char BOOL;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef UINT32 TPM_RESULT;
typedef UINT32 TPM_PCRINDEX;
typedef UINT32 TPM_DIRINDEX;
typedef UINT32 TPM_HANDLE;
typedef TPM_HANDLE TPM_AUTHHANDLE;
typedef TPM_HANDLE TCPA_HASHHANDLE;
typedef TPM_HANDLE TCPA_HMACHANDLE;
typedef TPM_HANDLE TCPA_ENCHANDLE;
typedef TPM_HANDLE TPM_KEY_HANDLE;
typedef TPM_HANDLE TCPA_ENTITYHANDLE;
typedef UINT32 TPM_RESOURCE_TYPE;
typedef UINT32 TPM_COMMAND_CODE;
typedef UINT16 TPM_PROTOCOL_ID;
typedef BYTE TPM_AUTH_DATA_USAGE;
typedef UINT16 TPM_ENTITY_TYPE;
typedef UINT32 TPM_ALGORITHM_ID;
typedef UINT16 TPM_KEY_USAGE;
typedef UINT16 TPM_STARTUP_TYPE;
typedef UINT32 TPM_CAPABILITY_AREA;
typedef UINT16 TPM_ENC_SCHEME;
typedef UINT16 TPM_SIG_SCHEME;
typedef UINT16 TPM_MIGRATE_SCHEME;
typedef UINT16 TPM_PHYSICAL_PRESENCE;
typedef UINT32 TPM_KEY_FLAGS;
#define TPM_DIGEST_SIZE 20 // Don't change this
typedef BYTE TPM_AUTHDATA[TPM_DIGEST_SIZE];
typedef TPM_AUTHDATA TPM_SECRET;
typedef TPM_AUTHDATA TPM_ENCAUTH;
typedef BYTE TPM_PAYLOAD_TYPE;
typedef UINT16 TPM_TAG;
// Data Types of the TCS
typedef UINT32 TCS_AUTHHANDLE; // Handle addressing a authorization session
typedef UINT32 TCS_CONTEXT_HANDLE; // Basic context handle
typedef UINT32 TCS_KEY_HANDLE; // Basic key handle
// ************************* STRUCTURES **********************************
typedef struct TPM_VERSION {
BYTE major;
BYTE minor;
BYTE revMajor;
BYTE revMinor;
} TPM_VERSION;
static const TPM_VERSION TPM_STRUCT_VER_1_1 = { 1,1,0,0 };
typedef struct TPM_DIGEST {
BYTE digest[TPM_DIGEST_SIZE];
} TPM_DIGEST;
typedef TPM_DIGEST TPM_PCRVALUE;
typedef TPM_DIGEST TPM_COMPOSITE_HASH;
typedef TPM_DIGEST TPM_DIRVALUE;
typedef TPM_DIGEST TPM_HMAC;
typedef TPM_DIGEST TPM_CHOSENID_HASH;
typedef struct TPM_NONCE {
BYTE nonce[TPM_DIGEST_SIZE];
} TPM_NONCE;
typedef struct TPM_KEY_PARMS {
TPM_ALGORITHM_ID algorithmID;
TPM_ENC_SCHEME encScheme;
TPM_SIG_SCHEME sigScheme;
UINT32 parmSize;
BYTE* parms;
} TPM_KEY_PARMS;
typedef struct TPM_RSA_KEY_PARMS {
UINT32 keyLength;
UINT32 numPrimes;
UINT32 exponentSize;
BYTE* exponent;
} TPM_RSA_KEY_PARMS;
typedef struct TPM_STORE_PUBKEY {
UINT32 keyLength;
BYTE* key;
} TPM_STORE_PUBKEY;
typedef struct TPM_PUBKEY {
TPM_KEY_PARMS algorithmParms;
TPM_STORE_PUBKEY pubKey;
} TPM_PUBKEY;
typedef struct TPM_KEY {
TPM_VERSION ver;
TPM_KEY_USAGE keyUsage;
TPM_KEY_FLAGS keyFlags;
TPM_AUTH_DATA_USAGE authDataUsage;
TPM_KEY_PARMS algorithmParms;
UINT32 PCRInfoSize;
BYTE* PCRInfo; // this should be a TPM_PCR_INFO, or NULL
TPM_STORE_PUBKEY pubKey;
UINT32 encDataSize;
BYTE* encData;
} TPM_KEY;
typedef struct TPM_PCR_SELECTION {
UINT16 sizeOfSelect; /// in bytes
BYTE* pcrSelect;
} TPM_PCR_SELECTION;
typedef struct TPM_PCR_COMPOSITE {
TPM_PCR_SELECTION select;
UINT32 valueSize;
TPM_PCRVALUE* pcrValue;
} TPM_PCR_COMPOSITE;
typedef struct TPM_PCR_INFO {
TPM_PCR_SELECTION pcrSelection;
TPM_COMPOSITE_HASH digestAtRelease;
TPM_COMPOSITE_HASH digestAtCreation;
} TPM_PCR_INFO;
typedef struct TPM_BOUND_DATA {
TPM_VERSION ver;
TPM_PAYLOAD_TYPE payload;
BYTE* payloadData;
} TPM_BOUND_DATA;
typedef struct TPM_STORED_DATA {
TPM_VERSION ver;
UINT32 sealInfoSize;
BYTE* sealInfo;
UINT32 encDataSize;
BYTE* encData;
} TPM_STORED_DATA;
typedef struct TCS_AUTH {
TCS_AUTHHANDLE AuthHandle;
TPM_NONCE NonceOdd; // system
TPM_NONCE NonceEven; // TPM
BOOL fContinueAuthSession;
TPM_AUTHDATA HMAC;
} TCS_AUTH;
// structures for dealing with sizes followed by buffers in all the
// TCG structure.
typedef struct pack_buf_t {
UINT32 size;
BYTE * data;
} pack_buf_t;
typedef struct pack_constbuf_t {
UINT32 size;
const BYTE* data;
} pack_constbuf_t;
// **************************** CONSTANTS *********************************
// BOOL values
#define TRUE 0x01
#define FALSE 0x00
#define TCPA_MAX_BUFFER_LENGTH 0x2000
//
// TPM_COMMAND_CODE values
#define TPM_PROTECTED_ORDINAL 0x00000000UL
#define TPM_UNPROTECTED_ORDINAL 0x80000000UL
#define TPM_CONNECTION_ORDINAL 0x40000000UL
#define TPM_VENDOR_ORDINAL 0x20000000UL
#define TPM_ORD_OIAP (10UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OSAP (11UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuth (12UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_TakeOwnership (13UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthAsymStart (14UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthAsymFinish (15UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ChangeAuthOwner (16UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Extend (20UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PcrRead (21UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Quote (22UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Seal (23UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Unseal (24UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DirWriteAuth (25UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DirRead (26UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_UnBind (30UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateWrapKey (31UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadKey (32UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetPubKey (33UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_EvictKey (34UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateMigrationBlob (40UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReWrapKey (41UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ConvertMigrationBlob (42UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_AuthorizeMigrationKey (43UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateMaintenanceArchive (44UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadMaintenanceArchive (45UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_KillMaintenanceFeature (46UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadManuMaintPub (47UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReadManuMaintPub (48UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CertifyKey (50UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Sign (60UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetRandom (70UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_StirRandom (71UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SelfTestFull (80UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SelfTestStartup (81UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CertifySelfTest (82UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ContinueSelfTest (83UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetTestResult (84UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Reset (90UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerClear (91UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisableOwnerClear (92UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ForceClear (93UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisableForceClear (94UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapabilitySigned (100UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapability (101UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetCapabilityOwner (102UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerSetDisable (110UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalEnable (111UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalDisable (112UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetOwnerInstall (113UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_PhysicalSetDeactivated (114UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetTempDeactivated (115UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_CreateEndorsementKeyPair (120UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_MakeIdentity (121UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ActivateIdentity (122UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_ReadPubek (124UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_OwnerReadPubek (125UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_DisablePubekRead (126UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetAuditEvent (130UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetAuditEventSigned (131UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_GetOrdinalAuditStatus (140UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetOrdinalAuditStatus (141UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Terminate_Handle (150UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Init (151UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveState (152UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_Startup (153UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SetRedirection (154UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Start (160UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Update (161UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1Complete (162UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SHA1CompleteExtend (163UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_FieldUpgrade (170UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveKeyContext (180UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadKeyContext (181UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_SaveAuthContext (182UL + TPM_PROTECTED_ORDINAL)
#define TPM_ORD_LoadAuthContext (183UL + TPM_PROTECTED_ORDINAL)
#define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINAL)
//
// TPM_RESULT values
//
// just put in the whole table from spec 1.2
#define TPM_BASE 0x0 // The start of TPM return codes
#define TPM_VENDOR_ERROR 0x00000400 // Mask to indicate that the error code is vendor specific for vendor specific commands
#define TPM_NON_FATAL 0x00000800 // Mask to indicate that the error code is a non-fatal failure.
#define TPM_SUCCESS TPM_BASE // Successful completion of the operation
#define TPM_AUTHFAIL TPM_BASE + 1 // Authentication failed
#define TPM_BADINDEX TPM_BASE + 2 // The index to a PCR, DIR or other register is incorrect
#define TPM_BAD_PARAMETER TPM_BASE + 3 // One or more parameter is bad
#define TPM_AUDITFAILURE TPM_BASE + 4 // An operation completed successfully but the auditing of that operation failed.
#define TPM_CLEAR_DISABLED TPM_BASE + 5 // The clear disable flag is set and all clear operations now require physical access
#define TPM_DEACTIVATED TPM_BASE + 6 // The TPM is deactivated
#define TPM_DISABLED TPM_BASE + 7 // The TPM is disabled
#define TPM_DISABLED_CMD TPM_BASE + 8 // The target command has been disabled
#define TPM_FAIL TPM_BASE + 9 // The operation failed
#define TPM_BAD_ORDINAL TPM_BASE + 10 // The ordinal was unknown or inconsistent
#define TPM_INSTALL_DISABLED TPM_BASE + 11 // The ability to install an owner is disabled
#define TPM_INVALID_KEYHANDLE TPM_BASE + 12 // The key handle presented was invalid
#define TPM_KEYNOTFOUND TPM_BASE + 13 // The target key was not found
#define TPM_INAPPROPRIATE_ENC TPM_BASE + 14 // Unacceptable encryption scheme
#define TPM_MIGRATEFAIL TPM_BASE + 15 // Migration authorization failed
#define TPM_INVALID_PCR_INFO TPM_BASE + 16 // PCR information could not be interpreted
#define TPM_NOSPACE TPM_BASE + 17 // No room to load key.
#define TPM_NOSRK TPM_BASE + 18 // There is no SRK set
#define TPM_NOTSEALED_BLOB TPM_BASE + 19 // An encrypted blob is invalid or was not created by this TPM
#define TPM_OWNER_SET TPM_BASE + 20 // There is already an Owner
#define TPM_RESOURCES TPM_BASE + 21 // The TPM has insufficient internal resources to perform the requested action.
#define TPM_SHORTRANDOM TPM_BASE + 22 // A random string was too short
#define TPM_SIZE TPM_BASE + 23 // The TPM does not have the space to perform the operation.
#define TPM_WRONGPCRVAL TPM_BASE + 24 // The named PCR value does not match the current PCR value.
#define TPM_BAD_PARAM_SIZE TPM_BASE + 25 // The paramSize argument to the command has the incorrect value
#define TPM_SHA_THREAD TPM_BASE + 26 // There is no existing SHA-1 thread.
#define TPM_SHA_ERROR TPM_BASE + 27 // The calculation is unable to proceed because the existing SHA-1 thread has already encountered an error.
#define TPM_FAILEDSELFTEST TPM_BASE + 28 // Self-test has failed and the TPM has shutdown.
#define TPM_AUTH2FAIL TPM_BASE + 29 // The authorization for the second key in a 2 key function failed authorization
#define TPM_BADTAG TPM_BASE + 30 // The tag value sent to for a command is invalid
#define TPM_IOERROR TPM_BASE + 31 // An IO error occurred transmitting information to the TPM
#define TPM_ENCRYPT_ERROR TPM_BASE + 32 // The encryption process had a problem.
#define TPM_DECRYPT_ERROR TPM_BASE + 33 // The decryption process did not complete.
#define TPM_INVALID_AUTHHANDLE TPM_BASE + 34 // An invalid handle was used.
#define TPM_NO_ENDORSEMENT TPM_BASE + 35 // The TPM does not a EK installed
#define TPM_INVALID_KEYUSAGE TPM_BASE + 36 // The usage of a key is not allowed
#define TPM_WRONG_ENTITYTYPE TPM_BASE + 37 // The submitted entity type is not allowed
#define TPM_INVALID_POSTINIT TPM_BASE + 38 // The command was received in the wrong sequence relative to TPM_Init and a subsequent TPM_Startup
#define TPM_INAPPROPRIATE_SIG TPM_BASE + 39 // Signed data cannot include additional DER information
#define TPM_BAD_KEY_PROPERTY TPM_BASE + 40 // The key properties in TPM_KEY_PARMs are not supported by this TPM
#define TPM_BAD_MIGRATION TPM_BASE + 41 // The migration properties of this key are incorrect.
#define TPM_BAD_SCHEME TPM_BASE + 42 // The signature or encryption scheme for this key is incorrect or not permitted in this situation.
#define TPM_BAD_DATASIZE TPM_BASE + 43 // The size of the data (or blob) parameter is bad or inconsistent with the referenced key
#define TPM_BAD_MODE TPM_BASE + 44 // A mode parameter is bad, such as capArea or subCapArea for TPM_GetCapability, phsicalPresence parameter for TPM_PhysicalPresence, or migrationType for TPM_CreateMigrationBlob.
#define TPM_BAD_PRESENCE TPM_BASE + 45 // Either the physicalPresence or physicalPresenceLock bits have the wrong value
#define TPM_BAD_VERSION TPM_BASE + 46 // The TPM cannot perform this version of the capability
#define TPM_NO_WRAP_TRANSPORT TPM_BASE + 47 // The TPM does not allow for wrapped transport sessions
#define TPM_AUDITFAIL_UNSUCCESSFUL TPM_BASE + 48 // TPM audit construction failed and the underlying command was returning a failure code also
#define TPM_AUDITFAIL_SUCCESSFUL TPM_BASE + 49 // TPM audit construction failed and the underlying command was returning success
#define TPM_NOTRESETABLE TPM_BASE + 50 // Attempt to reset a PCR register that does not have the resettable attribute
#define TPM_NOTLOCAL TPM_BASE + 51 // Attempt to reset a PCR register that requires locality and locality modifier not part of command transport
#define TPM_BAD_TYPE TPM_BASE + 52 // Make identity blob not properly typed
#define TPM_INVALID_RESOURCE TPM_BASE + 53 // When saving context identified resource type does not match actual resource
#define TPM_NOTFIPS TPM_BASE + 54 // The TPM is attempting to execute a command only available when in FIPS mode
#define TPM_INVALID_FAMILY TPM_BASE + 55 // The command is attempting to use an invalid family ID
#define TPM_NO_NV_PERMISSION TPM_BASE + 56 // The permission to manipulate the NV storage is not available
#define TPM_REQUIRES_SIGN TPM_BASE + 57 // The operation requires a signed command
#define TPM_KEY_NOTSUPPORTED TPM_BASE + 58 // Wrong operation to load an NV key
#define TPM_AUTH_CONFLICT TPM_BASE + 59 // NV_LoadKey blob requires both owner and blob authorization
#define TPM_AREA_LOCKED TPM_BASE + 60 // The NV area is locked and not writtable
#define TPM_BAD_LOCALITY TPM_BASE + 61 // The locality is incorrect for the attempted operation
#define TPM_READ_ONLY TPM_BASE + 62 // The NV area is read only and can't be written to
#define TPM_PER_NOWRITE TPM_BASE + 63 // There is no protection on the write to the NV area
#define TPM_FAMILYCOUNT TPM_BASE + 64 // The family count value does not match
#define TPM_WRITE_LOCKED TPM_BASE + 65 // The NV area has already been written to
#define TPM_BAD_ATTRIBUTES TPM_BASE + 66 // The NV area attributes conflict
#define TPM_INVALID_STRUCTURE TPM_BASE + 67 // The structure tag and version are invalid or inconsistent
#define TPM_KEY_OWNER_CONTROL TPM_BASE + 68 // The key is under control of the TPM Owner and can only be evicted by the TPM Owner.
#define TPM_BAD_COUNTER TPM_BASE + 69 // The counter handle is incorrect
#define TPM_NOT_FULLWRITE TPM_BASE + 70 // The write is not a complete write of the area
#define TPM_CONTEXT_GAP TPM_BASE + 71 // The gap between saved context counts is too large
#define TPM_MAXNVWRITES TPM_BASE + 72 // The maximum number of NV writes without an owner has been exceeded
#define TPM_NOOPERATOR TPM_BASE + 73 // No operator authorization value is set
#define TPM_RESOURCEMISSING TPM_BASE + 74 // The resource pointed to by context is not loaded
#define TPM_DELEGATE_LOCK TPM_BASE + 75 // The delegate administration is locked
#define TPM_DELEGATE_FAMILY TPM_BASE + 76 // Attempt to manage a family other then the delegated family
#define TPM_DELEGATE_ADMIN TPM_BASE + 77 // Delegation table management not enabled
#define TPM_TRANSPORT_EXCLUSIVE TPM_BASE + 78 // There was a command executed outside of an exclusive transport session
// TPM_STARTUP_TYPE values
#define TPM_ST_CLEAR 0x0001
#define TPM_ST_STATE 0x0002
#define TPM_ST_DEACTIVATED 0x003
// TPM_TAG values
#define TPM_TAG_RQU_COMMAND 0x00c1
#define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
#define TPM_TAG_RQU_AUTH2_COMMAND 0x00c3
#define TPM_TAG_RSP_COMMAND 0x00c4
#define TPM_TAG_RSP_AUTH1_COMMAND 0x00c5
#define TPM_TAG_RSP_AUTH2_COMMAND 0x00c6
// TPM_PAYLOAD_TYPE values
#define TPM_PT_ASYM 0x01
#define TPM_PT_BIND 0x02
#define TPM_PT_MIGRATE 0x03
#define TPM_PT_MAINT 0x04
#define TPM_PT_SEAL 0x05
// TPM_ENTITY_TYPE values
#define TPM_ET_KEYHANDLE 0x0001
#define TPM_ET_OWNER 0x0002
#define TPM_ET_DATA 0x0003
#define TPM_ET_SRK 0x0004
#define TPM_ET_KEY 0x0005
/// TPM_ResourceTypes
#define TPM_RT_KEY 0x00000001
#define TPM_RT_AUTH 0x00000002
#define TPM_RT_TRANS 0x00000004
#define TPM_RT_CONTEXT 0x00000005
// TPM_PROTOCOL_ID values
#define TPM_PID_OIAP 0x0001
#define TPM_PID_OSAP 0x0002
#define TPM_PID_ADIP 0x0003
#define TPM_PID_ADCP 0x0004
#define TPM_PID_OWNER 0x0005
// TPM_ALGORITHM_ID values
#define TPM_ALG_RSA 0x00000001
#define TPM_ALG_DES 0x00000002
#define TPM_ALG_3DES 0X00000003
#define TPM_ALG_SHA 0x00000004
#define TPM_ALG_HMAC 0x00000005
#define TCPA_ALG_AES 0x00000006
// TPM_ENC_SCHEME values
#define TPM_ES_NONE 0x0001
#define TPM_ES_RSAESPKCSv15 0x0002
#define TPM_ES_RSAESOAEP_SHA1_MGF1 0x0003
// TPM_SIG_SCHEME values
#define TPM_SS_NONE 0x0001
#define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002
#define TPM_SS_RSASSAPKCS1v15_DER 0x0003
// TPM_KEY_USAGE values
#define TPM_KEY_EK 0x0000
#define TPM_KEY_SIGNING 0x0010
#define TPM_KEY_STORAGE 0x0011
#define TPM_KEY_IDENTITY 0x0012
#define TPM_KEY_AUTHCHANGE 0X0013
#define TPM_KEY_BIND 0x0014
#define TPM_KEY_LEGACY 0x0015
// TPM_AUTH_DATA_USAGE values
#define TPM_AUTH_NEVER 0x00
#define TPM_AUTH_ALWAYS 0x01
// Key Handle of owner and srk
#define TPM_OWNER_KEYHANDLE 0x40000001
#define TPM_SRK_KEYHANDLE 0x40000000
// ---------------------- Functions for checking TPM_RESULTs -----------------
#include <stdio.h>
// FIXME: Review use of these and delete unneeded ones.
// these are really badly dependent on local structure:
// DEPENDS: local var 'status' of type TPM_RESULT
// DEPENDS: label 'abort_egress' which cleans up and returns the status
#define ERRORDIE(s) do { status = s; \
fprintf (stderr, "*** ERRORDIE in %s at %s: %i\n", __func__, __FILE__, __LINE__); \
goto abort_egress; } \
while (0)
// DEPENDS: local var 'status' of type TPM_RESULT
// DEPENDS: label 'abort_egress' which cleans up and returns the status
// Try command c. If it fails, set status to s and goto abort.
#define TPMTRY(s,c) if (c != TPM_SUCCESS) { \
status = s; \
printf("ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
goto abort_egress; \
} else {\
status = c; \
}
// Try command c. If it fails, print error message, set status to actual return code. Goto abort
#define TPMTRYRETURN(c) do { status = c; \
if (status != TPM_SUCCESS) { \
fprintf(stderr, "ERROR in %s at %s:%i code: %s.\n", __func__, __FILE__, __LINE__, tpm_get_error_name(status)); \
goto abort_egress; \
} \
} while(0)
#pragma pack(pop)
#endif //__TCPA_H__
-1
View File
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/blktap2/drivers/hashtable.c
* - tools/vtpm_manager/util/hashtable.c
*/
#include "hashtable.h"
-1
View File
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/blktap2/drivers/hashtable.h
* - tools/vtpm_manager/util/hashtable.h
*/
#ifndef __HASHTABLE_CWC22_H__
-1
View File
@@ -3,7 +3,6 @@
/*
* There are duplicates of this code in:
* - tools/blktap2/drivers/hashtable_private.h
* - tools/vtpm_manager/util/hashtable_private.h
*/
#ifndef __HASHTABLE_PRIVATE_CWC22_H__
-1
View File
@@ -143,7 +143,6 @@ AC_CONFIG_FILES([
tests/unpause/Makefile
tests/vcpu-pin/Makefile
tests/vcpu-disable/Makefile
tests/vtpm/Makefile
tests/xapi/Makefile
tests/enforce_dom0_cpus/Makefile
tests/cpupool/Makefile
-1
View File
@@ -27,5 +27,4 @@ sysrq
unpause
vcpu-disable
vcpu-pin
vtpm
xapi
-1
View File
@@ -22,4 +22,3 @@ sysrq 01_sysrq_basic_neg.test 02_sysrq_sync_pos.test
unpause
vcpu-disable
vcpu-pin
vtpm
-1
View File
@@ -1,2 +1 @@
xapi
vtpm 09_vtpm-xapi.test
-1
View File
@@ -59,7 +59,6 @@ class XenConfig:
# These options need to be lists
self.defaultOpts["disk"] = []
self.defaultOpts["vif"] = []
self.defaultOpts["vtpm"] = []
self.opts = self.defaultOpts
-1
View File
@@ -25,7 +25,6 @@ SUBDIRS = \
unpause \
vcpu-disable \
vcpu-pin \
vtpm \
enforce_dom0_cpus \
save restore migrate \
cpupool
@@ -1,40 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# verify list
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
try:
domain.start(noConsole=True)
except DomainError, e:
if verbose:
print e.extra
vtpm_cleanup(domain.getName())
FAIL("Unable to create domain")
domName = domain.getName()
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
status, output = traceCommand("xm vtpm-list %s" % domain.getId())
eyecatcher = "/local/domain/0/backend/vtpm"
where = output.find(eyecatcher)
if status != 0:
FAIL("xm vtpm-list returned bad status, expected 0, status is %i" % status)
elif where < 0:
FAIL("Fail to list virtual TPM device")
domain.stop()
@@ -1,49 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# check list of pcrs
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
domain.closeConsole()
domain.stop()
if not re.search("PCR-00:",run["output"]):
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
@@ -1,99 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# check list of pcrs; suspend and resume the domain and
# check list of pcrs again
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
consoleHistory = console.getHistory()
domain.closeConsole()
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm save %s %s.save" %
(domName, domName),
timeout=30)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm save did not succeed")
try:
status, ouptut = traceCommand("xm restore %s.save" %
(domName),
timeout=30)
except TimeoutError, e:
os.remove("%s.save" % domName)
saveLog(consoleHistory)
FAIL(str(e))
os.remove("%s.save" % domName)
if status != 0:
saveLog(consoleHistory)
FAIL("xm restore did not succeed")
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
loop += 1
domain.closeConsole()
domain.stop()
@@ -1,93 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# check list of pcrs; locally migrate the domain and
# check list of pcrs again
# This test does local live migration.
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
consoleHistory = console.getHistory()
domain.closeConsole()
old_domid = domid(domName)
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm migrate -l %s localhost" %
domName,
timeout=90)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm migrate did not succeed. External device migration activated?")
domName = domain.getName()
new_domid = domid(domName)
if (old_domid == new_domid):
FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
(old_domid,loop))
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
loop += 1
domain.closeConsole()
domain.stop()
@@ -1,93 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# check list of pcrs; locally migrate the domain and
# check list of pcrs again
# This test does local (non-live) migration.
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
consoleHistory = console.getHistory()
domain.closeConsole()
old_domid = domid(domName)
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm migrate %s localhost" %
domName,
timeout=90)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm migrate did not succeed. External device migration activated?")
domName = domain.getName()
new_domid = domid(domName)
if (old_domid == new_domid):
FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
(old_domid,loop))
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
loop += 1
domain.closeConsole()
domain.stop()
@@ -1,125 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# extend a pcr
# check list of pcrs; suspend and resume the domain and
# check list of pcrs again and validate extended pcr
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("mknod /dev/tpm0 c 10 224")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while creating /dev/tpm0")
try:
run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while extending PCR 0")
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
consoleHistory = console.getHistory()
domain.closeConsole()
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm save %s %s.save" %
(domName, domName),
timeout=30)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm save did not succeed")
try:
status, ouptut = traceCommand("xm restore %s.save" %
(domName),
timeout=30)
except TimeoutError, e:
os.remove("%s.save" % domName)
saveLog(consoleHistory)
FAIL(str(e))
os.remove("%s.save" % domName)
if status != 0:
saveLog(consoleHistory)
FAIL("xm restore did not succeed")
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
loop += 1
domain.closeConsole()
domain.stop()
@@ -1,119 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# extend a pcr
# check list of pcrs; locally migrate the domain and
# check list of pcrs again and validate extended pcr
# This test does local live migration.
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("mknod /dev/tpm0 c 10 224")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while creating /dev/tpm0")
try:
run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while extending PCR 0")
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
consoleHistory = console.getHistory()
domain.closeConsole()
old_domid = domid(domName)
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm migrate -l %s localhost" %
domName,
timeout=90)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm migrate did not succeed. External device migration activated?")
domName = domain.getName()
new_domid = domid(domName)
if (old_domid == new_domid):
FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
(old_domid,loop))
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
loop += 1
domain.closeConsole()
domain.stop()
@@ -1,119 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Positive Test: create domain with virtual TPM attached at build time,
# extend a pcr
# check list of pcrs; locally migrate the domain and
# check list of pcrs again and validate extended pcr
# This test does local (non-live) migration.
from XmTestLib import *
from vtpm_utils import *
import commands
import os
import os.path
import atexit
config = {"vtpm":"instance=1,backend=0"}
domain = XmTestDomain(extraConfig=config)
domName = domain.getName()
consoleHistory = ""
try:
console = domain.start()
except DomainError, e:
if verbose:
print e.extra
FAIL("Unable to create domain (%s)" % domName)
atexit.register(vtpm_cleanup, vtpm_get_uuid(domid(domName)))
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("mknod /dev/tpm0 c 10 224")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while creating /dev/tpm0")
try:
run = console.runCmd("echo -ne \"\\x00\\xc1\\x00\\x00\\x00\\x22\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\0xf\\x10\\x11\\x12\\x13\\x14\" > seq; cat seq > /dev/tpm0")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("Error while extending PCR 0")
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Extend did not lead to expected result (1E A7 BD ...): \n%s" % run["output"])
consoleHistory = console.getHistory()
domain.closeConsole()
old_domid = domid(domName)
loop = 0
while loop < 3:
try:
status, ouptut = traceCommand("xm migrate %s localhost" %
domName,
timeout=90)
except TimeoutError, e:
saveLog(consoleHistory)
FAIL(str(e))
if status != 0:
saveLog(consoleHistory)
FAIL("xm migrate did not succeed. External device migration activated?")
domName = domain.getName()
new_domid = domid(domName)
if (old_domid == new_domid):
FAIL("xm migrate failed, domain id is still %s (loop=%d)" %
(old_domid,loop))
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("No result from dumping the PCRs")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM is not working correctly on /dev/vtpm on backend side")
if not re.search("PCR-00: 1E A7 BD",run["output"]):
saveLog(console.getHistory())
FAIL("Virtual TPM lost PCR 0 value: \n%s" % run["output"])
loop += 1
domain.closeConsole()
domain.stop()
-158
View File
@@ -1,158 +0,0 @@
#!/usr/bin/python
# Copyright (C) International Business Machines Corp., 2006
# Author: Stefan Berger <stefanb@us.ibm.com>
# Test to test the vtpm class through the Xen-API
#
# Tested methods:
# VTPM: get_uuid, get_backend, get_by_uuid, get_record
# create, destroy, get_VM
# VM: get_VTPMS
from XmTestLib import xapi
from XmTestLib.XenAPIDomain import XmTestAPIDomain
from XmTestLib import *
from vtpm_utils import *
import commands
import os
VTPM_RECORD_KEYS = [ 'backend', 'VM', 'uuid', 'other_config' ]
try:
# XmTestAPIDomain tries to establish a connection to XenD
domain = XmTestAPIDomain()
except Exception, e:
SKIP("Skipping test. Error: %s" % str(e))
vm_uuid = domain.get_uuid()
vtpmcfg = {}
vtpmcfg['backend'] = DOM0_UUID
vtpmcfg['VM'] = vm_uuid
session = xapi.connect()
vtpm_uuid = session.xenapi.VTPM.create(vtpmcfg)
vtpm_be = session.xenapi.VTPM.get_backend(vtpm_uuid)
if vtpm_be != vtpmcfg['backend']:
FAIL("vTPM's backend is in '%s', expected: '%s'" %
(vtpm_be, vtpmcfg['backend']))
vtpm_rec = session.xenapi.VTPM.get_record(vtpm_uuid)
miss_keys = []
for k in VTPM_RECORD_KEYS:
if k not in vtpm_rec.keys():
miss_keys.append(k)
if len(miss_keys) > 0:
FAIL("vTPM record is missing key(s): %s" % miss_keys)
if vtpm_rec['uuid'] != vtpm_uuid:
FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" %
(vtpm_rec['uuid'], vtpm_uuid))
if vtpm_rec['VM'] != vm_uuid:
FAIL("vTPM record shows VM uuid '%s', expected: '%s'" %
(vtpm_rec['VM'], vm_uuid))
if vtpm_rec['backend'] != vtpmcfg['backend']:
FAIL("vTPM record shows VM bakcned '%s', expected: '%s'" %
(vtpm_rev['backend'], vtpmcfg['backend']))
badkeys = []
keys = vtpm_rec.keys()
for k in keys:
if k not in VTPM_RECORD_KEYS:
badkeys.append(k)
if len(badkeys) > 0:
FAIL("Unexpected attributes in result: %s" % badkeys)
if vm_uuid != session.xenapi.VTPM.get_VM(vtpm_uuid):
FAIL("VM uuid from VTPM.get_VM different (%s) than expected (%s)." %
(vm_ref, vm_uuid))
uuid = session.xenapi.VTPM.get_uuid(vtpm_uuid)
if uuid != vtpm_uuid:
FAIL("vTPM from VTPM.get_uuid different (%s) than expected (%s)." %
(uuid, vtpm_uuid))
vtpm_ref = session.xenapi.VTPM.get_by_uuid(vtpm_uuid)
if vtpm_ref != vtpm_uuid:
FAIL("vTPM from VTPM.get_by_uuid different (%s) than expected (%s)." %
(vtpm_ref, vtpm_uuid))
vm_vtpms = session.xenapi.VM.get_VTPMs(vm_uuid)
if len(vm_vtpms) != 1:
FAIL("Number of vTPMs from get_VTPMs is (%d) not what was expected (%d)" %
(len(vm_vtpms), 1))
if vtpm_uuid not in vm_vtpms:
FAIL("Other vTPM uuid (%s) returned from VM.get_VTPMs than expected (%s)" %
(vm_vtpms[0], vtpm_uuid))
try:
console = domain.start()
except DomainError, e:
FAIL("Unable to create domain.")
try:
console.sendInput("input")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("1. No result from dumping the PCRs")
if re.search("No such file",run["output"]):
FAIL("TPM frontend support not compiled into (domU?) kernel")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("1. Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
try:
session.xenapi.VTPM.destroy(vtpm_uuid)
#Should never get here
FAIL("Could destroy vTPM while VM is running")
except:
pass
rc = session.xenapi.VM.suspend(vm_uuid)
if rc:
FAIL("Could not suspend VM")
try:
session.xenapi.VTPM.destroy(vtpm_uuid)
#May not throw an exception in 'suspend' state
except:
pass
rc = session.xenapi.VM.resume(vm_uuid, False)
if rc:
FAIL("Could not resume VM")
try:
console = domain.getConsole()
except ConsoleError, e:
FAIL(str(e))
try:
run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs")
except ConsoleError, e:
saveLog(console.getHistory())
FAIL("2. No result from dumping the PCRs. vTPM has been removed?")
if not re.search("PCR-00:",run["output"]):
saveLog(console.getHistory())
FAIL("2. Virtual TPM is not working correctly on /dev/vtpm on backend side: \n%s" % run["output"])
domain.stop()
try:
session.xenapi.VTPM.destroy(vtpm_uuid)
except:
FAIL("Could NOT destroy vTPM while domain is halted.")
domain.destroy()
-27
View File
@@ -1,27 +0,0 @@
SUBDIRS =
TESTS = 01_vtpm-list_pos.test \
02_vtpm-cat_pcrs.test \
03_vtpm-susp_res.test \
04_vtpm-loc_migr.test \
05_vtpm-loc_migr.test \
06_vtpm-susp_res_pcrs.test \
07_vtpm-mig_pcrs.test \
08_vtpm-mig_pcrs.test \
09_vtpm-xapi.test
XFAIL_TESTS =
EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) vtpm_utils.py
TESTS_ENVIRONMENT=@TENV@
%.test: %.py
cp $< $@
chmod +x $@
clean-local: am_config_clean-local
am_config_clean-local:
rm -f *test
rm -f *log
rm -f *~
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.