|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] PATCH [base vtpm and libxl patches 2/6] Bug fixes and breakout of vtpm_manager functionality
Fix numerous memory leaks, IO deadlocks, and other bugs that make
vtpm_manager barely usable. Also breakout the vtpm_manager compilation
into separate libraries to facilitate reusing parts of it in mini-os
domains. Finally, add new programs for communicating with the manager
correctly to avoid IO deadlock errors.
Signed off by Matthew Fioravante matthew.fioravante@xxxxxxxxxx
---
Changed since previous:
* rebased off of latest xen-unstable
diff --git a/tools/vtpm_manager/Makefile b/tools/vtpm_manager/Makefile
--- a/tools/vtpm_manager/Makefile
+++ b/tools/vtpm_manager/Makefile
@@ -1,9 +1,9 @@
-XEN_ROOT = $(CURDIR)/../..
+XEN_ROOT = $(realpath ../..)
# Base definitions and rules
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+include Rules.mk
-SUBDIRS = crypto tcs util manager migration
+SUBDIRS = crypto tcs util manager migration vtpmmgrtalk vtpmconnd
OPENSSL_HEADER = /usr/include/openssl/crypto.h
.PHONY: all clean install
diff --git a/tools/vtpm_manager/README b/tools/vtpm_manager/README
--- a/tools/vtpm_manager/README
+++ b/tools/vtpm_manager/README
@@ -43,9 +43,6 @@ 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
@@ -59,6 +56,10 @@ WELL_KNOWN_OWNER_AUTH -> Rather than randomly
generating the password for
lost. However this has no protection
from malicious app
issuing a TPM_OwnerClear to wipe the TPM
+VTPM_STUBDOM -> vtpm_manager runs in vtpm_stubdom mode with
+ vtpm instances running in mini-os domains
+ (see: stubdom/vtpm/README for details)
+
Requirements
============
- xen-unstable
diff --git a/tools/vtpm_manager/Rules.mk b/tools/vtpm_manager/Rules.mk
--- a/tools/vtpm_manager/Rules.mk
+++ b/tools/vtpm_manager/Rules.mk
@@ -6,7 +6,7 @@ include $(XEN_ROOT)/tools/Rules.mk
#
# General compiler flags
-CFLAGS = -Werror -g3
+CFLAGS = -Werror -g3 -I.
# Generic project files
HDRS = $(wildcard *.h)
@@ -31,18 +31,18 @@ $(OBJS): $(SRCS)
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))"
+#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
+CFLAGS += -DLOGGING_MODULES=0xff
# vtpm_manager listens on fifo's rather than backend
#CFLAGS += -DDUMMY_BACKEND
+# Build for use with vtpm-stubdom
+#CFLAGS += -DVTPM_STUBDOM
+
# TCS talks to fifo's rather than /dev/tpm. TPM Emulator assumed on fifos
#CFLAGS += -DDUMMY_TPM
@@ -52,8 +52,3 @@ CFLAGS +=
-DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
# 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
diff --git a/tools/vtpm_manager/crypto/Makefile
b/tools/vtpm_manager/crypto/Makefile
--- a/tools/vtpm_manager/crypto/Makefile
+++ b/tools/vtpm_manager/crypto/Makefile
@@ -1,5 +1,9 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
BIN = libtcpaCrypto.a
diff --git a/tools/vtpm_manager/crypto/crypto.c
b/tools/vtpm_manager/crypto/crypto.c
--- a/tools/vtpm_manager/crypto/crypto.c
+++ b/tools/vtpm_manager/crypto/crypto.c
@@ -45,6 +45,8 @@
#include "crypto.h"
#include "log.h"
+extern const EVP_CIPHER * SYM_CIPHER;
+
/**
* Initialize cryptography library
* @rand: random seed
@@ -83,6 +85,6 @@ void Crypto_GetRandom(void* data, int size) {
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));
+ vtpmlogerror (VTPM_LOG_CRYPTO, "RAND_pseudo_bytes failed: rc=%d
errstr=%s\n",
+ result, ERR_error_string (ERR_get_error(), NULL));
}
diff --git a/tools/vtpm_manager/crypto/crypto.h
b/tools/vtpm_manager/crypto/crypto.h
--- a/tools/vtpm_manager/crypto/crypto.h
+++ b/tools/vtpm_manager/crypto/crypto.h
@@ -76,7 +76,7 @@ typedef struct CRYPTO_INFO {
void Crypto_Init(const BYTE* rand, int size);
-void Crypto_Exit();
+void Crypto_Exit(void);
void Crypto_GetRandom(void* data, int size);
@@ -127,6 +127,8 @@ void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/
UINT32 pubExpSize,
/*[IN]*/ BYTE *modulus,
CRYPTO_INFO* cryptoInfo);
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo);
+
//
// symmetric pack and unpack operations
//
diff --git a/tools/vtpm_manager/crypto/rsa.c
b/tools/vtpm_manager/crypto/rsa.c
--- a/tools/vtpm_manager/crypto/rsa.c
+++ b/tools/vtpm_manager/crypto/rsa.c
@@ -149,6 +149,10 @@ void Crypto_RSABuildCryptoInfoPublic( /*[IN]*/
UINT32 pubExpSize,
}
+void Crypto_RSACryptoInfoFree(CRYPTO_INFO* cryptoInfo) {
+ RSA_free(cryptoInfo->keyInfo);
+}
+
int Crypto_RSAEnc( CRYPTO_INFO *key,
UINT32 inDataSize,
BYTE *inData,
@@ -161,6 +165,7 @@ int Crypto_RSAEnc( CRYPTO_INFO *key,
if (paddedData == NULL)
return -1;
+ memset(paddedData, 0, sizeof(BYTE) * paddedDataSize);
*outDataSize = 0;
diff --git a/tools/vtpm_manager/crypto/sym_crypto.c
b/tools/vtpm_manager/crypto/sym_crypto.c
--- a/tools/vtpm_manager/crypto/sym_crypto.c
+++ b/tools/vtpm_manager/crypto/sym_crypto.c
@@ -41,8 +41,16 @@
#include <openssl/rand.h>
#include "tcg.h"
+#include "log.h"
#include "sym_crypto.h"
+struct symkey_t {
+ buffer_t key;
+
+ EVP_CIPHER_CTX context;
+ const EVP_CIPHER * cipher;
+};
+
typedef enum crypt_op_type_t {
CRYPT_ENCRYPT,
CRYPT_DECRYPT
@@ -61,19 +69,22 @@ 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 Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t*
keybits) {
TPM_RESULT status = TPM_SUCCESS;
- EVP_CIPHER_CTX_init (&key->context);
+ *key = malloc(sizeof(symkey_t));
+
+ EVP_CIPHER_CTX_init (&(*key)->context);
- key->cipher = SYM_CIPHER;
+ (*key)->cipher = SYM_CIPHER;
- TPMTRYRETURN( buffer_init_copy (&key->key, keybits));
+ TPMTRYRETURN( buffer_init_copy (&(*key)->key, keybits));
goto egress;
abort_egress:
- EVP_CIPHER_CTX_cleanup (&key->context);
+ EVP_CIPHER_CTX_cleanup (&(*key)->context);
+ free(key);
egress:
@@ -82,19 +93,21 @@ TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key,
const buffer_t* keybits) {
-TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key) {
int res;
TPM_RESULT status = TPM_SUCCESS;
+
+ *key = malloc(sizeof(symkey_t));
// hmm, EVP_CIPHER_CTX_init does not return a value
- EVP_CIPHER_CTX_init (&key->context);
+ EVP_CIPHER_CTX_init (&(*key)->context);
- key->cipher = SYM_CIPHER;
+ (*key)->cipher = SYM_CIPHER;
- TPMTRYRETURN( buffer_init (&key->key,
EVP_CIPHER_key_length(key->cipher), NULL)) ;
+ 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);
+ res = RAND_pseudo_bytes ((*key)->key.bytes, (*key)->key.size);
if (res < 0)
ERRORDIE (TPM_SHORTRANDOM);
@@ -102,8 +115,9 @@ TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key) {
goto egress;
abort_egress:
- EVP_CIPHER_CTX_cleanup (&key->context);
- buffer_free (&key->key);
+ EVP_CIPHER_CTX_cleanup (&(*key)->context);
+ buffer_free (&(*key)->key);
+ free(key);
egress:
return status;
@@ -119,11 +133,11 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
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);
+ TPMTRYRETURN( 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);
@@ -139,6 +153,7 @@ TPM_RESULT Crypto_symcrypto_encrypt (symkey_t* key,
goto egress;
abort_egress:
+ buffer_free(o_cipher);
egress:
@@ -170,7 +185,7 @@ TPM_RESULT Crypto_symcrypto_decrypt (symkey_t* key,
// and decrypt
TPMTRYRETURN ( ossl_symcrypto_op (key, &cipher_alias, &iv, o_clear,
CRYPT_DECRYPT) );
-
+
goto egress;
abort_egress:
@@ -188,6 +203,8 @@ TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key) {
buffer_free (&key->key);
EVP_CIPHER_CTX_cleanup (&key->context);
+
+ free(key);
return TPM_SUCCESS;
}
@@ -235,3 +252,8 @@ TPM_RESULT ossl_symcrypto_op (symkey_t* key,
return status;
}
+
+buffer_t* Crypto_symkey_getkey(symkey_t* key)
+{
+ return &key->key;
+}
diff --git a/tools/vtpm_manager/crypto/sym_crypto.h
b/tools/vtpm_manager/crypto/sym_crypto.h
--- a/tools/vtpm_manager/crypto/sym_crypto.h
+++ b/tools/vtpm_manager/crypto/sym_crypto.h
@@ -40,21 +40,15 @@
#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;
+typedef struct symkey_t symkey_t;
-extern const EVP_CIPHER * SYM_CIPHER;
+//Allocates a symkey with random bits
+TPM_RESULT Crypto_symcrypto_genkey (symkey_t ** key);
-TPM_RESULT Crypto_symcrypto_genkey (symkey_t * key);
-
-TPM_RESULT Crypto_symcrypto_initkey (symkey_t * key, const buffer_t*
keybits);
+//Allocates a symkey with given keybits
+TPM_RESULT Crypto_symcrypto_initkey (symkey_t ** key, const buffer_t*
keybits);
// these functions will allocate their output buffers
@@ -66,7 +60,10 @@ 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
+//Frees the symkey
TPM_RESULT Crypto_symcrypto_freekey (symkey_t * key);
+//Get the raw key byte buffer
+buffer_t* Crypto_symkey_getkey(symkey_t* key);
+
#endif /* _SYM_CRYPTO_H */
diff --git a/tools/vtpm_manager/manager/Makefile
b/tools/vtpm_manager/manager/Makefile
--- a/tools/vtpm_manager/manager/Makefile
+++ b/tools/vtpm_manager/manager/Makefile
@@ -1,7 +1,18 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+
+
+MAINS := vtpmd.o
+MGRLIB := libvtpmmanager.a
+VTSPOBJS := vtsp.o
+VTSPLIB := libvtsp.a
+BIN := vtpm_managerd
+OBJS := $(filter-out $(MAINS) $(VTSPOBJS), $(OBJS))
-BIN = vtpm_managerd
.PHONY: all
all: build
@@ -28,8 +39,14 @@ clean:
mrproper: clean
rm -f *~
-$(BIN): $(OBJS)
- $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+$(BIN): $(MAINS) $(MGRLIB) $(VTSPLIB)
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
+
+$(VTSPLIB): $(VTSPOBJS)
+ $(AR) rcs $@ $^
+
+$(MGRLIB): $(OBJS)
+ $(AR) rcs $@ $^
# libraries
LIBS += ../tcs/libTCS.a ../util/libTCGUtils.a ../crypto/libtcpaCrypto.a
diff --git a/tools/vtpm_manager/manager/dmictl.c
b/tools/vtpm_manager/manager/dmictl.c
--- a/tools/vtpm_manager/manager/dmictl.c
+++ b/tools/vtpm_manager/manager/dmictl.c
@@ -40,6 +40,9 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdlib.h>
#include "vtpmpriv.h"
#include "bsg.h"
@@ -51,6 +54,13 @@
#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+#ifndef VTPM_STUBDOM
+// This is needed to all extra_close_dmi to close this to prevent a
+// broken pipe when no DMIs are left.
+vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+#endif
+
+
// 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
@@ -81,7 +91,7 @@ TPM_RESULT init_dmi(UINT32 dmi_id, BYTE dmi_type,
VTPM_DMI_RESOURCE **dmi_res) {
// 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);
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to insert instance %" PRIu32
"into table. Aborting.\n", dmi_id);
status = TPM_FAIL;
goto abort_egress;
}
@@ -116,6 +126,161 @@ TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res) {
return (VTPM_Close_DMI_Extra(dmi_res) );
}
+
+void free_dmi(VTPM_DMI_RESOURCE *dmi_res) {
+ if(dmi_res != NULL) {
+ free(dmi_res->NVMLocation);
+ }
+ free(dmi_res);
+}
+
+TPM_RESULT VTPM_New_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res, BYTE vm_type,
BYTE startup_mode) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+#ifndef VTPM_STUBDOM
+ 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, FALSE) != 0) ||
+ (vtpm_ipc_init(dmi_res->tx_vtpm_ipc_h, tx_vtpm_name, O_WRONLY,
TRUE, FALSE) != 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;
+#endif
+
+abort_egress:
+ //FIXME: Everything should be freed here
+ return (status);
+}
+
+TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE *dmi_res) {
+ TPM_RESULT status = TPM_SUCCESS;
+
+#ifndef VTPM_STUBDOM
+ 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);
+ free(dmi_res->tx_tpm_ipc_h);
+ free(dmi_res->tx_vtpm_ipc_h);
+
+#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
+#endif
+ return status;
+}
+
+
+
TPM_RESULT VTPM_Handle_New_DMI(const buffer_t *param_buf) {
@@ -254,7 +419,7 @@ TPM_RESULT VTPM_Handle_Delete_DMI( const buffer_t
*param_buf) {
// Close DMI first
TPMTRYRETURN(close_dmi( dmi_res ));
- free ( dmi_res );
+ free_dmi(dmi_res);
status=TPM_SUCCESS;
goto egress;
diff --git a/tools/vtpm_manager/manager/migration.c
b/tools/vtpm_manager/manager/migration.c
--- a/tools/vtpm_manager/manager/migration.c
+++ b/tools/vtpm_manager/manager/migration.c
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include <stdlib.h>
#include "vtpmpriv.h"
#include "bsg.h"
@@ -263,7 +264,7 @@ TPM_RESULT VTPM_Handle_Get_Migration_key( const
buffer_t *param_buf,
TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
buffer_t *result_buf) {
- TPM_RESULT status=TPM_FAIL;
+ TPM_RESULT status=TPM_SUCCESS;
VTPM_MIGKEY_LIST *mig_key;
vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
@@ -303,5 +304,5 @@ TPM_RESULT VTPM_Handle_Load_Migration_key( const
buffer_t *param_buf,
free(pubkey_exp_pack.data);
free(pubkey_mod_pack.data);
- return TPM_SUCCESS;
+ return status;
}
diff --git a/tools/vtpm_manager/manager/securestorage.c
b/tools/vtpm_manager/manager/securestorage.c
--- a/tools/vtpm_manager/manager/securestorage.c
+++ b/tools/vtpm_manager/manager/securestorage.c
@@ -42,7 +42,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
-
+#include <stdlib.h>
#include "tcg.h"
#include "vtpm_manager.h"
#include "vtpmpriv.h"
@@ -58,7 +58,7 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
CRYPTO_INFO *asymkey,
buffer_t *sealed_data) {
TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
+ symkey_t *symkey;
buffer_t data_cipher = NULL_BUF,
symkey_cipher = NULL_BUF;
@@ -69,14 +69,14 @@ TPM_RESULT envelope_encrypt(const buffer_t *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) );
+ TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (symkey, inbuf,
&data_cipher) );
// Encrypt symmetric key
TPMTRYRETURN( VTSP_Bind( asymkey,
- &symkey.key,
+ Crypto_symkey_getkey(symkey),
&symkey_cipher) );
// Create output blob: symkey_size + symkey_cipher +
state_cipher_size + state_cipher
@@ -86,8 +86,9 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
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));
+ memset(sealed_data->bytes, 0, sealed_data->size);
BSG_PackList(sealed_data->bytes, 2,
BSG_TPM_SIZE32_DATA, &symkey_cipher32,
@@ -109,11 +110,37 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
buffer_free ( &data_cipher);
buffer_free ( &symkey_cipher);
- Crypto_symcrypto_freekey (&symkey);
+ Crypto_symcrypto_freekey (symkey);
return status;
}
+TPM_RESULT symkey_encrypt(const buffer_t *inbuf,
+ CRYPTO_INFO *asymkey,
+ buffer_t *sealed_key) {
+ buffer_t symkey_cipher = NULL_BUF;
+ struct pack_constbuf_t symkey_cipher32;
+ TPM_RESULT status = TPM_SUCCESS;
+
+ // Encrypt symmetric key
+ TPMTRYRETURN( VTSP_Bind( asymkey,
+ inbuf,
+ &symkey_cipher));
+
+ symkey_cipher32.size = buffer_len(&symkey_cipher);
+ symkey_cipher32.data = symkey_cipher.bytes;
+
+ TPMTRYRETURN( buffer_init(sealed_key, sizeof(UINT32) +
symkey_cipher32.size, NULL));
+ BSG_PackList(sealed_key->bytes, 1,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+ goto egress;
+abort_egress:
+egress:
+ buffer_free( &symkey_cipher);
+ return status;
+}
+
+
TPM_RESULT envelope_decrypt(const buffer_t *cipher,
TCS_CONTEXT_HANDLE TCSContext,
TPM_HANDLE keyHandle,
@@ -121,15 +148,13 @@ TPM_RESULT envelope_decrypt(const buffer_t
*cipher,
buffer_t *unsealed_data) {
TPM_RESULT status = TPM_SUCCESS;
- symkey_t symkey;
+ 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;
+ struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF, data_cipher32 =
NULL_PACK_BUF;
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]);
@@ -159,7 +184,7 @@ TPM_RESULT envelope_decrypt(const buffer_t *cipher,
Crypto_symcrypto_initkey (&symkey, &symkey_clear);
// Decrypt State
- TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey,
&data_cipher, unsealed_data) );
+ 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++)
@@ -175,26 +200,64 @@ TPM_RESULT envelope_decrypt(const buffer_t
*cipher,
buffer_free ( &data_cipher);
buffer_free ( &symkey_clear);
buffer_free ( &symkey_cipher);
- Crypto_symcrypto_freekey (&symkey);
+ BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+ BSG_Destroy(BSG_TPM_SIZE32_DATA, &data_cipher32);
+ Crypto_symcrypto_freekey (symkey);
+
return status;
}
+TPM_RESULT symkey_decrypt(const buffer_t *cipher,
+ TCS_CONTEXT_HANDLE TCSContext,
+ TPM_HANDLE keyHandle,
+ const TPM_AUTHDATA *key_usage_auth,
+ buffer_t *symkey_clear) {
+
+ TPM_RESULT status = TPM_SUCCESS;
+ buffer_t symkey_cipher = NULL_BUF;
+ struct pack_buf_t symkey_cipher32 = NULL_PACK_BUF;
+
+ BSG_UnpackList(cipher->bytes, 1,
+ BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+
+ TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher,
+ symkey_cipher32.size,
+ symkey_cipher32.data) );
+
+ // Decrypt Symmetric Key
+ TPMTRYRETURN( VTSP_Unbind( TCSContext,
+ keyHandle,
+ &symkey_cipher,
+ key_usage_auth,
+ symkey_clear,
+ &(vtpm_globals->keyAuth) ) );
+
+ goto egress;
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to decrypt symmetric key
status=%d\n.", status);
+
+ egress:
+ BSG_Destroy(BSG_TPM_SIZE32_DATA, &symkey_cipher32);
+ 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;
+ int fh = -1;
long bytes_written;
buffer_t sealed_NVM = NULL_BUF;
-
- vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n",
buffer_len(inbuf));
+ const buffer_t* nvmbuf = inbuf;
- TPMTRYRETURN( envelope_encrypt(inbuf,
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n",
buffer_len(nvmbuf));
+
+ TPMTRYRETURN( envelope_encrypt(nvmbuf,
&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.
@@ -205,7 +268,6 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE
*myDMI,
status = TPM_IOERROR;
goto abort_egress;
}
- close(fh);
Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *)
&myDMI->NVM_measurement);
@@ -215,6 +277,7 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE
*myDMI,
vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
egress:
+ close(fh);
buffer_free(&sealed_NVM);
return status;
}
@@ -229,7 +292,8 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
buffer_t sealed_NVM = NULL_BUF;
long fh_size;
- int fh, stat_ret, i;
+ int fh = -1;
+ int stat_ret, i;
struct stat file_stat;
TPM_DIGEST sealedNVMHash;
@@ -241,6 +305,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
//Read sealed blob off disk from NVMLocation
fh = open(myDMI->NVMLocation, O_RDONLY);
+ printf("Filename: %s\n", myDMI->NVMLocation);
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
fh_size = file_stat.st_size;
@@ -254,7 +319,6 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
status = TPM_IOERROR;
goto abort_egress;
}
- close(fh);
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%d],\n",
buffer_len(&sealed_NVM));
@@ -289,14 +353,128 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE
*myDMI,
egress:
buffer_free( &sealed_NVM );
+ close(fh);
+
+ return status;
+}
+
+TPM_RESULT VTPM_Handle_Load_HashKey(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 = -1;
+ int 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);
+ printf("Filename: %s\n", myDMI->NVMLocation);
+ 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;
+ }
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Loading %d byte encryption key,\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 LoadKey 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;
+ }
+
+ //Decrypt the key into the output buffer
+ TPMTRYRETURN( symkey_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 Key\n.");
+
+ egress:
+ buffer_free( &sealed_NVM );
+ close(fh);
+
+ return status;
+}
+
+TPM_RESULT VTPM_Handle_Save_HashKey(VTPM_DMI_RESOURCE *myDMI,
+ const buffer_t *inbuf,
+ buffer_t *outbuf) {
+ TPM_RESULT status = TPM_SUCCESS;
+ int fh = -1;
+ long bytes_written;
+ buffer_t sealed_key = NULL_BUF;
+
+ TPMTRYRETURN( symkey_encrypt(inbuf,
+ &vtpm_globals->storageKey,
+ &sealed_key) );
+
+ vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d byte Encryption Key.\n",
buffer_len(inbuf));
+
+ // 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_key.bytes,
buffer_len(&sealed_key) ) != (long) buffer_len(&sealed_key))) {
+ vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed
to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_key));
+ status = TPM_IOERROR;
+ goto abort_egress;
+ }
+ Crypto_SHA1Full (sealed_key.bytes, buffer_len(&sealed_key), (BYTE *)
&myDMI->NVM_measurement);
+
+ goto egress;
+
+ abort_egress:
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to save Key\n.");
+
+ egress:
+ close(fh);
+ buffer_free(&sealed_key);
return status;
}
TPM_RESULT VTPM_SaveManagerData(void) {
TPM_RESULT status=TPM_SUCCESS;
- int fh, dmis=-1;
+ int fh = -1, 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;
@@ -364,6 +542,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
BSG_TPM_DIGEST,
&dmi_res->DMI_measurement);
} while (hashtable_iterator_advance(dmi_itr));
+ free(dmi_itr);
}
fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
@@ -389,6 +568,7 @@ TPM_RESULT VTPM_SaveManagerData(void) {
free(flat_boot_key);
free(flat_enc);
+ buffer_free(&clear_flat_global);
buffer_free(&enc_flat_global);
free(flat_dmis);
close(fh);
@@ -403,9 +583,10 @@ TPM_RESULT VTPM_LoadManagerData(void) {
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;
+ buffer_t unsealed_data = NULL_BUF;
+ buffer_t enc_table_abuf;
+ struct pack_buf_t storage_key_pack = NULL_PACK_BUF, boot_key_pack =
NULL_PACK_BUF;
+ UINT32 enc_size;
BYTE vtpm_manager_gen;
VTPM_DMI_RESOURCE *dmi_res;
@@ -438,9 +619,9 @@ TPM_RESULT VTPM_LoadManagerData(void) {
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) );
+ TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap,
boot_key_pack.size, boot_key_pack.data) );
+
//Load Boot Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
@@ -471,8 +652,8 @@ TPM_RESULT VTPM_LoadManagerData(void) {
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) );
+ TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap,
storage_key_pack.size, storage_key_pack.data) );
+
// Per DMI values to be saved
while ( step_size < fh_size ){
@@ -501,7 +682,10 @@ TPM_RESULT VTPM_LoadManagerData(void) {
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error =
%s\n", tpm_get_error_name(status));
egress:
+ BSG_Destroy(BSG_TPM_SIZE32_DATA, &boot_key_pack);
+ BSG_Destroy(BSG_TPM_SIZE32_DATA, &storage_key_pack);
+ buffer_free(&unsealed_data);
free(flat_table);
close(fh);
diff --git a/tools/vtpm_manager/manager/vtpm_ipc.c
b/tools/vtpm_manager/manager/vtpm_ipc.c
--- a/tools/vtpm_manager/manager/vtpm_ipc.c
+++ b/tools/vtpm_manager/manager/vtpm_ipc.c
@@ -36,26 +36,49 @@
//
// ===================================================================
+#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/select.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) {
+volatile sig_atomic_t IPC_QUIT_FLAG = 0;
+
+const static struct timeval TIMEOUT = {
+ .tv_sec = 1,
+ .tv_usec = 0
+};
+
+int vtpm_ipc_init(vtpm_ipc_handle_t *ipc_h, char* name, int flags, BOOL
create, BOOL preopen) {
+ int rc;
+
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;
+ if (create) {
+ if((rc = vtpm_ipc_create(ipc_h) != 0)) {
+ return rc;
+ }
+ }
+
+ if(preopen) {
+ ipc_h->fh = open(ipc_h->name, ipc_h->flags);
+ if ( ipc_h->fh == VTPM_IPC_CLOSED ) {
+ vtpmlogerror(VTPM_LOG_VTPM, "VTPM ERROR: Can't open %s\n",
ipc_h->name);
+ return -1;
+ }
+ }
+ 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))
@@ -68,8 +91,6 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
}
}
- ipc_h->fh = VTPM_IPC_CLOSED;
-
return 0;
}
@@ -78,6 +99,8 @@ int vtpm_ipc_create(vtpm_ipc_handle_t *ipc_h) {
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;
+ fd_set fds;
+ struct timeval timeout;
if (ipc_h) {
my_ipc_h = ipc_h;
@@ -94,9 +117,19 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE *
return -1;
}
+ FD_ZERO(&fds);
+ while(!FD_ISSET( my_ipc_h->fh, &fds )) {
+ timeout = TIMEOUT;
+ if (IPC_QUIT_FLAG) {
+ return -1;
+ }
+ FD_SET(my_ipc_h->fh, &fds);
+ select(my_ipc_h->fh + 1, &fds, NULL, NULL, &timeout);
+ }
+
result = read(my_ipc_h->fh, bytes, size);
if (result < 0) {
- my_ipc_h->fh = VTPM_IPC_CLOSED;
+ my_ipc_h->fh = VTPM_IPC_CLOSED;
}
return (result);
@@ -106,6 +139,8 @@ int vtpm_ipc_read(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE *
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;
+ fd_set fds;
+ struct timeval timeout;
if (ipc_h) {
my_ipc_h = ipc_h;
@@ -122,6 +157,16 @@ int vtpm_ipc_write(vtpm_ipc_handle_t *ipc_h,
vtpm_ipc_handle_t *alt_ipc_h, BYTE
return -1;
}
+ FD_ZERO(&fds);
+ while(!FD_ISSET( my_ipc_h->fh, &fds )) {
+ timeout = TIMEOUT;
+ if (IPC_QUIT_FLAG) {
+ return -1;
+ }
+ FD_SET(my_ipc_h->fh, &fds);
+ select(my_ipc_h->fh + 1, NULL, &fds, NULL, &timeout);
+ }
+
result = write(my_ipc_h->fh, bytes, size);
if (result < 0) {
my_ipc_h->fh = VTPM_IPC_CLOSED;
diff --git a/tools/vtpm_manager/manager/vtpm_ipc.h
b/tools/vtpm_manager/manager/vtpm_ipc.h
--- a/tools/vtpm_manager/manager/vtpm_ipc.h
+++ b/tools/vtpm_manager/manager/vtpm_ipc.h
@@ -39,10 +39,14 @@
#ifndef __VTPM_IO_H__
#define __VTPM_IO_H__
+#include <signal.h>
+
#include "tcg.h"
#define VTPM_IPC_CLOSED -1
+extern volatile sig_atomic_t IPC_QUIT_FLAG;
+
// Represents an (somewhat) abstracted io handle.
typedef struct vtpm_ipc_handle_t {
int fh; // IO handle.
@@ -53,7 +57,7 @@ typedef struct vtpm_ipc_handle_t {
} vtpm_ipc_handle_t;
-int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL
create);
+int vtpm_ipc_init(vtpm_ipc_handle_t *ioh, char* name, int flags, BOOL
create, BOOL preopen);
// Create the file that needs opening. Used only for FIFOs
// FYI: This may cause problems in other file IO schemes. We'll see.
diff --git a/tools/vtpm_manager/manager/vtpm_lock.c
b/tools/vtpm_manager/manager/vtpm_lock.c
--- a/tools/vtpm_manager/manager/vtpm_lock.c
+++ b/tools/vtpm_manager/manager/vtpm_lock.c
@@ -40,24 +40,24 @@
static pthread_rwlock_t vtpm_lock;
-void vtpm_lock_init() {
+void vtpm_lock_init(void) {
pthread_rwlock_init( &vtpm_lock, NULL);
}
-void vtpm_lock_destroy(){
+void vtpm_lock_destroy(void){
pthread_rwlock_destroy(&vtpm_lock);
}
-void vtpm_lock_rdlock(){
+void vtpm_lock_rdlock(void){
pthread_rwlock_rdlock(&vtpm_lock);
}
-void vtpm_lock_wrlock(){
+void vtpm_lock_wrlock(void){
pthread_rwlock_wrlock(&vtpm_lock);
}
-void vtpm_lock_unlock(){
+void vtpm_lock_unlock(void){
pthread_rwlock_unlock(&vtpm_lock);
}
diff --git a/tools/vtpm_manager/manager/vtpm_lock.h
b/tools/vtpm_manager/manager/vtpm_lock.h
--- a/tools/vtpm_manager/manager/vtpm_lock.h
+++ b/tools/vtpm_manager/manager/vtpm_lock.h
@@ -38,11 +38,11 @@
#ifndef __VTPM_LOCK_H__
#define __VTPM_LOCK_H__
-void vtpm_lock_init();
-void vtpm_lock_destroy();
+void vtpm_lock_init(void);
+void vtpm_lock_destroy(void);
-void vtpm_lock_rdlock();
-void vtpm_lock_wrlock();
-void vtpm_lock_unlock();
+void vtpm_lock_rdlock(void);
+void vtpm_lock_wrlock(void);
+void vtpm_lock_unlock(void);
#endif
diff --git a/tools/vtpm_manager/manager/vtpm_manager.c
b/tools/vtpm_manager/manager/vtpm_manager.c
--- a/tools/vtpm_manager/manager/vtpm_manager.c
+++ b/tools/vtpm_manager/manager/vtpm_manager.c
@@ -40,10 +40,12 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include <stdlib.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
#include "vtsp.h"
+#include "tpmddl.h"
#include "bsg.h"
#include "hashtable.h"
#include "hashtable_itr.h"
@@ -54,8 +56,8 @@
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};
+const TPM_AUTHDATA SRK_AUTH = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
#ifdef WELL_KNOWN_OWNER_AUTH
static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff,
@@ -74,7 +76,6 @@ static int equals32(void *k1, void *k2) {
}
// --------------------------- Functions ------------------------------
-
TPM_RESULT VTPM_Create_Manager(){
TPM_RESULT status = TPM_SUCCESS;
@@ -104,6 +105,7 @@ TPM_RESULT VTPM_Create_Manager(){
TPMTRYRETURN(VTSP_DisablePubekRead(vtpm_globals->manager_tcs_handle,
(const
TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
&vtpm_globals->keyAuth));
+ Crypto_RSACryptoInfoFree(&ek_cryptoInfo);
} else {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an
owner. Creating Keys off existing SRK.\n");
}
@@ -181,7 +183,7 @@ TPM_RESULT VTPM_Create_Manager(){
}
///////////////////////////////////////////////////////////////////////////////
-TPM_RESULT VTPM_Init_Manager() {
+TPM_RESULT VTPM_Init_Manager(void) {
TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize=256;
@@ -203,6 +205,11 @@ TPM_RESULT VTPM_Init_Manager() {
vtpm_globals->manager_tcs_handle = 0;
TPMTRYRETURN(TCS_create());
+
+ // Blow away all stale handles left in the tpm
+ if(TDDL_FlushAllResources() != TPM_SUCCESS) {
+ vtpmlogerror(VTPM_LOG_VTPM, "VTPM_FlushResources failed,
continuing anyway..\n");
+ }
// Create TCS Context for service
TPMTRYRETURN( TCS_OpenContext(&vtpm_globals->manager_tcs_handle ) );
@@ -228,7 +235,7 @@ TPM_RESULT VTPM_Init_Manager() {
TPMTRYRETURN( VTPM_Create_Manager() );
TPMTRYRETURN( VTPM_SaveManagerData() );
} else if (serviceStatus != TPM_SUCCESS) {
- vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file");
+ vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing manager file\n");
exit(1);
}
@@ -254,7 +261,7 @@ TPM_RESULT VTPM_Init_Manager() {
}
///////////////////////////////////////////////////////////////////////////////
-void VTPM_Stop_Manager() {
+void VTPM_Stop_Manager(void) {
VTPM_DMI_RESOURCE *dmi_res;
struct hashtable_itr *dmi_itr;
@@ -267,7 +274,7 @@ void VTPM_Stop_Manager() {
close_dmi( dmi_res ); // Not really interested in return code
} while (hashtable_iterator_advance(dmi_itr));
- free (dmi_itr);
+ free (dmi_itr);
}
if ( VTPM_SaveManagerData() != TPM_SUCCESS )
@@ -276,7 +283,21 @@ void VTPM_Stop_Manager() {
TCS_CloseContext(vtpm_globals->manager_tcs_handle);
TCS_destroy();
- hashtable_destroy(vtpm_globals->dmi_map, 1);
+ 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);
+ free_dmi(dmi_res);
+ } while (hashtable_iterator_advance(dmi_itr));
+ free (dmi_itr);
+ }
+ hashtable_destroy(vtpm_globals->dmi_map, 0);
+
+ /* Cleanup resources */
+ Crypto_RSACryptoInfoFree(&vtpm_globals->bootKey);
+ Crypto_RSACryptoInfoFree(&vtpm_globals->storageKey);
+ buffer_free(&vtpm_globals->bootKeyWrap);
+ buffer_free(&vtpm_globals->storageKeyWrap);
free(vtpm_globals);
Crypto_Exit();
diff --git a/tools/vtpm_manager/manager/vtpm_manager.h
b/tools/vtpm_manager/manager/vtpm_manager.h
--- a/tools/vtpm_manager/manager/vtpm_manager.h
+++ b/tools/vtpm_manager/manager/vtpm_manager.h
@@ -61,6 +61,8 @@
#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
+#define VTPM_ORD_SAVEHASHKEY (VTPM_ORD_BASE + 7) // DMI requests
encryption key for persistent storage
+#define VTPM_ORD_LOADHASHKEY (VTPM_ORD_BASE + 8) // DMI requests
symkey to be regenerated
// Priviledged VTPM Commands (From management console)
#define VTPM_ORD_OPEN (VTPM_PRIV_BASE + 1) // Creates/reopens DMI
@@ -147,4 +149,23 @@ VTPM_TPMCommand
*********************************************************************/
+#ifndef VTPM_STUBDOM
+#define TPM_EMULATOR_PATH "/usr/bin/vtpmd"
+#endif
+
+#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"
+#ifndef VTPM_STUBDOM
+#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"
+#endif
+#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"
+
#endif //_VTPM_MANAGER_H_
diff --git a/tools/vtpm_manager/manager/vtpm_manager_handler.c
b/tools/vtpm_manager/manager/vtpm_manager_handler.c
--- a/tools/vtpm_manager/manager/vtpm_manager_handler.c
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.c
@@ -41,6 +41,8 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
#include "vtpm_manager.h"
#include "vtpmpriv.h"
@@ -50,26 +52,13 @@
#include "hashtable_itr.h"
#include "log.h"
#include "buffer.h"
+#include "vtpm_manager_handler.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);
+volatile sig_atomic_t HANDLER_QUIT_FLAG = 0;
TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
@@ -80,12 +69,13 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
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;
+ BYTE *cmd_header=NULL, *in_param=NULL, *out_header=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;
+ int locked;
BOOL add_header=TRUE; // This indicates to prepend a header on
result_buf before sending
cmd_header = (BYTE *) malloc(VTPM_COMMAND_HEADER_SIZE_SRV);
@@ -93,7 +83,11 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
result_buf = (buffer_t *) malloc(sizeof(buffer_t));
// ------------------------ Main Loop --------------------------------
- while(1) {
+ while(!HANDLER_QUIT_FLAG) {
+ locked = 0;
+
+ buffer_init(command_buf, 0, NULL);
+ buffer_init(result_buf, 0, NULL);
vtpmhandlerloginfo(VTPM_LOG_VTPM, "%s waiting for messages.\n",
thread_name);
@@ -106,7 +100,9 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
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);
+ if (!IPC_QUIT_FLAG) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "%s can't read from ipc. Errono
= %d. Aborting... \n", thread_name, errno);
+ }
goto abort_command;
}
@@ -155,6 +151,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Failed to setup buffers.
Aborting...\n");
goto abort_command;
}
+ result_buf->is_owner = TRUE;
// -------------- Dispatch Commands to Handlers -----------
if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK)) {
@@ -162,6 +159,7 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
} else {
vtpm_lock_rdlock();
}
+ locked = 1;
if ( !(dmi_res = (VTPM_DMI_RESOURCE *)
hashtable_search(vtpm_globals->dmi_map, &dmi)) ||
(!dmi_res->connected) ) {
@@ -174,10 +172,22 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
if (tag == VTPM_TAG_REQ) {
status = vtpm_manager_handle_vtpm_cmd(dmi_res, ord, command_buf,
result_buf, is_priv, thread_name);
+ result_buf->is_owner = TRUE;
} else { // This is not a VTPM Command at all.
if (fw_tpm) {
+#ifdef VTPM_STUBDOM
+ /* In stubdom mode, we allow the vtpm domains to send raw tpm
commands down the pipe
+ * They can also just embed their tpm commands inside VTPM commands
if they wish to*/
+
+ /* Stick the header back onto the raw command (minus the dmiid) */
+ buffer_prepend_raw(command_buf, VTPM_COMMAND_HEADER_SIZE_CLT,
cmd_header + sizeof(UINT32));
+ status = VTPM_Handle_TPM_Command(dmi_res, command_buf, result_buf);
+#else
+ /* In normal mode, this is used for the guest to forward a raw
command to the vtpm process */
status = vtpm_manager_handle_tpm_cmd(fw_tx_ipc_h, fw_rx_ipc_h,
dmi_res, cmd_header, command_buf, result_buf, thread_name);
+#endif
+ result_buf->is_owner = TRUE;
// 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
@@ -207,36 +217,42 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
// ------------------- 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
+abort_with_error:
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;
+ out_header = (BYTE *) malloc (VTPM_COMMAND_HEADER_SIZE_SRV);
- BSG_PackList(out_message, 4,
+ BSG_PackList(out_header, 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
+ buffer_prepend_raw(result_buf, VTPM_COMMAND_HEADER_SIZE_SRV,
out_header);
+ free(out_header);
} else {
- reply = result_buf->bytes;
- reply_size = buffer_len(result_buf);
+#ifdef VTPM_STUBDOM
+ //In stubdom mode, we need to always prepend the dmiid so the
raw command can be returned to the right domain
+ out_header = (BYTE*) malloc(sizeof(UINT32));
+ BSG_PackList(out_header, 1,
+ BSG_TYPE_UINT32, (BYTE*) &dmi);
+ buffer_prepend_raw(result_buf, sizeof(UINT32), out_header);
+ free(out_header);
+#endif
}
+ reply = result_buf->bytes;
+ reply_size = buffer_len(result_buf);
+#ifndef VTPM_STUBDOM
size_write = vtpm_ipc_write(tx_ipc_h, (dmi_res ?
dmi_res->tx_vtpm_ipc_h : NULL), reply, reply_size );
+#else
+ if(reply_size >= 4096) {
+ vtpmhandlerlogerror(VTPM_LOG_VTPM, "MESSAGE TOO BIG!!!");
+ }
+ size_write = vtpm_ipc_write(tx_ipc_h, NULL, reply, reply_size );
+#endif
if (size_write > 0) {
vtpmhandlerloginfo(VTPM_LOG_VTPM_DEEP, "SENT: 0x");
for (i=0; i < reply_size; i++)
@@ -247,7 +263,6 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
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);
@@ -264,14 +279,22 @@ TPM_RESULT VTPM_Manager_Handler( vtpm_ipc_handle_t
*tx_ipc_h,
buffer_free(command_buf);
// If we have a write lock, save the manager table
- if ((tag == VTPM_TAG_REQ) && (ord & VTPM_PRIV_MASK) &&
+ if (locked && (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();
+ if(locked) {
+ vtpm_lock_unlock();
+ }
add_header = TRUE; // Reset to the default
} // End while(1)
+
+ free(cmd_header);
+ free(command_buf);
+ free(result_buf);
+
+ vtpmhandlerloginfo(VTPM_LOG_VTPM, "exiting\n", thread_name);
}
@@ -313,6 +336,16 @@ TPM_RESULT
vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
status = VTPM_Handle_Load_Migration_key(command_buf,
result_buf);
break;
+ case VTPM_ORD_SAVEHASHKEY:
+ status = VTPM_Handle_Save_HashKey(dmi_res,
+ command_buf,
+ result_buf);
+ break;
+ case VTPM_ORD_LOADHASHKEY:
+ status = VTPM_Handle_Load_HashKey(dmi_res,
+ command_buf,
+ result_buf);
+ break;
default:
// Privileged handlers can do maintanance
@@ -350,6 +383,7 @@ TPM_RESULT
vtpm_manager_handle_vtpm_cmd(VTPM_DMI_RESOURCE *dmi_res,
return(status);
}
+#ifndef VTPM_STUBDOM
/////////////////////////////////////////////////////////////////////
TPM_RESULT vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
vtpm_ipc_handle_t *rx_ipc_h,
@@ -485,4 +519,5 @@ TPM_RESULT
vtpm_manager_handle_tpm_cmd(vtpm_ipc_handle_t *tx_ipc_h,
return status;
}
+#endif
diff --git a/tools/vtpm_manager/manager/vtpm_manager_handler.h
b/tools/vtpm_manager/manager/vtpm_manager_handler.h
--- /dev/null
+++ b/tools/vtpm_manager/manager/vtpm_manager_handler.h
@@ -0,0 +1,21 @@
+#ifndef VTPM_MANAGER_HANDLER_H
+#define VTPM_MANAGER_HANDLER_H
+// ---------------------- 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);
+
+#ifndef VTPM_STUBDOM
+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);
+#endif
+
+#endif
diff --git a/tools/vtpm_manager/manager/vtpmd.c
b/tools/vtpm_manager/manager/vtpmd.c
--- a/tools/vtpm_manager/manager/vtpmd.c
+++ b/tools/vtpm_manager/manager/vtpmd.c
@@ -45,27 +45,13 @@
#include <signal.h>
#include <string.h>
#include <pthread.h>
+#include <stdlib.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;
@@ -76,180 +62,46 @@ struct vtpm_thread_params_s {
char *thread_name;
};
+static pthread_t master_thread;
+static pthread_t be_thread;
+static pthread_t hp_thread;
+#ifndef VTPM_STUBDOM
+static pthread_t dmi_thread;
+#endif
+
+
+#ifndef VTPM_STUBDOM
// 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;
+extern vtpm_ipc_handle_t *g_rx_tpm_ipc_h;
+#endif
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,
+ 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);
+ return NULL;
}
-
-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);
+void signal_handler(int signal) {
+ if (pthread_equal(pthread_self(), master_thread)) {
+ vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down for signal
%s(%d). Please wait..\n", strsignal(signal), signal);
+ HANDLER_QUIT_FLAG = IPC_QUIT_FLAG = 1;
}
-
- 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;
+ vtpm_ipc_handle_t *tx_be_ipc_h, *rx_be_ipc_h, tx_hp_ipc_h, rx_hp_ipc_h;
+ struct vtpm_thread_params_s be_thread_params, hp_thread_params;
+#ifndef VTPM_STUBDOM
+ vtpm_ipc_handle_t rx_tpm_ipc_h, rx_vtpm_ipc_h;
+ struct vtpm_thread_params_s dmi_thread_params;
+#endif
#ifdef DUMMY_BACKEND
vtpm_ipc_handle_t tx_dummy_ipc_h, rx_dummy_ipc_h;
@@ -258,34 +110,28 @@ int main(int argc, char **argv) {
#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)
+ if ((sigaction(SIGINT, &ctl_c_handler, NULL) == -1)
+ || (sigaction(SIGQUIT, &ctl_c_handler, NULL) == -1)
+ || (sigaction(SIGHUP, &ctl_c_handler, NULL) == -1) ) // For easier
debugging with gdb
+ {
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");
-
+ //Block all signals for child threads
sigset_t sig_mask;
- sigemptyset(&sig_mask);
- sigaddset(&sig_mask, SIGPIPE);
- sigprocmask(SIG_BLOCK, &sig_mask, NULL);
+ sigfillset(&sig_mask);
+ pthread_sigmask(SIG_SETMASK, &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) ) {
+ if ( (vtpm_ipc_init(&tx_dummy_ipc_h, VTPM_DUMMY_TX_BE_FNAME, O_RDWR,
TRUE, FALSE) != 0) ||
+ (vtpm_ipc_init(&rx_dummy_ipc_h, VTPM_DUMMY_RX_BE_FNAME, O_RDWR,
TRUE, FALSE) != 0) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to create Dummy BE FIFOs.\n");
exit(-1);
@@ -294,21 +140,29 @@ int main(int argc, char **argv) {
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);
+ if(vtpm_ipc_init(&real_be_ipc_h, VTPM_BE_FNAME, O_RDWR, FALSE, TRUE)
!= 0) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Unable to open backend device "
VTPM_BE_FNAME "\n");
+ exit(-1);
+ }
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) ) {
+ if (
+#ifndef VTPM_STUBDOM
+ (vtpm_ipc_init(&rx_tpm_ipc_h, VTPM_RX_TPM_FNAME, O_RDONLY, TRUE,
FALSE) != 0) ||
+ (vtpm_ipc_init(&rx_vtpm_ipc_h, VTPM_RX_VTPM_FNAME, O_RDWR, TRUE,
FALSE) != 0) || //FIXME: O_RDONLY?
+#endif
+ (vtpm_ipc_init(&tx_hp_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE,
TRUE) != 0) ||
+ (vtpm_ipc_init(&rx_hp_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE,
TRUE) != 0) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to create initial FIFOs.\n");
exit(-1);
}
+#ifndef VTPM_STUBDOM
g_rx_tpm_ipc_h = &rx_tpm_ipc_h;
+#endif
// -------------------- Set up thread params -------------
@@ -316,10 +170,15 @@ int main(int argc, char **argv) {
be_thread_params.rx_ipc_h = rx_be_ipc_h;
be_thread_params.fw_tpm = TRUE;
be_thread_params.fw_tx_ipc_h = NULL;
+#ifndef VTPM_STUBDOM
be_thread_params.fw_rx_ipc_h = &rx_tpm_ipc_h;
+#else
+ be_thread_params.fw_rx_ipc_h = NULL;
+#endif
be_thread_params.is_priv = FALSE;
be_thread_params.thread_name = "Backend Listener";
+#ifndef VTPM_STUBDOM
dmi_thread_params.tx_ipc_h = NULL;
dmi_thread_params.rx_ipc_h = &rx_vtpm_ipc_h;
dmi_thread_params.fw_tpm = FALSE;
@@ -327,6 +186,7 @@ int main(int argc, char **argv) {
dmi_thread_params.fw_rx_ipc_h = NULL;
dmi_thread_params.is_priv = FALSE;
dmi_thread_params.thread_name = "VTPM Listener";
+#endif
hp_thread_params.tx_ipc_h = &tx_hp_ipc_h;
hp_thread_params.rx_ipc_h = &rx_hp_ipc_h;
@@ -336,34 +196,50 @@ int main(int argc, char **argv) {
hp_thread_params.is_priv = TRUE;
hp_thread_params.thread_name = "Hotplug Listener";
+ // -------------------- Initialize Manager -----------------
+ if (VTPM_Init_Manager() != TPM_SUCCESS) {
+ vtpmlogerror(VTPM_LOG_VTPM, "Closing vtpmd due to error during
startup.\n");
+ return -1;
+ }
+
+
// --------------------- Launch Threads -----------------
vtpm_lock_init();
- vtpm_globals->master_pid = pthread_self();
+ master_thread = 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);
}
+#ifndef VTPM_STUBDOM
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);
}
-
+#endif
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);
}
+ //Turn signals back on for the master thread only
+ sigemptyset(&sig_mask);
+ sigaddset(&sig_mask, SIGPIPE);
+ pthread_sigmask(SIG_SETMASK, &sig_mask, NULL);
+
//Join the other threads until exit time.
pthread_join(be_thread, NULL);
+#ifndef VTPM_STUBDOM
pthread_join(dmi_thread, NULL);
+#endif
pthread_join(hp_thread, NULL);
- vtpmlogerror(VTPM_LOG_VTPM, "VTPM Manager shut down unexpectedly.\n");
+ vtpmloginfo(VTPM_LOG_VTPM, "VTPM Manager shutting down...\n");
VTPM_Stop_Manager();
vtpm_lock_destroy();
diff --git a/tools/vtpm_manager/manager/vtpmpriv.h
b/tools/vtpm_manager/manager/vtpmpriv.h
--- a/tools/vtpm_manager/manager/vtpmpriv.h
+++ b/tools/vtpm_manager/manager/vtpmpriv.h
@@ -40,6 +40,8 @@
#ifndef __VTPMPRIV_H__
#define __VTPMPRIV_H__
+#include <signal.h>
+
#include "vtpm_manager.h"
#include "tcg.h"
#include "tcs.h"
@@ -54,16 +56,19 @@
#define DMI_NVM_FILE "/var/vtpm/vtpm_dm_%d.data"
#define VTPM_CTL_DM 0
+extern volatile sig_atomic_t HANDLER_QUIT_FLAG;
+
// ------------------------ Private Structures -----------------------
typedef struct VTPM_DMI_RESOURCE_T {
+#ifndef VTPM_STUBDOM
// 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
+
+ pid_t dmi_pid;
-#ifndef VTPM_MULTI_VM
- pid_t dmi_pid;
#endif
// Non-persistent Information
@@ -77,6 +82,9 @@ typedef struct VTPM_DMI_RESOURCE_T {
BYTE dmi_type;
TPM_DIGEST NVM_measurement; // Equal to the SHA1 of the blob
TPM_DIGEST DMI_measurement; // Correct measurement of the
owning DMI
+
+ char* uuid;
+
} VTPM_DMI_RESOURCE;
typedef struct tdVTPM_MIGKEY_LIST {
@@ -89,10 +97,6 @@ typedef struct tdVTPM_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 #
@@ -123,8 +127,8 @@ 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_Init_Manager(void); // Start VTPM Service
+void VTPM_Stop_Manager(void); // 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
@@ -143,6 +147,11 @@ TPM_RESULT VTPM_Handle_Save_NVM(
VTPM_DMI_RESOURCE *myDMI,
const buffer_t *inbuf,
buffer_t *outbuf);
+TPM_RESULT VTPM_Handle_Get_NVM_Size( 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);
@@ -173,6 +182,9 @@ TPM_RESULT VTPM_Close_DMI_Extra(VTPM_DMI_RESOURCE
*dmi_res);
TPM_RESULT close_dmi(VTPM_DMI_RESOURCE *dmi_res);
TPM_RESULT init_dmi(UINT32 dmi_id, BYTE type, VTPM_DMI_RESOURCE
**dmi_res);
+/* Free's dmi_res and all of it's resources */
+void free_dmi(VTPM_DMI_RESOURCE *dmi_res);
+
TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
CRYPTO_INFO *asymkey,
buffer_t *sealed_data);
@@ -183,4 +195,14 @@ TPM_RESULT envelope_decrypt(const buffer_t *cipher,
const TPM_AUTHDATA *key_usage_auth,
buffer_t *unsealed_data);
+TPM_RESULT symkey_encrypt(const buffer_t *inbuf,
+ CRYPTO_INFO *asymkey,
+ buffer_t *sealed_key);
+
+TPM_RESULT symkey_decrypt(const buffer_t *cipher,
+ TCS_CONTEXT_HANDLE TCSContext,
+ TPM_HANDLE keyHandle,
+ const TPM_AUTHDATA *key_usage_auth,
+ buffer_t *symkey_clear);
+
#endif // __VTPMPRIV_H__
diff --git a/tools/vtpm_manager/manager/vtsp.c
b/tools/vtpm_manager/manager/vtsp.c
--- a/tools/vtpm_manager/manager/vtsp.c
+++ b/tools/vtpm_manager/manager/vtsp.c
@@ -38,6 +38,7 @@
// ==================================================================
#include <string.h>
+#include <stdlib.h>
#include "tcg.h"
#include "tcs.h"
#include "bsg.h"
@@ -312,7 +313,7 @@ TPM_RESULT VTSP_TakeOwnership( const
TCS_CONTEXT_HANDLE hContext,
TPM_PROTOCOL_ID proto_id = TPM_PID_OWNER;
BYTE *new_srk;
- BYTE *paramText; // Digest to make Auth.
+ BYTE *paramText = NULL; // Digest to make Auth.
UINT32 paramTextSize;
// vars for srkpubkey parameter
@@ -458,7 +459,7 @@ TPM_RESULT VTSP_CreateWrapKey( const
TCS_CONTEXT_HANDLE hContext,
vtpmloginfo(VTPM_LOG_VTSP, "Creating new key of type %d.\n", usage);
// vars for Calculate encUsageAuth
- BYTE *paramText;
+ BYTE *paramText = NULL;
UINT32 paramTextSize;
// vars for Calculate encUsageAuth
@@ -567,8 +568,7 @@ TPM_RESULT VTSP_CreateWrapKey( const
TCS_CONTEXT_HANDLE hContext,
osapSharedSecret, auth, 0) );
// Unpack/return key structure
- TPMTRYRETURN(buffer_init(pubKeyBuf, 0, 0) );
- TPMTRYRETURN(buffer_append_raw(pubKeyBuf, newKeyText.size,
newKeyText.data) );
+ TPMTRYRETURN(buffer_init(pubKeyBuf, newKeyText.size, newKeyText.data) );
goto egress;
@@ -664,6 +664,7 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE
hContext,
// Destroy rsaKeyParms
BSG_Destroy(BSG_TPM_RSA_KEY_PARMS, &rsaKeyParms);
+ BSG_Destroy(BSG_TPM_KEY, &newKey);
// Set encryption scheme
cryptoinfo->encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
@@ -733,8 +734,7 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE
hContext,
hContext) );
// Unpack/return key structure
- TPMTRYRETURN(buffer_init(clear_data, 0, 0));
- TPMTRYRETURN(buffer_append_raw (clear_data, clear_data_size,
clear_data_text) );
+ TPMTRYRETURN(buffer_init(clear_data, clear_data_size, clear_data_text) );
goto egress;
@@ -793,8 +793,7 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
vtpmlogerror(VTPM_LOG_VTSP, "Enc buffer just overflowed.\n");
}
- buffer_init(outData, 0, NULL);
- buffer_append_raw(outData, out_tmp_size, out_tmp);
+ buffer_init(outData, out_tmp_size, out_tmp);
vtpmloginfo(VTPM_LOG_TXDATA, "Bind Generated[%d] = 0x", out_tmp_size);
for(i = 0 ; i < out_tmp_size ; i++) {
@@ -1005,8 +1004,6 @@ TPM_RESULT VTSP_SaveState( const
TCS_CONTEXT_HANDLE hContext) {
vtpmloginfo(VTPM_LOG_VTSP, "Calling TPM_SaveState.\n");
- TPM_RESULT status = TPM_SUCCESS;
-
// Call TCS
return ( TCSP_SaveState ( hContext ) );
diff --git a/tools/vtpm_manager/manager/vtsp.h
b/tools/vtpm_manager/manager/vtsp.h
--- a/tools/vtpm_manager/manager/vtsp.h
+++ b/tools/vtpm_manager/manager/vtsp.h
@@ -42,6 +42,7 @@
#include "tcg.h"
#include "tcs.h"
+#include "crypto.h"
#define KEY_BUFFER_SIZE 2048
diff --git a/tools/vtpm_manager/migration/Makefile
b/tools/vtpm_manager/migration/Makefile
--- a/tools/vtpm_manager/migration/Makefile
+++ b/tools/vtpm_manager/migration/Makefile
@@ -1,5 +1,11 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
VPATH = ../manager
@@ -33,10 +39,10 @@ mrproper: clean
rm -f *~
$(BIND): $(OBJSD)
- $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
$(BINC): $(OBJSC)
- $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
# libraries
LIBS += ../util/libTCGUtils.a
diff --git a/tools/vtpm_manager/migration/vtpm_manager_if.c
b/tools/vtpm_manager/migration/vtpm_manager_if.c
--- a/tools/vtpm_manager/migration/vtpm_manager_if.c
+++ b/tools/vtpm_manager/migration/vtpm_manager_if.c
@@ -50,15 +50,12 @@
#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
+ if ( (vtpm_ipc_init(&tx_ipc_h, VTPM_TX_HP_FNAME, O_RDWR, TRUE, TRUE)
!= 0) || //FIXME: wronly
+ (vtpm_ipc_init(&rx_ipc_h, VTPM_RX_HP_FNAME, O_RDWR, TRUE, TRUE)
!= 0) ) { //FIXME: rdonly
vtpmlogerror(VTPM_LOG_VTPM, "Unable to connect to vtpm_manager.\n");
return TPM_IOERROR;
}
diff --git a/tools/vtpm_manager/tcs/Makefile
b/tools/vtpm_manager/tcs/Makefile
--- a/tools/vtpm_manager/tcs/Makefile
+++ b/tools/vtpm_manager/tcs/Makefile
@@ -1,5 +1,10 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../manager
+
BIN = libTCS.a
diff --git a/tools/vtpm_manager/tcs/contextmgr.c
b/tools/vtpm_manager/tcs/contextmgr.c
--- a/tools/vtpm_manager/tcs/contextmgr.c
+++ b/tools/vtpm_manager/tcs/contextmgr.c
@@ -195,6 +195,7 @@ BOOL DeleteHandleFromList( TCS_CONTEXT_HANDLE
hContext, // in
BOOL FreeHandleList( CONTEXT_HANDLE* pContextHandle) { // in
HANDLE_LIST* pCurrentHandle;
+ HANDLE_LIST* pNext;
BOOL returncode = TRUE;
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Freeing all handles for context\n");
@@ -205,6 +206,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE*
pContextHandle) { // in
pCurrentHandle = pContextHandle->pHandleList;
while (pCurrentHandle != NULL) {
+ pNext = pCurrentHandle->pNextHandle;
switch (pCurrentHandle->type) {
case TPM_RT_KEY:
returncode = returncode && !TCSP_EvictKey(pContextHandle->handle,
pCurrentHandle->handle);
@@ -216,7 +218,7 @@ BOOL FreeHandleList( CONTEXT_HANDLE*
pContextHandle) { // in
returncode = FALSE;
}
- pCurrentHandle = pCurrentHandle->pNextHandle;
+ pCurrentHandle = pNext;
}
diff --git a/tools/vtpm_manager/tcs/tcs.c b/tools/vtpm_manager/tcs/tcs.c
--- a/tools/vtpm_manager/tcs/tcs.c
+++ b/tools/vtpm_manager/tcs/tcs.c
@@ -77,7 +77,7 @@ CONTEXT_HANDLE *LookupContext( TCS_CONTEXT_HANDLE
hContext) {
//
---------------------------------------------------------------------------------
// Initialization/Uninitialization SubComponent API
//
---------------------------------------------------------------------------------
-TPM_RESULT TCS_create() {
+TPM_RESULT TCS_create(void) {
TDDL_RESULT hRes = TDDL_E_FAIL;
TPM_RESULT result = TPM_FAIL;
@@ -101,7 +101,7 @@ TPM_RESULT TCS_create() {
}
-void TCS_destroy()
+void TCS_destroy(void)
{
TCS_m_nCount--;
@@ -113,14 +113,13 @@ void TCS_destroy()
TCS_CONTEXT_HANDLE *hContext;
// Close all the TCS contexts. TCS should evict keys based on this
- if (hashtable_count(context_ht) > 0) {
+ while (hashtable_count(context_ht) > 0) {
context_itr = hashtable_iterator(context_ht);
- do {
- hContext = (TCS_CONTEXT_HANDLE *)
hashtable_iterator_key(context_itr);
- if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
- vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d
properly.\n", *hContext);
+
+ hContext = (TCS_CONTEXT_HANDLE *)
hashtable_iterator_key(context_itr);
+ if (TCS_CloseContext(*hContext) != TPM_SUCCESS)
+ vtpmlogerror(VTPM_LOG_TCS, "Failed to close context %d
properly.\n", *hContext);
- } while (hashtable_iterator_advance(context_itr));
free(context_itr);
}
hashtable_destroy(context_ht, 1);
@@ -534,6 +533,10 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE
hContext, // in
BSG_TYPE_UINT32, &handle);
// fill paramSize again as we now have the correct size
BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
+
+ if (!DeleteHandleFromList(hContext, handle)) {
+ vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+ }
// call the TPM driver
if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength))
@@ -545,9 +548,6 @@ TPM_RESULT TCSP_TerminateHandle(TCS_CONTEXT_HANDLE
hContext, // in
BSG_TYPE_UINT32, ¶mSize,
BSG_TPM_COMMAND_CODE, &returnCode);
- if (!DeleteHandleFromList(hContext, handle))
- vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
-
if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
// Print debug info
@@ -882,6 +882,7 @@ TPM_RESULT TCSP_CreateWrapKey(TCS_CONTEXT_HANDLE
hContext, // in
memcpy(*prgbKey, tempBuf, *pcKeySize);
+ BSG_Destroy(BSG_TPM_KEY, &wrappedKey);
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n",
paramSize);
} else
vtpmlogerror(VTPM_LOG_TCS, "TCSP_CreateWrapKey Failed with return
code %s\n", tpm_get_error_name(returnCode));
@@ -980,6 +981,10 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE
hContext, // in
BSG_Pack(BSG_TYPE_UINT32, &InLength, InBuf+2);
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Sending paramSize = %d\n", InLength);
+
+ if (!DeleteHandleFromList(hContext, hKey)) {
+ vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
+ }
// call the TPM driver
if ((hRes = TDDL_TransmitData(InBuf, InLength, OutBuf, &OutLength))
== TDDL_SUCCESS) {
@@ -989,10 +994,6 @@ TPM_RESULT TCSP_EvictKey(TCS_CONTEXT_HANDLE
hContext, // in
BSG_TYPE_UINT32, ¶mSize,
BSG_TPM_COMMAND_CODE, &returnCode);
- if (!DeleteHandleFromList(hContext, hKey)) {
- vtpmlogerror(VTPM_LOG_TCS, "KeyHandle not removed from list\n");
- }
-
if (returnCode == TPM_SUCCESS && tag == TPM_TAG_RSP_COMMAND) {
vtpmloginfo(VTPM_LOG_TCS_DEEP, "Received paramSize : %d\n",
paramSize);
} else {
@@ -1019,7 +1020,7 @@ TPM_RESULT TCSP_GetRandom(TCS_CONTEXT_HANDLE
hContext, // in
TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
// check input params
- if (bytesRequested == NULL || *randomBytes == NULL){
+ if (bytesRequested == NULL || randomBytes == NULL){
return TPM_BAD_PARAMETER;
}
diff --git a/tools/vtpm_manager/tcs/tcs.h b/tools/vtpm_manager/tcs/tcs.h
--- a/tools/vtpm_manager/tcs/tcs.h
+++ b/tools/vtpm_manager/tcs/tcs.h
@@ -50,8 +50,8 @@
// Exposed API
// ------------------------------------------------------------------
-TPM_RESULT TCS_create();
-void TCS_destroy();
+TPM_RESULT TCS_create(void);
+void TCS_destroy(void);
TPM_RESULT TCS_OpenContext( /* OUT */ TCS_CONTEXT_HANDLE* hContext );
diff --git a/tools/vtpm_manager/tcs/tpmddl.c
b/tools/vtpm_manager/tcs/tpmddl.c
--- /dev/null
+++ b/tools/vtpm_manager/tcs/tpmddl.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense. All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include <string.h>
+#include "tpmddl.h"
+#include "tcs.h"
+#include "bsg.h"
+#include "log.h"
+
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+
+TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
+ TDDL_UINT32 sub,
+ TDDL_BYTE* buffer,
+ TDDL_UINT32* size)
+{
+ TDDL_RESULT status;
+
+ TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+ UINT32 paramsize = 22;
+ UINT32 outsize;
+ TPM_COMMAND_CODE ord = TPM_ORD_GetCapability;
+ UINT32 subcapsize = 4;
+
+ BYTE inbuf[TCPA_MAX_BUFFER_LENGTH];
+ BYTE outbuf[TCPA_MAX_BUFFER_LENGTH];
+
+ int offset;
+
+ BSG_PackList(inbuf, 6,
+ BSG_TPM_TAG, &(tag),
+ BSG_TYPE_UINT32, &(paramsize),
+ BSG_TPM_COMMAND_CODE, &(ord),
+ BSG_TYPE_UINT32, &(cap),
+ BSG_TYPE_UINT32, &(subcapsize),
+ BSG_TYPE_UINT32, &(sub)
+ );
+
+ //Send the command, get the response
+ TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize));
+
+ offset = BSG_UnpackList(outbuf, 4,
+ BSG_TPM_TAG, &(tag),
+ BSG_TYPE_UINT32, &(paramsize),
+ BSG_TPM_RESULT, &(status),
+ BSG_TYPE_UINT32, size
+ );
+ if (status != TPM_SUCCESS || tag != TPM_TAG_RSP_COMMAND) {
+ return status;
+ }
+ if(*size >= TCPA_MAX_BUFFER_LENGTH - offset) {
+ return TPM_FAIL;
+ }
+ memcpy(buffer, outbuf + offset, *size);
+
+abort_egress:
+ return status;
+}
+
+TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle, TDDL_UINT32 res) {
+ /* FIXME: Add code here to check if TPM_FlushSpecific is not
supported (on 1.1 only TPMS?)
+ * If this is the case then we need to use TPM_EvictKey for key handles
+ * and TPM_Terminate_Handle/TPM_Reset for auth handles */
+ TDDL_RESULT status;
+
+ TPM_TAG tag = TPM_TAG_RQU_COMMAND;
+ UINT32 paramsize = 18;
+ TPM_COMMAND_CODE ord = TPM_ORD_FlushSpecific;
+
+ BYTE inbuf[TCPA_MAX_BUFFER_LENGTH];
+ BYTE outbuf[TCPA_MAX_BUFFER_LENGTH];
+ UINT32 outsize;
+
+ int offset;
+
+ BSG_PackList(inbuf, 5,
+ BSG_TPM_TAG, &(tag),
+ BSG_TYPE_UINT32, &(paramsize),
+ BSG_TPM_COMMAND_CODE, &(ord),
+ BSG_TPM_HANDLE, &(handle),
+ BSG_TPM_RESOURCE_TYPE, &(res)
+ );
+
+ //Send command
+ TPMTRYRETURN(TDDL_TransmitData( inbuf, paramsize, outbuf, &outsize ));
+
+ offset = BSG_UnpackList(outbuf, 4,
+ BSG_TPM_TAG, &(tag),
+ BSG_TYPE_UINT32, &(paramsize),
+ BSG_TPM_RESULT, &(status)
+ );
+
+abort_egress:
+ return status;
+
+}
+
+TDDL_RESULT TDDL_FlushAllResources(void) {
+ TDDL_RESULT status = TPM_SUCCESS;
+
+ TDDL_BYTE buf[TCPA_MAX_BUFFER_LENGTH];
+ TDDL_UINT32 bufsiz;
+
+ UINT16 packedsz;
+ int size;
+ UINT32 handle;
+ BYTE* ptr;
+
+ int i, j;
+
+#define RLISTSZ 6
+ TPM_RESOURCE_TYPE reslist[RLISTSZ] = { TPM_RT_KEY, TPM_RT_AUTH,
TPM_RT_TRANS, TPM_RT_COUNTER, TPM_RT_DAA_TPM, TPM_RT_CONTEXT };
+
+ //Iterate through each resource type and flush all handles
+ for(i = 0; i < RLISTSZ; ++i) {
+ TPM_RESOURCE_TYPE res = reslist[i];
+ // Get list of current key handles
+ if((status = TDDL_GetCapability( TPM_CAP_HANDLE, res, buf,
&bufsiz)) != TPM_SUCCESS) {
+ //This can happen if the resource type is not supported
+ //If this happens just silently skip the resource type
+ if(status == TPM_BAD_MODE) {
+ status = TPM_SUCCESS;
+ continue;
+ //Otherwise we just fail
+ } else {
+ TPMTRYRETURN(status);
+ }
+ }
+
+#if 0
+ //DEBUG PRINTOUTS
+ printf("TPM_GetCapability(TPM_CAP_HANDLE, %lu)\n", (unsigned long)
res);
+ for(j = 0; j < bufsiz; ++j) {
+ printf("%02X ", buf[j]);
+ }
+ printf("\n");
+#endif
+
+ ptr = buf;
+ ptr += BSG_Unpack(BSG_TYPE_UINT16, ptr, &(packedsz));
+ size = packedsz;
+
+ //Flush each handle
+ if(size) {
+ vtpmloginfo(VTPM_LOG_VTPM, "Flushing %u handle(s) of type %lu\n",
size, (unsigned long) res);
+ for(j = 0; j < size; ++j) {
+ ptr += BSG_Unpack(BSG_TPM_HANDLE, ptr, &(handle));
+ TPMTRYRETURN(TDDL_FlushSpecific(handle, res));
+ }
+ }
+
+ }
+
+ goto egress;
+abort_egress:
+egress:
+ return status;
+}
diff --git a/tools/vtpm_manager/tcs/tpmddl.h
b/tools/vtpm_manager/tcs/tpmddl.h
--- a/tools/vtpm_manager/tcs/tpmddl.h
+++ b/tools/vtpm_manager/tcs/tpmddl.h
@@ -50,13 +50,14 @@ 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_Open(void);
+TDDL_RESULT TDDL_Open_use_fd(int fd);
+void TDDL_Close(void);
TDDL_RESULT TDDL_TransmitData( TDDL_BYTE* in,
TDDL_UINT32 insize,
TDDL_BYTE* out,
TDDL_UINT32* outsize);
-TDDL_RESULT TDDL_GetStatus();
+TDDL_RESULT TDDL_GetStatus(void);
TDDL_RESULT TDDL_GetCapability( TDDL_UINT32 cap,
TDDL_UINT32 sub,
TDDL_BYTE* buffer,
@@ -66,4 +67,10 @@ TDDL_RESULT TDDL_SetCapability( TDDL_UINT32 cap,
TDDL_BYTE* buffer,
TDDL_UINT32* size);
+TDDL_RESULT TDDL_FlushSpecific(TDDL_UINT32 handle,
+ TDDL_UINT32 res);
+
+TDDL_RESULT TDDL_FlushAllResources(void);
+
+
#endif // __TPMDDL_H__
diff --git a/tools/vtpm_manager/tcs/transmit.c
b/tools/vtpm_manager/tcs/transmit.c
--- a/tools/vtpm_manager/tcs/transmit.c
+++ b/tools/vtpm_manager/tcs/transmit.c
@@ -104,12 +104,13 @@ TDDL_TransmitData( TDDL_BYTE* in,
return status;
}
-TPM_RESULT TDDL_Open() {
+TDDL_RESULT TDDL_Open(void) {
TDDL_RESULT status = TDDL_SUCCESS;
+ /* If tpm device is already open just silently return success */
if (g_TDDL_open)
- return TPM_FAIL;
+ return TPM_SUCCESS;
#ifdef DUMMY_TPM
*g_rx_fdp = open (TPM_RX_FNAME, O_RDWR);
@@ -117,7 +118,7 @@ TPM_RESULT TDDL_Open() {
g_tx_fd = open (TPM_TX_FNAME, O_RDWR);
if (g_tx_fd < 0) {
- vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed");
+ vtpmlogerror(VTPM_LOG_TXDATA, "TPM open failed\n");
return TPM_IOERROR;
}
@@ -126,7 +127,20 @@ TPM_RESULT TDDL_Open() {
return status;
}
-void TDDL_Close() {
+TDDL_RESULT TDDL_Open_use_fd(int fd) {
+ TDDL_RESULT status = TDDL_SUCCESS;
+
+ if(g_TDDL_open)
+ return TPM_FAIL;
+
+ g_tx_fd = fd;
+
+ g_TDDL_open = 1;
+
+ return status;
+}
+
+void TDDL_Close(void) {
if (! g_TDDL_open)
return;
diff --git a/tools/vtpm_manager/util/Makefile
b/tools/vtpm_manager/util/Makefile
--- a/tools/vtpm_manager/util/Makefile
+++ b/tools/vtpm_manager/util/Makefile
@@ -1,5 +1,10 @@
-XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+CFLAGS += -I../crypto
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
BIN = libTCGUtils.a
diff --git a/tools/vtpm_manager/util/bsg.c b/tools/vtpm_manager/util/bsg.c
--- a/tools/vtpm_manager/util/bsg.c
+++ b/tools/vtpm_manager/util/bsg.c
@@ -41,6 +41,7 @@
#include <string.h>
#include <stdarg.h>
#include <malloc.h>
+#include <stdlib.h>
#include "tcg.h"
#include "crypto.h"
#include "bsg.h"
@@ -317,7 +318,7 @@ static const BSG_Format* find_format (BSG_Type t) {
// 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 ()
+BOOL BSG_static_selfcheck (void)
{
int i;
diff --git a/tools/vtpm_manager/util/bsg.h b/tools/vtpm_manager/util/bsg.h
--- a/tools/vtpm_manager/util/bsg.h
+++ b/tools/vtpm_manager/util/bsg.h
@@ -161,6 +161,6 @@ 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 ();
+BOOL BSG_static_selfcheck (void);
#endif
diff --git a/tools/vtpm_manager/util/buffer.c
b/tools/vtpm_manager/util/buffer.c
--- a/tools/vtpm_manager/util/buffer.c
+++ b/tools/vtpm_manager/util/buffer.c
@@ -40,6 +40,7 @@
#include "tcg.h"
#include "bsg.h"
+#include "log.h"
#include "buffer.h"
static TPM_RESULT buffer_priv_realloc (buffer_t * buf, tpm_size_t newsize);
@@ -51,6 +52,7 @@ static TPM_RESULT buffer_priv_realloc (buffer_t * buf,
tpm_size_t newsize);
TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t initsize, const
BYTE* initval) {
if (initsize == 0) {
memset(buf, 0, sizeof(*buf));
+ buf->bytes = NULL;
return TPM_SUCCESS;
}
@@ -62,8 +64,11 @@ TPM_RESULT buffer_init (buffer_t * buf, tpm_size_t
initsize, const BYTE* initval
buf->size = initsize;
buf->alloc_size = initsize;
- if (initval)
+ if (initval) {
memcpy (buf->bytes, initval, initsize);
+ } else {
+ memset(buf->bytes, 0, initsize);
+ }
buf->is_owner = TRUE;
@@ -190,6 +195,29 @@ TPM_RESULT buffer_append_raw (buffer_t * buf,
tpm_size_t len, const BYTE* bytes)
return status;
}
+TPM_RESULT buffer_prepend_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) );
+ }
+
+ if(buf->size > 0) {
+ memmove(buf->bytes + len, buf->bytes, buf->size);
+ }
+ memcpy(buf->bytes, bytes, len);
+
+ buf->size += len;
+
+ goto egress;
+
+ abort_egress:
+
+ egress:
+
+ return status;
+}
+
tpm_size_t buffer_len (const buffer_t* buf) {
return buf->size;
}
@@ -199,7 +227,6 @@ TPM_RESULT buffer_free (buffer_t * buf) {
free (buf->bytes);
buf->bytes = NULL;
buf->size = buf->alloc_size = 0;
-
}
return TPM_SUCCESS;
@@ -224,3 +251,13 @@ TPM_RESULT buffer_priv_realloc (buffer_t * buf,
tpm_size_t newsize) {
return TPM_SUCCESS;
}
+
+TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len)
+{
+ if(len <= buf->size) {
+ buf->size = len;
+ return TPM_SUCCESS;
+ }
+
+ return TPM_FAIL;
+}
diff --git a/tools/vtpm_manager/util/buffer.h
b/tools/vtpm_manager/util/buffer.h
--- a/tools/vtpm_manager/util/buffer.h
+++ b/tools/vtpm_manager/util/buffer.h
@@ -92,4 +92,9 @@ TPM_RESULT buffer_free (buffer_t * buf);
TPM_RESULT buffer_append_raw (buffer_t * buf, tpm_size_t len, const
BYTE* bytes);
+TPM_RESULT buffer_prepend_raw(buffer_t * buf, tpm_size_t len, const
BYTE* bytes);
+
+//Reduce the size of the buffer, if len > buffer size returns an error
+TPM_RESULT buffer_truncate(buffer_t* buf, tpm_size_t len);
+
#endif // _TOOLS_H_
diff --git a/tools/vtpm_manager/util/hashtable.c
b/tools/vtpm_manager/util/hashtable.c
--- a/tools/vtpm_manager/util/hashtable.c
+++ b/tools/vtpm_manager/util/hashtable.c
@@ -32,12 +32,6 @@
* 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>
diff --git a/tools/vtpm_manager/util/hashtable.h
b/tools/vtpm_manager/util/hashtable.h
--- a/tools/vtpm_manager/util/hashtable.h
+++ b/tools/vtpm_manager/util/hashtable.h
@@ -32,11 +32,6 @@
* 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__
diff --git a/tools/vtpm_manager/util/hashtable_itr.c
b/tools/vtpm_manager/util/hashtable_itr.c
--- a/tools/vtpm_manager/util/hashtable_itr.c
+++ b/tools/vtpm_manager/util/hashtable_itr.c
@@ -32,11 +32,6 @@
* 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"
diff --git a/tools/vtpm_manager/util/hashtable_itr.h
b/tools/vtpm_manager/util/hashtable_itr.h
--- a/tools/vtpm_manager/util/hashtable_itr.h
+++ b/tools/vtpm_manager/util/hashtable_itr.h
@@ -32,11 +32,6 @@
* 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__
diff --git a/tools/vtpm_manager/util/hashtable_private.h
b/tools/vtpm_manager/util/hashtable_private.h
--- a/tools/vtpm_manager/util/hashtable_private.h
+++ b/tools/vtpm_manager/util/hashtable_private.h
@@ -32,12 +32,6 @@
* 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__
diff --git a/tools/vtpm_manager/util/log.c b/tools/vtpm_manager/util/log.c
--- a/tools/vtpm_manager/util/log.c
+++ b/tools/vtpm_manager/util/log.c
@@ -38,6 +38,17 @@
#include "buffer.h"
#include "tcg.h"
+char *module_names[] = { "",
+ "CRYPTO",
+ "BSG",
+ "TXDATA",
+ "TCS",
+ "TCS",
+ "VTSP",
+ "VTPM",
+ "VTPM",
+ "VTSP"
+ };
// Helper code for the consts, eg. to produce messages for error codes.
typedef struct error_code_entry_t {
diff --git a/tools/vtpm_manager/util/log.h b/tools/vtpm_manager/util/log.h
--- a/tools/vtpm_manager/util/log.h
+++ b/tools/vtpm_manager/util/log.h
@@ -36,6 +36,8 @@
#include <stdint.h> // for uint32_t
#include <stddef.h> // for pointer NULL
+#include <stdio.h>
+#include <tcg.h>
// =========================== LOGGING ==============================
@@ -50,17 +52,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"
- };
+extern char *module_names[];
// Default to standard logging
#ifndef LOGGING_MODULES
diff --git a/tools/vtpm_manager/util/tcg.h b/tools/vtpm_manager/util/tcg.h
--- a/tools/vtpm_manager/util/tcg.h
+++ b/tools/vtpm_manager/util/tcg.h
@@ -197,6 +197,7 @@ typedef struct pack_buf_t {
UINT32 size;
BYTE * data;
} pack_buf_t;
+#define NULL_PACK_BUF {0,0}
typedef struct pack_constbuf_t {
UINT32 size;
@@ -295,6 +296,35 @@ typedef struct pack_constbuf_t {
#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 TPM_ORD_SaveContext (184UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_LoadContext (185UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_FlushSpecific (186UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_PCR_Reset (200UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_DefineSpace (204UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_WriteValue (205UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_WriteValueAuth (206UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_ReadValue (207UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_NV_ReadValueAuth (208UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_UpdateVerification (209UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_Manage (210UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_CreateKeyDelegation (212UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_CreateOwnerDelegation (213UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_VerifyDelegation (214UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_LoadOwnerDelegation (216UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_ReadAuth (217UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_Delegate_ReadTable (219UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_CreateCounter (220UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_IncrementCounter (221UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReadCounter (222UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseCounter (223UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseCounterOwner (224UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_EstablishTransport (230UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ExecuteTransport (231UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_ReleaseTransportSigned (232UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_GetTicks (241UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_TickStampBlob (242UL +
TPM_PROTECTED_ORDINAL)
+#define TPM_ORD_MAX (256UL +
TPM_PROTECTED_ORDINAL)
+
#define TSC_ORD_PhysicalPresence (10UL + TPM_CONNECTION_ORDINAL)
@@ -419,8 +449,16 @@ typedef struct pack_constbuf_t {
/// TPM_ResourceTypes
#define TPM_RT_KEY 0x00000001
#define TPM_RT_AUTH 0x00000002
+#define TPM_RT_HASH 0x00000003
#define TPM_RT_TRANS 0x00000004
#define TPM_RT_CONTEXT 0x00000005
+#define TPM_RT_COUNTER 0x00000006
+#define TPM_RT_DELEGATE 0x00000007
+#define TPM_RT_DAA_TPM 0x00000008
+#define TPM_RT_DAA_V0 0x00000009
+#define TPM_RT_DAA_V1 0x0000000A
+
+
// TPM_PROTOCOL_ID values
#define TPM_PID_OIAP 0x0001
@@ -447,6 +485,64 @@ typedef struct pack_constbuf_t {
#define TPM_SS_RSASSAPKCS1v15_SHA1 0x0002
#define TPM_SS_RSASSAPKCS1v15_DER 0x0003
+/*
+ * TPM_CAPABILITY_AREA Values for TPM_GetCapability ([TPM_Part2],
Section 21.1)
+ */
+#define TPM_CAP_ORD 0x00000001
+#define TPM_CAP_ALG 0x00000002
+#define TPM_CAP_PID 0x00000003
+#define TPM_CAP_FLAG 0x00000004
+#define TPM_CAP_PROPERTY 0x00000005
+#define TPM_CAP_VERSION 0x00000006
+#define TPM_CAP_KEY_HANDLE 0x00000007
+#define TPM_CAP_CHECK_LOADED 0x00000008
+#define TPM_CAP_SYM_MODE 0x00000009
+#define TPM_CAP_KEY_STATUS 0x0000000C
+#define TPM_CAP_NV_LIST 0x0000000D
+#define TPM_CAP_MFR 0x00000010
+#define TPM_CAP_NV_INDEX 0x00000011
+#define TPM_CAP_TRANS_ALG 0x00000012
+#define TPM_CAP_HANDLE 0x00000014
+#define TPM_CAP_TRANS_ES 0x00000015
+#define TPM_CAP_AUTH_ENCRYPT 0x00000017
+#define TPM_CAP_SELECT_SIZE 0x00000018
+#define TPM_CAP_DA_LOGIC 0x00000019
+#define TPM_CAP_VERSION_VAL 0x0000001A
+
+/* subCap definitions ([TPM_Part2], Section 21.2) */
+#define TPM_CAP_PROP_PCR 0x00000101
+#define TPM_CAP_PROP_DIR 0x00000102
+#define TPM_CAP_PROP_MANUFACTURER 0x00000103
+#define TPM_CAP_PROP_KEYS 0x00000104
+#define TPM_CAP_PROP_MIN_COUNTER 0x00000107
+#define TPM_CAP_FLAG_PERMANENT 0x00000108
+#define TPM_CAP_FLAG_VOLATILE 0x00000109
+#define TPM_CAP_PROP_AUTHSESS 0x0000010A
+#define TPM_CAP_PROP_TRANSESS 0x0000010B
+#define TPM_CAP_PROP_COUNTERS 0x0000010C
+#define TPM_CAP_PROP_MAX_AUTHSESS 0x0000010D
+#define TPM_CAP_PROP_MAX_TRANSESS 0x0000010E
+#define TPM_CAP_PROP_MAX_COUNTERS 0x0000010F
+#define TPM_CAP_PROP_MAX_KEYS 0x00000110
+#define TPM_CAP_PROP_OWNER 0x00000111
+#define TPM_CAP_PROP_CONTEXT 0x00000112
+#define TPM_CAP_PROP_MAX_CONTEXT 0x00000113
+#define TPM_CAP_PROP_FAMILYROWS 0x00000114
+#define TPM_CAP_PROP_TIS_TIMEOUT 0x00000115
+#define TPM_CAP_PROP_STARTUP_EFFECT 0x00000116
+#define TPM_CAP_PROP_DELEGATE_ROW 0x00000117
+#define TPM_CAP_PROP_MAX_DAASESS 0x00000119
+#define TPM_CAP_PROP_DAASESS 0x0000011A
+#define TPM_CAP_PROP_CONTEXT_DIST 0x0000011B
+#define TPM_CAP_PROP_DAA_INTERRUPT 0x0000011C
+#define TPM_CAP_PROP_SESSIONS 0x0000011D
+#define TPM_CAP_PROP_MAX_SESSIONS 0x0000011E
+#define TPM_CAP_PROP_CMK_RESTRICTION 0x0000011F
+#define TPM_CAP_PROP_DURATION 0x00000120
+#define TPM_CAP_PROP_ACTIVE_COUNTER 0x00000122
+#define TPM_CAP_PROP_MAX_NV_AVAILABLE 0x00000123
+#define TPM_CAP_PROP_INPUT_BUFFER 0x00000124
+
// TPM_KEY_USAGE values
#define TPM_KEY_EK 0x0000
#define TPM_KEY_SIGNING 0x0010
diff --git a/tools/vtpm_manager/vtpmconnd/Makefile
b/tools/vtpm_manager/vtpmconnd/Makefile
--- /dev/null
+++ b/tools/vtpm_manager/vtpmconnd/Makefile
@@ -0,0 +1,30 @@
+# Copyright (c) 2010-2012 United States Government, as represented by
+# the Secretary of Defense. All rights reserved.
+#
+# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+# SOFTWARE.
+#
+
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+BIN=vtpmconnd
+OBJS=vtpmconnd.o
+CFLAGS=-O2 -Wall
+
+all: ${BIN}
+
+${BIN}: ${OBJS}
+ gcc -o $@ $<
+
+install: ${BIN}
+ install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN)
+
+.PHONY: mrproper
+mrproper: clean
+clean:
+ -rm ${BIN} ${OBJS}
diff --git a/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
--- /dev/null
+++ b/tools/vtpm_manager/vtpmconnd/vtpmconnd.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense. All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <ctype.h>
+#include "../manager/vtpm_manager.h"
+
+#define VTPM_BE "/dev/vtpm"
+#define TPM_DEV "/dev/tpm0"
+#define MAX_CMD 4096
+#define DEVNULL "/dev/null"
+#define TPM_SUCCESS_RESP "\x00\x00\x00\x00" "\x01\xC1"
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
+#define TPM_SUCCESS_RESPLEN 14
+
+static int quit = 0;
+
+struct Opts {
+ const char* vtpmbe;
+ const char* tpmdev;
+ int verbosity;
+ int daemon;
+};
+
+struct Opts opts = {
+ .vtpmbe = VTPM_BE,
+ .tpmdev = TPM_DEV,
+ .verbosity = 0,
+ .daemon = 1,
+};
+
+void usage(char* argv0) {
+fprintf(stderr, "Usage:\n \
+\t%s [options] [tpm device node]\n\
+\n\
+-h\t\tdisplay usage message\n\
+-v\t\tturn up verbosity level\n\
+-t <FILE>\tuse FILE for tpm device (default " TPM_DEV ")\n\
+-b <FILE>\tset vtpm backend device to FILE (default: " VTPM_BE ")\n\
+-f\t\trun in the foreground\n",
+argv0
+);
+}
+
+void sighandler(int signum) {
+ quit = 1;
+}
+
+int main_loop(int vbefd, int tpmfd) {
+ uint8_t buf[MAX_CMD];
+ ssize_t size, wrote;
+ int i;
+
+ while(!quit) {
+ /* Wait for cmd from vtpm_manager */
+ if((size = read(vbefd, buf, MAX_CMD)) < 0) {
+ if(errno == EFAULT) {
+ if(opts.verbosity > 0) {
+ fprintf(stderr, "read() failed with error: %s, non-fatal\n",
strerror(errno));
+ }
+ continue;
+ }
+ fprintf(stderr,"Error reading from %s, (%s)\n", opts.vtpmbe,
strerror(errno));
+ return 1;
+ }
+ if(opts.verbosity > 0) {
+ printf("\nvtpm_manager req(%ld):", (long) size);
+ for(i = 0; i < size; ++i) {
+ printf(" %02X", buf[i]);
+ }
+ printf("\n");
+ }
+
+ if(quit) {
+ break;
+ }
+
+ /* Forward the cmd to the tpm, exclude the dmi id */
+ if((wrote = write(tpmfd, buf + 4, size - 4)) != size - 4) {
+ fprintf(stderr,"Error writing to %s, (%s)\n", opts.tpmdev,
strerror(errno));
+ return 1;
+ }
+
+ if(quit) {
+ break;
+ }
+
+ /* Wait for response from tpm */
+ if((size = read(tpmfd, buf + 4, MAX_CMD - 4)) < 0) {
+ fprintf(stderr,"Error reading from %s, (%s)\n", opts.tpmdev,
strerror(errno));
+ return 1;
+ }
+ if(opts.verbosity > 0) {
+ printf("tpm resp(%ld):", (long) size);
+ for(i = 0; i < size + 4; ++i) {
+ printf(" %02X", buf[i]);
+ }
+ printf("\n");
+ }
+
+ if(quit) {
+ break;
+ }
+
+ /* Send response back to vtpm_manager */
+ if((wrote = write(vbefd, buf, size + 4)) != size + 4) {
+ fprintf(stderr, "Error writing to %s, (%s)\n", opts.vtpmbe,
strerror(errno));
+ return 1;
+ }
+ }
+
+ return 0;
+
+}
+
+int main(int argc, char** argv)
+{
+ int rc;
+ int vbefd, tpmfd;
+ int c;
+ int fd = -1;
+ struct sigaction sig;
+ pid_t pid;
+
+ /* Do cmdline opts */
+ opterr = 0;
+
+ while ((c = getopt (argc, argv, "hfvb:t:")) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ case 'f':
+ opts.daemon = 0;
+ break;
+ case 'v':
+ ++opts.verbosity;
+ break;
+ case 'b':
+ opts.vtpmbe = optarg;
+ break;
+ case 't':
+ opts.tpmdev = optarg;
+ break;
+ case '?':
+ if (optopt == 'c')
+ fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+ else if (isprint (optopt))
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr,
+ "Unknown option character `\\x%x'.\n",
+ optopt);
+ usage(argv[0]);
+ return 1;
+ default:
+ return 1;
+ }
+ }
+
+ /* DAEMONIZE */
+ if(opts.daemon) {
+ pid = fork();
+ if(pid < 0) {
+ fprintf(stderr, "failed to daemonize! fork() failed : %s\n",
strerror(errno));
+ return 1;
+ }
+
+ if (pid > 0) {
+ return 0;
+ }
+ }
+
+
+ /* SIGNAL HANDLING */
+ sig.sa_handler = sighandler;
+ sigemptyset(&sig.sa_mask);
+ sig.sa_flags = 0;
+
+ sigaction(SIGINT, &sig, NULL);
+ sigaction(SIGQUIT, &sig, NULL);
+ sigaction(SIGTERM, &sig, NULL);
+
+ /* FAKE OUT THE HOTPLUG SYSTEM */
+ /* Whenever hotplug writes a message let it go to dev null */
+ if(remove(VTPM_RX_HP_FNAME) != 0 && errno != ENOENT) {
+ fprintf(stderr, "Unable to remove %s : %s\n", VTPM_RX_HP_FNAME,
strerror(errno));
+ return -1;
+ }
+ if(symlink(DEVNULL, VTPM_RX_HP_FNAME) != 0) {
+ fprintf(stderr, "Unable to create symlink %s -> %s : %s\n",
VTPM_RX_HP_FNAME, DEVNULL, strerror(errno));
+ }
+
+ /* Whenever hotplug tries to read a response, always return success */
+ if(remove(VTPM_TX_HP_FNAME) != 0 && errno != ENOENT) {
+ fprintf(stderr, "Unable to remove %s : %s\n", VTPM_TX_HP_FNAME,
strerror(errno));
+ return -1;
+ }
+ if((fd = open(VTPM_TX_HP_FNAME, O_CREAT | O_WRONLY, S_IRUSR |
S_IWUSR)) < 0) {
+ fprintf(stderr, "Unable to open %s for writing : %s\n",
VTPM_TX_HP_FNAME, strerror(errno));
+ return -1;
+ }
+ if(write(fd, TPM_SUCCESS_RESP, TPM_SUCCESS_RESPLEN) !=
TPM_SUCCESS_RESPLEN) {
+ fprintf(stderr, "Unable to write to %s : %s\n", VTPM_TX_HP_FNAME,
strerror(errno));
+ return -1;
+ }
+ close(fd);
+ /* HOTPLUG FAKE OUT DONE */
+
+ /* Open the backend and tpm device */
+ if((vbefd = open(opts.vtpmbe, O_RDWR)) < 0) {
+ fprintf(stderr, "Unable to open `%s', (%s)\n", opts.vtpmbe,
strerror(errno));
+ return 1;
+ }
+ if((tpmfd = open(opts.tpmdev, O_RDWR)) < 0) {
+ fprintf(stderr, "Unable to open `%s', (%s)\n", opts.tpmdev,
strerror(errno));
+ return 1;
+ }
+ if(opts.verbosity > 0) {
+ fprintf(stderr, "Connected to vtpm backend: %s\n", opts.vtpmbe);
+ fprintf(stderr, "Connected to tpm: %s\n", opts.tpmdev);
+ }
+
+ rc = main_loop(vbefd, tpmfd);
+
+ close(vbefd);
+ close(tpmfd);
+
+ remove(VTPM_RX_HP_FNAME);
+ remove(VTPM_TX_HP_FNAME);
+
+
+ return rc;
+
+
+}
diff --git a/tools/vtpm_manager/vtpmmgrtalk/Makefile
b/tools/vtpm_manager/vtpmmgrtalk/Makefile
--- /dev/null
+++ b/tools/vtpm_manager/vtpmmgrtalk/Makefile
@@ -0,0 +1,35 @@
+# Copyright (c) 2010-2012 United States Government, as represented by
+# the Secretary of Defense. All rights reserved.
+#
+# THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+# ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+# INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+# FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+# DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+# SOFTWARE.
+#
+
+XEN_ROOT = $(realpath ../../..)
+include ../Rules.mk
+
+BIN=vtpmmgrtalk
+OBJS=vtpmmgrtalk.o
+CFLAGS=-Wall -O2 -g
+CFLAGS += -I../crypto
+CFLAGS += -I../util
+CFLAGS += -I../tcs
+CFLAGS += -I../manager
+
+
+all: ${BIN}
+
+${BIN}: ${OBJS}
+ gcc -o $@ $<
+
+install: all
+ install -m 0755 ${BIN} $(DESTDIR)$(BINDIR)/$(BIN)
+
+.PHONY: mrproper
+mrproper: clean
+clean:
+ rm -f ${BIN} ${OBJS}
diff --git a/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
--- /dev/null
+++ b/tools/vtpm_manager/vtpmmgrtalk/vtpmmgrtalk.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010-2012 United States Government, as represented by
+ * the Secretary of Defense. All rights reserved.
+ *
+ * THIS SOFTWARE AND ITS DOCUMENTATION ARE PROVIDED AS IS AND WITHOUT
+ * ANY EXPRESS OR IMPLIED WARRANTIES WHATSOEVER. ALL WARRANTIES
+ * INCLUDING, BUT NOT LIMITED TO, PERFORMANCE, MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT ARE HEREBY
+ * DISCLAIMED. USERS ASSUME THE ENTIRE RISK AND LIABILITY OF USING THE
+ * SOFTWARE.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "../manager/vtpm_manager.h"
+
+int main(int argc, char** argv) {
+ int wfd, rfd;
+ uint8_t buf[COMMAND_BUFFER_SIZE];
+ ssize_t size;
+ int i, c;
+ int rc = 0;
+
+ const char* wfile = VTPM_RX_HP_FNAME;
+ const char* rfile = VTPM_TX_HP_FNAME;
+
+ /* Open for writing in non-blocking mode and exit if
+ * the manager is not waiting on the other side */
+ if((wfd = open(wfile, O_WRONLY | O_NONBLOCK)) < 0) {
+ fprintf(stderr, "Error opening %s for writing : %s\n",
wfile,strerror(errno));
+ return 1;
+ }
+ /* Set the pipe back to blocking mode */
+ fcntl(wfd, F_SETFL, 0);
+
+ /* Open the read pipe */
+ if((rfd = open(rfile, O_RDONLY)) < 0) {
+ close(wfd);
+ fprintf(stderr, "Error opening %s for reading : %s\n",
rfile,strerror(errno));
+ return 1;
+ }
+
+ /*Grab the ASCII hex input from stdin and convert to binary */
+ for(i = 0; i < COMMAND_BUFFER_SIZE; ++i) {
+ c = scanf("%02hhX", buf + i);
+ if(c == EOF) {
+ break;
+ } else if ( c != 1) {
+ fprintf(stderr, "Malformed Input! Use ASCII hex!\n");
+ rc = 1;
+ goto quit;
+ }
+ }
+ size = i;
+
+ /* Send request to the manager only if a request was actually given */
+ if(size > 0) {
+ /* Lock the pipes for reading/writing */
+ if(flock(wfd, LOCK_EX)) {
+ fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno));
+ rc = 1;
+ goto quit;
+ }
+ if(flock(rfd, LOCK_EX)) {
+ fprintf(stderr, "Unable to lock %s : %s\n", wfile, strerror(errno));
+ rc = 1;
+ goto quit;
+ }
+
+ /* Write the binary data to the pipe */
+ if(write(wfd, buf, size) != size) {
+ fprintf(stderr, "Error writing to %s : %s\n", wfile, strerror(errno));
+ rc = 1;
+ goto quit;
+ }
+
+ /* Read the response from the manager */
+ size = read(rfd, buf, COMMAND_BUFFER_SIZE);
+ if(size < 0) {
+ fprintf(stderr, "Error reading %s : %s\n", rfile, strerror(errno));
+ rc = 1;
+ goto quit;
+ }
+ /* Output the hex */
+ for(i = 0; i < size; ++i) {
+ printf("%02X", buf[i]);
+ }
+ fprintf(stderr,"\n");
+
+ /* Unlock the pipes */
+ flock(rfd, LOCK_UN);
+ flock(wfd, LOCK_UN);
+ }
+
+ rc = 0;
+quit:
+ close(rfd);
+ close(wfd);
+ return rc;
+}
Attachment:
smime.p7s _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |