mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
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:
1 parent
dde22055ac
commit
b918dce5bb
101 files changed
+2
-17106
No files matched your search
@@ -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
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
/*
|
||||
* There are duplicates of this code in:
|
||||
* - tools/xenstore/hashtable.c
|
||||
* - tools/vtpm_manager/util/hashtable.c
|
||||
*/
|
||||
|
||||
#include "hashtable.h"
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
// ===================================================================
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__*/
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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__
|
||||
@@ -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"
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,5 +27,4 @@ sysrq
|
||||
unpause
|
||||
vcpu-disable
|
||||
vcpu-pin
|
||||
vtpm
|
||||
xapi
|
||||
@@ -22,4 +22,3 @@ sysrq 01_sysrq_basic_neg.test 02_sysrq_sync_pos.test
|
||||
unpause
|
||||
vcpu-disable
|
||||
vcpu-pin
|
||||
vtpm
|
||||
@@ -1,2 +1 @@
|
||||
xapi
|
||||
vtpm 09_vtpm-xapi.test
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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