# HG changeset patch # User Joseph Cihula # Date 1188344455 25200 # Node ID 2a74acaf6f11decab4f0494deaa2b5f4887bcd26 # Parent 5648dc802679e6f298b9d4f7feb5c294c75b4bc9 Intel(R) Trusted Execution Technology (Intel(R) TXT) support for Xen sboot tools files. Signed-off-by: Joseph Cihula Signed-off-by: Shane Wang Signed-off-by: James Xu Signed-off-by: Rossey Liu Signed-off-by: Edmund Song Signed-off-by: Shincy Tu Signed-off-by: Kevy Zhang diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/Makefile Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,27 @@ +XEN_ROOT = ../../ +include $(XEN_ROOT)/sboot/tools/Rules.mk + +SUBDIRS-y := +SUBDIRS-y += trousers +SUBDIRS-y += lcptools + +.PHONY: all +all: + @set -e; for subdir in $(SUBDIRS-y); do \ + $(MAKE) -C $$subdir $@; \ + done + +.PHONY: install +install: + @set -e; for subdir in $(SUBDIRS-y); do \ + $(MAKE) -C $$subdir $@; \ + done + +.PHONY: clean +clean: + @set -e; for subdir in $(SUBDIRS-y); do \ + $(MAKE) -C $$subdir $@; \ + done + +.PHONY: distclean +distclean: clean diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/Rules.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/Rules.mk Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,46 @@ +# -*- mode: Makefile; -*- + +# `all' is the default target +all: + +include $(XEN_ROOT)/Config.mk + +# Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers) +ifeq ($(CONFIG_X86)$(call cc-ver,$(CC),0x030400),yn) +$(error Xen tools require at least gcc-3.4) +endif + +# General compiler flags +# 32-bit x86 does not perform well with -ve segment accesses on Xen. +CFLAGS-$(CONFIG_X86_32) += $(call cc-option,$(CC),-mno-tls-direct-seg-refs) +CFLAGS += $(CFLAGS-y) +CFLAGS = -Werror -g3 + +# For generating dependencies +#CFLAGS += -Wp,-MD,.$(@F).d + +DEP_FILES = .*.d + +# Generic project files +HDRS = $(wildcard *.h) +SRCS = $(wildcard *.c) +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +# Generic (non-header) dependencies +$(SRCS): Makefile $(XEN_ROOT)/sboot/tools/Rules.mk + +#$(OBJS): $(SRCS) + +-include $(DEP_FILES) + +# Make sure these are just rules +.PHONY : all build install clean + +%.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +%.o: %.cc + $(CC) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/Linux_LCP_Tools_User_Manual.doc Binary file sboot/tools/lcptools/Linux_LCP_Tools_User_Manual.doc has changed diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/Linux_LCP_Tools_User_Manual.pdf Binary file sboot/tools/lcptools/Linux_LCP_Tools_User_Manual.pdf has changed diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/Makefile Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,55 @@ +XEN_ROOT = ../../../ + +# Base definitions and rules +include $(XEN_ROOT)/sboot/tools/Rules.mk + +TPMNV_TARGETS := \ + tpmnv_defindex \ + tpmnv_relindex \ + tpmnv_lock \ + tpmnv_getcap + +LCP_TARGETS := \ + lcp_writepol \ + lcp_readpol \ + lcp_crtpconf \ + lcp_crtpol \ + lcp_mlehash + +UTIL_OBJS := lcptools.o lcputils.o + + +# libraries +LIBS += -lssl -ltspi + + +# +# rules +# + +.PHONY: all +all: build + +.PHONY: build +build: $(TPMNV_TARGETS) $(LCP_TARGETS) + +.PHONY: install +install: build + +.PHONY: clean +clean: + rm -f *.a *.so *.o *.rpm $(DEP_FILES) + +.PHONY: mrproper +mrproper: clean + rm -f $(TPMNV_TARGETS) $(LCP_TARGETS) *~ + +# +# dependencies +# + +$(TPMNV_TARGETS): tpmnv_% : %.o $(UTIL_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(LCP_TARGETS): lcp_% : %.o $(UTIL_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/crtpconf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/crtpconf.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,221 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * crtpconf.c + * + * Command: lcp_crtpconf. + * + * This command can create PConf data for use when creating LCP policy data. + * + */ + + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + + +#define MAX_INDEX 24 + +static uint8_t locality = 0x1f; +static char *file = NULL; +static unsigned char *pcr_val = NULL; +static int help_input = 0; + +static const char *short_option = "hp:f:"; +static const char *usage_string = "lcp_crtpconf "\ + "-p PCR_index1,PCR_index2,...,PCR_indexn "\ + "[-f filename] [-h]\n"; + +static const char * option_strings[] ={ + "-p PCR_Index1,PCR_Index2,...: uint8. \n", + "-f file name of SRTMMeasurement: string. Content is appended.\n", + "-h help. Will print out this help message.\n", + 0 +}; + +/* function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + uint32_t temp = 0; + + while (((c = getopt(argc, (char ** const)argv, short_option)) != -1)) + switch (c){ + case 'p': + pcr_val = optarg; + break; + + case 'f': + file = optarg; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +int +main(int argc, char *argv[]) +{ + uint16_t i = 0; + uint32_t index[MAX_INDEX] = {0}; + uint32_t idx_num = 0; + unsigned char *pcr_num[MAX_INDEX] = {NULL}; + FILE *p_file = NULL; + unsigned char* srtm_data = NULL; + uint32_t data_len = 0; + TPM_LOCALITY_SELECTION local_sel; + + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + uint32_t temp = 0; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Parse the parameters input to decide + * what parameters will be passed to TSS API. + */ + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Parse command line string to get the PCR numbers. + */ + if ( pcr_val == NULL ) { + log_error("Must input PCR numbers to creat PConf data.\n"); + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + + for (i = 0; i < MAX_INDEX; i++) { + pcr_num[i] = (unsigned char *)malloc(10); + if ( pcr_num[i] == NULL ) { + ret_value = LCP_E_OUTOFMEMORY; + goto _error_end; + } + } + if ( str_split(pcr_val, &pcr_num, &idx_num) < 0 ) { + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + for (i = 0; i < idx_num; i++) { + if ( strtonum(pcr_num[i], &temp) < 0 ) { + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + if ( temp < 0 || temp > 23 ) { + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + index[i] = temp; + } + + local_sel = (TPM_LOCALITY_SELECTION)locality; + ret_value = lcp_create_pconf(idx_num, + index, 0, NULL, local_sel, &data_len, &srtm_data); + if ( ret_value == LCP_SUCCESS ) { + if ( file != NULL ) { + /* + * Write Platform configure data to file. + */ + p_file = fopen(file, "a"); + if ( !p_file ) { + log_error("Open file %s error!\n", file); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + log_debug("Data length is %d.\n", data_len); + if ( data_len != fwrite(srtm_data, 1, data_len, p_file) ) { + log_error("Write SRTM data into file error!"\ + "Data length is %d.\n",data_len); + fclose(p_file); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + fclose(p_file); + } else + print_hexmsg("the PConf data is:\n", data_len, srtm_data); + if(srtm_data) + free(srtm_data); + } else + goto _error_end; + + return LCP_SUCCESS; +_error_end: + /* + * Error when execute. + */ + for (i = 0; i < MAX_INDEX; i++) { + if ( pcr_num ) + if ( pcr_num[i] ) + free(pcr_num[i]); + } + if ( srtm_data ) + free(srtm_data); + log_error("\nCommand CrtPConf failed:\n"); + print_error(ret_value); + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/crtpol.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/crtpol.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,523 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * crtpol.c + * + * Command: lcp_crtpol + * + * This command can create the LCP policy. + * + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +#define MAX_LISTNUM 2 +#define BUFFER_SIZE 1024 + +static uint8_t pol_type = 0xff; +static uint32_t alg = LCP_POLHALG_SHA1; +static uint8_t ver = 0; +static uint32_t pcf_val = 0; +static uint8_t sinit_revoc = 0; +static char *pol_file = NULL; +static char *mle_file = NULL; +static char *pol_data_file = NULL; +static char *srtm_file = NULL; +static int help_input = 0; + +static const char * short_option = "ht:a:v:s:m:o:b:"; +static struct option longopts[]= { + {"sr", 1, 0, 'n'}, + {"pcf", 1, 0, 'p'}, + {0, 0, 0, 0}, +}; + +static const char * usage_string = "lcp_crtpol -t policy_type [-a hashalg] "\ + "[-v version] [-sr SINIT revocation_counter] [-s srtm_file] "\ + "[-m mle_file] [-o policyfile] [-b policydata_file] [-h]\n"; + +static const char * option_strings[] ={ + "-t Policy type: uint8/string.\n"\ + "\tPolicy type is:\n"\ + "\tLCP_POLTYPE_HASHONLY: 0 or \"hashonly\" \n"\ + "\tLCP_POLTYPE_UNSIGNED: 1 or \"unsigned\" \n"\ + "\tLCP_POLTYPE_SIGNED: 2 or \"signed\" \n"\ + "\tLCP_POLTYPE_ANY: 3 or \"any\" \n"\ + "\tLCP_POLTYPE_FORCEOWNERPOLICY: 4 or \"forceowner\" \n", + "-a algorithm: uint8/string. algorithm used in the policy.\n"\ + "\tAlgorithm choice:\n"\ + "\t\tLCP_POLHALG_SHA1: 0 or \"sha1\" \n"\ + "\tCurrently we only support SHA-1 algorithm.\n", + "-v version: uint8. version number.\n"\ + "\tCurrently only 0 is allowed.\n", + "-s PConf file name: String. File name of PConf data.\n", + "-m MLE hash file name: String. File containing the MLE hashes.\n", + "-o LCPPOLICY file name: String. File to save the output Policy.\n", + "-b LCPPOLICYDATA file name: String. File to save Policy data.\n", + "-sr SINIT Revocation count number: uint8.\n", + "-pcf Policy Control Field: uint32.\n", + "-h help. Will print out this help message.\n" + ,0 +}; + +static param_option_t poltype_option_table[] = { + {"hashonly", LCP_POLTYPE_HASHONLY}, + {"unsigned", LCP_POLTYPE_UNSIGNED}, + {"signed", LCP_POLTYPE_SIGNED}, + {"any", LCP_POLTYPE_ANY}, + {"forceowner", LCP_POLTYPE_FORCEOWNERPOLICY}, + {NULL, -1} +}; + +/* + * function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + unsigned int temp = 0; + + while ((c = getopt_long_only(argc, (char ** const)argv, + short_option, longopts, NULL)) != -1) + switch (c) { + case 't': + /* check whether user inputs the string for policy type*/ + temp = parse_input_option(poltype_option_table, optarg); + + /* + * if not, then the users should input the 0~4 number, + */ + if ( temp == -1 ) + if ( strtonum(optarg, &temp) ) + return LCP_E_INVALID_PARAMETER; + + if ( temp < 0 || temp > 4 ) { + log_error("policy type out of range.\n"); + return LCP_E_INVALID_PARAMETER; + } + pol_type = temp; + break; + + case 'a': + if ( strcasecmp(optarg, "sha1") == 0 ) + alg = LCP_POLHALG_SHA1; + else if ( strtonum(optarg, &alg) ) + return LCP_E_INVALID_PARAMETER; + if ( alg != LCP_POLHALG_SHA1 ) { + log_error("Policy algorithm not supported!\n"); + return LCP_E_INVALID_PARAMETER; + } + break; + + case 'v': + if ( strtonum(optarg, &temp) ) + return LCP_E_INVALID_PARAMETER; + /* + * Currently we only support version 0. + */ + if ( temp > 0 ) { + log_error("version %d is not supported!\n", ver); + return LCP_E_INVALID_PARAMETER; + } + ver = temp; + break; + + case 's': + srtm_file = optarg; + break; + + case 'm': + mle_file = optarg; + break; + + case 'o': + pol_file = optarg; + break; + + case 'b': + pol_data_file = optarg; + break; + + case 'n': + if ( strtonum(optarg, &temp) ) + return LCP_E_INVALID_PARAMETER; + if ( temp > 0xff || temp < 0 ) + return LCP_E_INVALID_PARAMETER; + sinit_revoc = temp; + break; + + case 'p': + if ( strtonum(optarg, &pcf_val) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +/* read data from file */ +static int +read_data(const char *filename, unsigned int *size, unsigned char *data) +{ + FILE *pfile = NULL; + unsigned int len; + + if ( filename == NULL || data == NULL ) + return -1; + + pfile = fopen(filename, "rb"); + if ( pfile == NULL ) { + //log_error("Can't open MLE/PConf file\n"); + return -1; + } + fseek(pfile, 0, SEEK_END); + len = ftell(pfile); + fseek(pfile, 0, SEEK_SET); + if ( len > BUFFER_SIZE ) { + log_error("the file %s is too long. File size is %d.\n", filename, len); + fclose(pfile); + return -1; + } + fread(data, 1, len, pfile); + *size = len; + fclose(pfile); + return 0; +} + +/* save data to file */ +static int +save_data(unsigned char *data, unsigned int len, const char *file) +{ + FILE *pfile = NULL; + + if ( data == NULL || file == NULL ) + return -1; + + pfile = fopen(file, "wb"); + if ( pfile == NULL ) { + log_error("Open file %s error!\n", file); + return -1; + } + if ( len != fwrite(data, 1, len, pfile) ) { + fclose(pfile); + log_error("Write data into file error!\n"); + return -1; + } + fclose(pfile); + return 0; +} + +static int +convert_hashes(unsigned int mle_len_ascii, + unsigned char *mle_data_ascii, + unsigned int *mle_len, + unsigned char *mle_data) +{ + unsigned long data; + char *curr, *next; + char tmp[3]; + + curr = mle_data_ascii; + *mle_len = 0; + while ( curr < (char *)(mle_data_ascii + mle_len_ascii) ) { + errno = 0; + data = 0; + data = strtoul(curr, &next, 16); + + /* overflow, which means there were no spaces in input */ + if ( errno == ERANGE || (data & ~0xff) != 0 ) { + /* copy 2 chars into separate buffer and convert them */ + tmp[0] = *curr; tmp[1] = *(curr+1); tmp[2] = '\0'; + data = strtoul(tmp, NULL, 16); + next = curr + 2; + } + else if ( errno != 0 ) /* some other error */ + break; + + if ( next == curr ) /* done */ + break; + + mle_data[(*mle_len)++] = (unsigned char)data; + curr = next; + } + + if ( curr < (char *)(mle_data_ascii + mle_len_ascii - 1) ) + return -1; + else + return 0; +} + +/* create policy and policy data */ +static lcp_result_t +create_policy(lcp_policy_t *lcppolicy, + unsigned char *mledata, + unsigned int mlelen, + unsigned char *pconfdata, + unsigned int pconflen, + unsigned char *policy, + unsigned int *policylen, + unsigned char *poldata, + unsigned int *poldatalen) +{ + pdlist_src_t listdata[MAX_LISTNUM]; + unsigned int listnum = 0; + uint32_t poldataver = 0; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + switch (pol_type) { + case LCP_POLTYPE_HASHONLY: + if ( (mledata == NULL) || (mlelen == 0) ) { + log_error("Please use MLE file to input the HASH value!\n"); + return LCP_E_INVALID_PARAMETER; + } + if ( (ret_value = lcp_create_policy(lcppolicy, + mlelen, mledata, policylen, policy)) != LCP_SUCCESS ) { + log_error("create policy error\n"); + return ret_value; + } + break; + + case LCP_POLTYPE_UNSIGNED: + if ( ((mledata == NULL) || (mlelen == 0)) + && ((pconfdata == NULL) || (pconflen == 0)) ) { + log_error("Haven't input MLE file or PConf file.\n"); + return LCP_E_INVALID_PARAMETER; + } + + if ( mlelen != 0 ) { + //print_hexmsg("the mle data is:\n", mlelen, mledata); + listdata[listnum].algorithm = alg; + listdata[listnum].type = LCP_POLDESC_MLE_UNSIGNED; + listdata[listnum].list_version = 0;/*default value*/ + listdata[listnum].listdata_length = mlelen; + listdata[listnum].listdata= mledata; + listnum++; + } + if ( pconflen != 0 ) { + //print_hexmsg("the pconf data is:\n", pconflen, pconfdata); + listdata[listnum].algorithm = alg; + listdata[listnum].type= LCP_POLDESC_PCONF_UNSIGNED; + listdata[listnum].list_version = 0;/*default value*/ + listdata[listnum].listdata_length= pconflen; + listdata[listnum].listdata = pconfdata; + listnum++; + } + if ( (ret_value = lcp_create_unsigned_poldata(poldataver, + listnum, listdata, poldatalen, + poldata)) != LCP_SUCCESS ) { + log_error("create policy data error\n"); + return ret_value; + } + if ( (ret_value = lcp_create_policy(lcppolicy, + *poldatalen, poldata, policylen, + policy)) != LCP_SUCCESS ) { + log_error("create policy error\n"); + return ret_value; + } + break; + + case LCP_POLTYPE_ANY: + if ( (ret_value = lcp_create_policy(lcppolicy, + 0, NULL, policylen, policy)) != LCP_SUCCESS ) { + log_error("create policy error\n"); + return ret_value; + } + break; + + case LCP_POLTYPE_FORCEOWNERPOLICY: + if ( (ret_value = lcp_create_policy(lcppolicy, + 0, NULL, policylen, policy)) != LCP_SUCCESS ) { + log_error("create policy error\n"); + return ret_value; + } + break; + + case LCP_POLTYPE_SIGNED: + default: + log_error("Unsupported Policy type!\n"); + return LCP_E_INVALID_PARAMETER; + } + return LCP_SUCCESS; +} + +static unsigned char policy_data[BUFFER_SIZE]; +static unsigned char policy[BUFFER_SIZE]; +static unsigned char mle_data_ascii[BUFFER_SIZE]; +static unsigned char mle_data[BUFFER_SIZE]; +static unsigned char srtm_data[BUFFER_SIZE]; + +int +main (int argc, char *argv[]) +{ + unsigned int pol_len = BUFFER_SIZE; + unsigned int pol_data_len = BUFFER_SIZE; + unsigned int srtm_len = 0; + unsigned int mle_len = 0, mle_len_ascii = 0; + lcp_policy_t lcppolicy; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Parse the parameters input to decide + * what parameters will be passed to TSS API. + */ + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + if ( pol_type == 0xff ) { + log_error("No Policy type value has been input. "\ + "Must input Policy type value to create Policy Object! \n"); + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + + lcppolicy.version = ver; + lcppolicy.hash_alg = alg; + lcppolicy.policy_type = pol_type; + lcppolicy.sinit_revocation_counter = sinit_revoc; + lcppolicy.reserved[0] = 0; + lcppolicy.reserved[1] = 0; + lcppolicy.reserved[2] = 0; + lcppolicy.policy_control = pcf_val; + + if ( mle_file ) { + /* read ASCII hash data */ + if ( read_data(mle_file, &mle_len_ascii, mle_data_ascii) < 0 ) { + log_error("Can't open mle file.\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + /* ensure that convert_hashes() won't overrun the buffer */ + mle_data_ascii[BUFFER_SIZE] = '\0'; + /* convert ASCII hashes to binary */ + if ( convert_hashes(mle_len_ascii, mle_data_ascii, &mle_len, + mle_data) < 0 ) { + log_error("Can't convert ASCII MLE hashes to binary.\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + } + + if ( srtm_file ) { + if ( read_data(srtm_file, &srtm_len, srtm_data) < 0 ) { + log_error("Can't open PConf file.\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + } + + /* + * Create policy data and policy. + */ + if ( (ret_value = create_policy(&lcppolicy, + mle_data, mle_len, srtm_data, srtm_len, + policy, &pol_len, policy_data, + &pol_data_len)) != LCP_SUCCESS ) { + log_error("Create policy data and policy error!\n"); + goto _error_end; + } + /* + * Write policy into file. + */ + if ( pol_file != NULL ) { + if ( save_data(policy, pol_len, pol_file) < 0 ) { + log_error("Write policy into file error!\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + } else + print_hexmsg("the policy is:\n", pol_len, policy); + + if ( pol_type == LCP_POLTYPE_UNSIGNED ) { + /* + * Write policy data into file. + */ + if ( pol_data_file != NULL ) { + if ( save_data(policy_data, pol_data_len, pol_data_file) < 0 ) { + log_error("Write policy data into file error!\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto _error_end; + } + } else + print_hexmsg("the policy data is:\n", pol_data_len, policy_data); + printf("Successfully create the policy and the policy data\n"); + } else + printf("Successfully create the policy\n"); + + return LCP_SUCCESS; + +_error_end: + /* + * Error when execution. + */ + log_error("\nCommand CrtPol failed:\n"); + print_error(ret_value); + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/defindex.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/defindex.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,371 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * defindex.c + * + * Command: tpmnv_defindex. + * + * This command can define the index in TPM NV Storage. + * + */ + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + + +static uint32_t index_value = 0; +static uint32_t per_value = 0xffff; +static uint32_t data_size = 0; +static char *auth_value = NULL; +static uint32_t auth_length = 0; +static uint8_t r_loc_arg = 0; +static uint8_t w_loc_arg = 0; +static char *password = NULL; +static uint32_t password_len = 0; +static int help_input = 0; + +static const char *short_option = "hi:s:p:"; +static struct option longopts[] = { + {"pv", 1, 0, 'v'}, + {"av", 1, 0, 'a'}, + {"wl", 1, 0, 'w'}, + {"rl", 1, 0, 'r'}, + {0, 0, 0, 0}}; + +static char *usage_string = "tpmnv_defindex -i index [-s size] "\ + "[-pv permission_value] "\ + "[-p passwd] [-av authentication_value] "\ + "[-wl write_locality] [-rl read_locality] [-h]"; + +static const char * option_strings[] = { + "-i index value: uint32/string.\n"\ + "\tINDEX_LCP_DEF:0x50000001 or \"default\",\n"\ + "\tINDEX_LCP_OWN:0x40000001 or \"owner\",\n"\ + "\tINDEX_AUX:0x50000002 or \"aux\"\n", + "-pv permission value: uint32.\n"\ + "\tOptional for indices INDEX_LCP_DEF, INDEX_LCP_OWN, INDEX_AUX.\n"\ + "\tDefault value for indices: INDEX_LCP_DEF:0x00002000;\n"\ + "\tINDEX_LCP_OWN:0x00000002; INDEX_AUX:0x0; Othr:0x0\n", + "-s data size: UNIT32. \n"\ + "\tOptional for indices INDEX_LCP_DEF, INDEX_LCP_OWN and INDEX_AUX.\n"\ + "\tDefault value for indices:\n"\ + "\tINDEX_LCP_DEF and INDEX_LCP_OWN:33; INDEX_AUX:64. Unit is byte\n", + "-av auth value: string. Auth value for defined index.\n", + "-p password: string. \n", + "-rl read locality value: uint8. There are 5 localities:0~4.\n"\ + "\tFor example, locality value is 0x18 if locality 3 or 4. \n", + "-wl write locality value: uint8. The same as read locality value.\n", + "-h help. Will print out this help message.\n", + 0 +}; + +static param_option_t index_option_table[] = { + {"default", INDEX_LCP_DEF}, + {"owner", INDEX_LCP_OWN}, + {"aux", INDEX_AUX}, + {NULL, -1} +}; + +/* + * function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char* argv[]) +{ + int c; + uint32_t temp = 0; + + while ((c = getopt_long_only(argc,(char ** const)argv, + short_option, longopts, NULL)) != -1) + switch (c) { + case 'i': + /* check whether user inputs the string for reserved indices */ + index_value = parse_input_option(index_option_table, optarg); + + /* + * if not, then the users should input the non-0 number, + * 0 is not allowed for index + */ + if ( index_value == -1 ) + if ( strtonum(optarg, &index_value) || (index_value == 0) ) + return LCP_E_INVALID_PARAMETER; + + break; + + case 's': + if ( strtonum(optarg, &data_size) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'p': + password = optarg; + password_len = strlen(password); + break; + + case 'h': + help_input = 1; + break; + + case 'v': + if ( strtonum(optarg, &per_value) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'a': + auth_value = optarg; + auth_length = strlen(auth_value); + break; + + case 'w': + if ( strtonum(optarg, &temp) ) + return LCP_E_INVALID_PARAMETER; + if (temp > 0x1f || temp < 1) + return LCP_E_INVALID_PARAMETER; + w_loc_arg = temp; + break; + + case 'r': + if ( strtonum(optarg, &temp) ) + return LCP_E_INVALID_PARAMETER; + if ( temp > 0x1f || temp < 1 ) + return LCP_E_INVALID_PARAMETER; + r_loc_arg = temp; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +int +main (int argc, char* argv[]) +{ + in_nv_definespace_t in_defspace; + uint32_t per_authwrite = 0; + uint32_t per_authread = 0; + /* + * Currently assume pcr selection size is 3. + */ + uint16_t pcr_size = 3; + /* + * PCR short info size is 2+3+1+20 = 26. + */ + unsigned char rd_pcrcom[26] = {0}; + unsigned char *pdata; + unsigned char wrt_pcrcom[26] = {0}; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Check whether parameter of index value has been input. + */ + if ( index_value == 0 ) { + ret_value = LCP_E_NO_INDEXVALUE; + goto _error_end; + } + in_defspace.index = index_value; + /* + * Check whether parameter of permission value has been input. + */ + if ( per_value == 0xffff ) { + switch (in_defspace.index) { + case INDEX_LCP_DEF: + in_defspace.permission = PERMISSION_DEF; + log_info("Haven't input permission value, "\ + "use default value 0x%lx\n", + in_defspace.permission); + break; + + case INDEX_LCP_OWN: + in_defspace.permission = PERMISSION_OWN; + log_info("Haven't input permission value, "\ + "use default value 0x%lx\n", + in_defspace.permission); + break; + + case INDEX_AUX: + in_defspace.permission = PERMISSION_AUX; + log_info("Haven't input permission value, "\ + "use default value 0x%lx\n", + in_defspace.permission); + break; + + default: + ret_value = LCP_E_NO_PER_VALUE; + goto _error_end; + } + } else + in_defspace.permission = per_value; + + /* + * Check whether parameter of datasize has been input. + */ + if ( data_size == 0 ) { + switch (in_defspace.index) { + case INDEX_LCP_DEF: + in_defspace.size = DATASIZE_POL; + log_info("Haven't input data size, "\ + "use default value %ld\n",\ + in_defspace.size); + break; + + case INDEX_LCP_OWN: + in_defspace.size = DATASIZE_POL; + log_info("Haven't input data size, "\ + "use default value %ld\n",\ + in_defspace.size); + break; + + case INDEX_AUX: + in_defspace.size = DATASIZE_AUX; + log_info("Haven't input data size, "\ + "use default value %ld\n",\ + in_defspace.size); + break; + + default : + ret_value = LCP_E_NO_DATASIZE; + goto _error_end; + } + } else + in_defspace.size = data_size; + + /* + * Check whether authentication value has been input. + */ + if ( auth_value == NULL ) { + /* + * Check the permission value, + * if it needs authorization to read or write, + * the authentication value should be inputted. + */ + per_authwrite = (in_defspace.permission & 0x4) >> 2; + per_authread = (in_defspace.permission & 0x40000) >> 18; + if ( per_authwrite || per_authread ) { + ret_value = LCP_E_NO_AUTH; + goto _error_end; + } + } + + /* + * Check whether read locality value has been input. + * If user hasn't input, set as default value: 0x1f. + */ + if ( r_loc_arg != 0 && r_loc_arg <= 0x1f ) { + in_defspace.r_loc = r_loc_arg; + } else if ( r_loc_arg == 0 ) { + in_defspace.r_loc = LOCALITY_DEFAULT; + } else { + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + + /* + * Check whether write locality value has been input. + * If user hasn't input, set as default value: 0x1f. + */ + if ( w_loc_arg != 0 ) { + in_defspace.w_loc = w_loc_arg; + if ( (in_defspace.index == INDEX_AUX) + && (in_defspace.w_loc != WR_LOCALITY_AUX) ) { + ret_value = LCP_E_INVALID_PARAMETER; + goto _error_end; + } + } else { + if ( in_defspace.index == INDEX_AUX ) + in_defspace.w_loc = WR_LOCALITY_AUX; + else + in_defspace.w_loc = LOCALITY_DEFAULT; + } + + /* build the pcr_short_info for read_pcrcomposite*/ + pdata = rd_pcrcom; + lcp_loaddata_uint16(pcr_size, &pdata, 1); + pdata += pcr_size; + lcp_loaddata_byte((unsigned char)in_defspace.r_loc, &pdata); + + /* build the pcr_short_info for write_pcrcomposite*/ + pdata = wrt_pcrcom; + lcp_loaddata_uint16(pcr_size, &pdata, 1); + pdata += pcr_size; + lcp_loaddata_byte((unsigned char)in_defspace.w_loc, &pdata); + + ret_value = lcp_define_index(&in_defspace, auth_value, auth_length, + password, password_len, rd_pcrcom, wrt_pcrcom); + + if ( ret_value == LCP_SUCCESS ) { + log_info("\nSuccessfully defined index 0x%08lx "\ + "as permission 0x%lx, data size is %ld \n", + in_defspace.index, + in_defspace.permission, in_defspace.size); + return ret_value; + } + +_error_end: + /* + * Error when execute. + */ + log_error("\nCommand DefIndex failed:\n"); + print_error(ret_value); + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/getcap.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/getcap.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,321 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * getcap.c + * + * Command: tpmnv_getcap. + * + * This command can get basic information from TPM like the the PCR number, + * the indices have been defined and the public data associated with the specified index. + * + */ + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +#define BUFFER_SIZE 1024 + +static int32_t index_value = 0; +static int help_input = 0; + +static const char *short_option = "hi:"; +static char *usage_string = "tpmnv_getcap [-i index] [-h]"; + +static const char * option_strings[] ={ + "-i index value: uint32/string. To get the public data of this index.\n"\ + "\tINDEX_LCP_DEF:0x50000001 or \"default\",\n"\ + "\tINDEX_LCP_OWN:0x40000001 or \"owner\",\n"\ + "\tINDEX_AUX:0x50000002 or \"aux\"\n", + "-h help. Will print out this help message.\n", + 0 +}; + +static param_option_t index_option_table[] = { + {"default", INDEX_LCP_DEF}, + {"owner", INDEX_LCP_OWN}, + {"aux", INDEX_AUX}, + {NULL, -1} +}; + +/* + * function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + while (((c = getopt(argc, (char ** const)argv, short_option)) != -1)) + switch (c){ + case 'i': + /* check whether user inputs the string for reserved indices */ + index_value = parse_input_option(index_option_table, optarg); + + /* + * if not, then the users should input the non-0 number, + * 0 is not allowed for index + */ + if ( index_value == -1 ) + if ( strtonum(optarg, &index_value) || (index_value == 0) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +/* print the message return by getcap command */ +static void +print_nv_caps_msg(int datasize, const unsigned char *data, const char *msg) +{ + uint16_t i = 0; + uint32_t ibyte; + for (i = 0; i < datasize; i++) { + if ( (i % 32) == 0 ) { + if ( datasize > 32 ) { + log_info("\n\t"); + } + log_info("%s", msg); + } else if ( (i % 4) == 0 ) { + log_info(" %s", msg); + } + ibyte = *(data + i); + ibyte &= 0x000000ff; + log_info("%02x", ibyte); + } + log_info("\n"); +} + +/* function: get_pubdata + * + * get public data of the index + * public data format is: + * { + * TPM_STRUCTURE_TAG tag; + * TPM_NV_INDEX nvIndex; + * TPM_PCR_INFO_SHORT pcrInfoRead; + * TPM_PCR_INFO_SHORT pcrInfoWrite; + * TPM_NV_ATTRIBUTES permission; + * TPM_BOOL bReadSTClear; + * TPM_BOOL bWriteSTClear; + * TPM_BOOL bWriteDefine; + * UINT32 dataSize; + * } + */ +static lcp_result_t +get_pubdata(uint32_t index) +{ + uint32_t cap_area = TSS_TPMCAP_NV_INDEX; + uint32_t subcaplen = 4; + uint32_t index_retrieve = 0; + uint16_t pcrread_sizeofselect = 0; + uint16_t pcrwrite_sizeofselect = 0; + uint32_t permission; + uint32_t datasize = 0; + unsigned char buffer[BUFFER_SIZE]; + unsigned char *pbuffer; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + ret_value = lcp_get_tpmcap(cap_area, + subcaplen, + (unsigned char *)&index_value, + &datasize, + buffer); + + if ( ret_value != LCP_SUCCESS ) { + return ret_value; + } + if ( datasize != 0 ) { + /* start to parse public data of the index */ + pbuffer = buffer + sizeof(TPM_STRUCTURE_TAG); + /* get the index value */ + lcp_unloaddata_uint32(&index_retrieve, &pbuffer, 1); + + /* + * If the index retrieved correctly, + * print the public data to the screen. + */ + if ( index_retrieve == index_value ) { + log_info("\nThe public data value of index 0x%08lx is: \n", + index_value); + /* print the public data to the screen */ + print_nv_caps_msg(datasize, buffer, ""); + + /* parse pcrInfoRead */ + lcp_unloaddata_uint16(&pcrread_sizeofselect, &pbuffer, 1); + pbuffer += pcrread_sizeofselect; + log_info("\n\tRead locality: "); + print_locality(*pbuffer); + log_info(".\n"); + + /* move the pbuffer to the start of pcrInfoWrite */ + pbuffer += pcrread_sizeofselect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + /* parse pcrInfoWrite */ + lcp_unloaddata_uint16(&pcrwrite_sizeofselect, &pbuffer, 1); + pbuffer += pcrwrite_sizeofselect; + log_info("\n\tWrite locality: "); + print_locality(*pbuffer); + log_info(".\n"); + + /* move the pointer and get permission value */ + pbuffer += pcrwrite_sizeofselect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_STRUCTURE_TAG); + lcp_unloaddata_uint32(&permission, &pbuffer, 1); + log_info("\n\tPermission value is 0x%lx:\n", permission); + print_permissions(permission, "\t\t"); + + /* move the pointer and get data size */ + pbuffer += sizeof(unsigned char) + sizeof(unsigned char) + + sizeof(unsigned char); + lcp_unloaddata_uint32(&datasize, &pbuffer, 1); + log_info("\n\tData size is %ld.\n", datasize); + } else + return LCP_E_NV_AREA_NOT_EXIST; + } else + return LCP_E_NV_AREA_NOT_EXIST; + + return LCP_SUCCESS; +} + +/* get the pcr number and nv index list of the TPM device */ +static lcp_result_t +get_common() +{ + uint32_t subcap = 0; + uint32_t cap_area = 0; + uint32_t subcaplen = 0; + uint16_t tmplen = 0; + unsigned char buffer[BUFFER_SIZE]; + uint32_t datasize = 0; + lcp_result_t result = LCP_E_COMD_INTERNAL_ERR; + + /* + * Get the PCR number. + */ + cap_area = TSS_TPMCAP_PROPERTY; + subcap = TSS_TPMCAP_PROP_PCR; + + subcaplen = 4; + + log_debug("parameter is cap_area = 0x%lx; subcaplen = 0x%lx; " + "subCap = 0x%lx.\n", cap_area, subcaplen, subcap); + result = lcp_get_tpmcap(cap_area, + subcaplen, (unsigned char *)&subcap, &datasize, buffer); + + if ( result != LCP_SUCCESS ) { + log_error("Error get PCR number. \n"); + return result; + } else { + if ( datasize != 4 ) { + log_error("Error get PCR number. \n"); + return LCP_E_GETCAP_REP_ERROR; + } else + log_info("\nPCR number is %d. \n", *((uint32_t *)buffer)); + } + + /* + * Get the NV list. + */ + cap_area = TSS_TPMCAP_NV_LIST; + subcaplen = 0; + + result = lcp_get_tpmcap(cap_area, 0, NULL, &datasize, buffer); + + if ( result != LCP_SUCCESS ) { + log_error("Error get NV index list. \n"); + return result; + } + if ( datasize != 0 ) { + tmplen = datasize/4; + log_info("\n%d indices have been defined\n", tmplen); + log_info("list of indices for defined NV storage areas:\n"); + print_nv_caps_msg(datasize, buffer, "0x"); + } else + log_info("No index has been defined. \n"); + + return LCP_SUCCESS; +} + +int +main (int argc, char *argv[]) +{ + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + if ( index_value != 0 ) { + if ( (ret_value = get_pubdata(index_value)) != LCP_SUCCESS ) + goto _error_end; + } else if ( (ret_value = get_common()) != LCP_SUCCESS ) + goto _error_end; + + return LCP_SUCCESS; + +_error_end: + /* + * Error when execute. + */ + log_error("\nCommand TpmCap failed:\n"); + print_error(ret_value); + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/lcptools.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/lcptools.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,974 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * lcptools.c + * + * This file implements all key functions used by LCP tools commands. + * + */ +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +#define MAX_POLICY_LIST_SIZE 1024 + +/* Define the index + * parameters: + * p_in_defspace: contain the attributes of the index, + * for example, datasize, permission + * auth: password for the index with AUTHREAD/AUTHWRITE + * auth_length: the length of auth password + * passwd: the owner password + * passwd_length: the length of the passwd + * pcr_info_read: the pcr_short_info for pcrInfoRead + * pcr_info_write: the pcr_short_info for pcrInfoWrite + */ +lcp_result_t +lcp_define_index(in_nv_definespace_t *p_in_defspace, + const char *auth, + uint32_t auth_length, + const char *passwd, + uint32_t passwd_length, + const unsigned char *pcr_info_read, + const unsigned char *pcr_info_write) +{ + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HNVSTORE hnvstore = NULL_HNVSTORE; + TSS_HPOLICY hpolobj = NULL_HOBJECT; + TSS_HPCRS hwrtpcrcomp = NULL_HPCRS; + TSS_HPCRS hrdpcrcomp = NULL_HPCRS; + TSS_HPOLICY hpolicy = NULL_HPOLICY; + TSS_HTPM htpm = NULL_HTPM; + + TSS_RESULT result; + + uint16_t pcr_size = 0; + unsigned char *pdata; + unsigned char rd_locality = 0; + unsigned char wrt_locality = 0; + + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + + if ( passwd != NULL ) { + set_tpm_secret(hcontext, &htpm, &hpolicy, passwd, passwd_length); + CHECK_TSS_RETURN_VALUE("set_tpm_secret", result, ret); + } + + /* + * Create TPM NV object + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_NV, + 0,&hnvstore); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", result, ret); + + /* + * if the nv object need authentication + */ + if ( auth != NULL ) { + set_nv_secret(hcontext, hnvstore, &hpolobj, auth, auth_length); + CHECK_TSS_RETURN_VALUE("set_nv_secret", result, ret); + } + + /* + * Set the index to be defined. + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_INDEX, + 0, p_in_defspace->index); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 index", result, ret); + + /* + * Set the permission for the index. + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_PERMISSIONS, + 0, p_in_defspace->permission); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 permission", result, ret); + + /* + * Set the data size to be defined. + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_DATASIZE, + 0, p_in_defspace->size); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 data size", result, ret); + + /* + * Define the space according to the parameters: index, + * permission and datasize. + * If the index is INDEX_AUX, the third parameter of + * Tspi_NV_DefineSpace should be set. + */ + if ( p_in_defspace->index == INDEX_AUX ) { + /* + * Set PCR composite object. + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_PCRS, + 3,&hwrtpcrcomp); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", result, ret); + + /* + * Set LocalityAtRelease inside the PCR composite object. + * Locality Write for INDEX_AUX should be 3 or 4. + */ + result = Tspi_PcrComposite_SetPcrLocality(hwrtpcrcomp, WR_LOCALITY_AUX); + CHECK_TSS_RETURN_VALUE("Tspi_PcrComposite_SetPcrLocality", + result, ret); + + result = Tspi_NV_DefineSpace(hnvstore, 0, hwrtpcrcomp); + } else { + /* + * Set the locality number. + */ + if ( pcr_info_read ) { + /* parse the pcr_info_read which is pcr_short_info format */ + pdata = (unsigned char *)pcr_info_read; + lcp_unloaddata_uint16(&pcr_size, &pdata, 1); + pdata += pcr_size; + lcp_unloaddata_byte(&rd_locality, &pdata); + if ( rd_locality == 0 || rd_locality > 0x1f ) { + log_error("Wrong read locality number!\n"); + ret = LCP_E_TPM_BAD_LOCALITY; + goto exit; + } + /* + * Set PCR composite object. + */ + result = Tspi_Context_CreateObject(hcontext, + TSS_OBJECT_TYPE_PCRS, 3, &hrdpcrcomp); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", + result, ret); + + /* + * Set LocalityAtRelease inside the PCR composite object. + * Locality Write for INDEX_AUX should be 3 or 4. + */ + result = Tspi_PcrComposite_SetPcrLocality(hrdpcrcomp, rd_locality); + CHECK_TSS_RETURN_VALUE("Tspi_PcrComposite_SetPcrLocality", + result, ret); + } + + if ( pcr_info_write != NULL ) { + /* parse the pcr_info_write which is pcr_short_info format */ + pdata = (unsigned char *)pcr_info_write; + lcp_unloaddata_uint16(&pcr_size, &pdata, 1); + pdata += pcr_size; + lcp_unloaddata_byte(&wrt_locality, &pdata); + if ( wrt_locality == 0 || wrt_locality > 0x1f ) { + log_error("Wrong read locality number!\n"); + ret = LCP_E_TPM_BAD_LOCALITY; + goto exit; + } + /* + * Set PCR composite object. + */ + result = Tspi_Context_CreateObject(hcontext, + TSS_OBJECT_TYPE_PCRS, 3, &hwrtpcrcomp); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", + result, ret); + + /* + * Set LocalityAtRelease inside the PCR composite object. + * Locality Write for INDEX_AUX should be 3 or 4. + */ + result = Tspi_PcrComposite_SetPcrLocality(hwrtpcrcomp, + wrt_locality); + CHECK_TSS_RETURN_VALUE("Tspi_PcrComposite_SetPcrLocality", + result, ret); + } + + result = Tspi_NV_DefineSpace(hnvstore, hrdpcrcomp, hwrtpcrcomp); + } + + /* + * Print error massage for Tspi_NV_DefineSpace. + */ + if ( result != TSS_SUCCESS ) { + log_error("Tspi_NV_DefineSpace failed: %s \n", + Trspi_Error_String(result)); + } + ret = convert_error(result); + +exit: + /* + * Close context for the operation. + */ + close_tss_context(hcontext); + + return ret; +} + +/* Release the index + * Parameters: + * index: the index to be release + * passwd: the owner password + * passwd_length: the length of the passwd + */ +lcp_result_t +lcp_release_index(uint32_t index, + const char *passwd, + uint32_t passwd_length) +{ + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HNVSTORE hnvstore = NULL_HNVSTORE; + TSS_HOBJECT hpolobj = NULL_HOBJECT; + TSS_HPOLICY hpolicy = NULL_HPOLICY; + TSS_HTPM htpm = NULL_HTPM; + + TSS_RESULT result; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + + + if ( passwd != NULL ) { + set_tpm_secret(hcontext, &htpm, &hpolicy, passwd, passwd_length); + CHECK_TSS_RETURN_VALUE("set_tpm_secret", result, ret); + } + + /* + * Create TPM NV object + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_NV, + 0,&hnvstore); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", result, ret); + + /* + * Set the index to be released. + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_INDEX, + 0, index); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 for setting NV index", + result, ret); + + /* + * Release the space according to the parameters: index and datasize. + */ + result = Tspi_NV_ReleaseSpace(hnvstore); + + /* + * Print error massage for Tspi_NV_ReleaseSpace. + */ + if ( result != TSS_SUCCESS ) { + log_error("Tspi_NV_ReleaseSpace failed: %s \n", + Trspi_Error_String(result)); + } + ret = convert_error(result); + +exit: + /* + * Close context for the operation. + */ + close_tss_context(hcontext); + + return ret; +} + +/* Read the content from the specified index + * Parameters: + * index: the index to be release + * password: the owner password or the auth password of the index + * passwd_length: the length of the passwd + * read_offset: the offset to read + * read_length: the length to read + * data_length: the length of the data + * data: the data read from the index + */ +lcp_result_t +lcp_read_index(uint32_t index, + const char *password, + uint32_t pass_length, + uint32_t read_offset, + uint32_t read_length, + uint32_t *data_length, + unsigned char *data) +{ + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HNVSTORE hnvstore = NULL_HNVSTORE; + TSS_HTPM htpm = NULL_HOBJECT; + + TSS_RESULT result; + TSS_HPOLICY hnvpol; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + uint32_t retlen; + unsigned char *presult = NULL; + unsigned char *policydata = NULL; + + uint32_t pwd_length = pass_length; + uint32_t read_space = 0; + + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + + /* + * Create TPM NV object + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_NV, + 0,&hnvstore); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject for nv object", + result, ret); + + /* + * Set the index to read + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_INDEX, + 0, index); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 for setting NV index", + result, ret); + + if ( password != NULL ) { + set_nv_secret(hcontext, hnvstore, &hnvpol, password, pwd_length); + CHECK_TSS_RETURN_VALUE("set_nv_secret", result, ret); + } + + /* + * Data length to read. + */ + read_space = read_length; + if ( (read_length == 0)&&(read_offset == 0) ) { + result = Tspi_Context_GetTpmObject(hcontext, &htpm); + CHECK_TSS_RETURN_VALUE("Tspi_Context_GetTpmObject", result, ret); + + result = Tspi_TPM_GetCapability(htpm, + TSS_TPMCAP_NV_INDEX, + 4, (unsigned char *)&index, + &retlen, &presult); + CHECK_TSS_RETURN_VALUE("Tspi_TPM_GetCapability", result, ret); + + presult += retlen - 4; + if ( retlen != 0 ) + lcp_unloaddata_uint32(&read_space, &presult, 1); + else { + ret = LCP_E_TPM_BADINDEX; + goto exit; + } + } + + if ( data == NULL || read_space > *data_length ) { + log_info("Data size to read is %d.\n", read_space); + log_info("Not enought memory allocated for output data! "\ + "Max size allocated is %d.\n", + *data_length); + ret = LCP_E_INVALID_PARAMETER; + goto exit; + } + + /* + * Read policy data from NV store. + */ + log_debug("begin to call the tss Tspi_NV_ReadValue\n"); + result = Tspi_NV_ReadValue(hnvstore, read_offset, &read_space, &policydata); + + /* + * Print error massage. + */ + if ( result != TSS_SUCCESS ) { + ret = convert_error(result); + goto exit; + } + + ret = LCP_SUCCESS; + memcpy(data, policydata, read_space); + *data_length = read_space; + +exit: + close_tss_context(hcontext); + return ret; +} + +/* Write the data into the specified index + * Parameters: + * index: the index to be release + * password: the owner password or the auth password of the index + * passwd_length: the length of the passwd + * write_offset: the offset to write + * length: the length of the data + * data: the data to write + */ +lcp_result_t +lcp_write_index(uint32_t index, + const char *password, + uint32_t passwd_length, + uint32_t write_offset, + uint32_t length, + const unsigned char *data) +{ + + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HNVSTORE hnvstore = NULL_HNVSTORE; + TSS_RESULT result; + TSS_HPOLICY hnvpol; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + uint32_t pwd_length = passwd_length; + + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + + /* + * Create TPM NV object + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_NV, + 0,&hnvstore); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", result, ret); + + /* + * Set the index to write + */ + result = Tspi_SetAttribUint32(hnvstore, TSS_TSPATTRIB_NV_INDEX, + 0, index); + CHECK_TSS_RETURN_VALUE("Tspi_SetAttribUint32 for setting NV index", + result, ret); + + if ( password != NULL ) { + set_nv_secret(hcontext, hnvstore, &hnvpol, password, pwd_length); + CHECK_TSS_RETURN_VALUE("set_nv_secret", result, ret); + } + + /* + * Write data value to the NV store area. + */ + result = Tspi_NV_WriteValue(hnvstore, + write_offset, length, (unsigned char *)data); + + /* + * Print error massage. + */ + if ( result != TSS_SUCCESS ) { + ret = convert_error(result); + goto exit; + } + ret = LCP_SUCCESS; + +exit: + close_tss_context(hcontext); + return ret; +} + +/* create the platform configuration + * parameters: + * num_indices: the count of the pcr_number + * indices: the array of the pcr_numbers + * pcr_len: the length of the pcr_hash_value + * pcr_hash_val: the array of the pcr_values + * locality: the locality value for the pcr_short_info + * datalen: the length of produced pconf data + * data: the produced pconf data + */ +lcp_result_t +lcp_create_pconf(uint32_t num_indices, + uint32_t *indices, + uint32_t pcr_len, + const unsigned char *pcr_hash_val, + unsigned char locality, + uint32_t *datalen, + unsigned char **data) +{ + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HNVSTORE hnvstore = NULL_HNVSTORE; + TSS_HOBJECT hpolobj = NULL_HOBJECT; + TSS_HPCRS hpcrs = NULL_HPCRS; + TSS_HTPM htpm = NULL_HOBJECT; + TPM_PCR_SELECTION pselect; + + TSS_RESULT result = TSS_SUCCESS; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + uint32_t i; + uint32_t idx; + uint16_t bytes_to_hold; + unsigned char *pcrval = NULL; + uint32_t pcrlen; + unsigned char hpcrhash[SHA1_HASH_LEN]; + uint32_t hashlen = SHA1_HASH_LEN; + uint64_t offset = 0; + unsigned char *pdata; + unsigned char *pcr_info = NULL; + uint32_t pcr_info_size = 0; + uint32_t size, index; + unsigned char mask; + unsigned char *pcr_read = NULL; + uint32_t pcr_hash_size = 0; + + if ( (num_indices == 0) || (indices == NULL) ) + return LCP_E_INVALID_PARAMETER; + + /* calculate the sizeofselect for the pconf*/ + ret = calc_sizeofselect(num_indices, indices, &pselect); + if ( ret != LCP_SUCCESS ) + goto free_memory; + + /* decide whether need to read the pcr_value from the TPM */ + if ( pcr_hash_val != NULL ) { + /* use the pcr values from the input */ + if ( pcr_len != num_indices * SHA1_HASH_LEN ) { + log_error("Hash value length is not correct!\n"); + ret = LCP_E_INVALID_PARAMETER; + return ret; + } + + if ( Trspi_Hash(TSS_HASH_SHA1, pcr_len, (unsigned char *)pcr_hash_val, + hpcrhash) != TSS_SUCCESS ) { + log_error("Calculate Hash value for Policy Data error!\n"); + ret = LCP_E_HASH_ERROR; + return ret; + } + } else { + /* get the pcr value from the tpm*/ + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + /* + * Get the TPM object. + */ + result = Tspi_Context_GetTpmObject(hcontext, &htpm); + CHECK_TSS_RETURN_VALUE("Tspi_Context_GetTpmObject", result, ret); + + /* + * Create PCR Composite object + */ + result = Tspi_Context_CreateObject(hcontext, TSS_OBJECT_TYPE_PCRS, + TSS_PCRS_STRUCT_INFO_SHORT,&hpcrs); + CHECK_TSS_RETURN_VALUE("Tspi_Context_CreateObject", result, ret); + + /* malloc the data buffer for the pcr value*/ + pcr_hash_size = num_indices * SHA1_HASH_LEN; + pcr_read = (unsigned char *)malloc(pcr_hash_size); + if ( pcr_read == NULL ) { + log_error("Out of memory!\n"); + ret = LCP_E_OUTOFMEMORY; + return ret; + } + + /* read the pcr value for each pcr_number in the pselect */ + pdata = pcr_read; + for (size = 0; size < pselect.sizeOfSelect; size++) { + for (index = 0, mask = 1; index < 8; index++, mask = mask << 1) { + if ( pselect.pcrSelect[size] & mask ) { + idx = index + (size << 3); + /* + * Read the PCR value. + */ + if ( (result = Tspi_TPM_PcrRead(htpm, idx, &pcrlen, + &pcrval)) != TSS_SUCCESS ) { + log_error("Read PCR value error! PCR Index = %d\n", + idx); + log_error("TSS API returns error.\n"); + ret = LCP_E_TSS_ERROR; + goto exit; + } + /* + * Load the PCR value read from TPM. + */ + lcp_loaddata(SHA1_HASH_LEN, &pdata, pcrval); + } + } + } + + if ( Trspi_Hash(TSS_HASH_SHA1, pcr_hash_size, + pcr_read, hpcrhash) != TSS_SUCCESS ) { + log_error("Calculate Hash value for Policy Data error!\n"); + ret = LCP_E_HASH_ERROR; + return ret; + } + } + /* + * Caculate return length and allocate memory. + */ + pcr_info_size = sizeof(pselect.sizeOfSelect) + + pselect.sizeOfSelect + 1 + hashlen; + if ( (pcr_info = calloc(1, pcr_info_size)) == NULL ) { + log_error("Out of memory!\n"); + ret = LCP_E_OUTOFMEMORY; + goto exit; + } + + /* + *Create the PCR_INFO_SHORT structure. + */ + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, pcr_info, &pselect); + Trspi_LoadBlob_BYTE(&offset, locality, pcr_info); + Trspi_LoadBlob(&offset, hashlen, pcr_info, hpcrhash); + + *data = pcr_info; + *datalen = pcr_info_size; + + /* + * Execute successfully. + */ + log_info("Successfully Created PConf data!\n"); + if ( pcr_read != NULL ) + free(pcr_read); + + return LCP_SUCCESS; +exit: + close_tss_context(hcontext); + +free_memory: + if ( ret != LCP_SUCCESS ) { + if ( pcr_info != NULL ) + free(pcr_info); + } + if ( pselect.pcrSelect != NULL ) + free(pselect.pcrSelect); + if ( pcr_read != NULL ) + free(pcr_read); + return ret; +} + +/* Create the policy list for the policy data + * the list format is : + * { + * uint16_t listtype; + * uint8_t list_version; + * uint8_t listsize; + * union { + * LCP_HASH HashList[listsize]; + * TPM_PCR_INFO_SHORT PCRInfoList[listsize]; + * } + * Parameters: + * src: the input of the data, type, version + * data_length: the length of produced policy list + * data: the produced policy list + * big_endian: create the big or little endian policy list + */ +lcp_result_t +lcp_create_policy_list(pdlist_src_t src, + uint32_t *data_length, + unsigned char *data, + uint8_t big_endian) +{ + uint8_t ver = src.list_version; + uint8_t hashlen = SHA1_HASH_LEN; + uint8_t listsize = 0; + uint32_t read_offset = 0; + unsigned char *pdata = data; + unsigned char *pread_data; + uint16_t select; + uint16_t pcr_length; + uint16_t list_type; + uint32_t len = sizeof(src.type) + sizeof(src.list_version) + + sizeof(listsize) + src.listdata_length; + + lcp_result_t result = LCP_E_COMD_INTERNAL_ERR; + + if ( data == NULL ) { + log_error("Pass in NULL pointer when creating LCP Policy List!\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + if ( *data_length < len ) { + log_error("the data have no enough space\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + switch (src.type) { + case LCP_POLDESC_MLE_UNSIGNED: + list_type = LCP_POLDESC_MLE_UNSIGNED; + /* + * allow the 1 more data length in the file + */ + if ( (src.listdata_length % hashlen > 1) + ||(src.listdata_length / hashlen > 255) ) { + log_error("the policy list data is not correct\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + listsize = src.listdata_length / hashlen; + lcp_loaddata_uint16(list_type, &pdata, big_endian); + + lcp_loaddata_byte(ver, &pdata); + lcp_loaddata_byte(listsize, &pdata); + lcp_loaddata(listsize*hashlen, &pdata, src.listdata); + *data_length = len - (src.listdata_length % hashlen); + + break; + + case LCP_POLDESC_PCONF_UNSIGNED: + list_type = LCP_POLDESC_PCONF_UNSIGNED; + + lcp_loaddata_uint16(list_type, &pdata, big_endian); + lcp_loaddata_byte(ver, &pdata); + pdata += 1; + /* + * we will write the list size value + * after parse data finished, just skip 1 byte now. + * Parse the pconf list first + */ + pread_data = (unsigned char *)src.listdata; + read_offset = 0; + listsize =0; + for ( ; read_offset < src.listdata_length - 1; listsize++) { + /* + * we need to read at least 2 byte to get the sizeof select + */ + lcp_unloaddata_uint16(&select, &pread_data, 1); + log_debug("the select of list [%d] is %d\n", listsize, select); + pcr_length = select + sizeof(select) + + sizeof(TPM_LOCALITY_SELECTION) + SHA1_HASH_LEN; + /* check whether the data input is long enough */ + if ( (pcr_length + (pread_data - src.listdata) -2) + > src.listdata_length ) { + log_error("the policy list data is not correct\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + /* load the data into the policy list */ + lcp_loaddata_uint16(select, &pdata, big_endian); + lcp_loaddata(pcr_length - 2, &pdata, pread_data); + pread_data += pcr_length - 2; + + read_offset = (uint32_t)(pread_data - src.listdata); + /* check whether the data input is too long*/ + if ( (listsize == 255) + && ((src.listdata_length - read_offset) > 1) ){ + log_error("the policy list data is too big\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + } + + /* + * check whether the input is correct, allow 1 more char + */ + if ( src.listdata_length - read_offset > 1 ) { + log_error("the policy list data is not correct\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + /* + * reset the offset value after parsing data finished. + */ + pdata = data + 3; + lcp_loaddata_byte(listsize, &pdata); + + *data_length = len - (src.listdata_length - read_offset); + + break; + + default: + log_error("the policy list type is not supported\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + return LCP_SUCCESS; +} + +/* Create the unsigned lcp policy data in little endian format + * Parameters: + * version: the policy data version + * list_number: the count of the policy list + * listdata: the plicylist array + * data_length: the length of produced policy data + * data: the produced policy data +*/ +lcp_result_t +lcp_create_unsigned_poldata(uint8_t version, + uint8_t list_number, + pdlist_src_t *listdata, + uint32_t *data_length, + unsigned char *data) +{ + unsigned char policylist[MAX_POLICY_LIST_SIZE]; + uint32_t policy_list_len = MAX_POLICY_LIST_SIZE; + uint32_t i = 0; + unsigned char *pdata = data; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + uuid_t uuid = LCP_POLICY_DATA_UUID; + + if ( *data_length < + (sizeof(uuid_t) + sizeof(version) + sizeof(list_number)) ) { + log_error("the policy data buf is not enough\n"); + ret = LCP_E_INVALID_PARAMETER; + return ret; + } + /* begin to produce the header of the policy data */ + lcp_loaddata_uint32(uuid.data1, &pdata, 0); + lcp_loaddata_uint16(uuid.data2, &pdata, 0); + lcp_loaddata_uint16(uuid.data3, &pdata, 0); + lcp_loaddata_uint16(uuid.data4, &pdata, 0); + lcp_loaddata(6, &pdata, uuid.data5); + lcp_loaddata_byte(version, &pdata); + lcp_loaddata_byte(list_number, &pdata); + + for (i = 0; i < list_number; i++ ) { + log_debug("create the policy list %d\n", i); + policy_list_len = MAX_POLICY_LIST_SIZE; + if ( lcp_create_policy_list(*(listdata+i), &policy_list_len, + policylist, 0) ) { + ret = LCP_E_CREATE_POLLIST; + return ret; + } + /* check whether the return buffer is enough */ + if ( ((pdata -data) + policy_list_len) > *data_length ) { + log_error("the policy data buf is not enough\n"); + ret = LCP_E_INVALID_PARAMETER; + return ret; + } + lcp_loaddata(policy_list_len, &pdata, policylist); + } + *data_length = (uint32_t)(pdata -data); + return LCP_SUCCESS; +} + +/* Create the lcp policy in big endian format + * Parameters: + * policy: the input infoes for policy, for example, the version, type... + * length: the length of the policy data or the mle hash value + * policy_dataorhash: the policy data or the mle hash value + * data_length: the length of the produced policy + * data: the length of the produced policy + */ +lcp_result_t +lcp_create_policy(lcp_policy_t *policy, + uint32_t length, + const unsigned char *policy_dataorhash, + uint32_t *data_length, + unsigned char *data) +{ + unsigned char polhash[SHA1_HASH_LEN] = { 0 }; + uint32_t policy_length = DATASIZE_POL; + unsigned char hashval[SHA1_HASH_LEN]; + uint32_t hash_len = SHA1_HASH_LEN; + unsigned char *pdata = data; + lcp_result_t result = LCP_E_COMD_INTERNAL_ERR; + + if ( policy->policy_type == LCP_POLTYPE_SIGNED ) { + log_error("signed policy is not support\n"); + result = LCP_E_INVALID_PARAMETER; + return result; + } + + if ( *data_length < policy_length ) { + log_error("the data buf is not enough\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + + lcp_loaddata_byte(policy->version, &pdata); + lcp_loaddata_byte(policy->hash_alg, &pdata); + lcp_loaddata_byte(policy->policy_type, &pdata); + lcp_loaddata_byte(policy->sinit_revocation_counter, &pdata); + lcp_loaddata_uint32(policy->policy_control, &pdata, 1); + lcp_loaddata_uint16(policy->reserved[0], &pdata, 1); + lcp_loaddata_uint16(policy->reserved[1], &pdata, 1); + lcp_loaddata_uint16(policy->reserved[2], &pdata, 1); + + if ( policy->policy_type == LCP_POLTYPE_UNSIGNED ) { + + if ( Trspi_Hash(TSS_HASH_SHA1, length, + (unsigned char *)policy_dataorhash, + hashval) != TSS_SUCCESS ) { + log_error("Calculate Hash value for Policy Data error!\n"); + result = LCP_E_HASH_ERROR; + return result; + } + lcp_loaddata(hash_len, &pdata, hashval); + } else if ( policy->policy_type == LCP_POLTYPE_HASHONLY ) { + if ( length != (policy_length - (DATASIZE_POL - SHA1_HASH_LEN)) ) { + log_error("the hash length is not correct\n"); + result = LCP_E_COMD_INTERNAL_ERR; + return result; + } + lcp_loaddata(length, &pdata, (unsigned char *)policy_dataorhash); + } else { + lcp_loaddata(SHA1_HASH_LEN, &pdata, polhash); + } + + *data_length = policy_length; + return LCP_SUCCESS; +} + +/* get the tpm capibilities + * Parameters: + * caparea: the capability to get + * subcaplen: the length of the sub capablity value + * subcap: the sub capolibity to get + * outlen: the length of return value + * resp_data: the response data + */ +lcp_result_t +lcp_get_tpmcap(uint32_t caparea, + uint32_t subcaplen, + const unsigned char *subcap, + uint32_t *outlen, + unsigned char *resp_data) +{ + TSS_HCONTEXT hcontext = NULL_HCONTEXT; + TSS_HOBJECT hpolobj = NULL_HOBJECT; + TSS_HPOLICY hpolicy = NULL_HPOLICY; + TSS_HTPM htpm = NULL_HTPM; + + TSS_RESULT result; + uint32_t i = 0; + lcp_result_t ret = LCP_E_COMD_INTERNAL_ERR; + unsigned char *resp; + + result = init_tss_context(&hcontext); + CHECK_TSS_RETURN_VALUE("init_tss_context", result, ret); + + /* + * Get the TPM object. + */ + result = Tspi_Context_GetTpmObject(hcontext, &htpm); + CHECK_TSS_RETURN_VALUE("Tspi_Context_GetTpmObject", result, ret); + + result = Tspi_TPM_GetCapability(htpm, + caparea, subcaplen, (unsigned char *)subcap, + outlen, &resp); + CHECK_TSS_RETURN_VALUE("Tspi_TPM_GetCapability", result, ret); + + log_debug("The response data is:\n" ); + for (i = 0; i < *outlen; i++) { + log_debug("%02x ", resp[i]); + + if ( i%16 == 15 ) + log_debug("\n"); + } + log_debug("\n"); + + memcpy(resp_data, resp, *outlen); + ret = LCP_SUCCESS; + +exit: + close_tss_context(hcontext); + return ret; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/lcptools.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/lcptools.h Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,153 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LCPTOOLS_H__ +#define __LCPTOOLS_H__ + +#define NULL_HCONTEXT 0 +#define NULL_HOBJECT 0 +#define NULL_HNVSTORE 0 +#define NULL_HPCRS NULL_HOBJECT +#define NULL_HPOLICY NULL_HOBJECT +#define NULL_HTPM NULL_HOBJECT + +/* + * Define the return value of the commands. + */ +typedef uint16_t lcp_result_t; + +#define LCP_SUCCESS 0 /* The command execute successful */ +#define LCP_E_INVALID_PARAMETER 1 /* The input parameter not match + the requirement */ +#define LCP_E_NO_INDEXVALUE 2 /* Haven't input index value */ +#define LCP_E_NO_DATASIZE 3 /* Haven't input data size value */ +#define LCP_E_TSS_ERROR 4 /* TSS API revoke failed */ +#define LCP_E_NV_AREA_EXIST 5 /* NV area reference have been defined, + can't be defined again */ +#define LCP_E_TPM_BADINDEX 6 /* Index value is invalid */ +#define LCP_E_TPM_BAD_DATASIZE 7 /* The data size is invalid */ +#define LCP_E_TPM_MAXNVWRITES 8 /* Exceed the max write time of NV */ +#define LCP_E_NO_AUTH 9 /* Haven't input authentication value */ +#define LCP_E_NV_AREA_NOT_EXIST 10 /* NV area reference haven't been + defined before, can't be released */ +#define LCP_E_TPM_AREA_LOCKED 11 /* The NV area is locked + and not writeable */ +#define LCP_E_GETCAP_REP_ERROR 12 /* Get capability returns + incorrect response */ +#define LCP_E_NO_PER_VALUE 13 /* Haven't input permission value */ +#define LCP_E_INVALID_HANDLER 14 /* Invalid handler is returned */ +#define LCP_E_AUTH_CONFLICT 15 /* Authentication method conflict */ +#define LCP_E_AUTH_FAIL 16 /* Authentication failed */ +#define LCP_E_OWNER_SET 17 /* TSS return error */ +#define LCP_E_TPM_WRONGPCRVALUE 18 /* TSS return error */ +#define LCP_E_INVALID_STRUCTURE 19 /* TSS return error */ +#define LCP_E_NOWRITE 20 /* TSS return error */ +#define LCP_E_TPM_BAD_LOCALITY 21 /* TSS return error */ +#define LCP_E_TPM_BAD_PRESENCE 22 /* TSS return error */ +#define LCP_E_TPM_DISABLED_CMD 23 /* TSS return error */ +#define LCP_E_TPM_NOSPACE 24 /* TSS return error */ +#define LCP_E_TPM_NOT_FULLWRITE 25 /* TSS return error */ +#define LCP_E_NO_SUCH_PARAMETER 26 /* Can't find such kind of parameter */ +#define LCP_E_CREATE_POLLIST 27 /* Create Polict List error */ +#define LCP_E_OUTOFMEMORY 28 /* Failed memory assign */ +#define LCP_E_HASH_ERROR 29 /* Failed when hash */ +#define LCP_E_NO_INPUTPARA 30 /* No parameter has been input */ +#define LCP_E_COMD_INTERNAL_ERR 31 /* Other err when run the command */ + +#define SHA1_HASH_LEN 20 +#define SHA256_HASH_LEN 32 + +typedef struct { + uint32_t index; + uint32_t permission; + uint32_t size; + uint8_t r_loc; + uint8_t w_loc; +} in_nv_definespace_t; + +typedef struct { + uint8_t algorithm; + uint8_t list_version; + uint16_t type; + uint32_t listdata_length; + unsigned char *listdata; +} pdlist_src_t; + +lcp_result_t lcp_define_index(in_nv_definespace_t *p_in_defspace, + const char *auth, + uint32_t auth_length, + const char *passwd, + uint32_t passwd_length, + const unsigned char *read_srtm, + const unsigned char *write_srtm); +lcp_result_t lcp_release_index(uint32_t index_value, + const char *passwd, + uint32_t passwd_length); +lcp_result_t lcp_read_index(uint32_t index_value, + const char* password, + uint32_t pass_length, + uint32_t read_offset, + uint32_t read_length, + uint32_t* datalength, + unsigned char* data); +lcp_result_t lcp_write_index(uint32_t index_value, + const char* password, + uint32_t passwd_length, + uint32_t write_offset, + uint32_t fleng, + const unsigned char* policydata); +lcp_result_t lcp_create_pconf(uint32_t num_indices, + uint32_t* indices, + uint32_t pcr_len, + const unsigned char* pcr_hash_val, + unsigned char locality, + uint32_t* dataLen, + unsigned char** srtmdata); +lcp_result_t lcp_create_policy_list(pdlist_src_t policylist_src, + uint32_t* policy_list_length, + unsigned char* policy_list, + uint8_t big_endian); +lcp_result_t lcp_create_unsigned_poldata(uint8_t policydata_version, + uint8_t list_number, + pdlist_src_t * listdata, + uint32_t* data_length, + unsigned char* data); +lcp_result_t lcp_create_policy(lcp_policy_t *policy, + uint32_t length, + const unsigned char* policy_dataorhash, + uint32_t* data_length, + unsigned char* data); +lcp_result_t lcp_get_tpmcap(uint32_t caparea, + uint32_t subcaplen, + const unsigned char *subcap, + uint32_t *outlen, + unsigned char *respdata); + +#endif diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/lcputils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/lcputils.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,594 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * lcputils.c + * + * This file implements all common functions used by the commands + * and key functions. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +static const char *ret_info[] = +{ + NULL, /* 0-LCP_SUCCESS, Each command will has its own success message.*/ + "Incorrect parameter input.", /* 1-LCP_E_INVALID_PARAMETER */ + "Please input the index value", /* 2-LCP_E_NO_INDEXVALUE */ + "Please input the data size to be defined", /* 3-LCP_E_NO_DATASIZE */ + "TSS API failed", /* 4-LCP_E_TSS_ERROR */ + "Index has already been defined.", /* 5-LCP_E_NV_AREA_EXIST */ + "The index is incorrect or wrong "\ + "permission value.", /* 6-LCP_E_TPM_BADINDEX */ + "The size of the data parameter is bad or "\ + "inconsistent with the referenced key.", /* 7-LCP_E_TPM_BAD_DATASIZE */ + "The maximum number of NV writes without an owner has been reached.", + /* 8-LCP_E_TPM_MAXNVWRITES */ + "Please input authentication value.", /* 9-LCP_E_NO_AUTH */ + "Index does not exist.", /* 10-LCP_E_NV_AREA_NOT_EXIST*/ + "TPM_AREA_LOCKED. The index has been locked.", + /* 11-LCP_E_TPM_AREA_LOCKED */ + "Incorrect response when getting capability.", + /* 12-LCP_E_GETCAP_REP_ERROR */ + "Please input the permission value for the index to be defined!", + /* 13-LCP_E_NO_PER_VALUE */ + "Invalid handler is returned.", /* 14-LCP_E_INVALID_HANDLER */ + "Authentication method conflict.", /* 15-LCP_E_AUTH_CONFLICT */ + "Authentication failed. Password or authencation value not match", + /* 16-LCP_E_AUTH_FAIL */ + "TPM owner set error!", /* 17-LCP_E_OWNER_SET */ + "Wrong PCR value!", /* 18-LCP_E_TPM_WRONGPCRVALUE*/ + "Invalid structure!", /* 19-LCP_E_INVALID_STRUCTURE*/ + "TPM No Write error!", /* 20-LCP_E_NOWRITE */ + "Bad locality error!", /* 21-LCP_E_TPM_BAD_LOCALITY */ + "Bad presence error!", /* 22-LCP_E_TPM_BAD_PRESENCE */ + "TPM disabled command error!", /* 23-LCP_E_TPM_DISABLED_CMD */ + "TPM no space error!", /* 24-LCP_E_TPM_NOSPACE */ + "TPM not full write error!", /* 25-LCP_E_TPM_NOT_FULLWRITE*/ + "Incorrect parameter input.", /* 26-LCP_E_NO_SUCH_PARAMETER*/ + "Creat policy_list error", /* 27-LCP_E_CREATE_POLLIST */ + "Failed assign memory!", /* 28-LCP_E_OUTOFMEMORY */ + "Hash failed!", /* 29-LCP_E_HASH_ERROR */ + "Haven't input any parameter, please use -h for help", + /* 30-LCP_E_NO_INPUTPARA */ + "Internal error when executing the command", /* 31-LCP_E_COMD_INTERNAL_ERR*/ + NULL +}; + +/* + * Parse the input param and return the corresponding option value + * If the parameter is not correct, it will return -1 + */ +uint32_t +parse_input_option(param_option_t *table, const char *arg) +{ + param_option_t *p = table; + uint32_t ret_value = -1; + + while (p && p->param){ + if ( strcasecmp(arg, p->param) == 0 ) { + ret_value = p->option; + break; + } + p++; + } + return ret_value; +} + +/* + * Convert the string input into number. + * This function can support both decimalist and hex + */ +int +strtonum(const char *in_para, unsigned int *num_out) +{ + int ret_value = -1; + char* endptr; + uint64_t test_value; + + if( in_para == NULL || num_out == NULL ) + return -1; + + errno = 0; + *num_out = (unsigned int)strtoul(in_para, &endptr, 0); + if ( (*endptr == '\0') && (*in_para != '\0') && (errno == 0) ){ + test_value = (uint64_t)strtoull(in_para, &endptr, 0); + if ( test_value == (uint64_t)(*num_out) ) + ret_value = 0; + } + + return ret_value; +} + +void +print_help(const char *usage_str, const char * option_string[]) +{ + uint16_t i = 0; + if ( usage_str == NULL || option_string == NULL ) + return; + + printf("\nUsage: %s\n", usage_str); + + for (; option_string[i] != 0; i++) + printf("%s", option_string[i]); +} + +void +print_error(lcp_result_t ret_value) +{ + log_error("\t%s\n", ret_info[ret_value]); +} + +/* + * Convert TSS error codes to our defined error codes. + */ +lcp_result_t +convert_error(TSS_RESULT result) +{ + lcp_result_t ret; + switch (result & 0xfff) { + case TSS_SUCCESS: ret = LCP_SUCCESS; break; + case TSS_E_INVALID_HANDLE: ret = LCP_E_INVALID_HANDLER; break; + case TSS_E_NV_AREA_EXIST: ret = LCP_E_NV_AREA_EXIST; break; + case TSS_E_NV_AREA_NOT_EXIST: ret = LCP_E_NV_AREA_NOT_EXIST; break; + case TSS_E_BAD_PARAMETER: ret = LCP_E_INVALID_PARAMETER; break; + case TSS_E_INTERNAL_ERROR: ret = LCP_E_COMD_INTERNAL_ERR; break; + case TPM_E_BADINDEX: ret = LCP_E_TPM_BADINDEX; break; + case TPM_E_AUTH_CONFLICT: ret = LCP_E_AUTH_CONFLICT; break; + case TPM_E_AUTHFAIL: ret = LCP_E_AUTH_FAIL; break; + case TPM_E_OWNER_SET: ret = LCP_E_OWNER_SET; break; + case TPM_E_BAD_DATASIZE: ret = LCP_E_TPM_BAD_DATASIZE; break; + case TPM_E_MAXNVWRITES: ret = LCP_E_TPM_MAXNVWRITES; break; + case TPM_E_INVALID_STRUCTURE: ret = LCP_E_INVALID_STRUCTURE; break; + case TPM_E_PER_NOWRITE: ret = LCP_E_NOWRITE; break; + case TPM_E_AREA_LOCKED: ret = LCP_E_TPM_AREA_LOCKED; break; + case TPM_E_BAD_LOCALITY: ret = LCP_E_TPM_BAD_LOCALITY; break; + case TPM_E_BAD_PRESENCE: ret = LCP_E_TPM_BAD_PRESENCE; break; + case TPM_E_DISABLED_CMD: ret = LCP_E_TPM_DISABLED_CMD; break; + case TPM_E_NOSPACE: ret = LCP_E_TPM_NOSPACE; break; + case TPM_E_NOT_FULLWRITE: ret = LCP_E_TPM_NOT_FULLWRITE; break; + case TPM_E_WRONGPCRVAL: ret = LCP_E_TPM_WRONGPCRVALUE; break; + default: ret = LCP_E_TSS_ERROR; + } + + return ret; +} + +void +print_hexmsg(const char *header_msg, int datalength, const unsigned char *data) +{ + int i; + + log_info("%s", header_msg); + + for (i = 0; i < datalength; i++) { + log_info("%02x ", *(data + i)); + if ( i % 16 == 15 ) + log_info("\n"); + } + + log_info("\n"); +} + +/* split the input string in the format: num1,num2,...,numN + * into the array = {num1, num2, ... , numN} +*/ +int +str_split(const char *str_in, char **str_out, int *number) +{ + char * temp; + int num = 0; + char * sep = ","; + int str_length = 0; + char *string = (char *)malloc(strlen(str_in) + 1); + if ( string == NULL ) + return -1; + if ( str_in == NULL || str_out == NULL || number == NULL ) { + free(string); + return -1; + } + strcpy(string, str_in); + temp =strtok(string, sep); + if ( temp != NULL && str_out[num] ) + strcpy(str_out[num], temp);//strtok(string, sep)); + while (str_out[num] != NULL) { + str_length += strlen(str_out[num]); + num++; + temp = strtok(NULL, sep); + if ( temp != NULL ) + strcpy(str_out[num], temp); + else + str_out[num] = NULL; + } + free(string); + *number = num; + str_length += num - 1; + if ( str_length != strlen(str_in) ) + return -1; + return 0; +} + +uint16_t +lcp_decode_uint16(const unsigned char *in, uint8_t big_endian) +{ + uint16_t temp = 0; + if ( in == NULL ) + return 0; + if ( big_endian ) { + temp = (in[1] & 0xFF); + temp |= (in[0] << 8); + } else { + temp = (in[0] & 0xFF); + temp |= (in[1] << 8); + } + return temp; +} + +void +lcp_uint32toarray(uint32_t i, unsigned char *out, uint8_t big_endian) +{ + if ( out == NULL ) + return; + + if ( big_endian ) { + out[0] = (unsigned char) ((i >> 24) & 0xFF); + out[1] = (unsigned char) ((i >> 16) & 0xFF); + out[2] = (unsigned char) ((i >> 8) & 0xFF); + out[3] = (unsigned char) (i & 0xFF); + } else { + out[3] = (unsigned char) ((i >> 24) & 0xFF); + out[2] = (unsigned char) ((i >> 16) & 0xFF); + out[1] = (unsigned char) ((i >> 8) & 0xFF); + out[0] = (unsigned char) (i & 0xFF); + } +} + +void +lcp_uint16toarray(uint16_t i, unsigned char *out, uint8_t big_endian) +{ + if ( out == NULL ) + return; + + if ( big_endian ) { + out[0] = (unsigned char) ((i >> 8) & 0xFF); + out[1] = (unsigned char) (i & 0xFF); + } else { + out[1] = (unsigned char) ((i >> 8) & 0xFF); + out[0] = (unsigned char) (i & 0xFF); + } +} + +uint32_t +lcp_decode_uint32(const unsigned char *y, uint8_t big_endian) +{ + uint32_t x = 0; + if ( y == NULL ) + return 0; + + if ( big_endian ) { + x = y[0]; + x = ((x << 8) | (y[1] & 0xFF)); + x = ((x << 8) | (y[2] & 0xFF)); + x = ((x << 8) | (y[3] & 0xFF)); + } else { + x = y[3]; + x = ((x << 8) | (y[2] & 0xFF)); + x = ((x << 8) | (y[1] & 0xFF)); + x = ((x << 8) | (y[0] & 0xFF)); + } + + return x; +} + +void +lcp_loaddata_uint32(uint32_t in, unsigned char **blob, uint8_t big_endian) +{ + if ( blob == NULL ) + return; + + if ( *blob != NULL ) + lcp_uint32toarray(in, *blob, big_endian); + *blob += sizeof(in); +} + +void +lcp_loaddata_uint16(uint16_t in, unsigned char **blob, uint8_t big_endian) +{ + if ( blob == NULL ) + return; + + if ( *blob != NULL ) + lcp_uint16toarray(in, *blob, big_endian); + *blob += sizeof(in); +} + +void +lcp_unloaddata_uint32(uint32_t *out, unsigned char **blob, uint8_t big_endian) +{ + if ( blob == NULL || out == NULL ) + return; + + *out = lcp_decode_uint32(*blob, big_endian); + *blob += sizeof(*out); +} + +void +lcp_unloaddata_uint16(uint16_t *out, unsigned char **blob, uint8_t big_endian) +{ + if ( blob == NULL || out == NULL ) + return; + + *out = lcp_decode_uint16(*blob, big_endian); + *blob += sizeof(*out); +} + +void +lcp_loaddata_byte(unsigned char data, unsigned char **blob) +{ + if ( blob == NULL ) + return; + + if ( *blob != NULL ) + **blob = data; + (*blob)++; +} + +void +lcp_unloaddata_byte(unsigned char *dataout, unsigned char **blob) +{ + if ( blob == NULL || dataout == NULL ) + return; + + *dataout = **blob; + (*blob)++; +} + +void +lcp_loaddata(uint32_t size, unsigned char **container, unsigned char *object) +{ + if ( container == NULL || object == NULL ) + return; + + if ( *container ) + memcpy(*container, object, size); + (*container) += size; +} + +void +lcp_unloaddata(uint32_t size, unsigned char **container, unsigned char *object) +{ + if ( *container == NULL || object == NULL ) + return; + + memcpy(object, *container, size); + (*container) += size; +} + +/* init the context in the TSS */ +TSS_RESULT +init_tss_context(TSS_HCONTEXT *hcontext) +{ + TSS_RESULT result; + result = Tspi_Context_Create(hcontext); + if ( (result) != TSS_SUCCESS ) + return result; + + result = Tspi_Context_Connect(*hcontext, NULL); + return result; +} + +/* close the TSS context */ +void +close_tss_context(TSS_HCONTEXT hcontext) +{ + if ( hcontext != NULL_HCONTEXT ) { + Tspi_Context_FreeMemory(hcontext, NULL); + Tspi_Context_Close(hcontext); + } +} + +/* Set the password to the tpm object of the tss context */ +TSS_RESULT +set_tpm_secret(TSS_HCONTEXT hcontext, + TSS_HTPM *htpm, + TSS_HPOLICY *hpolicy, + const char *passwd, + uint32_t passwd_length) +{ + TSS_RESULT result; + /* + * Get TPM object + */ + result = Tspi_Context_GetTpmObject(hcontext, htpm); + if ( result != TSS_SUCCESS ) + return result; + + result = Tspi_GetPolicyObject(*htpm, TSS_POLICY_USAGE, hpolicy); + if ( result != TSS_SUCCESS ) + return result; + + /* + * Set password + */ + result = Tspi_Policy_SetSecret(*hpolicy, TSS_SECRET_MODE_PLAIN, + passwd_length, (unsigned char *)passwd); + return result; +} + +/* Create the NV policy object and assign it to the NV object */ +TSS_RESULT +set_nv_secret(TSS_HCONTEXT hcontext, + TSS_HNVSTORE hnvstore, + TSS_HPOLICY *hpolobj, + const char *auth, + uint32_t auth_len) +{ + TSS_RESULT result; + /* + * Create policy object for the NV object + */ + result = Tspi_Context_CreateObject(hcontext, + TSS_OBJECT_TYPE_POLICY, + TSS_POLICY_USAGE, hpolobj); + if ( result != TSS_SUCCESS ) + return result; + + /* + * Set password + */ + result = Tspi_Policy_SetSecret(*hpolobj, TSS_SECRET_MODE_PLAIN, + auth_len, (unsigned char *)auth); + if ( result != TSS_SUCCESS ) + return result; + + /* + * Set password + */ + result = Tspi_Policy_AssignToObject(*hpolobj, hnvstore); + return result; +} + +/* calculate the size of select for the pcr selection */ +lcp_result_t +calc_sizeofselect(uint32_t num_indices, + uint32_t *indices, + TPM_PCR_SELECTION *pselect) +{ + uint32_t i; + uint32_t idx; + uint16_t bytes_to_hold; + lcp_result_t ret; + + idx = indices[0]; + bytes_to_hold = (idx / 8) + 1; + + log_debug("bytes to hold is %d.\n", bytes_to_hold); + /* + * Create selection index first. + */ + if ( (pselect->pcrSelect = malloc(bytes_to_hold)) == NULL ) { + ret = LCP_E_OUTOFMEMORY; + return ret; + } + pselect->sizeOfSelect = bytes_to_hold; + memset(pselect->pcrSelect, 0, bytes_to_hold); + + /* + * set the bit in the selection structure + */ + pselect->pcrSelect[idx / 8] |= (1 << (idx % 8)); + + for (i = 1; i < num_indices; i++) { + idx = indices[i]; + bytes_to_hold = (idx / 8) + 1; + log_debug("bytes to hold is %d.\n", bytes_to_hold); + log_debug("size of select is %d.\n", pselect->sizeOfSelect); + if ( pselect->sizeOfSelect < bytes_to_hold ) { + if ( (pselect->pcrSelect = realloc(pselect->pcrSelect, bytes_to_hold)) + == NULL ) { + ret = LCP_E_OUTOFMEMORY; + return ret; + } + /* + * set the newly allocated bytes to 0 + */ + memset(&pselect->pcrSelect[pselect->sizeOfSelect], 0, + bytes_to_hold - pselect->sizeOfSelect); + pselect->sizeOfSelect = bytes_to_hold; + + } + pselect->pcrSelect[idx / 8] |= (1 << (idx % 8)); + } + return LCP_SUCCESS; +} + +void print_locality(unsigned char loc) +{ + char s[32] = ""; + + if ( loc & ~0x1f ) + sprintf(s, "unknown (%x)", (unsigned int)loc); + else { + if ( !(loc & 0x1f) ) + strcat(s, "--, "); + if ( loc & TPM_LOC_ZERO ) + strcat(s, "0, "); + if ( loc & TPM_LOC_ONE ) + strcat(s, "1, "); + if ( loc & TPM_LOC_TWO ) + strcat(s, "2, "); + if ( loc & TPM_LOC_THREE ) + strcat(s, "3, "); + if ( loc & TPM_LOC_FOUR ) + strcat(s, "4, "); + /* remove trailing ", " */ + s[strlen(s) - 2] = '\0'; + } + + log_info(s); +} + +void print_permissions(UINT32 perms, const char *prefix) +{ + if ( perms == 0 ) + log_info("%s --\n", prefix); + if ( perms & TPM_NV_PER_READ_STCLEAR ) + log_info("%s TPM_NV_PER_READ_STCLEAR\n", prefix); + if ( perms & TPM_NV_PER_AUTHREAD ) + log_info("%s TPM_NV_PER_AUTHREAD\n", prefix); + if ( perms & TPM_NV_PER_OWNERREAD ) + log_info("%s TPM_NV_PER_OWNERREAD\n", prefix); + if ( perms & TPM_NV_PER_PPREAD ) + log_info("%s TPM_NV_PER_PPREAD\n", prefix); + if ( perms & TPM_NV_PER_GLOBALLOCK ) + log_info("%s TPM_NV_PER_GLOBALLOCK\n", prefix); + if ( perms & TPM_NV_PER_WRITE_STCLEAR ) + log_info("%s TPM_NV_PER_WRITE_STCLEAR\n", prefix); + if ( perms & TPM_NV_PER_WRITEDEFINE ) + log_info("%s TPM_NV_PER_WRITEDEFINE\n", prefix); + if ( perms & TPM_NV_PER_WRITEALL ) + log_info("%s TPM_NV_PER_WRITEALL\n", prefix); + if ( perms & TPM_NV_PER_AUTHWRITE ) + log_info("%s TPM_NV_PER_AUTHWRITE\n", prefix); + if ( perms & TPM_NV_PER_OWNERWRITE ) + log_info("%s TPM_NV_PER_OWNERWRITE\n", prefix); + if ( perms & TPM_NV_PER_PPWRITE ) + log_info("%s TPM_NV_PER_PPWRITE\n", prefix); +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/lcputils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/lcputils.h Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,135 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LCPUTILS_H__ +#define __LCPUTILS_H__ + +/* + * Log message functions + */ +#define log_message(dest, fmt, ...) fprintf(dest, fmt, ## __VA_ARGS__) + +/* + * Error logging + */ +#define log_error(fmt, ...) log_message(stderr, fmt, ##__VA_ARGS__) + +/* + * Info Logging + */ +#define log_info(fmt, ...) log_message(stdout, fmt, ##__VA_ARGS__) + +#ifdef LCP_DEBUG +#define log_debug(fmt, ...) log_message(stdout, fmt, ##__VA_ARGS__) +#else +#define log_debug(fmt, ...) +#endif + +#define CHECK_TSS_RETURN_VALUE(api_name, result, ret) \ + do { if ((result) != TSS_SUCCESS) { \ + log_error("%s failed: %s\n", (api_name), \ + Trspi_Error_String((result))); \ + (ret) = LCP_E_TSS_ERROR; \ + goto exit; \ + } \ + }while (0) + +typedef struct { + char *param; + uint32_t option; +} param_option_t; + +uint32_t parse_input_option(param_option_t *table, const char *arg); +int strtonum(const char *in_para, + unsigned int *num_out); +void print_help(const char *usage_str, + const char *option_string[]); +void print_error(lcp_result_t ret_value); +lcp_result_t convert_error(TSS_RESULT result); + +void print_hexmsg(const char *header_msg, + int datalength, + const unsigned char *data); + +uint16_t lcp_decode_uint16(const unsigned char *in, + uint8_t big_endian); +void lcp_uint32toarray(uint32_t i, + unsigned char *out, + uint8_t big_endian); +void lcp_uint16toarray(uint16_t i, + unsigned char *out, + uint8_t big_endian); +uint32_t lcp_decode_uint32(const unsigned char *y, + uint8_t big_endian); +void lcp_loaddata_uint32(uint32_t in, + unsigned char **blob, + uint8_t big_endian); +void lcp_loaddata_uint16(uint16_t in, + unsigned char **blob, + uint8_t big_endian); +void lcp_unloaddata_uint32(uint32_t * out, + unsigned char **blob, + uint8_t big_endian); +void lcp_unloaddata_uint16(uint16_t *out, + unsigned char **blob, + uint8_t big_endian); +void lcp_loaddata_byte(unsigned char data, + unsigned char **blob); +void lcp_unloaddata_byte(unsigned char *dataout, + unsigned char **blob); +void lcp_loaddata(uint32_t size, + unsigned char **container, + unsigned char *object); +void lcp_unloaddata(uint32_t size, + unsigned char **container, + unsigned char *object); + +TSS_RESULT init_tss_context(TSS_HCONTEXT *hcontext); +void close_tss_context(TSS_HCONTEXT hcontext); +TSS_RESULT set_tpm_secret(TSS_HCONTEXT hcontext, + TSS_HTPM *htpm, + TSS_HPOLICY *hpolicy, + const char *passwd, + uint32_t passwd_length); +TSS_RESULT set_nv_secret(TSS_HCONTEXT hcontext, + TSS_HNVSTORE hnvstore, + TSS_HPOLICY *hpolobj, + const char *auth, + uint32_t auth_len); + +lcp_result_t +calc_sizeofselect(uint32_t num_indices, + uint32_t *indices, + TPM_PCR_SELECTION *pselect); + +void print_locality(unsigned char loc); +void print_permissions(UINT32 perms, const char *prefix); + +#endif diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/lock.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/lock.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,151 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * nvlock.c + * + * Command: tpmnv_lock. + * + * This command can lock the TPM NV Storage. + * + */ + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +static int force = 0; +static int help_input = 0; + +static const char *short_option = "hf"; +static const char *usage_string = "tpmnv_lock [-f] [-h]"; + +static const char * option_strings[] ={ + "-f force to lock.\n", + "-h help. Will print out this help message.\n" + ,0 +}; + +/* function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + while (((c = getopt(argc, (char ** const)argv, short_option)) != -1)) + switch (c){ + case 'f': + force = 1; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +int +main (int argc, char *argv[]) +{ + char confirm_lock[1024] = {0}; + in_nv_definespace_t in_defspace; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if (help_input) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Check whether force to lock. + */ + if ( force == 0 ) { + /* + * If haven't input force to lock, reminder to confirm + * whether lock or not. + */ + do { + log_info("Really want to lock TPM NV? (Y/N) "); + scanf("%s", confirm_lock); + } while (strcmp(confirm_lock, "N") && strcmp(confirm_lock, "n") && + strcmp(confirm_lock, "Y") && strcmp(confirm_lock, "y")); + if ( !strcmp(confirm_lock, "N") || !strcmp(confirm_lock, "n") ) { + ret_value = LCP_SUCCESS; + return ret_value; + } + } + /* + * Set index as TPM_NV_INDEX_LOCK, datasize as 0 to lock TPM NV + */ + in_defspace.index = TPM_NV_INDEX_LOCK; + in_defspace.permission = 0; + in_defspace.size = 0; + + ret_value = lcp_define_index(&in_defspace, + NULL, 0, NULL, 0, NULL, NULL); + + if ( ret_value == LCP_SUCCESS ) { + /* + * Execute successfully. + */ + log_info("Successfully locked TPM NV!\n"); + return ret_value; + } + +_error_end: + /* + * Error when execute. + */ + log_error("\nCommand NvLock failed:\n"); + print_error(ret_value); + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/mlehash.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/mlehash.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,431 @@ +/* + * mhash.c: tool to determine the SHA-1 hash of a Intel(R) TXT MLE + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../include/elf.h" +#include "../../include/txt/txt_defs.h" + +#define SHA1_LENGTH 20 + +static bool verbose = false; + +void log_info(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); + +void log_info(const char *fmt, ...) +{ + va_list ap; + + if ( !verbose ) + return; + vprintf(fmt, ap); +} + + +/* + * is_elf_image + * + * check an image is elf or not? + * + */ +static bool is_elf_image(const void *image, const size_t size) +{ + elf_header_t *elf; + + log_info("checking whether image is an elf image ... "); + if ( image == NULL ) { + log_info(": failed! - Pointer is zero.\n"); + return false; + } + + /* check size */ + if ( sizeof(elf_header_t) > size ) { + log_info(": failed! - Image size is smaller than ELF header size.\n"); + return false; + } + + elf = (elf_header_t *)image; + + /* check magic number for ELF */ + if (( elf->e_ident[EI_MAG0] != ELFMAG0 ) + || ( elf->e_ident[EI_MAG1] != ELFMAG1 ) + || ( elf->e_ident[EI_MAG2] != ELFMAG2 ) + || ( elf->e_ident[EI_MAG3] != ELFMAG3 )) { + log_info(": failed! - ELF magic number is not matched.\n"); + return false; + } + + /* check data encoding in ELF */ + if ( elf->e_ident[EI_DATA] != ELFDATA2LSB ) { + log_info(": failed! - ELF data encoding is not the least significant " + "byte occupying the lowest address.\n"); + return false; + } + + /* check ELF image is executable? */ + if ( elf->e_type != ET_EXEC ) { + log_info(": failed! - ELF image is not executable.\n"); + return false; + } + + /* check ELF image is for IA? */ + if ( elf->e_machine != EM_386 ) { + log_info(": failed! - ELF image is not for IA.\n"); + return false; + } + + /* check ELF version is valid? */ + if ( elf->e_version != EV_CURRENT ) { + log_info(": failed! - ELF version is invalid.\n"); + return false; + } + + if ( sizeof(elf_program_header_t) > elf->e_phentsize ) { + log_info(": failed! - Program size is smaller than program " + "header size.\n"); + return false; + } + + log_info(": succeeded!\n"); + return true; +} + +static bool get_elf_image_range(const elf_header_t *elf, void **start, + void **end) +{ + int i; + unsigned long u_start, u_end; + + if (elf == NULL) { + log_info("Error: ELF header pointer is zero.\n"); + return false; + } + + /* assumed that already passed is_elf_image() check */ + + if ((start == NULL) || (end == NULL)) { + log_info("Error: Output pointers are zero.\n"); + return false; + } + + u_start = 0; + u_end = 0; + for (i = 0; i < elf->e_phnum; i++) { + elf_program_header_t *ph = (elf_program_header_t *) + ((void *)elf + elf->e_phoff + i*elf->e_phentsize); + if (ph->p_type == PT_LOAD) { + if (u_start > ph->p_paddr) + u_start = ph->p_paddr; + if (u_end < ph->p_paddr+ph->p_memsz) + u_end = ph->p_paddr+ph->p_memsz; + } + } + + if (u_start >= u_end) { + *start = NULL; + *end = NULL; + return false; + } + else { + *start = (void *)u_start; + *end = (void *)u_end; + return true; + } +} + +/* + * + * expand entire file into memory + * + */ +static bool expand_elf_image(const elf_header_t *elf, void *base, size_t size) +{ + int i; + + log_info("expanding elf image ... "); + if ( elf == NULL ) { + log_info(": failed! - ELF header pointer is zero.\n"); + return false; + } + + /* assumed that already passed is_elf_image() check */ + + /* load elf image into memory */ + for (i = 0; i < elf->e_phnum; i++) { + elf_program_header_t *ph = (elf_program_header_t *) + ((void *)elf + elf->e_phoff + i*elf->e_phentsize); + + if (ph->p_type == PT_LOAD) { + if ( ph->p_memsz > size ) { + log_info("expanded image exceeded allocated size\n"); + return false; + } + memcpy(base, (void *)elf + ph->p_offset, ph->p_filesz); + memset(base + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); + base += ph->p_memsz; + size -= ph->p_memsz; + } + } + + log_info(": succeeded!.\n"); + return true; +} + +/* + * print_dump + * + * dump the memory + * + */ +#if 0 +static void print_dump(uint32_t s, uint32_t e) +{ + uint32_t i,j; + unsigned char* p; + for ( i = s, j = 0; i < e; i++, j++ ) { + p = (unsigned char*)i; + log_info("%02x ", *p); + if ( j % 20 == 0 ) + log_info("\n"); + } + log_info("\n"); +} +#endif + +/* + * read_file + * + * read file from disk, if compressed, uncompress it + * + */ +static bool read_file(const char *filename, void **buffer, size_t *length) +{ + FILE *fcommand = NULL; + FILE *fdecompressed = NULL; + struct stat filestat = {0}; + char tmpbuffer[1024], command[256]; + unsigned long i; + + *length = 0; + *buffer = NULL; + + /* check the file exists or not */ + log_info("checking whether the file exists or not ... "); + if ( stat(filename, &filestat) ) + goto error; + log_info(": existed!\n"); + + /* try uncompress the file */ + log_info("trying to uncompress the file ... "); + sprintf(command, "zcat %s", filename); + fcommand = popen(command, "r"); + if ( !fcommand ) + goto error; + log_info(": succeeded!\n"); + + log_info("creating a temporary file to uncompress ... "); + fdecompressed = tmpfile(); + if ( !fdecompressed ) + goto error; + log_info(": succeeded!\n"); + + log_info("opening the decompressed file ... "); + while ( !feof(fcommand) ) { + i = fread(tmpbuffer, 1, 1024, fcommand); + *length += i; + fwrite(tmpbuffer, 1, i, fdecompressed); + } + log_info(": succeeded!\n"); + + log_info("testing decompression is ... "); + if ( *length > 0 ) { + log_info(": succeeded!\n"); + /* uncompression succeeded */ + fseek(fdecompressed, 0, SEEK_SET); + } + else { + log_info(": failed!\n"); + log_info("opening the original file as normal ... "); + /* uncompression failed: it isn't a compressed file */ + fdecompressed = fopen(filename, "r"); + if (!fdecompressed) + goto error; + *length = filestat.st_size; + log_info(": succeeded!\n"); + } + fclose(fcommand); + + /* read file into buffer */ + log_info("reading the decompressed file ... "); + *buffer = malloc(*length); + if ( *buffer == NULL ) + goto error; + memset(*buffer, 0, *length); + if ( fread(*buffer, 1, *length, fdecompressed) != *length ) + goto error; + fclose(fdecompressed); + log_info(": succeeded!\n"); + return true; + +error: + log_info(": failed!\n"); + if ( fcommand ) + fclose(fcommand); + if ( fdecompressed ) + fclose(fdecompressed); + return false; +} + +static mle_hdr_t *find_mle_hdr(void *start, size_t size) +{ + static uint32_t mle_hdr_guid[4] = MLE_HDR_GUID; + + while ( size > 0 ) { + if ( memcmp(start, mle_hdr_guid, sizeof(mle_hdr_guid)) == 0 ) + return (mle_hdr_t *)start; + start += sizeof(mle_hdr_guid); + size -= sizeof(mle_hdr_guid); + } + return NULL; +} + +/* + * main + */ +int main(int argc, char* argv[]) +{ + void *elf_start=NULL, *elf_end=NULL; + void *exp_start=NULL; + void *base=NULL; + size_t size, exp_size; + elf_header_t *base_as_elf; + uint8_t hash[SHA1_LENGTH]; + mle_hdr_t *mle_hdr; + int i, c; + static const char *options = "hv"; + bool help = false; + char *mle_file; + extern int optind; /* current index of get_opt() */ + + while ((c = getopt(argc, (char ** const)argv, options)) != -1) { + switch (c) { + case 'h': + help = true; + break; + case 'v': + verbose = true; + break; + } + } + if ( help || (optind == argc) ) { + printf("mhash [-h] [-v] mle_file\n" + "\t-h Help: will print out this help message.\n" + "\t-v Verbose: display progress indications.\n" + "\tmle_file: file name of MLE binary (gzip or not) to hash.\n"); + return 1; + } + mle_file = argv[optind]; + + /* read file */ + if ( !read_file(mle_file, &base, &size) ) + goto error; + + /* expand image */ + if ( !is_elf_image(base, size) ) + goto error; + base_as_elf = (elf_header_t *)base; + + /* get expanded size and allocate memory for it */ + if ( !get_elf_image_range(base_as_elf, &elf_start, &elf_end) ) + goto error; + exp_size = elf_end - elf_start; + exp_start = malloc(exp_size); + if ( exp_start == NULL ) { + log_info("not enough memory for expanded image\n"); + goto error; + } + + /* expand the image */ + if ( !expand_elf_image(base_as_elf, exp_start, exp_size) ) + goto error; + + /* find the MLE header in the expanded image */ + mle_hdr = find_mle_hdr(exp_start, exp_size); + if ( mle_hdr == NULL ) { + log_info("no MLE header found in image\n"); + goto error; + } + + /* SHA-1 the MLE portion of the image */ + SHA1(exp_start + mle_hdr->mle_start_off, + mle_hdr->mle_end_off - mle_hdr->mle_start_off, + (unsigned char *)hash); + log_info("SHA-1 = "); + + /* we always print the hash regardless of verbose mode */ + for ( i = 0; i < SHA1_LENGTH; i++ ) { + printf("%02x", hash[i]); + if ( i < SHA1_LENGTH - 1 ) + printf(" "); + } + printf("\n"); + + free(base); + free(exp_start); + return 0; + +error: + free(base); + free(exp_start); + return 1; +} + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/readpol.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/readpol.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,251 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * readpol.c + * Command: lcp_readpol. + * This command can read LCP policy from TPM NV Storage. + */ +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +#define BUFFER_SIZE 1024 + +static uint32_t index_value = 0; +static char* file = NULL; +static uint32_t size = 0; +static char *password = NULL; +static uint32_t passwd_length = 0; +static int help_input = 0; + +static const char *short_option = "hi:f:s:p:"; +static const char *usage_string = "lcp_readpol -i index_value "\ + "[-s read_size] [-f output_file] [-p passwd] [-h]"; + +static const char *option_strings[] ={ + "-i index value: uint32/string.\n"\ + "\tINDEX_LCP_DEF:0x50000001 or \"default\",\n"\ + "\tINDEX_LCP_OWN:0x40000001 or \"owner\",\n"\ + "\tINDEX_AUX:0x50000002 or \"aux\"\n", + "-f file_name: string. Name of file to store the policy data in. \n", + "-s size to read: uint32. Value size to read from NV store.\n", + "-p password: string. \n", + "-h help. Will print out this help message.\n", + 0 +}; + +static param_option_t index_option_table[] = { + {"default", INDEX_LCP_DEF}, + {"owner", INDEX_LCP_OWN}, + {"aux", INDEX_AUX}, + {NULL, -1} +}; + +/* + * function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + while (((c = getopt(argc, (char ** const)argv, short_option)) != -1)) + switch (c){ + case 'i': + /* check whether user inputs the string for reserved indices */ + index_value = parse_input_option(index_option_table, optarg); + + /* + * if not, then the users should input the non-0 number, + * 0 is not allowed for index + */ + if ( index_value == -1 ) + if ( strtonum(optarg, &index_value) || (index_value == 0) ) + return LCP_E_INVALID_PARAMETER; + + break; + + case 'f': + file = optarg; + break; + + case 'p': + password = optarg; + passwd_length = strlen(password); + break; + + case 's': + if ( strtonum(optarg, &size) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +static void print_hash(lcp_hash_t *hash) +{ + int i; + + for ( i = 0; i < sizeof(hash->sha1)/sizeof(hash->sha1[0]); i++ ) + log_info("%02x ", hash->sha1[i]); + log_info("\n"); +} + +static void print_policy(unsigned char* pol_buf, uint32_t buf_len) +{ + lcp_policy_t pol; + unsigned char *pdata = pol_buf; + static char *pol_types[] = {"LCP_POLTYPE_HASHONLY", "LCP_POLTYPE_UNSIGNED", + "LCP_POLTYPE_SIGNED", "LCP_POLTYPE_ANY", + "LCP_POLTYPE_FORCEOWNERPOLICY"}; + + lcp_unloaddata_byte(&pol.version, &pdata); + lcp_unloaddata_byte(&pol.hash_alg, &pdata); + lcp_unloaddata_byte(&pol.policy_type, &pdata); + lcp_unloaddata_byte(&pol.sinit_revocation_counter, &pdata); + lcp_unloaddata_uint32(&pol.policy_control, &pdata, 1); + lcp_unloaddata_uint16(&pol.reserved[0], &pdata, 1); + lcp_unloaddata_uint16(&pol.reserved[1], &pdata, 1); + lcp_unloaddata_uint16(&pol.reserved[2], &pdata, 1); + lcp_unloaddata(sizeof(pol.policy_hash.sha1), &pdata, + (unsigned char *)&pol.policy_hash); + + log_info("version: %d\n", (int)pol.version); + log_info("hash_alg: %d\n", (int)pol.hash_alg); + log_info("policy_type: %d", (int)pol.policy_type); + if ( pol.policy_type < sizeof(pol_types)/sizeof(pol_types[0]) ) + log_info(" - %s\n", pol_types[pol.policy_type]); + else + log_info(" - unknown\n"); + log_info("sinit_revocation_counter: %d\n", + (int)pol.sinit_revocation_counter); + log_info("policy_control: %x\n", pol.policy_control); + log_info("policy_hash: "); print_hash(&pol.policy_hash); +} + +int +main (int argc, char *argv[]) +{ + FILE *p_file = NULL; + unsigned char policy_data[BUFFER_SIZE]; + uint32_t data_length = BUFFER_SIZE; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto exit; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Check whether parameter of index value has been input. + */ + if ( index_value == 0 ) { + ret_value = LCP_E_NO_INDEXVALUE; + goto exit; + } + + if ( size == 0 ) + log_info("No size has been specified. Will read all index data.\n"); + + /* + * Read NV data from TPM NV store. + */ + ret_value = lcp_read_index(index_value, password, passwd_length, + 0, size, &data_length, policy_data); + + if ( ret_value ) + goto exit; + + + if ( file != NULL ) { + /* + * Write policy data into file. + */ + p_file = fopen(file, "wb"); + if ( !p_file ) { + log_error("Open file %s error!\n", file); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto exit; + } + + if ( data_length != fwrite(policy_data, 1, data_length, p_file) ) { + log_error("Write policy data into file error!\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto exit; + } + } else { + print_hexmsg("the policy is:\n", data_length, policy_data); + print_policy(policy_data, data_length); + } + +exit: + if ( p_file != NULL ) + fclose(p_file); + if ( ret_value != LCP_SUCCESS ) { + log_error("\nCommand ReadPol failed:\n"); + print_error(ret_value); + } else + log_info("Successfully read value from index: 0x%08lx.\n", index_value); + + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/relindex.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/relindex.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,177 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * relindex.c + * + * Command: tpmnv_relindex. + * + * This command can release the index defined in TPM NV Storage. + * + */ + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + + +static uint32_t index_value = 0; +static char *password = NULL; +static uint32_t passwd_length = 0; +static int help_input = 0; + +static const char *short_option = " hi:p:"; +static const char *usage_string = "tpmnv_relindex -i index -p passwd [-h]"; + +static const char * option_strings[] ={ + "-i index value: uint32/string.\n"\ + "\tINDEX_LCP_DEF:0x50000001 or \"default\",\n"\ + "\tINDEX_LCP_OWN:0x40000001 or \"owner\",\n"\ + "\tINDEX_AUX:0x50000002 or \"aux\"\n", + "-p password: string. \n", + "-h help. Will print out this help message.\n", + 0 +}; + +static param_option_t index_option_table[] = { + {"default", INDEX_LCP_DEF}, + {"owner", INDEX_LCP_OWN}, + {"aux", INDEX_AUX}, + {NULL, -1} +}; + + +/* function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + while (((c = getopt(argc,(char ** const)argv, short_option)) != -1)) + switch (c){ + case 'i': + /* check whether user inputs the string for reserved indices */ + index_value = parse_input_option(index_option_table, optarg); + + /* + * if not, then the users should input the non-0 number, + * 0 is not allowed for index + */ + if ( index_value == -1 ) + if ( strtonum(optarg, &index_value) || (index_value == 0) ) + return LCP_E_INVALID_PARAMETER; + break; + + case 'p': + password = optarg; + passwd_length = strlen(password); + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +int +main (int argc, char *argv[]) +{ + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Parse the parameters input to decide + * what parameters will be passed to TSS API. + */ + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto _error_end; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + if ( index_value == 0 ) { + ret_value = LCP_E_NO_INDEXVALUE; + goto _error_end; + } + + if ( password == NULL ) { + ret_value = LCP_E_AUTH_FAIL; + log_error("No password input! ", \ + "Password is needed to release index.\n"); + goto _error_end; + } + + ret_value = lcp_release_index(index_value, password, passwd_length); + + if ( ret_value == LCP_SUCCESS ) { + /* + * Execute successfully. + */ + log_info("Successfully released index 0x%08lx \n", index_value); + return ret_value; + } + +_error_end: + /* + * Error when execute. + */ + log_error("\nCommand RelIndex failed:\n"); + print_error(ret_value); + return ret_value; +} + diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/lcptools/writepol.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/lcptools/writepol.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,233 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name Intel Corporation nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * writepol.c + * Command: lcp_writepol. + * This command can write LCP policy into TPM NV Storage. + */ + +#include +#include +#include +#include +#include + +#include "../../include/txt/lcp.h" +#include "lcptools.h" +#include "lcputils.h" + +static uint32_t index_value = 0; +static char *file_arg=NULL; +static uint32_t fLeng; +static unsigned char *policyData = NULL; +static char *password = NULL; +static uint32_t passwd_length = 0; +static int help_input = 0; + +static const char *short_option = " ehi:f:p:"; +static const char *usage_string = "lcp_writepol -i index_value "\ + "[-f policy_file] [-e] [-p passwd] [-h]"; + +static const char * option_strings[] ={ + "-i index value: uint32/string.\n"\ + "\tINDEX_LCP_DEF:0x50000001 or \"default\",\n"\ + "\tINDEX_LCP_OWN:0x40000001 or \"owner\",\n"\ + "\tINDEX_AUX:0x50000002 or \"aux\"\n", + "-f file_name: string. File name of the policy data is stored. \n", + "-p password: string. \n", + "-e write 0 length data to the index.\n"\ + "\tIt will be used for some special index.\n"\ + "\tFor example, the index with permission WRITEDEFINE.\n", + "-h help. Will print out this help message.\n", + 0 +}; + +static param_option_t index_option_table[] = { + {"default", INDEX_LCP_DEF}, + {"owner", INDEX_LCP_OWN}, + {"aux", INDEX_AUX}, + {NULL, -1} +}; + +/* + * function: parse_cmdline + * description: parse the input of commandline + */ +static int +parse_cmdline(int argc, const char * argv[]) +{ + int c; + while (((c = getopt(argc, (char ** const)argv, short_option)) != -1)) + switch (c){ + case 'i': + /* check whether user inputs the string for reserved indices */ + index_value = parse_input_option(index_option_table, optarg); + + /* + * if not, then the users should input the non-0 number, + * 0 is not allowed for index + */ + if ( index_value == -1 ) + if ( strtonum(optarg, &index_value) || (index_value == 0) ) + return LCP_E_INVALID_PARAMETER; + + break; + + case 'f': + file_arg = optarg; + break; + + case 'p': + password = optarg; + passwd_length = strlen(password); + break; + + case 'e': + policyData = ""; + fLeng = 0; + break; + + case 'h': + help_input = 1; + break; + + default: + return LCP_E_NO_SUCH_PARAMETER; + } + if ( optind < argc ) + return LCP_E_INVALID_PARAMETER; + + return LCP_SUCCESS; +} + +int +main (int argc, char *argv[]) +{ + char *file = NULL; + FILE *p_file = NULL; + + TSS_RESULT result = TSS_E_FAIL; + lcp_result_t ret_value = LCP_E_COMD_INTERNAL_ERR; + + /* + * No parameter input will print out the help message. + */ + if ( argc == 1 ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + /* + * Parse the parameters input to decide + * what parameters will be passed to TSS API. + */ + ret_value = parse_cmdline(argc, (const char **)argv); + if ( ret_value ) + goto exit; + + /* + * If user input -h(help), just print guide to + * users and ignore other parameters. + */ + if ( help_input ) { + print_help(usage_string, option_strings); + return LCP_SUCCESS; + } + + if ( index_value == 0 ) { + ret_value = LCP_E_NO_INDEXVALUE; + goto exit; + } + + if ( file_arg && (policyData == NULL) ) + file = file_arg; + else if ( file_arg && !strcmp(policyData, "") ) { + log_error("Cannot use '-f' and '-e' option at the same time!\n"); + ret_value = LCP_E_INVALID_PARAMETER; + goto exit; + } + + if ( (file_arg == NULL) && (policyData == NULL) ) { + log_error("Must specify policy file name or use -e option! \n"); + ret_value = LCP_E_INVALID_PARAMETER; + goto exit; + } + + if ( policyData == NULL ) { + p_file = fopen(file, "rb"); + if ( !p_file ) { + log_error("Open file %s error!\n", file); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto exit; + } + /* + * Get length of file. + */ + fseek(p_file, 0, SEEK_END); + fLeng = ftell(p_file); + fseek(p_file, 0, SEEK_SET); + + policyData = (unsigned char *)malloc(fLeng); + if ( !policyData ) { + log_error("Memory alloc error!\n"); + ret_value = LCP_E_OUTOFMEMORY; + goto exit; + } + + /* + * Read policy data from file. + */ + if ( fLeng != fread(policyData, 1, fLeng, p_file) ) { + log_error("Read policy data from file error!\n"); + ret_value = LCP_E_COMD_INTERNAL_ERR; + goto exit; + } + } + + ret_value = lcp_write_index(index_value, + password, passwd_length, 0, fLeng, policyData); + +exit: + if ( ret_value != LCP_SUCCESS ) { + log_error("\nCommand WritePol failed:\n"); + print_error(ret_value); + } else { + log_info("\nSuccessfully write policy into index 0x%08lx \n", + index_value); + } + + if ( (policyData != NULL) && (strcmp(policyData, "")) ) + free(policyData); + if ( p_file != NULL ) + fclose(p_file); + + return ret_value; +} diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/trousers/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/trousers/Makefile Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,50 @@ +XEN_ROOT = ../../../ + +# Base definitions and rules +include $(XEN_ROOT)/sboot/tools/Rules.mk + +TARGET_DIR = trousers +TARGET = $(TARGET_DIR)/src/tcsd/tcsd +TARGET_TGZ = trousers.tar.gz + +TROUSERS_HEADER_DIR = /usr/local/include/tss/ + +# +# rules +# + +.PHONY: all +all: build + +.PHONY: build +build: $(TARGET_DIR) $(TARGET) + +.PHONY: install +install: build + +.PHONY: clean +clean: + $(MAKE) -C $(TARGET_DIR) clean + rm -f $(TARGET) + +.PHONY: mrproper +mrproper: clean + rm -rf $(TARGET_DIR) *~ + +# +# dependencies +# + +$(TARGET_DIR): $(TARGET_TGZ) + @echo Extracting $^ ... $@ + tar -xzf $^ + +$(TARGET): $(TARGET_DIR)/Makefile + $(MAKE) -C $(TARGET_DIR) install + $(INSTALL_DATA) $(TARGET_DIR)/src/include/tss/tcs_defines.h $(TROUSERS_HEADER_DIR) + +$(TARGET_DIR)/Makefile: $(TARGET_DIR)/configure + cd $(TARGET_DIR) && ./configure + +$(TARGET_DIR)/configure: + cd $(TARGET_DIR) && sh bootstrap.sh diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/txt-test/build32 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/txt-test/build32 Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,1 @@ +make -C ../../../build-linux-2.6.18-xen_x86_32/ M=`pwd` modules diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/txt-test/build64 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/txt-test/build64 Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,1 @@ +make -C ../../../build-linux-2.6.18-xen_x86_64/ M=`pwd` modules diff -r 5648dc802679 -r 2a74acaf6f11 sboot/tools/txt-test/txt-test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/tools/txt-test/txt-test.c Tue Aug 28 16:40:55 2007 -0700 @@ -0,0 +1,378 @@ +/* + * txt-test: Linux kernel module that will display various information about + * the status of TXT. It also indicates whether the various TXT + * memory regions are protected from access by the kernel. + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../sboot/include/txt/config_regs.h" +#include "../../sboot/include/tpm.h" +#include "../../sboot/include/uuid.h" +#include "../../sboot/include/sboot.h" + +/* device name for Intel(r) TXT device we create */ +#define DEVICE_NAME "txt" + +static struct file_operations fops; +static int dev_major; + +#define SBOOT_MEM_BASE (0x70000 - 3*PAGE_SIZE) + /* 0x90000 is Xen's start of trampoline code */ +#define SBOOT_MEM_SIZE (0x90000 - SBOOT_MEM_BASE) + +#define TXT_CONFIG_REGS_SIZE (NR_TXT_CONFIG_PAGES*PAGE_SIZE) +#define TPM_LOCALITY_SIZE (NR_TPM_LOCALITY_PAGES*PAGE_SIZE) + +#define TPM_REG_ACCESS 0x00000000 + +static inline uint64_t read_txt_config_reg(void *config_regs_base, + uint32_t reg) +{ + /* these are MMIO so make sure compiler doesn't optimize */ + return *(volatile uint64_t *)(config_regs_base + reg); +} + +static void display_config_regs(void *txt_config_base) +{ + printk("Intel(r) TXT Configuration Registers:\n"); + + /* STS */ + printk("\tSTS: 0x%Lx\n", read_txt_config_reg(txt_config_base, TXTCR_STS)); + + /* ESTS */ + printk("\tESTS: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_ESTS)); + + /* E2STS */ + printk("\tE2STS: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_E2STS)); + + /* ERRORCODE */ + printk("\tERRORCODE: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_ERRORCODE)); + + /* DIDVID */ + printk("\tDIDVID: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_DIDVID)); + + /* SINIT.BASE/SIZE */ + printk("\tSINIT.BASE: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_SINIT_BASE)); + printk("\tSINIT.SIZE: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_SINIT_SIZE)); + + /* HEAP.BASE/SIZE */ + printk("\tHEAP.BASE: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_HEAP_BASE)); + printk("\tHEAP.SIZE: 0x%Lx\n", read_txt_config_reg(txt_config_base, + TXTCR_HEAP_SIZE)); +} + +static void display_sb_log(void *txt_config_base) +{ + void *sb_base, *curr; + sb_log_t *log; + static const uuid_t log_uuid = SB_LOG_UUID; + static char buf[512]; + int curr_pos; + + /* need to map SBOOT's memory before we can search for log */ + sb_base = (void *)ioremap_nocache(SBOOT_MEM_BASE, SBOOT_MEM_SIZE); + + if ( sb_base == NULL ) { + printk(KERN_ALERT + "ERROR: unable to map SBOOT to find log\n"); + return; + } + + curr = sb_base; + do { + if ( are_uuids_equal(curr, &log_uuid) ) + break; + curr++; + } while ( curr < sb_base + SBOOT_MEM_SIZE ); + + if ( curr >= sb_base + SBOOT_MEM_SIZE ) { + printk("unable to find SBOOT log\n"); + return; + } + log = (sb_log_t *)curr; + + printk("SBOOT log:\n"); + printk("\t max_size=%x\n", log->max_size); + printk("\t curr_pos=%x\n", log->curr_pos); + printk("\t buf:\n"); + /* log is too big for single printk(), so break it up */ + for ( curr_pos = 0; curr_pos < log->curr_pos; curr_pos += sizeof(buf)-1 ) { + strncpy(buf, log->buf + curr_pos, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + printk(buf); + } + printk("\n"); + + iounmap(sb_base); +} + +static bool test_access_txt_priv_config(void) +{ + void *ptr = NULL; + + printk("testing for access to TXT private config space...\n"); + + /* try to get pointer to TXT private config space */ + ptr = (void *)ioremap_nocache(TXT_PRIV_CONFIG_REGS_BASE, + TXT_CONFIG_REGS_SIZE); + if ( ptr == NULL ) + printk(KERN_ALERT "ERROR: ioremap_nocache for private space failed\n"); + else { + printk(KERN_ALERT "ioremap_nocache for private space succeeded\n"); + iounmap(ptr); + } + return (ptr == NULL); +#if 0 + /* try using hypercall */ + { + struct xen_domctl domctl = { 0 }; + privcmd_hypercall_t hypercall = { 0 }; + int ret = -1; + + domctl.cmd = XEN_DOMCTL_iomem_permission; + domctl.domain = DOMID_DOM0; + domctl.u.iomem_permission.first_mfn = 0xfed20; + domctl.u.iomem_permission.nr_mfns = 0x10; + domctl.u.iomem_permission.allow_access = 1; + domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_domctl; + hypercall.arg[0] = (unsigned long)domctl; + + ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, + (unsigned long)hypercall); + if ( ret < 0 ) + printk(KERN_ALERT "\nERROR: failed to set iomem permissions\n"); + else { + if ((PrivatePtr = (void *)ioremap_nocache(0xFED20000, 0x1000)) == NULL) + printk(KERN_ALERT "\nERROR: ioremap_nocache for private space failed\n\n"); + else { + printk(KERN_ALERT "ioremap_nocache for private space succeeded\n"); + iounmap(PrivatePtr); + } + } + } +#endif +} + +static bool test_access_tpm_localities(void) +{ + int locality; + void *base, *ptr=NULL; + int access; + + printk("testing for access to TPM localities " + "(ff = locality unavailable):\n"); + + for ( locality = 0; locality < TPM_NR_LOCALITIES; locality++ ) { + base = (void *)(unsigned long)TPM_LOCALITY_BASE_N(locality); + ptr = (void *)ioremap_nocache((unsigned long)base, TPM_LOCALITY_SIZE); + if ( ptr == NULL ) { + printk(KERN_ALERT + "ERROR: ioremap_nocache for TPM locality %d failed\n", + locality); + return false; + } + + access = readb(ptr + TPM_REG_ACCESS); + printk(KERN_ALERT "TPM: Locality %d access = %x\n", locality, access); + + iounmap(ptr); + } + + return true; +} + +static bool test_access_txt_heap(void *txt_config_base) +{ + void *ptr; + uint64_t base, size; + + printk("testing for access to SINIT and TXT heap memory...\n"); + + /* SINIT */ + base = read_txt_config_reg(txt_config_base, TXTCR_SINIT_BASE); + size = read_txt_config_reg(txt_config_base, TXTCR_SINIT_SIZE); + ptr = (void *)ioremap_nocache(base, size); + if ( ptr == NULL ) { + printk(KERN_ALERT + "ERROR: ioremap_nocache for SINIT failed\n"); + } + else { + printk(KERN_ALERT "ioremap_nocache for SINIT succeeded\n"); + iounmap(ptr); + return false; + } + + /* TXT heap */ + base = read_txt_config_reg(txt_config_base, TXTCR_HEAP_BASE); + size = read_txt_config_reg(txt_config_base, TXTCR_HEAP_SIZE); + ptr = (void *)ioremap_nocache(base, size); + if ( ptr == NULL ) { + printk(KERN_ALERT + "ERROR: ioremap_nocache for TXT heap failed\n"); + return true; + } + else { + printk(KERN_ALERT "ioremap_nocache for TXT heap succeeded\n"); + iounmap(ptr); + return false; + } +} + +static bool test_access_sboot(void) +{ + void *ptr; + + printk("testing for access to sboot memory...\n"); + + ptr = (void *)ioremap_nocache(SBOOT_MEM_BASE, SBOOT_MEM_SIZE); + if ( ptr == NULL ) { + printk(KERN_ALERT + "ERROR: ioremap_nocache for sboot failed\n"); + return true; + } + else { + printk(KERN_ALERT "ioremap_nocache for sboot succeeded\n"); + iounmap(ptr); + return false; + } +} + +static bool is_txt_supported(void) +{ + return true; +} + +static __init int mod_init(void) +{ + void *txt_pub = NULL; + + if ( !is_txt_supported() ) { + printk(KERN_ALERT "Intel(r) TXT is not supported\n"); + return 0; + } + + /* make sure no one else has grabbed the public config space */ + if ( check_mem_region(TXT_PUB_CONFIG_REGS_BASE, TXT_CONFIG_REGS_SIZE) ) { + printk(KERN_ALERT + "ERROR: TXT public config space is already reserved\n"); + return -EBUSY; + } + + /* register a TXT device (let kernel pick major #) */ + dev_major = register_chrdev(0, DEVICE_NAME, &fops); + if ( dev_major < 0 ) { + printk (KERN_ALERT "ERROR: failed to create TXT device (%d)\n", + dev_major); + return 0; + } + + /* + * display config regs + */ + if ( request_mem_region((unsigned long)TXT_PUB_CONFIG_REGS_BASE, + TXT_CONFIG_REGS_SIZE, DEVICE_NAME) == 0 ) { + printk(KERN_ALERT + "ERROR: request_mem_region for public space failed\n"); + goto done; + } + txt_pub = (void *)ioremap_nocache(TXT_PUB_CONFIG_REGS_BASE, + TXT_CONFIG_REGS_SIZE); + if ( txt_pub == NULL ) { + printk(KERN_ALERT "ERROR: ioremap_nocache for public space failed\n"); + goto done; + } + display_config_regs(txt_pub); + + /* + * display the SBOOT log + */ + display_sb_log(txt_pub); + + /* + * begin tests + */ + test_access_txt_priv_config(); + + test_access_tpm_localities(); + + test_access_txt_heap(txt_pub); + + test_access_sboot(); + + done: + if ( txt_pub != NULL ) + iounmap(txt_pub); + release_mem_region(TXT_PUB_CONFIG_REGS_BASE, TXT_CONFIG_REGS_SIZE); + unregister_chrdev(dev_major, DEVICE_NAME); + return 0; +} + +static __exit void mod_exit(void) +{ + printk("txt-test module unloading\n"); +} + +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("BSD"); + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */