diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/examples/myguest.cfg xen-unstable-trp-sdp/stubdom/vtpm/examples/myguest.cfg --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/examples/myguest.cfg 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/examples/myguest.cfg 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,5 @@ +bootloader = pygrub +memory = 192 +name = 'myguest' +disk = ['file:/tmp/myguest.img,hda1,w'] +vtpm = ['backend=myvtpm'] diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/examples/myvtpm.cfg xen-unstable-trp-sdp/stubdom/vtpm/examples/myvtpm.cfg --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/examples/myvtpm.cfg 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/examples/myvtpm.cfg 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,8 @@ +kernel = '/boot/vtpm-stubdom.gz' +memory = '8' +name = 'vtpm' +on_shutdown = 'destroy' +on_crash = 'destroy' +disk = ['file:/tmp/myvtpm.img,hda,w'] +extra = 'loglevel=info pvm clear' +vtpm = ['backend=vtpmmgrdom,uuid=4209a551-9b79-4feb-ad4d-b4ff1c1bc355'] diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/Makefile xen-unstable-trp-sdp/stubdom/vtpm/Makefile --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/Makefile 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,53 @@ +#LICENSE AND DISCLAIMER +# +#Copyright © 2010 The Johns Hopkins University/Applied Physics +#Laboratory +# +#This software was developed at The Johns Hopkins University/Applied +#Physics Laboratory (“JHU/APL”) that is the author thereof under the +#“work made for hire” provisions of the copyright law. Permission is +#hereby granted, free of charge, to any person obtaining a copy of this +#software and associated documentation (the “Software”), to use the +#Software without restriction, including without limitation the rights to +#copy, modify, merge, publish, distribute, sublicense, and/or sell copies +#of the Software, and to permit others to do so, subject to the following +#conditions: +# +#1. This LICENSE AND DISCLAIMER, including the copyright notice, shall +#be included in all copies of the Software, including copies of +#substantial portions of the Software; +# +#2. JHU/APL assumes no obligation to provide support of any kind with +#regard to the Software. This includes no obligation to provide assistance +#in using the Software nor to provide updated versions of the Software; and +# +#3. THE 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. USERS ARE ADVISED TO +#TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE +#JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, +#WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR +#CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE +#SOFTWARE. + +TPMEMU_DIR=../tpm_emulator-$(XEN_TARGET_ARCH)/tpmd +TPMEMU_OBJS=$(wildcard $(TPMEMU_DIR)/*.o) +XEN_ROOT=../.. + +PSSL_DIR=../polarssl-$(XEN_TARGET_ARCH)/library +PSSL_OBJS=aes.o padlock.o sha1.o + +TARGET=vtpm.a +OBJS=vtpm.o vtpm_cmd.o vtpmblk.o + +CPPFLAGS+=-I$(MNGR_ROOT)/manager -I${TPMEMU_DIR} + +$(TARGET): $(OBJS) + ar -cr $@ $(OBJS) $(TPMEMU_OBJS) $(foreach obj,$(PSSL_OBJS),$(PSSL_DIR)/$(obj)) + +clean: + -rm $(TARGET) $(OBJS) + +.PHONY: clean diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpmblk.c xen-unstable-trp-sdp/stubdom/vtpm/vtpmblk.c --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpmblk.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpmblk.c 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,335 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#include +#include "tpm_emulator_config.h" +#include "vtpmblk.h" +#include "tpm/tpm_marshalling.h" +#include "vtpm_cmd.h" +#include "polarssl/aes.h" +#include "polarssl/sha1.h" +#include +#include +#include +#include + +/*Encryption key and block sizes */ +#define BLKSZ 16 + +static struct blkfront_dev* blkdev = NULL; +static int blkfront_fd = -1; + +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev) +{ + struct blkfront_info blkinfo; + info("Initializing persistent NVM storage\n"); + + if((blkdev = init_blkfront(NULL, &blkinfo)) == NULL) { + error("BLKIO: ERROR Unable to initialize blkfront"); + return -1; + } + if (blkinfo.info & VDISK_READONLY || blkinfo.mode != O_RDWR) { + error("BLKIO: ERROR block device is read only!"); + goto error; + } + if((blkfront_fd = blkfront_open(blkdev)) == -1) { + error("Unable to open blkfront file descriptor!"); + goto error; + } + + return 0; +error: + shutdown_blkfront(blkdev); + blkdev = NULL; + return -1; +} + +void shutdown_vtpmblk(void) +{ + close(blkfront_fd); + blkfront_fd = -1; + blkdev = NULL; +} + +int write_vtpmblk_raw(uint8_t *data, size_t data_length) +{ + int rc; + uint32_t lenbuf; + debug("Begin Write data=%p len=%u", data, data_length); + + lenbuf = cpu_to_be32((uint32_t)data_length); + + lseek(blkfront_fd, 0, SEEK_SET); + if((rc = write(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) { + error("write(length) failed! error was %s", strerror(errno)); + return -1; + } + if((rc = write(blkfront_fd, data, data_length)) != data_length) { + error("write(data) failed! error was %s", strerror(errno)); + return -1; + } + + info("Wrote %u bytes to NVM persistent storage", data_length); + + return 0; +} + +int read_vtpmblk_raw(uint8_t **data, size_t *data_length) +{ + int rc; + uint32_t lenbuf; + + lseek(blkfront_fd, 0, SEEK_SET); + if(( rc = read(blkfront_fd, (uint8_t*)&lenbuf, 4)) != 4) { + error("read(length) failed! error was %s", strerror(errno)); + return -1; + } + *data_length = (size_t) cpu_to_be32(lenbuf); + if(*data_length == 0) { + error("read 0 data_length for NVM"); + return -1; + } + + *data = tpm_malloc(*data_length); + if((rc = read(blkfront_fd, *data, *data_length)) != *data_length) { + error("read(data) failed! error was %s", strerror(errno)); + return -1; + } + + info("Read %u bytes from NVM persistent storage", *data_length); + return 0; +} + +int encrypt_vtpmblk(uint8_t* clear, size_t clear_len, uint8_t** cipher, size_t* cipher_len, uint8_t* symkey) +{ + int rc = 0; + uint8_t iv[BLKSZ]; + aes_context aes_ctx; + UINT32 temp; + int mod; + + uint8_t* clbuf = NULL; + + uint8_t* ivptr; + int ivlen; + + uint8_t* cptr; //Cipher block pointer + int clen; //Cipher block length + + /*Create a new 256 bit encryption key */ + if(symkey == NULL) { + rc = -1; + goto abort_egress; + } + tpm_get_extern_random_bytes(symkey, NVMKEYSZ); + + /*Setup initialization vector - random bits and then 4 bytes clear text size at the end*/ + temp = sizeof(UINT32); + ivlen = BLKSZ - temp; + tpm_get_extern_random_bytes(iv, ivlen); + ivptr = iv + ivlen; + tpm_marshal_UINT32(&ivptr, &temp, (UINT32) clear_len); + + /*The clear text needs to be padded out to a multiple of BLKSZ */ + mod = clear_len % BLKSZ; + clen = mod ? clear_len + BLKSZ - mod : clear_len; + clbuf = malloc(clen); + if (clbuf == NULL) { + rc = -1; + goto abort_egress; + } + memcpy(clbuf, clear, clear_len); + /* zero out the padding bits - FIXME: better / more secure way to handle these? */ + if(clen - clear_len) { + memset(clbuf + clear_len, 0, clen - clear_len); + } + + /* Setup the ciphertext buffer */ + *cipher_len = BLKSZ + clen; /*iv + ciphertext */ + cptr = *cipher = malloc(*cipher_len); + if (*cipher == NULL) { + rc = -1; + goto abort_egress; + } + + /* Copy the IV to cipher text blob*/ + memcpy(cptr, iv, BLKSZ); + cptr += BLKSZ; + + /* Setup encryption */ + aes_setkey_enc(&aes_ctx, symkey, 256); + + /* Do encryption now */ + aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, clear_len, iv, clbuf, cptr); + + goto egress; +abort_egress: +egress: + free(clbuf); + return rc; +} +int decrypt_vtpmblk(uint8_t* cipher, size_t cipher_len, uint8_t** clear, size_t* clear_len, uint8_t* symkey) +{ + int rc = 0; + uint8_t iv[BLKSZ]; + uint8_t* ivptr; + UINT32 u32, temp; + aes_context aes_ctx; + + uint8_t* cptr = cipher; //cipher block pointer + int clen = cipher_len; //cipher block length + + /* Pull out the initialization vector */ + memcpy(iv, cipher, BLKSZ); + cptr += BLKSZ; + clen -= BLKSZ; + + /* Setup the clear text buffer */ + if((*clear = malloc(clen)) == NULL) { + rc = -1; + goto abort_egress; + } + + /* Get the length of clear text from last 4 bytes of iv */ + temp = sizeof(UINT32); + ivptr = iv + BLKSZ - temp; + tpm_unmarshal_UINT32(&ivptr, &temp, &u32); + *clear_len = u32; + + /* Setup decryption */ + aes_setkey_dec(&aes_ctx, symkey, 256); + + /* Do decryption now */ + if ((clen % BLKSZ) != 0) { + error("Decryption Error: Cipher block size was not a multiple of %u", BLKSZ); + rc = -1; + goto abort_egress; + } + aes_crypt_cbc(&aes_ctx, AES_DECRYPT, clen, iv, cptr, *clear); + + /* Chop off extra block padding bits */ + *clear = realloc(*clear, *clear_len); + + goto egress; +abort_egress: +egress: + return rc; +} + +int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length) { + int rc; + uint8_t* cipher = NULL; + size_t cipher_len = 0; + uint8_t hashkey[HASHKEYSZ]; + uint8_t* symkey = hashkey + HASHSZ; + + /* Encrypt the data */ + if((rc = encrypt_vtpmblk(data, data_length, &cipher, &cipher_len, symkey))) { + goto abort_egress; + } + /* Write to disk */ + if((rc = write_vtpmblk_raw(cipher, cipher_len))) { + goto abort_egress; + } + /* Get sha1 hash of data */ + sha1(cipher, cipher_len, hashkey); + + /* Send hash and key to manager */ + if((rc = VTPM_SaveHashKey(tpmfront_dev, hashkey, HASHKEYSZ)) != TPM_SUCCESS) { + goto abort_egress; + } + goto egress; +abort_egress: +egress: + free(cipher); + return rc; +} + +int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t *data_length) { + int rc; + uint8_t* cipher = NULL; + size_t cipher_len = 0; + size_t keysize; + uint8_t* hashkey = NULL; + uint8_t hash[HASHSZ]; + uint8_t* symkey; + + /* Retreive the hash and the key from the manager */ + if((rc = VTPM_LoadHashKey(tpmfront_dev, &hashkey, &keysize)) != TPM_SUCCESS) { + goto abort_egress; + } + if(keysize != HASHKEYSZ) { + error("Manager returned a hashkey of invalid size! expected %d, actual %d", NVMKEYSZ, keysize); + rc = -1; + goto abort_egress; + } + symkey = hashkey + HASHSZ; + + /* Read from disk now */ + if((rc = read_vtpmblk_raw(&cipher, &cipher_len))) { + goto abort_egress; + } + + /* Compute the hash of the cipher text and compare */ + sha1(cipher, cipher_len, hash); + if(memcmp(hash, hashkey, HASHSZ)) { + int i; + error("NVM Storage Checksum failed!"); + printf("Expected: "); + for(i = 0; i < HASHSZ; ++i) { + printf("%02hhX ", hashkey[i]); + } + printf("\n"); + printf("Actual: "); + for(i = 0; i < HASHSZ; ++i) { + printf("%02hhX ", hash[i]); + } + printf("\n"); + rc = -1; + goto abort_egress; + } + + /* Decrypt the blob */ + if((rc = decrypt_vtpmblk(cipher, cipher_len, data, data_length, symkey))) { + goto abort_egress; + } + goto egress; +abort_egress: +egress: + free(cipher); + free(hashkey); + return rc; +} + diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpmblk.h xen-unstable-trp-sdp/stubdom/vtpm/vtpmblk.h --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpmblk.h 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpmblk.h 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,54 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#ifndef NVM_H +#define NVM_H +#include +#include +#include + +#define NVMKEYSZ 32 +#define HASHSZ 20 +#define HASHKEYSZ (NVMKEYSZ + HASHSZ) + +int init_vtpmblk(struct tpmfront_dev* tpmfront_dev); +void shutdown_vtpmblk(void); + +/* Encrypts and writes data to blk device */ +int write_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t *data, size_t data_length); +/* Reads, Decrypts, and returns data from blk device */ +int read_vtpmblk(struct tpmfront_dev* tpmfront_dev, uint8_t **data, size_t *data_length); + +#endif diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm.c xen-unstable-trp-sdp/stubdom/vtpm/vtpm.c --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpm.c 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,415 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tpm_emulator_config.h" +#include "tpm/tpm_emulator.h" +#include "vtpm.h" +#include "vtpm_cmd.h" +#include "vtpmblk.h" + +//FIXME: 0.6.1 hacks +#define TPM_LOG_INFO LOG_INFO +#define TPM_LOG_ERROR LOG_ERR +#define TPM_LOG_DEBUG LOG_DEBUG + +/* Global commandline options - default values */ +struct Opt_args opt_args = { + .mode = MODE_PVM, + .startup = ST_CLEAR, + .loglevel = TPM_LOG_INFO, + .entropysrc = ENT_TPM, + .tpmconf = 0, + .exclusive_uuids = NULL +}; + +struct tpmfront_dev* tpmfront_dev; + +void get_rand_bytes_rand(uint8_t* buf, size_t nbytes) +{ + int r, i; + while (nbytes > 0) { + r = rand(); + for(i = sizeof(int); i > 0 && nbytes > 0; --i) { + --nbytes; + buf[nbytes] = ((uint8_t*)&r)[i]; + } + } +} + +void tpm_get_extern_random_bytes(void *buf, size_t nbytes) +{ + switch(opt_args.entropysrc) { + case ENT_TPM: + VTPM_GetRandom(tpmfront_dev, buf, nbytes); + break; + case ENT_RAND: + get_rand_bytes_rand(buf, nbytes); + break; + default: + break; + } +} + +int tpm_read_from_file(uint8_t **data, size_t *data_length) { + return read_vtpmblk(tpmfront_dev, data, data_length); +} + +int tpm_write_to_file(uint8_t *data, size_t data_length) { + return write_vtpmblk(tpmfront_dev, data, data_length); +} + +int tpm_extern_init_fake(void) { + return 0; +} + +void tpm_extern_release_fake(void) { +} + + +void *vtpm_malloc(size_t size) +{ + return malloc(size); +} + +void vtpm_free(/*const*/ void *ptr) +{ + if (ptr != NULL) free((void*)ptr); +} + +uint64_t tpm_get_ticks(void) +{ + static uint64_t old_t = 0; + uint64_t new_t, res_t; + struct timeval tv; + gettimeofday(&tv, NULL); + new_t = (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec; + res_t = (old_t > 0) ? new_t - old_t : 0; + old_t = new_t; + return res_t; +} + + +void tpm_log(int priority, const char *fmt, ...) +{ + if(opt_args.loglevel >= priority) { + va_list v; + va_start(v, fmt); + vprintf(fmt, v); + va_end(v); + } +} + + +int init_random(void) { + int rc; + unsigned int seed = 0; + + if((rc = VTPM_GetRandom(tpmfront_dev, (BYTE*)&seed, sizeof(seed)))) { + error("VTPM_GetRandom failed with error code %d", rc); + return rc; + } + srand(seed); + + info("Seeded the RNG with %lu bytes of entropy", (unsigned long) sizeof(seed)); + return 0; + +} + +static void main_loop(void) { + tpmcmd_t* tpmcmd = NULL; + domid_t domid; /* Domid of frontend */ + unsigned int handle; /* handle of frontend */ + uint8_t* out; + uint32_t out_len; + int res = -1; + + info("VTPM Initializing\n"); + /* Set require tpm config args */ +#if 0 + opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE; + opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG; + opt_args.tpmconf |= TPM_CONF_GENERATE_EK; + opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA; +#endif + /* Initialize the emulator */ + tpm_emulator_init(opt_args.startup); + + /* Wait for the frontend domain to connect */ + info("Waiting for frontend domain to connect.."); + if(tpmback_wait_for_frontend_connect(&domid, &handle) == 0) { + info("VTPM attached to Frontend %u/%u", (unsigned int) domid, handle); + } else { + error("Unable to attach to a frontend"); + } + + tpmcmd = tpmback_req(domid, handle); + while(tpmcmd) { + /* Handle the request */ + if(tpmcmd->req_len) { + out = NULL; + out_len = 0; + res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &out, &out_len); + if(res < 0) { + error("tpm_handle_command() failed"); + } + else + { + tpmcmd->resp = out; + tpmcmd->resp_len = out_len; + } + } + + /* Send the response */ + tpmback_resp(tpmcmd); + + /* Free the out buffer if it was allocated */ + if(tpmcmd->req_len && res >= 0) { + tpm_free(out); + } + + /* Wait for the next request */ + tpmcmd = tpmback_req(domid, handle); + + } + + info("VTPM Shutting down\n"); + + tpm_emulator_shutdown(); +} + +int parse_cmd_line(int argc, char** argv) +{ + char sval[25]; + char* logstr = NULL; + /* Parse the command strings */ + for(unsigned int i = 1; i < argc; ++i) { + if (sscanf(argv[i], "loglevel=%25s", sval) == 1){ + if (!strcmp(sval, "debug")) { + opt_args.loglevel = TPM_LOG_DEBUG; + logstr = "debug"; + } + else if (!strcmp(sval, "info")) { + logstr = "info"; + opt_args.loglevel = TPM_LOG_INFO; + } + else if (!strcmp(sval, "error")) { + logstr = "error"; + opt_args.loglevel = TPM_LOG_ERROR; + } + } + else if (!strcmp(argv[i], "pvm")) { + opt_args.mode = MODE_PVM; + } + else if (!strcmp(argv[i], "hvm")) { + opt_args.mode = MODE_HVM; + } + else if (!strcmp(argv[i], "clear")) { + opt_args.startup = ST_CLEAR; + } + else if (!strcmp(argv[i], "save")) { + opt_args.startup = ST_SAVE; + } + else if (!strcmp(argv[i], "deactivated")) { + opt_args.startup = ST_DEACTIVATED; + } + else if (!strncmp(argv[i], "entropysrc=", 11)) { + if (!strcmp(argv[i] + 11, "tpm")) { + opt_args.entropysrc = ENT_TPM; + } + else if (!strcmp(argv[i] + 11, "rand")) { + opt_args.entropysrc = ENT_RAND; + } + } + else if (!strncmp(argv[i], "tpmconf=", 8)) { + opt_args.tpmconf = strtol(argv[i] + 8, NULL, 0); + } + else if (!strncmp(argv[i], "hostuuids=", 10)) { + char* uuid; + int num_alloc = 4; + int num_uuids = 0; + opt_args.exclusive_uuids = malloc(sizeof(char*) * num_alloc); + opt_args.exclusive_uuids[0] = NULL; + + uuid = strtok(argv[i] + 10, ","); + while(uuid != NULL) { + if(num_uuids + 1 == num_alloc) { + num_alloc*=2; + opt_args.exclusive_uuids = realloc(opt_args.exclusive_uuids, num_alloc); + } + opt_args.exclusive_uuids[num_uuids] = uuid; + opt_args.exclusive_uuids[num_uuids+1] = NULL; + ++num_uuids; + uuid = strtok(NULL, ","); + } + } + else { + error("Invalid command line option `%s'", argv[i]); + } + + } + + /* Check Errors and print results */ + switch (opt_args.mode) { + case MODE_HVM: + error("hvm mode is not currently supported!"); + return -1; + break; + case MODE_PVM: + info("Running in pvm mode"); + break; + default: + error("Mode not specified! You must specify either pvm or hvm on the command line"); + return -1; + } + + switch(opt_args.startup) { + case ST_CLEAR: + info("Startup mode is `clear'"); + break; + case ST_SAVE: + info("Startup mode is `save'"); + break; + case ST_DEACTIVATED: + info("Startup mode is `deactivated'"); + break; + default: + error("Invalid startup mode %d", opt_args.startup); + return -1; + } + + switch(opt_args.entropysrc) + { + case ENT_TPM: + info("Will use Hardware TPM for entropy source"); + break; + case ENT_RAND: + info("Will use rand() for entropy source"); + break; + default: + error("Invalid entropy source %d", opt_args.entropysrc); + return -1; + } + + if(opt_args.exclusive_uuids != NULL) { + char** ptr; + info("Exclusive Host UUIDs set:"); + for(ptr = opt_args.exclusive_uuids; *ptr != NULL; ++ptr) { + info("\t%s", *ptr); + } + } + + info("Log level set to %s", logstr); + + return 0; +} + +void cleanup_opt_args(void) { + if(opt_args.exclusive_uuids != NULL) { + free(opt_args.exclusive_uuids); + } +} + +int main(int argc, char **argv) +{ + //FIXME: initializing blkfront without this sleep causes the domain to crash on boot + sleep(2); + +#if 0 //Disable for 0.6.1 + /* Setup extern function pointers */ + tpm_extern_init = tpm_extern_init_fake; + tpm_extern_release = tpm_extern_release_fake; + tpm_malloc = vtpm_malloc; + tpm_free = vtpm_free; + tpm_log = vtpm_log; + tpm_get_extern_random_bytes = vtpm_get_extern_random_bytes; + tpm_get_ticks = vtpm_get_ticks; + tpm_write_to_storage = vtpm_write_to_file; + tpm_read_from_storage = vtpm_read_from_file; +#endif + + info("starting TPM Emulator (1.2.%s.%s-%s)", TPM_STR(VERSION_MAJOR), TPM_STR(VERSION_MINOR), TPM_STR(VERSION_BUILD)); + if(parse_cmd_line(argc, argv)) { + error("Error parsing commandline\n"); + return -1; + } + + /* Initialize devices */ + init_tpmback(opt_args.exclusive_uuids); + if((tpmfront_dev = init_tpmfront(NULL)) == NULL) { + error("Unable to initialize tpmfront device"); + goto abort_posttpmfront; + } + + /* Seed the RNG with entropy from hardware TPM */ + if(init_random()) { + error("Unable to initialize RNG"); + goto abort_postrng; + } + + /* Initialize blkfront device */ + if(init_vtpmblk(tpmfront_dev)) { + error("Unable to initialize Blkfront persistent storage"); + goto abort_postvtpmblk; + } + + /* Run main loop */ + main_loop(); + + /* Shutdown blkfront */ + shutdown_vtpmblk(); +abort_postvtpmblk: +abort_postrng: + + /* Close devices */ + shutdown_tpmfront(tpmfront_dev); +abort_posttpmfront: + shutdown_tpmback(); + + cleanup_opt_args(); + + return 0; +} diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm_cmd.c xen-unstable-trp-sdp/stubdom/vtpm/vtpm_cmd.c --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm_cmd.c 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpm_cmd.c 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,217 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include "tpm/tpm_marshalling.h" +#include +#include "vtpm_cmd.h" + +#define TRYFAILGOTO(C) \ + if((C)) { \ + status = TPM_FAIL; \ + goto abort_egress; \ + } +#define TRYFAILGOTOMSG(C, msg) \ + if((C)) { \ + status = TPM_FAIL; \ + error(msg); \ + goto abort_egress; \ + } +#define CHECKSTATUSGOTO(ret, fname) \ + if((ret) != TPM_SUCCESS) { \ + error("%s failed with error code (%lu)", fname, (unsigned long) ret); \ + status = ord; \ + goto abort_egress; \ + } + +#define ERR_MALFORMED "Malformed response from backend" +#define ERR_TPMFRONT "Error sending command through frontend device" + +struct shpage { + void* page; + grant_ref_t grantref; +}; + +typedef struct shpage shpage_t; + +static inline int pack_header(uint8_t** bptr, UINT32* len, TPM_TAG tag, UINT32 size, TPM_COMMAND_CODE ord) +{ + return *bptr == NULL || + tpm_marshal_UINT16(bptr, len, tag) || + tpm_marshal_UINT32(bptr, len, size) || + tpm_marshal_UINT32(bptr, len, ord); +} + +static inline int unpack_header(uint8_t** bptr, UINT32* len, TPM_TAG* tag, UINT32* size, TPM_COMMAND_CODE* ord) +{ + return *bptr == NULL || + tpm_unmarshal_UINT16(bptr, len, tag) || + tpm_unmarshal_UINT32(bptr, len, size) || + tpm_unmarshal_UINT32(bptr, len, ord); +} + +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32 numbytes) { + TPM_RESULT status = TPM_SUCCESS; + uint8_t* cmdbuf, *resp, *bptr; + size_t resplen = 0; + UINT32 len; + + /*Ask the real tpm for random bytes for the seed */ + TPM_TAG tag = TPM_TAG_RQU_COMMAND; + UINT32 size; + TPM_COMMAND_CODE ord = TPM_ORD_GetRandom; + len = size = sizeof(TPM_TAG) + sizeof(UINT32) + sizeof(TPM_COMMAND_CODE) + sizeof(UINT32); + + /*Create the raw tpm command */ + bptr = cmdbuf = malloc(size); + TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord)); + TRYFAILGOTO(tpm_marshal_UINT32(&bptr, &len, numbytes)); + + /* Send cmd, wait for response */ + TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), + ERR_TPMFRONT); + + bptr = resp; len = resplen; + TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED); + + //Check return status of command + CHECKSTATUSGOTO(ord, "TPM_GetRandom()"); + + // Get the number of random bytes in the response + TRYFAILGOTOMSG(tpm_unmarshal_UINT32(&bptr, &len, &size), ERR_MALFORMED); + + /* FIXME: Does this ever really happen? */ + if(size != numbytes) { + error("TPM_GetRandom() returned insufficient number of bytes!"); + status = TPM_FAIL; + goto abort_egress; + } + + //Get the random bytes out, tpm may give us less bytes than what we wanrt + TRYFAILGOTOMSG(tpm_unmarshal_BYTE_ARRAY(&bptr, &len, bytes, numbytes), ERR_MALFORMED); + + goto egress; +abort_egress: +egress: + free(cmdbuf); + return status; + +} + +TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length) +{ + TPM_RESULT status = TPM_SUCCESS; + uint8_t* bptr, *resp; + uint8_t* cmdbuf = NULL; + size_t resplen = 0; + UINT32 len; + + TPM_TAG tag = VTPM_TAG_REQ; + UINT32 size; + TPM_COMMAND_CODE ord = VTPM_ORD_LOADHASHKEY; + + /*Create the command*/ + len = size = VTPM_COMMAND_HEADER_SIZE_CLT; + bptr = cmdbuf = malloc(size); + TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord)); + + /* Send the command to vtpm_manager */ + info("Requesting Encryption key from backend"); + TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT); + + /* Unpack response header */ + bptr = resp; + len = resplen; + TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED); + + /* Check return code */ + CHECKSTATUSGOTO(ord, "VTPM_LoadHashKey()"); + + /* Get the size of the key */ + *data_length = size - VTPM_COMMAND_HEADER_SIZE_CLT; + + /* Copy the key bits */ + *data = malloc(*data_length); + memcpy(*data, bptr, *data_length); + + goto egress; +abort_egress: + error("VTPM_LoadHashKey failed"); +egress: + free(cmdbuf); + return status; +} + +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length) +{ + TPM_RESULT status = TPM_SUCCESS; + uint8_t* bptr, *resp; + uint8_t* cmdbuf = NULL; + size_t resplen = 0; + UINT32 len; + + TPM_TAG tag = VTPM_TAG_REQ; + UINT32 size; + TPM_COMMAND_CODE ord = VTPM_ORD_SAVEHASHKEY; + + /*Create the command*/ + len = size = VTPM_COMMAND_HEADER_SIZE_CLT + data_length; + bptr = cmdbuf = malloc(size); + TRYFAILGOTO(pack_header(&bptr, &len, tag, size, ord)); + memcpy(bptr, data, data_length); + bptr += data_length; + + /* Send the command to vtpm_manager */ + info("Sending encryption key to backend"); + TRYFAILGOTOMSG(tpmfront_cmd(tpmfront_dev, cmdbuf, size, &resp, &resplen), ERR_TPMFRONT); + + /* Unpack response header */ + bptr = resp; + len = resplen; + TRYFAILGOTOMSG(unpack_header(&bptr, &len, &tag, &size, &ord), ERR_MALFORMED); + + /* Check return code */ + CHECKSTATUSGOTO(ord, "VTPM_SaveHashKey()"); + + goto egress; +abort_egress: + error("VTPM_SaveHashKey failed"); +egress: + free(cmdbuf); + return status; +} diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm_cmd.h xen-unstable-trp-sdp/stubdom/vtpm/vtpm_cmd.h --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm_cmd.h 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpm_cmd.h 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,51 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#ifndef MANAGER_H +#define MANAGER_H + +#include "tpm_emulator_config.h" +#include +#include "tpm/tpm_emulator.h" +#include "tpm/tpm_structures.h" + +/* Request random bytes from hardware tpm, returns 0 on success */ +TPM_RESULT VTPM_GetRandom(struct tpmfront_dev* tpmfront_dev, BYTE* bytes, UINT32 numbytes); +/* Retreive 256 bit AES encryption key from manager */ +TPM_RESULT VTPM_LoadHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t** data, size_t* data_length); +/* Manager securely saves our 256 bit AES encryption key */ +TPM_RESULT VTPM_SaveHashKey(struct tpmfront_dev* tpmfront_dev, uint8_t* data, size_t data_length); + +#endif diff -Naur xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm.h xen-unstable-trp-sdp/stubdom/vtpm/vtpm.h --- xen-unstable-trp-sdp-pristine/stubdom/vtpm/vtpm.h 1969-12-31 19:00:00.000000000 -0500 +++ xen-unstable-trp-sdp/stubdom/vtpm/vtpm.h 2011-02-23 19:40:48.000000000 -0500 @@ -0,0 +1,66 @@ +/* LICENSE AND DISCLAIMER + * + * Copyright © 2010 The Johns Hopkins University/Applied Physics + * Laboratory + + * This software was developed at The Johns Hopkins University/Applied + * Physics Laboratory (“JHU/APL”) that is the author thereof under the + * “work made for hire” provisions of the copyright law. Permission is + * hereby granted, free of charge, to any person obtaining a copy of this + * software and associated documentation (the “Software”), to use the + * Software without restriction, including without limitation the rights to + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit others to do so, subject to the following + * conditions: + + * 1. This LICENSE AND DISCLAIMER, including the copyright notice, shall + * be included in all copies of the Software, including copies of + * substantial portions of the Software; + + * 2. JHU/APL assumes no obligation to provide support of any kind with + * regard to the Software. This includes no obligation to provide assistance + * in using the Software nor to provide updated versions of the Software; and + + * 3. THE 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. USERS ARE ADVISED TO + * TEST THE SOFTWARE THOROUGHLY BEFORE RELYING ON IT. IN NO EVENT SHALL THE + * JOHNS HOPKINS UNIVERSITY BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING, + * WITHOUT LIMITATION, ANY LOST PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, ARISING OUT OF THE USE OR INABILITY TO USE THE + * SOFTWARE. + */ + +#ifndef VTPM_H +#define VTPM_H + +/* For testing */ +#define VERS_CMD "\x00\xC1\x00\x00\x00\x16\x00\x00\x00\x65\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x01\x03" +#define VERS_CMD_LEN 22 + +/* Global commandline options */ +struct Opt_args { + enum Mode{ + MODE_INVALID, + MODE_PVM, + MODE_HVM + } mode; + enum StartUp { + ST_CLEAR = 1, + ST_SAVE = 2, + ST_DEACTIVATED = 3 + } startup; + enum EntropySource { + ENT_TPM, + ENT_RAND + } entropysrc; + int loglevel; + int tpmconf; + char** exclusive_uuids; +}; +extern struct Opt_args opt_args; + +#endif +